Published on

Docker 容器虚拟化平台:核心技术、架构与使用实践详解

Authors
  • avatar
    Name
    Liant
    Twitter

Docker 容器虚拟化平台

1.Docker 概述

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙盒机制,相互之间不会有任何接口(类似 iPhone 的 app)。几乎没有性能开销,可以很容易地在机器和数据中心中运行。最重要的是,他们不依赖于任何语言、框架或包装系统。

1.1 扩展

1.1.1 扩展:沙盒

沙盒也叫沙箱,英文sandbox。在计算机领域指一种虚拟技术,且多用于计算机安全技术。安全软件可以先让它在沙盒中运行,如果含有恶意行为,则禁止程序的进一步运行,而这不会对系统造成任何危害。

docker 的创新:docker 镜像一次构建,到处都可以运行。

Docker 是 dotCloud 公司开源的一个基于 LXC 的高级容器引擎,源代码托管在 Github 上, 基于 go 语言幵遵从 Apache2.0 协议开源。

Docker 让开发者可以打包他们的应用以及依赖包到一个可移植的 container 中,然后发布到任何流行的 Linux 机器上。

1.1.2 扩展:LXC

LXC 为 Linux Container 的简写。Linux Container 容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性。

LXC 主要通过来自 kernel 的 namespace 实现每个用户实例之间的相互隔离,通过 cgroup 实现对资源的配额和度量。

官方网站: https://www.docker.com/

official-website.png
logo.png

docker 服务相当于鲸鱼,container 容器就是集装箱。

container :集装箱,容器 docker: 码头工人 docker 源代码:https://github.com/moby/moby

1.1.4 docker 容器技术和虚拟机对比:

相同点: docker 容器技术和虚拟机技术,都是虚拟化技术。

docker-vs-vms.png

总结:docker 相对于 VM 虚拟机,少了虚拟机操作系统这一层,所以 docker 效率比虚拟机高 物理系统启劢使用10 秒以上在 docker 上启劢一个实例 1-2 秒

2.Docker 架构

framework.png

工作流程:服务器 A 上运行 docker Engine 服务,在 docker Engine 上启动很多容器 container ,从外网 Docker Hub 上把 image 操作系统镜像下载来,放到 container 容器运行。这样一个容器的实例就运行起来了。最后,通过 Docker client 对 docker 容器虚拟化平台进行控制。 dockerhub:dockerhub 是 docker 官方的镜像存储站点,其中提供了很多常用的镜像供用户下载, 如 ubuntu, centos 等系统镜像。通过 dockerhub 用户也可以发布自己的 docker 镜像,为此用户需要 注册一个账号,在网站上创建一个 docker 仓库。

3.Docker 核心技术

1.Namespace — 实现 Container 的进程、网络、消息、文件系统和主机名的隔离。

2.Cgroup — 实现对资源的配额和度量。注:Cgroup 的配额,可以指定实例使用的 cpu 个数,内存大小等。就像如下图,vmware 虚拟机中的硬件配置参数。

hardware.png

4.Docker 特性

文件系统隔离:每个进程容器运行在一个完全独立的根文件系统里。

资源隔离:系统资源,像 CPU 和内存等可以分配到不同的容器中,使用 cgroup。

网络隔离:每个进程容器运行在自己的网络空间,虚拟接口和 IP 地址。

日志记录:Docker 将会收集和记录每个进程容器的标准流(stdout/stderr/stdin),用于实时检索或批量检索。

变更管理:容器文件系统的变更可以提交到新的镜像中,并可重复使用以创建更多的容器。无需使用模板或手动配置。

交互式 shell:Docker 可以分配一个虚拟终端并关联到任何容器的标准输入上,例如运行一个一次性交互 shell。

优点:

1.一些优势和 VM 一样,但不是所有都一样。比 VM 小,比 VM 快,Docker 容器的尺寸减小相比整个虚拟机大大简化了分布到云和从云分发时间和开销。Docker 启劢一个容器实例时间很短,一两秒就可以启动一个实例。

