从零自制docker-7-【Union File System】(Union File System overlay 挂载 docker 的overlay2 镜像和容器和overlay2 疑问点)

本文详细解释了UnionFileSystem的工作原理,包括copy-on-write机制,以及如何使用overlay挂载技术将镜像层、init层和容器层合并到merged目录。同时介绍了实操步骤和遇到的问题,指出需深入源代码理解完整流程。
摘要由CSDN通过智能技术生成


https://cloud.tencent.com/developer/article/2272892

Union File System

  • 就是将多个目录合并到一个一个目录中去
  • 使用一种称为 copy-on-write (COW)的机制。如果需要修改的文件位于只读层,UnionFS 会将该文件复制到最上面的可写层,然后在那里进行修改。这样就保证了底层的文件系统保持不变,而改动仅仅发生在顶层。

overlay 挂载

使用mount命令来挂载到某个位置,需要指定lowerdir ,upperdir,workdir,merged_dir

mount -t overlay overlay -o lowerdir=lower1:lower2:lower3,upperdir=upper,workdir=work merged_dir

该命令将 lower1,lower2,lower3,和upper和work这些目录内的内容放到merged_dir目录中

lowerdir :只读层,对应到当前层之下的所有层的文件
upperdir:读写层,当前层的文件
workdir:不用管
merged_dir:合并后放的位置

此时如果修改某个文件的内容,如果该文件来自lowdir,那么该文件修改后,upperdir内会多出一个修改的内容的文件,但lowdir中的内容不会改变

此时如果修改删除merged_dir的一个文件,如果该文件来自lowdir,那么merged_dir修改后,upperdir内会多出一个whiteout的文件(就是标志该文件在已经没了),但lowdir中的文件没有变化

sudo docker info

查看docker相关配置信息

在这里插入图片描述

存储Docker镜像的文件系统为extfs。支持d_type为真。

Docker镜像和容器数据被储存在“/ var / snap / docker / common / var-lib-docker”目录中。具体来说,镜像位于“/ var / snap / docker / common / var-lib-docker / image”目录中,而容器数据和其他相关文件则位于“/ var / snap / docker / common / var-lib-docker”目录中。

在这里插入图片描述

docker 的overlay2

docker 拉取一个镜像,该镜像位置在

/var/snap/docker/common/var-lib-docker/overlay2

查看该目录
在这里插入图片描述
除了l目录其他都是镜像层

  • diff:该镜像层的文件
  • link:当前镜像层的diff 在 l 目录中的软连接名称
  • lower:此镜像层之下的所有层的软链接名称(对于到diff,即之下所有镜像的所有文件)

在这里插入图片描述

镜像和容器和overlay2

实际上,/var/snap/docker/common/var-lib-docker/overlay2下还能存放init层,和容器层,一个完整的容器分为3层:镜像层、init层和容器层,当docker创建一个容器时候就会创建init层和容器层

overlay2 通过联合挂载技术,将镜像层的diff、init层的diff与容器层的diff挂载到容器层的merged目录

  • init层:做些容器需要的一些配置但因为镜像层是只读层不能被修改所以使用init来配置
  • 镜像层:对应到为该容器层之下的各个镜像
  • 容器层:对应到为挂载的merge所在的目录

此时该对应到的overlay挂载层次如下

  • lowerdir:容器层之下的各个镜像的diff文件
  • upperdir: 容器层的diff文件
  • merged:容器层的merged

在这里插入图片描述
容器层将同名的init层和镜像层合并到容器层的merged层里
在这里插入图片描述

实操

https://github.com/FULLK/llkdocker/tree/main/unionfilesystem

建立五个文件夹

  • lower1:1.txt
  • lower2:2.txt
  • upper:3.txt
  • work:无
  • merged:无
sudo mount -t overlay overlay -olowerdir=lower1:lower2,upperdir=upper,workdir=work merged
挂载到merged上去

在这里插入图片描述

然后分别删除merged里面1.txt的内容,发现diff多了一个whiteout的1.txt文件,修改merged里面2.txt的内容,发现diff多了一个修改后的2.txt文件,在到merge新建一个4.txt,upper也出现一个一模一样的4.txt

llk@llk-virtual-machine:~/Desktop/docker/unionfilesystem$ sudo tree -L 2 
.
├── lower1
│   └── 1.txt
├── lower2
│   └── 2.txt
├── merged
│   ├── 1.txt
│   ├── 2.txt
│   └── 3.txt
├── upper
│   └── 3.txt
└── work
    └── work

6 directories, 6 files
llk@llk-virtual-machine:~/Desktop/docker/unionfilesystem$ cat ./merged/1.txt
from lower 1 
llk@llk-virtual-machine:~/Desktop/docker/unionfilesystem$ rm ./merged/1.txt
llk@llk-virtual-machine:~/Desktop/docker/unionfilesystem$ sudo tree -L 2 
.
├── lower1
│   └── 1.txt
├── lower2
│   └── 2.txt
├── merged
│   ├── 2.txt
│   └── 3.txt
├── upper
│   ├── 1.txt
│   └── 3.txt
└── work
    └── work

6 directories, 6 files
llk@llk-virtual-machine:~/Desktop/docker/unionfilesystem$ cd merged
llk@llk-virtual-machine:~/Desktop/docker/unionfilesystem/merged$ touch 4.txt
llk@llk-virtual-machine:~/Desktop/docker/unionfilesystem/merged$ sudo tree -L 2 
.
├── 2.txt
├── 3.txt
└── 4.txt

0 directories, 3 files
llk@llk-virtual-machine:~/Desktop/docker/unionfilesystem/merged$ cd ../
llk@llk-virtual-machine:~/Desktop/docker/unionfilesystem$ sudo tree -L 2 
.
├── lower1
│   └── 1.txt
├── lower2
│   └── 2.txt
├── merged
│   ├── 2.txt
│   ├── 3.txt
│   └── 4.txt
├── upper
│   ├── 1.txt
│   ├── 3.txt
│   └── 4.txt
└── work
    └── work

6 directories, 8 files
llk@llk-virtual-machine:~/Desktop/docker/unionfilesystem$ editor merged/2.txt
llk@llk-virtual-machine:~/Desktop/docker/unionfilesystem$ sudo tree -L 2 
.
├── lower1
│   └── 1.txt
├── lower2
│   └── 2.txt
├── merged
│   ├── 2.txt
│   ├── 3.txt
│   └── 4.txt
├── upper
│   ├── 1.txt
│   ├── 2.txt
│   ├── 3.txt
│   └── 4.txt
└── work
    └── work

6 directories, 9 files
llk@llk-virtual-machine:~/Desktop/docker/unionfilesystem$ 

疑问点

就是docker运行容器后,会将镜像层和init层和当前容器层的diff挂载到容器层的meged里,发现merged没有内容
而且mount | grep overlay2 也没有找到docker启动容器时候应该挂载的那个merged

大佬说需要参考源代码才能知道最新的流程,这里先留着,等以后搓的时候遇到如何实现后再回来看看

https://github.com/microsoft/docker/blob/master/volume/volume.go#L18

https://github.com/microsoft/docker/blob/master/daemon/graphdriver/overlay/overlay.go#L234

在这里插入图片描述

  • 10
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

看星猩的柴狗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值