本文介绍Docker架构

一、Docker系统架构

1.Docker基础架构

容器架构解读ppt 容器技术架构_docker

1)Docker守护进程
负责容器的创建、运行和监控,以及镜像的构建和存储。
docker daemon

2)Docker客户端
通过HTTP与Docker守护进程通信。
默认使用Unix域套接字(Unix domain socket)实现,但为了支持远程客户端也可以使用TCP socket。
Docker客户端和守护进程是由同一个二进制文件发布的。

3)Docker寄存服务
负责存储和发布镜像。(Docker Hub)
当Docker守护进程收到docker pull请求后,便会从寄存服务器下载镜像;当遇到docker run请求或Dockerfile中的FROM指令时,若本地没有所需的镜像,Docker守护进程会自动从服务器下载镜像。

2.底层技术
Docker守护进程通过执行驱动程序(execution driver)来创建容器,它的runc驱动程序与内核功能密不可分。

  • cgroups:负责管理容器使用的资源,冻结和解冻容器这两个docker pause命令所需的功能;
  • Namespaces:负责容器之间的隔离,确保系统的其他部分与容器的文件系统、主机名、用户、网络和进程分开;
  • 联合文件系统(Union File System,UFS):负责储存容器的镜像层;

3.周边技术
Swarm:集群方案
Compose:负责构建和运行由多个容器所组成的应用程序工具(用于开发和测试);
Machine:在本地或远程资源上安装和配置Docker主机,配置Docker客户端,切换环境;
Kitematic:Mac OS和Windows上的GUI,用于运行和管理Dokcer;
Docker Trusted Registry:用于存储和管理Docker镜像,Docker Hub的本地版本,与企业的安全架构集成;
网络连接:Weave、Project Calico、Overlay
网络解决方案:Consul、Registrator、SkyDNS、etcd
服务编排及集群管理:Kubernetes、Marathon、Fleet、Swarm
存储系统集成:volume plugin、Flocker、GlusterFS

二、镜像是如何生成的

1.构建环境的上下文
docker build命令需要Dockerfile和构建环境的上下文(build context)。
上下文是一组本地文件和目录,它被Dockerfile的ADD或COPY指令所引用,通常以目录路径的形式指定。

docker build -t test/cowsay-dockerfile .
其中“.”就是上下文,即当前目录,该目录下的所有文件和目录形成构建环境的上下文,并在生成镜像的过程中传递给Docker守护进程。
若没有指定上下文则被视为空。

注意:不要用“/”作为构建环境的上下文
说明:由于构建环境的上下文会被放进一个tar文件,然后传递给Docker守护进程,因此不要使用一个含有大量文件的目录,因为客户端需要把所有文件归档,交给守护进程(/home/user、downloads),这将花费大量时间处理。

其他方式的上下文:
A.URL以http或https开头
它会被假定为直接指向Dockerfile的链接,不会与任何上下文关联
B.git仓库
Docker客户端会把仓库和任何子模组(submodule)复制(clone)至另一个临时目录,并把它传给Docker守护进程作为构建环境的上下文。
以github.com/、git@、git://开头的路径被视为git仓库。
C.STDIN输入
在提供上下文参数处使用“-”,可以不包含上下文的Dockerfile,或是一个包含上下文及Dockerfile的归档文件。(tar.gz、xz、bzip2)

.dockerignore文件
从构建环境的上下文中排出不必要的文件,不支持完整的正则([A-Z]*)

.git   (.git会被排除,但dir1/.git不会)
*/.git  (dir1/.git会被排除,但.git和dir1/dir2/.git不会)
*/*/.git   (dir1/dir2/.git会被排除,但.git和dir1/.git不会)
*.sw?   (所有以sw后任一字符为后缀的文件会被排除,但dir1/test.swp不会)

2.镜像层
Dockerfile中的每个指令执行后都会产生一个新的镜像层,这个镜像层可以用来启动容器,一个新的镜像层的建立,是用上一层的镜像启动容器,然后执行Dockerfile的指令后,把它保存为一个新的镜像。
当Dockerfile指令成功执行后,中间使用过的容器将被删除,除非使用--rm=false参数。

注意:
虽然可以在RUN指令中执行持久的进程(SSH、MYSQL),但到下个指令或启动容器时,就不再运行了,除非使用ENTRYPOINT或CMD指令启动。

查看所有镜像层

容器架构解读ppt 容器技术架构_Docker_02

当构建失败时,可以将失败前的那个层启动起来

FROM busybox:latest

RUN echo "This should work"
RUN /bin/bash -c echo "This won't"

之后开始构建镜像:
docker build -t echotest .

分析:
1)Docker为了执行指令而创建一个临时容器,分配容器ID
2)分配该容器所建立的镜像ID
3)将临时容器删除

3.缓存
Docker为了加速镜像构建速度,会将每一个镜像层缓存下来。
但是想要使用缓存,指令必须满足以下条件:

  • 上一个指令能够在缓存中找到
  • 缓存中存在一个镜像层,而它的指令和你的指令一模一样,父层也完全相同
  • 在使用COPY和ADD指令时,如果他们引用文件的校验和或元数据发生变化,缓存也将失效

缓存失效

docker build --no-cache

4.基础镜像
当创建自己的镜像时,你需要决定从哪个基础镜像开始。

注意:
不同镜像会共享相同的基础镜像层,比如你已经有了ubuntu:14:04镜像,然后从Hub又下载一个基于它的镜像,那么你只会得到它在基础镜像之上改变过的部分,而非整个镜像。

重建镜像
当执行docker build时,Docker会查看FROM指令所指定的镜像,若本地没有则下载,若本地有则使用,而不会先检查有没有更新的版本。
这意味着必须对所有被依赖的父镜像显式地执行docker pull或删除,使build命令下载最新版。

5.Dockerfile指令
Exec:需要一个JSON数组,如[“executable”,“param1”,“param2”]
Shell:自由形式的字符串,字符串会传递给/bin/sh -c执行

可用指令集:
ADD
从构建环境上下文或远程URL复制文件至镜像。

CMD
当容器启动时执行指定的指令。多个CMD只有最后一个生效。

COPY
与ADD作用相同。不能指定上下文以外的src路径

COPY src dest
COPY ["src","dest"]

ENTRYPOINT
设置一个容器启动时运行的可执行文件以及默认参数。
常用于提供“启动”脚本,目的是在解析参数前,对变量和服务进行初始化。

ENV
设置镜像内的环境变量。可被随后的指令引用。

EXPOSE
向Docker表示该容器将会有一个进程监听所指定的端口。

FROM
设置Dockerfile使用的基础镜像。

MAINTAIER
把镜像中的作者元数据设定为指定的字符串。

ONBUILD
指定当镜像被用作另一个镜像的基础镜像时会执行的指令。
例如:把代码从一个已选定的目录中复制出来,并在执行构建脚本时使用它。

RUN
在容器内执行指定的指令,并把结果保存下来。

USER
设置任何后续的RUN、CMD或ENTRYPOINT指令执行时所用的用户。
注意:UID在主机和容器中时相同的,但用户名则可能被分配到不同的UID。

VOLUME
指定为数据卷的文件或目录。

WORKDIR
对任何后续的RUN、CMD、ENTRYPOINT、ADD或COPY指令设置工作目录。