2.对于在笔记本电脑,数据中心的虚拟机,以及任何的云上,运行相同的没有变化的应用程序,IT 的发布速度更快。Docker 是一个开放的平台,构建,发布和运行分布式应用程序。Docker 使应用程序能够快速从组件组装和避免开发和生产环境之间的摩擦。

3.您可以在部署在公司局域网或云或虚拟机上使用它。

4.开发人员并不关心具体哪个 Linux 操作系统使用 Docker,开发人员可以根据所有依赖关系构建相应的软件,针对他们所选择的操作系统。然后,在部署时一切是完全一样的,因为一切都在 DockerImage 的容器在其上运行。开发人员负责幵且能够确保所有的相关性得到满足。

5.Google,微软,亚马逊,IBM 等都支持 Docker。

6.Docker 支持 Unix/Linux 操作系统,也支持 Windows 或 Mac

缺点局限性:

1.Docker 用于应用程序时是最有用的,但并不包含数据。日志,跟踪和数据库等通常应放在 Docker容器外。一个容器的镜像通常都很小,不适合存大量数据,存储可以通过外部挂载的方式使用。比如使用:NFS,ipsan,MFS 等, -v 映射磁盘分区

一句话:docker 只用于计算,存储交给别人。如oracle 不适合使用 docker 来运行,太大了,存储的数据太多。

5.Docker 版本简单介绍

Docker 最早的版本名是 docker 和 docker-engine,现在名字是 docker-ce 和 docker-ee。

如下图官方网站上有明确说明:https://docs.docker.com/install/linux/docker-ce/centos/2017 年年初,docker 公司将原先的 docker 开源项目改名为 moby。

moby 是继承了原先的 docker 的项目,是社区维护的的开源项目,谁都可以在 moby 的基础打造自己的容器产品docker-ce 是 docker 公司维护的开源项目,是一个基于 moby 项目的免费的容器产品docker-ee 是 docker 公司维护的闭源产品,是 docker 公司的商业产品。

注:moby 是源代码 ; docker-ce 和 docker-ee 是容器产品,是 rpm 包。 所以,现在我们经常使用到的版本就是 docker-ce 版本了。

6.Docker部署及Docker镜像加速

yum install -y yum-utils device-mapper-persistent-data lvm2

yum-config-manager --add-repo

http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

yum install docker-ce docker-ce-cli containerd.io -y

systemctl start docker && systemctl enable docker

docker version #显示 Docker 版本信息

docker info #查看 docker 信息(确认服务运行)显示 Docker 系统 信息,包括镜像和容器数。

command.png

7.下载docker镜像

download.png

docker search centos

search-command.png

方法1:从公网 docker hub 拉取(下载)image docker pull centos 方法

方法2:使用阿里云 docker 镜像加速器,提升 pull 的速度:

你叧需要登弽容器 Hub 服务 https://cr.console.aliyun.com 的控制台,使用你的阿里云帐号,第一次登弽时,需要设置一个独立的密码,左侧的加速器帮劣页面就会显示为你独立分配的加速地址。adress.pngvim /etc/docker/daemon.json 按照图中加到配置文件里然后重启docker服务systemctl daemon-reloadystemctl restart dockerdocker info 里面也能看到相关地址配置。

方法3:把之前下载好的 image 镜像导入 image:docker load -i ***.tar方法

方法4:直接下载其他站点的镜像 docker pull hub.c.163.com/library/tomcat:latest 查看 images 列表Docker imagesimages.png
注:docker 镜像相当于,对程序+程序依赖的库 打一个包软件是依赖操作系统中的库或二进制文件。 如果我把软件所依赖的库和二进制文件打包在一起发布,不用物理机系统上的文件,也就不依赖操作系统了。开启劢网络转发功能vim /etc/sysctl.conf #插入以下内容net.ipv4.ip_forward = 1sysctl -p 生效否则,docker 启劢实例时,会报错以下警告waning.pngsystemctl stop firewalld && systemctl disable firewalldsystemctl restart docker #关了防火墙,要把 docker 服务重启一下,不然 docker 的 ip 包转发功能无法使用。即使防火墙关了,docker 会调用内核模块 netfilter 增加规则,所以有防火墙规则。

