Docker第四篇(docker镜像特性)
镜像特性
容器创建是需要指定使用的镜像,每个镜像都由唯一的标识Image ID,和容器的Container ID一样,他们默认都是128位,可以使用前16位作为缩略形式,也可以使用镜像镜像名和版本号两个部分组合成唯一表示,例如nginx:latest,如果省略版本号,默认使用的是最新版本标签,也就是latest,所以如果默认直接写nginx,其实系统执行的实际命令就是nginx:latest。
Docker 文件系统
Linux系统包含内核空间kernal和用户空间rootfs两部分,Docker容器只使用各自的rootfs但共用主机host的内核kernal,这样就产生了镜像结构分层。
rootfs是Docker容器在启动时内部进程可见的文件系统,也就是Docker容器的根目录。rootfs包含一个操作系统运行所需的文件系统。例如:可能包含典型类UNIX系统中的目录系统/dev/、/proc、/bin、/etc、/usr、/tmp...及运行Docker容器所需的配置文件、工具等。

在传统Linux内核启动时,首先会挂载一个只读的rootfs,当系统检测其完整性之后,再将其切换为读写模式。而在Docker架构中,当docker daemon为Docker容器改在rootfs时,会沿用Linux内核启动时的做法,也就是将rootfs设置为只读模式。当挂载完毕后,利用联合挂载union mount技术在已有的只读rootfs上再挂载一个读写层。这样,可读写的层处于Docker容器文件系统的最顶层,其下可能联合挂载了多个只读的层,只有在Docker容器运行过程中文件系统发生变化时,才会把变化的文件内容写到可读写层,并隐藏只读层中的旧版本文件。
由于所有Docker容器都共用host主机的kernal内核,所以在容器中是不能对Linux内核kernal进行升级的。

Docker支持通过扩展现有镜像来创建新的镜像,实际上Docker Hub中99%的镜像都是通过在Base镜像中安装和配置需要的软件构建出来的。

一个Docker镜像Images由多个可读的镜像层Read Layer,然后运行的容器会在这个Docker的镜像上多加一层可写的容器层Read-Write Layer,任何对文件的更改都只存在于此容器层,因此任何对容器的操作均不会影响到镜像。

容器是如何获取镜像层文件而又不影响镜像层的呢?
Docker中如果需要获取某个文件,容器层会从上到下去下一层的镜像层中去获取文件,如果该层文件不存在,那么就会去下一层镜像中寻找,直到最后一层。对于用户而言,用户面对的是一个叠加后的文件系统。
任何对于文件的操作都会记录在容器层,例如:修改文件时容器层会把在镜像层找到的文件拷贝到容器层然后进行修改,删除文件时则会在容器层内记录删除文件的条目。

当容器启动时,一个新的可写层writable被加载到镜像的顶部,这一层通常被称为容器层container,容器层之下的都叫做镜像层。
典型的Linux在启动后,会将rootfs置为只读readonly并进行一些列检查,然后将其切换为可读写readwrite供用户使用。在Docker中起初也是将rootfs以只读的readonly的方式加载并检查,然后接下来利用union mount联合挂载将一个readwrite文件系统挂载在readonly的rootfs之上,并且允许再次将下层的文件系统设定为只读readonly,并向上叠加。这样一组只读readonly和一个可写writeable的结果就构成了一个容器container的运行目录,每个镜像被称为一层layer。

Docker镜像为什么要采用分层结果呢?
- 每个软件都是基于某个镜像去运行的,因此一旦某个底层环境出现问题,就不需要去修改全部基于该镜像的软件的镜像,只需要修改底层环境的镜像。
- 共享资源,其它相同环境的软件镜像都共同去享用同一个环境镜像,而不需要每个软件镜像要去创建一个底层环境。
链接:https://www.jianshu.com/p/d1ac41c31245
来源:简书

浙公网安备 33010602011771号