龙空技术网

重学容器32: 理解容器文件系统OverlayFS

架构小白 522

前言:

眼前你们对“容器文件系统”大概比较注重,咱们都想要剖析一些“容器文件系统”的相关内容。那么小编也在网上收集了一些关于“容器文件系统””的相关文章,希望各位老铁们能喜欢,朋友们一起来了解一下吧!

前面在第9节"Containerd是如何存储容器镜像和数据的"中介绍了,containerd的snapshotter的主要作用就是通过mount各个层为容器准备rootfs。containerd默认配置的snapshotter是overlayfs,overlayfs是联合文件系统的一种实现。 overlayfs将只读的镜像层成为lowerdir,将读写的容器层成为upperdir,最后联合挂载呈现出mergedir。

OverlayFS从linux kernel 3.18已经被合并到了主干分支,containerd默认使用overlayfs准备容器的RootFS。 OverlayFS对文件系统的挂载涉及到4类目录,分别是lowerdir, upperdir, mergeddir, workdir。

lowerdir是OverlayFS中只读的层,不能被修改,OverlayFS支持多个lowerdirupperdir是可读写的,OverlayFS中对文件的创建、修改、删除操作都在这一层体现。mergeddir是挂载点(mount point)目录,也是用户最终看到的目录workdir用来存放临时文件,用来存放文件修改中间过程的临时文件

本节将根据Julia Evans博客–overlayfs/中的内容,对OverlayFS使用实际操作一遍,加深对OverlayFS的理解。

下面来创建一个我们自己的OverlayFS,将创建lowerdir, upperdir, 以及创建一个mergeddir来挂载合并后的文件系统。

mkdir /root/myoverlayfscd /root/myoverlayfsmkdir upper lower merged workecho "from lower" > lower/in_lower.txt echo "from upper" > upper/in_upper.txtecho "Ifrom lower" > lower/in_both.txt echo "from upper" > upper/in_both.txt 

将lower, upper目录联合挂载到merged目录十分简单,只需使用mount命令:

mount -t overlay overlay -o lowerdir=lower,upperdir=upper,workdir=work merged

可以看到挂载到merged目录的文件系统:

mount | grep myoverlayfsoverlay on /root/myoverlayfs/merged type overlay (rw,relatime,lowerdir=lower,upperdir=upper,workdir=work)

查看merged目录可以得到下面的结果:

ls mergedin_both.txt  in_lower.txt  in_upper.txtcat merged/in_both.txtfrom uppercat merged/in_lower.txtfrom lowercat merged/in_upper.txtfrom upper 

in_lower.txt文件来自lower目录,in_upper.txt文件来自upper目录,in_both.txt文件来自upper目录(覆盖了lower目录中的同名文件)。

下面merged目录中创建一个文件,会发现新建的文件出现在upper目录,即upper目录为读写层。

echo 'new file' > merged/new_filels *lower:in_both.txt  in_lower.txtmerged:in_both.txt  in_lower.txt  in_upper.txt  new_fileupper:in_both.txt  in_upper.txt  new_file

删除merged目录中的in_both.txt文件,upper目录里的in_both.txt文件不变,lower目录中的文件in_both.txt变成了一个特殊文件,标记其被删除,而且其不再出现在merged目录里:

rm -f merged/in_both.txtls -l upper/in_both.txt lower/in_both.txt merged/in_both.txtls: cannot access merged/in_both.txt: No such file or directory-rw-r--r-- 1 root root   12 lower/in_both.txtc--------- 1 root root 0, 0 upper/in_both.txt

修改merged目录中的in_lower.txt,会在upper目录中新建一个in_lower.txt文件包含新的内容。

echo "modify lower" >> merged/in_lower.txt cat lower/in_lower.txtfrom lowercat upper/in_lower.txtfrom lowermodify lowercat merged/in_lower.txtfrom lowermodify lower

通过这个例子基本上就理解OverlayFS如何工作了。

最后再来看一下使用nerdctl启动一个containerd容器时,rootfs是如何挂载的。

nerdctl run -d redis:alpine3.145e8a35c2f7a161424d87cc4acfc2e1183407fa562c3884a4f7e7180ab8bd9db2mount | grep 5e8a35c2f7a161424d87cc4acfc2e1183407fa562c3884a4f7e7180ab8bd9db2overlay on /run/containerd/io.containerd.runtime.v2.task/default/5e8a35c2f7a161424d87cc4acfc2e1183407fa562c3884a4f7e7180ab8bd9db2/rootfs type overlay (rw,relatime,lowerdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/464/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/463/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/462/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/461/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/460/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/459/fs,upperdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/824/fs,workdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/824/work)

可以看到容器镜像的各层挂载为overlayfs的lowerdir,可读写层挂载为overlayfs的upperdir,最终联合挂载合并呈现的目录为/run/containerd/io.containerd.runtime.v2.task/default/5e8a35c2f7a161424d87cc4acfc2e1183407fa562c3884a4f7e7180ab8bd9db2/rootfs为容器的rootfs,ls查看这个目录可以看到一个典型的linux系统目录结构。

参考–overlayfs/

标签: #容器文件系统