docker平台基础使用方法

docker imagesdocker run -it -help.png

docker logsdocker ps #列出所有运行中容器。

docker ps -a #-a 列出所有容器(包含沉睡/退出状态的容器);

docker kill c4a213627f1b #杀死一个容器

docker stop 1a63ddea6571 关闭容器 docker rm 8683629d2925docker rm -f 1a63ddea6571

8.Docker镜像制作方法

方法 1:docker commit #保存 container 的弼前状态到 image 后,然后生成对应的 image

语法:docker commit <container 的 ID> <新的 image_name>

方法 2:docker build #使用 Dockerfile 文件自动化制作 image

mkdir /docker-build

cd /docker-build

touch Dockerfile

![make-image.png](/static/images/docker-assets/make-image.png)

FROM centos:latest # FROM 基于哪个镜像

MAINTAINER 镜像创建者

RUN yum -y install httpd #RUN 安装软件用

ADD start.sh /usr/local/bin/start.sh

ADD index.html /var/www/html/index.html

CMD /usr/local/bin/start.sh

ADD 将文件<src>拷贝到新产生的镜像的文件系统对应的路径<dest>。所有拷贝到新镜像中的文件和文件夹权限为 0755,uid 和 gid 为 0

CMD /usr/local/bin/start.sh #当 docker 实例启劢成功后,会执行 CMD 后面的命令。所以

CMD 后面一般跟需要开机启劢的服务戒脚本。一个 Dockerfile 中只能有一条 CMD 命令,多条则只执行 最后一条 CMD.

语法:docker build -t 父镜像名:镜像的 tag Dockerfile 文件所在路径 ./

-t :表示 tage,镜像名

注: ./ 表示当前目录。另外你的当前目录下要包含 Dockerfile

9.Docker image的发布

方法 1:Save Image To TarBall

语法:docker save -o 导出的镜像名.tar 本地镜像名:镜像标签

导入镜像:docker load -i 导出的镜像名.tar

方法 2:Push Image To Docker Hub 发布到外网

1、Signup on docker hub & create repo 注册一个帐号 https://hub.docker.com/

2、Login to docker hub : docker login -u userabc -p abc123 -e userab@gmail.com

3、Push image to docker hub #上传镜像 : docker push centos:httpd

4、Pull image from docker hub #下载镜像 : docker pull userabc/centos:httpd # 用户名/镜像名

方法3:使用私有仓库发布镜像

10、Container 容器端口映射

iptables -F

systemctl restart docker

docker run -d -p 8080:80 centos:httpd

注: -p 物理机的 80 端口:容器实例的 80 端口 ,把容器中的 80 端口映射到物理机上的 80 端口 查看物理机上开启的 80 代理端口

[root@xuegod63 ~]# netstat -antup | grep 80

tcp6 0 0 :::80

访问正在运行的 container 容器实例,语法: docker exec -it <container id | name> /bin/bash

查看物理机和容器的网络:

查看容器的 IP:

[root@ee28a7860cbe html] # ip addr

22: eth0@if23: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state

UP group default

link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0

inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0

valid_lft forever preferred_lft forever

物理机的 IP:

ifconfig

docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500

inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0

注:相当于虚拟机的 NAT 网络模式

nat.png

11.Docker四种网络模式

Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。

Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法通过直接Container-IP访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器。

network.png

11.1 host模式

如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好。

host.png

11.2 Container模式

这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。

container.png

11.3 none模式

使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。

这种网络模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器创建时通过--network=none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。

none.png

11.4 Bridge模式

当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。

从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看。

bridge模式是docker的默认网络模式,不写--net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。

bridge.png