1. 镜像是什么?

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行库、环境变量和配置文件。

所有的应用,直接打包docker镜像,就可以直接运行!

如何获取镜像:

  • 下载拷贝别人的镜像:从远程仓库下载
  • 自己制作一个镜像DockerFile

2. Docker镜像加载原理

2.1 UnionFS(联合文件系统)

UnionFS是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层一层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下 。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

镜像特性:一次同时加载多个文件系统,但从外面只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

2.2 镜像加载原理

Docker镜像实际上由一层一层文件系统组成,这种层级的文件系统就叫UnionFS。

bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,Docker镜像的最底层是bootfs。这一层与典型的Linux和Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核都在内存中,此时内存的使用权由bootfs转交给内核,此时系统也会卸载bootfs。

自动拉镜像 自动镜像收集是什么_自动拉镜像

rootfs(root file system),在bootfs之上。包含典型Linux系统中的/dev, /proc, /bin, /etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。

思考:平时我们安装进虚拟机的Centos都是好几个G,为什么在docker里面安装Centos只有200M?

对于一个精简的OS,rootfs可以很小,只需要包含最基本的命令、工具和程序库。因为底层直接用主机的内核,自己仅需提供rootfs。可见对于不同的Linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。

3. Docker镜像分层理解

3.1 分层的镜像

下载镜像的时候,我们观察下载日志输出会发现是一层一层的下载。那么,为什么Docker镜像要采用这种分层结构呢?

采用分层结构最大的好处就是资源共享和资源重用。比如由多个镜像都是从相同的基础镜像上构建而来,那么宿主机只需要在磁盘上保留一份基础镜像,同时内存中也只需要加载一份基础镜像,这样基础镜像就可以为所有容器服务了,而且镜像的每一层都可以被共享。

可以通过这个命令来查看镜像分层方式:

docker images inspect redis:latest

3.2 理解分层镜像

所有Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层上创建新的镜像层。

举个栗子:基于Ubuntu Linux 16.04创建一个新的镜像,这就是新镜像的第一层;继续在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。

自动拉镜像 自动镜像收集是什么_docker_02

在添加额外镜像层的同时,镜像始终保持当前所有镜像的组合。下图中每个镜像层包含了3个文件,而镜像包含了来自两个镜像层的6个文件。

自动拉镜像 自动镜像收集是什么_自动拉镜像_03

 下图中展示的三层镜像,外部看只有6个文件,这是因为顶层的文件7是中间层文件5的更新版本。此时,文件的更新版本作为一个新镜像层添加到镜像中。

自动拉镜像 自动镜像收集是什么_linux_04

Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。

Linux可用的存储引擎由AUFS, Overlay2, Device Mapper, Btrfs以及ZFS。而Docker在Windows上仅支持windowfilter一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW。

下图展示了与系统显示相同的3层镜像。所有镜像层堆叠并合并,对外提供统一的视图。

自动拉镜像 自动镜像收集是什么_docker_05

 3.3 镜像特点

Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部,这一层就是容器层,容器之下的都叫镜像层。

举个栗子:

dockerhub中,tomcat镜像有6层,我们下载(pull)tomcat镜像的时候把6个层都下载了下来,运行tomcat时如果我们在tomcat中做额外的操作,那么新的操作就会在镜像层上新建一层容器层,我们所有的操作都是基于容器层的。

自动拉镜像 自动镜像收集是什么_docker_06