容器的文件系统到底在磁盘上是什么样?这篇用一个特权容器进入 Docker Desktop 的虚拟机,直接看容器的 overlay 挂载选项,列出每个 lower 目录里的文件,再看容器里写文件时 upperdir 的变化。
docker info:Storage Driver = overlayfs;DriverStatus = [[driver-type io.containerd.snapshotter.v1]] docker inspect 的 GraphDriver = null(没有 overlay2 的 LowerDir / UpperDir 字段) 镜像 bwlab-c19 有 4 层(RootFS.Layers)
这个 Docker Desktop(Docker Engine 29.8.2)用的是 containerd 的 overlayfs snapshotter,docker info 里 Storage Driver 是 overlayfs,docker inspect 的 GraphDriver 是 null,目录在虚拟机里 /var/lib/desktop-containerd/…/snapshots/ 下,不是文章里常说的 /var/lib/docker/overlay2。经典 overlay2 驱动的目录结构我没有测。
挂载点:/var/lib/docker/rootfs/overlayfs/<容器ID>;文件系统类型:overlay
lowerdir 有 5 个目录(镜像 4 层);第一个:<snapshots>/2005/fs
upperdir = <snapshots>/2006/fs
workdir = <snapshots>/2006/work
lowerdir 的顺序:最上面一层在最前面。逐个看每个 lower 目录里有什么:
lower[0] 有:dev etc
lower[1] 有:big.bin
lower[2] 有:two.txt
lower[3] 有:one.txt
lower[4] 有:bin dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
lower[0] 里的文件:/etc/hostname /etc/resolv.conf /etc/hosts /etc/mtab /.dockerenv /dev/console(镜像只有 4 层,多出来的这一层是容器创建时加的)进入虚拟机(特权容器加 nsenter -t 1)查 /proc/mounts,容器的根是一个 overlay 挂载,选项里有 lowerdir(5 个目录,最上层在前)、upperdir 和 workdir。多出来的那个 lower 里是 hostname、hosts、resolv.conf 等容器创建时生成的文件。
容器启动后 upperdir 里:(空) 容器里创建 new.txt、新目录 newdir,并往原有的 one.txt 追加一行之后,upperdir 里:new.txt newdir one.txt upperdir 里的 one.txt 内容:one | changed 每个 lower 里的 one.txt:['无', '无', '无', 'one', '无'] 没改动的 big.bin 在 upperdir 里吗?False
新建的文件和目录直接出现在 upperdir;修改 lower 里已有的文件,先整个复制进 upperdir 再改(copy-up,见后面的专题),没改动的大文件不会被复制。
在挂载点上 ls:big.bin bin dev etc home lib media mnt new.txt newdir one.txt opt proc root run sbin srv sys tmp two.txt usr var 挂载点上 cat one.txt:one | changed;容器里 cat one.txt:one | changed
挂载点就是合并后的视图:所有层的文件并集,同名文件取最上层的。宿主(虚拟机)上 cat 和容器里 cat 的结果相同。
upperdir 还在吗?在;挂载点还在吗?1 行挂载记录 docker rm -f 之后:upperdir 已删除;挂载记录 0 行 容器创建时多出来的 lower[0]:已删除;镜像的层 lower[1]:在
docker rm -f 之后 upperdir 和容器创建时的那一层都被删除,挂载记录消失,镜像的层还在。需要保留的数据应该放在 volume 里。