本章节是对上章节Docker镜像原理理解的巩固,从Linux系统运行基础到OverlayFS存储机制 去了解与分析;在底层,镜像是怎样实现存储的;并且会详细说明存储文件的作用。
一、Linux 系统运行基础
Linux 系统正常运行, 通常需要两个文件系统:
bootfs)
1、 包含 Boot Loader与Kernel文件,用户不能修改这些文件。并且在系统启动过程完成之后,
整个系统的内核都会被加载进内存。此时bootfs会被卸载, 从而释放出所占用的系统内存。
Docker运行是需要内核支持 的。
3、Linux系统中典型的bootfs目录: (核心) /boot/vmlinuz、(核心解压缩所需 RAM Disk) /boot/initramfs
rootfs)
1、不同的Linux发行版本, bootfs相同, rootfs不同(二进制文件)。
rootfs, 它来自不同的 Linux 发行版的基础镜像,包括 Ubuntu, Debian 和 SUSE 等。
3、使用不同的rootfs 就决定了, 在构建镜像的过程中, 可以使用哪些系统的命令。 4) 典型的rootfs 目录: /dev、/proc、/bin、/etc、 /lib、/usr
2、OverlayFS 存储原理
OverlayFS 结构分为三个层: LowerDir、Upperdir、MergedDir
1、LowerDir (只读)
只读的 image layer,其实就是 rootfs, 在使用 Dockfile 构建镜像的时候, Image Layer
可以分很多层,所以对应的 lowerdir 会很多(源镜像)。
2、Upperdir (读写)
比如容器启动写入的日志文件,或者是应用程序写入的临时 文件。
3、MergedDir (展示)
merged 目录是容器的挂载点,在用户视角能够看到的所有文件,都是从这层展示的。
、Upperdir、MergedDir 关系图:
3、分析镜像存储结构
1、获取镜像存储路径
通过镜像信息获取到物理存储位置
[root@master jdk]# docker image inspect jre8:1.0
.......
"GraphDriver": {
"Data": {
"LowerDir": "/data/docker/overlay2/0dabd34b699bd07a6fedc787305c029837a509ba325dc19c913a83c1cdb42a3b/diff:/data/docker/overlay2/f0d9e8983ce0eb5189d1343a750ead40fff0b8bf2e7366a288746addca5e64f3/diff:/data/docker/overlay2/203eca2fa309cfded560ddbacaea64e1fe5644a74f8c682cdb94961b7f93f99a/diff:/data/docker/overlay2/cd72a119f6ac0b9796511e54070635c2f6250987163e851005079c310e020b80/diff:/data/docker/overlay2/7468ae5cef2f56d4db4a92d71b979bc2af007af9b5e4f6b3a635db1702a9d429/diff",
"MergedDir": "/data/docker/overlay2/871f67b56f58f71f9774021c44b1ff35e7ef492dabb0dcf9a515353b085bf3f5/merged",
"UpperDir": "/data/docker/overlay2/871f67b56f58f71f9774021c44b1ff35e7ef492dabb0dcf9a515353b085bf3f5/diff",
"WorkDir": "/data/docker/overlay2/871f67b56f58f71f9774021c44b1ff35e7ef492dabb0dcf9a515353b085bf3f5/work"
},
"Name": "overlay2"
},......
2、分析Lower层
LowerDir 层的存储是不允许创建文件, 此时的LowerDir实际上是其他的镜像的UpperDir层,也就是说在构建镜像的时候, 如果发现构建的内容相同, 那么不会重复的构建目录,而是使用其他镜像的Upper 层来作为本镜像的Lower
[root@master jdk]# touch /data/docker/overlay2/0dabd34b699bd07a6fedc787305c029837a509ba325dc19c913a83c1cdb42a3b/diff/lower.txt
3、分析Upper层
[root@master jdk]# touch /data/docker/overlay2/871f67b56f58f71f9774021c44b1ff35e7ef492dabb0dcf9a515353b085bf3f5/diff/upper.txt
4、分析Merged层
属于对外展示层,只能在运行中的容器查看,镜像是查看不了的
4、运行中容器的存储结构
前台启动,直接进入到容器
[root@master lihanghang]# docker run -it jre8:1.0 bash # 重新ssh 开个窗口
bash-4.3#
2、查看容器挂在信息
容器启动以后,挂载merged、lowerdir、upperdir以及workdir目录
lowerdir是只读的image layer,其实就是rootfs
[root@master jdk]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6816ade398c3 repo.abc.com/nginx:v1.0 "/docker-entrypoint.…" 4 hours ago Up 4 hours 0.0.0.0:9091->80/tcp condescending_shaw
3、查看容器存储目录信息
#注意在所有的启动容器中会自动添加init目录, 此目录是存放系统的hostname与域名解析文件。
[root@master jdk]# docker inspect 6816ade398c3
"Data": {
"LowerDir": "/data/docker/overlay2/768c9e3cbf17b6dd61a47fa5ae935c5c7bc6adfc2a5c0ea79b38a9a3443ac929-init/diff:/data/docker/overlay2/696103a495dc761560c3ec0de8414619b559c483c5e6e66ec01fc2c5e6af12e1/diff:/data/docker/overlay2/b8e2bc89bb28f516fea555be11d33bf14334008be9c1e547e81088a54112510a/diff:/data/docker/overlay2/e2abf1e74fb5ee048de2066f1c2ee2e3750302cbbfbbd36bd9eff4d8872ec572/diff:/data/docker/overlay2/75c9819b8bf9e1de7b7471ee96632c3e20f82d1a88d5a58555a0b46f4ce952d8/diff:/data/docker/overlay2/0c809e2915134cf1ac493c5d5a814320923982d2384c1de0484d2c8bd5d9ad05/diff",
"MergedDir": "/data/docker/overlay2/768c9e3cbf17b6dd61a47fa5ae935c5c7bc6adfc2a5c0ea79b38a9a3443ac929/merged",
"UpperDir": "/data/docker/overlay2/768c9e3cbf17b6dd61a47fa5ae935c5c7bc6adfc2a5c0ea79b38a9a3443ac929/diff",
"WorkDir": "/data/docker/overlay2/768c9e3cbf17b6dd61a47fa5ae935c5c7bc6adfc2a5c0ea79b38a9a3443ac929/work"
},
5、容器文件存储解析
1、容器运行时的UpperDir目录结构
# 本地窗口
[root@master jdk]# touch /data/docker/overlay2/d6e4e36c309de456d6025d56144feaf4097c9d133b7cda4a20baa8526ebe671a/diff/upper.txt
[root@master jdk]# echo 11111 > /data/docker/overlay2/d6e4e36c309de456d6025d56144feaf4097c9d133b7cda4a20baa8526ebe671a/diff/upper.txt
# 容器里面
bash-4.3# ls /
bin etc lib media opt root sbin sys upper.txt var
dev home lib64 mnt proc run srv tmp usr
bash-4.3# cat /upper.txt
11111
Work 目录
work目录用于联合挂载指定的工作目录,在overlay 把文件挂载到 upperdir后, work内容会
被清空,且在使用过程中(为空)其内容用户不可见。
3、用户视角层Merged
#最后给用户展示的层,一般看到为一个完整的操作系统文件系统结构
[root@master jdk]# ll /data/docker/overlay2/d6e4e36c309de456d6025d56144feaf4097c9d133b7cda4a20baa8526ebe671a/merged
bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp upper.txt usr var
4、Lower 层
#Lower 包括两个层:a. 系统的init。b.容器的镜像层
Lower 记录父层的链接名称
[root@node-2 ~]# cat /var/lib/docker/overlay2/d4dc057329ecbf5a2f97293b6d49078e9cce6869a9f049ba5bc365f6fba424d2/lower
l/QCXVWDWYPFM5NRVMB2ZC2BE5WU:l/PUSOZBTJKJ2OBNKK2UQDNQLHCU
init 层 / 容器镜像层
1、查看init层地址指向
容器在启动的过程中, Lower 会自动挂载init的一些文件
[root@master jdk]# ls /data/docker/overlay2/d6e4e36c309de456d6025d56144feaf4097c9d133b7cda4a20baa8526ebe671a-init/diff/etc
hostname hosts mtab resolv.conf
init层主要内容是什么?
Lower)和读写层(upperdir)之间,
作用只是存放/etc/hosts、/etc/resolv.conf 等文件。
3、为什么需要init层?
主 机名与域名地址, 那么就需要添加init层中的文件(hostname, resolv.conf), 用于解决此类问 题.
2、修改的内容只对当前的容器生效, 而在docker commit提交为镜像时候,并不会将init层提
交。
3、init 文件存放的目录为/var/lib/docker/overlay2/<init_id>/diff
4、查看init层文件
hostname与resolv.conf 全部为空文件, 在系统启动以后由系统写入。注:不能在打镜像的时候copy进去,copy进去用这个镜像启动时,启动起来以后文件也是空的。
[root@master jdk]# ll /data/docker/overlay2/d6e4e36c309de456d6025d56144feaf4097c9d133b7cda4a20baa8526ebe671a-init/diff/etc
总用量 0
-rwxr-xr-x. 1 root root 0 8月 24 00:03 hostname
-rwxr-xr-x. 1 root root 0 8月 24 00:03 hosts
lrwxrwxrwx. 1 root root 12 8月 24 00:03 mtab -> /proc/mounts
-rwxr-xr-x. 1 root root 0 8月 24 00:03 resolv.conf
总结
- 1、镜像所挂载的目录层为 Lower 层,然后通过 Merged 展示所有的文件目录与文件。用户写入的所有文件都是在 UpperDir 目录,并且会在 UpperDir 建立于 Merged 层展示的文件 目录结构, 所以用户就可以看到写入的文件。并且底层的镜像是不能被修改(如果挂载目 录为 UpperDir,则可以修改源镜像)。
- 2、在下次重新启动已经停止的容器的时候, 如果容器的 ID 没有发生改变,那么所写入的文 件是存在物理系统中的; 反之就会是一个新的容器,之前手工创建的文件是不存在的。
3、基于容器创建的镜像,就相当于容器的快照, 可以删除原来的容器, 但是不能删除原来 的镜像
4、基于镜像创建的镜像,原来的镜像就是新镜像的 low 层 (build), tag 则是没有区别
5、容器启动以后,镜像就存在于容器的low 层,所有的写入都是在upper