前文说到要深入到操作系统级别的运行环境一致性,还是需要 深化 Mount Namespace 这项技术。
Docker在镜像的设计中引入了层(layer)的概念。也就是说,用户制作镜像的每一步操作,都会生成一个层,也就是一个增量 rootfs。
为了实现这种想法,就用到了 联合文件系统 (Union File System) 的能力。
Union File System
最主要的功能是将多个不同的目录联合挂载到同一个目录下。
$ tree
.
├── A
│ ├── a
│ └── x
└── B
├── b
└── x
执行 挂载命令
mount -t aufs -o dirs=./A:./B none ./C
A 和 B 目录将被合并。
在docker中,其目录就被放置在 /var/lib/docker 路径下。最新的已经被overlay技术所取代,其实和aufs差不多。
# ll
total 0
drwx------. 3 root root 30 Jul 15 22:13 2e4d691c410329787b40cc0031dd1a67246cd7fe40906b12431295d42fcbccaa
brw-------. 1 root root 253, 0 Jul 16 23:30 backingFsBlockDev
drwx------. 4 root root 55 Jul 15 22:48 dfb8572a4ed3d8a81e2c8b4466bec6f4cdf89dc0b374f315b1992db24fc0e45d
drwx------. 4 root root 55 Jul 15 22:22 dfb8572a4ed3d8a81e2c8b4466bec6f4cdf89dc0b374f315b1992db24fc0e45d-init
drwx------. 2 root root 108 Jul 15 22:22 l
当我拉取一个容器镜像时,所谓的镜像就是一个Ubuntu操作系统的rootfs。他的内容是Ubuntu操作系统的所有文件和目录。不过与普通的rootfs相较而言,这里往往是由多个层组成的。
# docker image inspect ubuntu:latest
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:ba9de9d8475e7f5e40086358a1353b3cc080994fc6d31e4272dd3acb69b0151e",
"sha256:fbd2732ad777cb5db2515fa62b6122b797be233d01db02e0a19e5d894688cad6",
"sha256:dda1518598187bf87704acc22aa0ec2a67d9e7835c24346dfca118ab42c5cd0b",
"sha256:75e70aa52609fdbd63b58d46d6f7c20470062e1c9bb75616f7703a358a61e5ca"
]
},
可以看到,这个镜像实际是有4个层组成,每一层实际上是ubuntu操作系统文件与目录的一部分。而在使用镜像时,需要将这些联合层,挂载到一个统一的挂载点上。
$ ls /var/lib/docker/overlay2/1a0eeaa99c53a69b48475f6ceadd62f906967bcaca31dd01bf1b3b8c646d447b/diff
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
查看overlay 的挂载信息。
# cat /proc/mounts |grep overlay
overlay /var/lib/docker/overlay2/bd308d4fea3953483cd7b96f3d9eccad149891d2125d7ef945124bc2f7abb137/merged overlay rw,seclabel,relatime,lowerdir=/var/lib/docker/overlay2/l/QG6AEZLLLXQ6OCRVFGTZOMYR4Z:/var/lib/docker/overlay2/l/5L5RY3F4J6ZTZYR23L37PVSGGV:/var/lib/docker/overlay2/l/EHAGOXJHQYKSPQVQWHUIBWHPIU:/var/lib/docker/overlay2/l/O2GCQLLMA5EKZF4EIUJS6A5SLS:/var/lib/docker/overlay2/l/5CMOOZLGPWNPEKBPPGFO3HYXUB,upperdir=/var/lib/docker/overlay2/bd308d4fea3953483cd7b96f3d9eccad149891d2125d7ef945124bc2f7abb137/diff,workdir=/var/lib/docker/overlay2/bd308d4fea3953483cd7b96f3d9eccad149891d2125d7ef945124bc2f7abb137/work 0 0
rootfs 由 底层的只读层,init层(ro+wh) ,可读写层(rw)组成。overlay 改成了 upper层,lower层,merge层。
只读层时只读的,但还有wh,wh是删除时,底层将删除文件遮住。
init层夹在只读层与读写层之间,init 层是docker项目单独生成的一个内部层。专门用来放 /etc/hosts/ , /etc/resove.conf 等信息。
需要这样一个层的原因是,这些文件本来只属于只读的一部分,但是需要启动容器是由一些改变。
读写层就是可以读写的了,挂载方式为rw。修改的是以增量的方式递增。
网友评论