因为容器都是基于镜像创建的,所以了解镜像的原理和内部结构显得尤为重要。
base 镜像
base
镜像即基础镜像,通常基础镜像表示一个简单的 linux
镜像,比如 ubuntu
,我们可以在它的基础之上安装我们需要的软件和 APP
。但是严格意义的 base
镜像是需要我们从 0
开始制作的(比如 scratch
就是一个除了 metadata
外没有其他东西的空镜像)。从之前的内容我们已经知道 Docker
的 ubuntu
镜像只有 70
多 MB
,但是完整的 ubuntu
镜像一般在 2G
以上,Docker
是怎么将 ubuntu
容器镜像做到这么小的呢?这就得从 Docker
镜像的结构入手来看。
镜像的分层结构
典型的 Linux
系统启动需要两个 FS
,即 bootfs
和 rootfs
,其分别归属内核空间和用户空间,Linux
启动时加载 bootfs
,启动完毕后就会将其卸载掉。而 rootfs
则一直存在,其包含了系统运行需要的/dev,/proc,/bin
等文件目录。base
镜像的内核空间直接使用 Host
的,只需要提供自己的 rootfs
即可,而 rootfs
可以根据自己的需要进行精简,这样就实现了 Docker
镜像的轻量化。容器只能使用 Host
的内核,并且无权修改,如果你的应用只能在某个内核版本下运行,则不建议使用容器,使用虚拟机即可。
镜像分层结构图
如上图所示,新镜像是在 base
镜像的基础上安装软件,每执行一次安装操作就会向镜像增加一层,为什么要采用这种方式呢?因为这样可以共享资源,基于这个镜像创建的不同的容器都共享 image
层,每个容器的不同之处就是各自拥有不同的容器层,用来记录镜像变化的部分,这个特性,我们称其为:Copy-on-Write
,即只有镜像发生变化的时候才复制一份到容器层。
总结一下:容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享。