root@test-1:~# echo"just a test in lower_1" > /root/test_2/lower_1/test.txt root@test-1:~# echo"just a test in lower_2" > /root/test_2/lower_2/test.txt root@test-1:~# echo"just a test in upper" > /root/test_2/upper/test.txt
root@test-1:~# mount -t overlay overlay -o lowerdir=/root/test_2/lower_1:/root/test_2/lower_2,upperdir=/root/test_2/upper,workdir=/root/test_2/work /root/test_2/merged root@test-1:~# mount | grep overlay overlay on /root/test_2/merged type overlay (rw,relatime,lowerdir=/root/test_2/lower_1:/root/test_2/lower_2,upperdir=/root/test_2/upper,workdir=/root/test_2/work)
root@test-1:~# cat /root/test_2/merged/test.txt just a testin upper
root@test-1:~# cat /root/test/merged/new_file_1.txt this is new file 1 root@test-1:~# cat /root/test/upper/new_file_1.txt this is new file 1
root@test-1:~# echo"change file context in new_file_1.txt" >> /root/test/merged/new_file_1.txt
root@test-1:~# cat /root/test/merged/new_file_1.txt this is new file 1 change file context in new_file_1.txt root@test-1:~# cat /root/test/upper/new_file_1.txt this is new file 1 change file context in new_file_1.txt
root@test-1:~# cat /root/test/merged/lower_2_file.txt this is lower_2 file root@test-1:~# cat /root/test/lower_2/lower_2_file.txt this is lower_2 file
root@test-1:~# echo"change file context in lower_2_file.txt" >> /root/test/merged/lower_2_file.txt
root@test-1:~# cat /root/test/merged/lower_2_file.txt this is lower_2 file change file context in lower_2_file.txt root@test-1:~# cat /root/test/lower_2/lower_2_file.txt this is lower_2 file
mount 的时候可以支持配置多个 lower 目录,也就可以支持多层的镜像文件。在容器启动后,对镜像文件中修改就会被保存在 upper 层里了:
1 2 3
root@docker-rancher:~# mount | grep overlay overlay on /var/lib/docker/overlay2/cd127ce0c9234a83bfa6a8af489523ac5b4d0f75193376e12c4fb7f7ee9fac60/merged type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/GJSFUGAX44YTMZ5OEJU4EXI3V3:/var/lib/docker/overlay2/l/32VGIMNNHRGYLLLQMKQ6YSLCA5:/var/lib/docker/overlay2/l/NVATVK5SZLFEWVJDHMSOTH6E2S:/var/lib/docker/overlay2/l/LI5UP7MHJZPMFRX5HO6DBIJEXW:/var/lib/docker/overlay2/l/S6ZRHMIZB2OGWJDCWMG2SWD7OS:/var/lib/docker/overlay2/l/EL5MTVHUJTMMZVEVE6DWVKFCWN,upperdir=/var/lib/docker/overlay2/cd127ce0c9234a83bfa6a8af489523ac5b4d0f75193376e12c4fb7f7ee9fac60/diff,workdir=/var/lib/docker/overlay2/cd127ce0c9234a83bfa6a8af489523ac5b4d0f75193376e12c4fb7f7ee9fac60/work) overlay on /var/lib/docker/overlay2/2230388d2e79adfb7d077ef2efc96e2a12bf0da12a1ecdf5a4f17184f7b3dbbf/merged type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/WKVVQYWDX6XM3WQHFJZ3HEVXHA:/var/lib/docker/overlay2/l/2CX3IUCN65XNPMTWYAKXDY36YY:/var/lib/docker/overlay2/l/73UR25NJGJRBHGV4XW76QS23NU:/var/lib/docker/overlay2/l/U5X27QU3RFE72DW4MKLW5B5AA2:/var/lib/docker/overlay2/l/U3T6GTKZI3BVEYC76NT3UB4QKM:/var/lib/docker/overlay2/l/XF5V6O44CJFWHWGXCBVZNDWD3J:/var/lib/docker/overlay2/l/MSBV2RGM5OXHK2ZXI3KDKGQESW:/var/lib/docker/overlay2/l/JLAAA7DI2PCNETKIP3QWNIKJ5V:/var/lib/docker/overlay2/l/RR7DLQW2OR3KJ4ROSWHGKUO7ZJ:/var/lib/docker/overlay2/l/ZE6CWQSI5BLQ4EDMNRZYZXXXUR:/var/lib/docker/overlay2/l/WZHHR5UGHAYDPPM32EXW7LDU7O:/var/lib/docker/overlay2/l/IDOVDLLKLV3O52ISM7OFDTKMZR:/var/lib/docker/overlay2/l/QS5CLJTQ2J2KD4DRBZ2D7SNJH3:/var/lib/docker/overlay2/l/YPMNY7WF5O525QRRKR3CDLVQ2O:/var/lib/docker/overlay2/l/NUBYELS36USEBZQ2YPUEHRJQM4:/var/lib/docker/overlay2/l/QXH2NMXKWNDUZ5OWFCAFXD2IJB:/var/lib/docker/overlay2/l/GLNEY32NVXKYJR7VXTOQJKGOVR:/var/lib/docker/overlay2/l/NLSYPVG4Y6DFRAGFWPRU674NNY:/var/lib/docker/overlay2/l/PDHSJV7EF3QZT6L7M4JIB2XMPU,upperdir=/var/lib/docker/overlay2/2230388d2e79adfb7d077ef2efc96e2a12bf0da12a1ecdf5a4f17184f7b3dbbf/diff,workdir=/var/lib/docker/overlay2/2230388d2e79adfb7d077ef2efc96e2a12bf0da12a1ecdf5a4f17184f7b3dbbf/work)
Overlay2
OverlayFS 提供了两个存储驱动,Overlay 和 Overlay2。早期 Docker 使用 Overlay 一段时间后会出现 too many links problem 的错误,所以现在高版本都缺省使用 Overlay2。
镜像结构
通过 docker inspect 查看镜像的具体信息,可以看到 Data 下包含 OverlayFS 的结构:
/var/lib/docker/overlay2 下就包含所有镜像的 lower、upper、merged、work 层级,同时还有一个 l 目录,这个目录里是一些短标识命名的软链接,链接到上面这些目录,目的是短标识用于避免 mount 命令参数页面大小限制:
1 2 3 4 5 6 7 8
root@docker-rancher:~# ls /var/lib/docker/overlay2/l -l total 0 lrwxrwxrwx 1 root root 72 Feb 7 20:54 245UGIT5O7BRVNYUCJRVOZU5NL -> ../38928d95f9c344b85fc2d4be2d0cfc621389da81a585b89091be1063a5d82ca7/diff lrwxrwxrwx 1 root root 72 Dec 26 16:25 24DGEJWBI2GKVF6PQUI45IKZ2O -> ../9f1229bbb00f7dba2fea670cef286aa13498c94454df42b5b67af4cd3a54f9da/diff lrwxrwxrwx 1 root root 72 Dec 25 16:32 24P6O5MZCXGY2QX5KXEXAAQO37 -> ../6bf5c7cb636eb0345849ace23fde6935a07ee5d7bc1bb7160e3058882079dcf8/diff lrwxrwxrwx 1 root root 72 Dec 4 15:27 26WQOKXKRSNS4JW4YRJZMTMU4Y -> ../c824524f1baf30988dc66b504ac6b21d34dec52e68aecded117fdc9f2ca7d4c5/diff lrwxrwxrwx 1 root root 72 Mar 3 09:35 2C2EPWTZN3ZFMKJPDSJ46L2I7Y -> ../a848cd02f9af6a522db2729795fbc81be9a72d098dba7ba8a3b4ce9adeadc211/diff ...
除了 l 之外的目录下有这些内容:
1 2
root@docker-rancher:~# ls /var/lib/docker/overlay2/38928d95f9c344b85fc2d4be2d0cfc621389da81a585b89091be1063a5d82ca7 committed diff link lower work
diff 目录存放这一层的内容:
1 2 3
root@docker-rancher:~# ls -l /var/lib/docker/overlay2/38928d95f9c344b85fc2d4be2d0cfc621389da81a585b89091be1063a5d82ca7/diff/ total 0 drwxr-xr-x 3 root root 17 Dec 22 2023 var
root@docker-rancher:~# ls -l /var/lib/docker/image/overlay2/layerdb/sha256/ total 0 drwx------ 2 root root 85 Dec 26 16:25 0039114f0040d66de95932fc6860e7bb10b00ba7795dacd4cd539ed9d80d9876
root@docker-rancher:/var/lib/docker/image/overlay2/layerdb/mounts# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fb59b89245b8 harbor.warnerchen.com/rancher/rancher:v2.11.1 "entrypoint.sh" 11 days ago Up 6 days 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp rancher dbac81c2435f harbor.warnerchen.com/dreamacro/clash:v1.18.0 "/clash" 3 weeks ago Up 6 days 0.0.0.0:7890-7891->7890-7891/tcp, :::7890-7891->7890-7891/tcp, 0.0.0.0:9090->9090/tcp, :::9090->9090/tcp clash-paofucloud
root@docker-rancher:/var/lib/docker/overlay2# mount | grep overlay overlay on /var/lib/docker/overlay2/2230388d2e79adfb7d077ef2efc96e2a12bf0da12a1ecdf5a4f17184f7b3dbbf/merged type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/WKVVQYWDX6XM3WQHFJZ3HEVXHA:/var/lib/docker/overlay2/l/2CX3IUCN65XNPMTWYAKXDY36YY:/var/lib/docker/overlay2/l/73UR25NJGJRBHGV4XW76QS23NU:/var/lib/docker/overlay2/l/U5X27QU3RFE72DW4MKLW5B5AA2:/var/lib/docker/overlay2/l/U3T6GTKZI3BVEYC76NT3UB4QKM:/var/lib/docker/overlay2/l/XF5V6O44CJFWHWGXCBVZNDWD3J:/var/lib/docker/overlay2/l/MSBV2RGM5OXHK2ZXI3KDKGQESW:/var/lib/docker/overlay2/l/JLAAA7DI2PCNETKIP3QWNIKJ5V:/var/lib/docker/overlay2/l/RR7DLQW2OR3KJ4ROSWHGKUO7ZJ:/var/lib/docker/overlay2/l/ZE6CWQSI5BLQ4EDMNRZYZXXXUR:/var/lib/docker/overlay2/l/WZHHR5UGHAYDPPM32EXW7LDU7O:/var/lib/docker/overlay2/l/IDOVDLLKLV3O52ISM7OFDTKMZR:/var/lib/docker/overlay2/l/QS5CLJTQ2J2KD4DRBZ2D7SNJH3:/var/lib/docker/overlay2/l/YPMNY7WF5O525QRRKR3CDLVQ2O:/var/lib/docker/overlay2/l/NUBYELS36USEBZQ2YPUEHRJQM4:/var/lib/docker/overlay2/l/QXH2NMXKWNDUZ5OWFCAFXD2IJB:/var/lib/docker/overlay2/l/GLNEY32NVXKYJR7VXTOQJKGOVR:/var/lib/docker/overlay2/l/NLSYPVG4Y6DFRAGFWPRU674NNY:/var/lib/docker/overlay2/l/PDHSJV7EF3QZT6L7M4JIB2XMPU,upperdir=/var/lib/docker/overlay2/2230388d2e79adfb7d077ef2efc96e2a12bf0da12a1ecdf5a4f17184f7b3dbbf/diff,workdir=/var/lib/docker/overlay2/2230388d2e79adfb7d077ef2efc96e2a12bf0da12a1ecdf5a4f17184f7b3dbbf/work)