Docker 容器中的文件查找如何工作

How file lookup work in Docker container

根据Docker docs,每个Docker文件指令创建一个图层,当你在旧图像的基础上创建新图像时,所有图层都被保留。然后当我创建自己的图像时,由于基础图像层的递归继承,我可能涉及数百层。

据我了解,容器中的文件查找是这样工作的:

  1. 进程想要访问文件 a,查找从容器层(薄 w/r 层)开始。
  2. UnionFS检查该层是否有记录(有或标记为已删除)。如果是,则分别 return 或说未找到,结束查找。如果不是,则将任务交给下一层。
  3. 底层查找结束

如果是这样,考虑一个位于底层且其他层未更改的文件,/bin/sh可能需要遍历所有层到底部。尽管这些层可能非常轻量级,但查找仍然需要比普通层多 100 倍的时间,这一点很明显。但根据我的经验,Docker 非常快,几乎与本地 OS 相同。我哪里错了?

这都要感谢UnionFS and Union mounts

直接来自维基百科:

It allows files and directories of separate file systems, known as branches, to be transparently overlaid, forming a single coherent file system.

来自一个有趣的 article:

In the kernel, the filesystems are stacked in order of their mount sequence, the first mounted filesystem is at the bottom of the mount stack, and the latest mount is at the top of the stack. Only the files and directories of the top of the mount stack are visible. With union mounts, directory entries from the lower filesystems are merged with the directory entries of upper filesystem, thus making a logical combination of all mounted filesystems. Files with the same name in a lower filesystem are masked, as the upper one takes precedence.

所以它不是传统意义上的 "go through layers"(例如一次一个),而是它知道(在任何给定时间)哪个文件驻留在哪个磁盘上。

在文件系统层执行此操作还意味着 none 软件必须担心文件所在的位置,它知道请求 /bin/sh 并且文件系统知道从哪里获取它。

可以在 webinar 中找到更多信息。

所以回答你的问题:

Where am I wrong?

您认为它必须一次一层地查看,而实际上它不必这样做。 (UnionFS 太棒了!)

为了补充正确的先前答案,写时复制 (CoW) 和联合文件系统实现者希望具有接近本机的性能,因此,当然,已经调整了它们的实现并且 "API" 具有最好的 lookup/filesystem 表现。

就是说,很高兴知道 Docker 并不是仅在 union/CoW 文件系统的单个 'type' 之上运行,而是有一小部分可用选项,默认值取决于安装它的 Linux 发行版。

AUFS 和 overlay(fs) 是最常见的,但 Docker 还支持 devicemapper(Red Hat 在 Fedora/RHEL/CentOS 上提供和支持)、btrfs 和 zfs。我有一个 blog post 比较和对比可能感兴趣的各种选项。