事情是这样的:
今天只说overlay,当然躲不了OverlayFS。
其实OverlayFS就是把linux主机上的两个目录合并(merged)成一个目录,但是是按层的思想来合并的。为了显得腻害和专业把这个操作称呼为“联合挂载”。
既然是按层的思想来“联合挂载”,那参与“联合挂载”的两个目录必然有一个目录做底层,叫做lowerdir,另外一个做高层叫upperdir。然后两者这么结合后的视图叫做merged。跟“丈夫--妻子 -->夫妻”概念很像,而且都能生搬硬套一个在“上”一个在“下”。
下面是一个常见的解释overlay分层的图
其实我觉得这个图有问题,按照这个图的说法,OverlayFS的upperdir在这个图里面作为Docker的容器层,那在容器层里的修改不就会影响upperdir目录吗,感觉所谓的Container layer应该是在upperdir之上呢,不知道是不是我理解错了谁来解答一下。
当一个文件同时存在于upperdir和lowerdir时,使用upperdir的,由于overlay只支持上下两层,因此本来Docker所需要的多层镜像是无法使用overlay的,但是可以利用硬链接来解决这个问题,比如除了上面说的upperdir和lowerdir,现在又来个在lowerdir下面的比如lowestdir该怎么办呢,此时在lowerdir为lowestdir的所有文件创建一个硬链接。
1.使用overlay运行docker daemon,使用docker info确认。
2.在该物理机上跑了一个容器,使用docker ps查看。
3.用mount看一下linux系统实际因为这个容器mount的OverlayFS。
看不太清楚,直接分行写出来,方便分析。
/dev/xvda1 on /home/docker/overlay type ext4 (rw,relatime,grpquota,data=ordered)
/home/docker/overlay on /home/docker/overlay/8be6a561d236b056d6c13c02aefee1020d9880bef1310e15b87e78fde49d8ff9/merged type overlay (rw,relatime,
lowerdir=/home/docker/overlay/280fb8222f4a626cee5b97c3d312de6fa422cc5df3627024018d0ee24d4de0ee/root,
upperdir=/home/docker/overlay/8be6a561d236b056d6c13c02aefee1020d9880bef1310e15b87e78fde49d8ff9/upper,
workdir=/home/docker/overlay/8be6a561d236b056d6c13c02aefee1020d9880bef1310e15b87e78fde49d8ff9/work)
解释一下:
以上可以看到docker容器在运行时overlay只能看到两层目录,实际上我们的镜像不止这两层,如前所述,所谓的lowestdir的文件都以硬链接的方式存在于lowerdir中,比如root/bin/ls这个文件肯定是存在于我们看不到的最底层的,我们能看到的lowerdir中的root/bin/ls文件绝对是最底层中这个ls文件的硬连接。如下图所示。
因此,一个在overlay上运行中的容器,相关的目录构成是这样的。
图中merged是所有镜像层合并后的结果(容器中进程看到的结果);upper是最上面的只读层;work是overlay生成的用来做cow相关操的;lower-id是个文件,里面写的是该层下面的那一层的cache-id。(参考https://blog.csdn.net/tanzhe2017/article/details/81010495)
综上,假设机器本地存放了n个镜像,则/home/docker/overlay下就至少有n*3个子目录,为什么呢,因为对于每个镜像来说,都会有:
注意按照overlayFS的mount结果,这里的upperdir是可写的,比如按照上面的例子,则/home/docker/overlay/8be.../upper目录下的内容是可写的。于是Docker在实际运行中会另外专门在容器层(对应overlayFS的upperdir)之上创建一个读写层。