如何使用 OverlayFS?

如何使用 OverlayFS?

回答电子邮件表明 Ubuntu 11.10 中存在一种名为“OverlayFS”的东西,并且将强制取代 Ubuntu 12.04 中的 aufs。

我如何使用它?它的文档在哪里?

答案1

编辑:自从写这个答案以来,overlayfs 中的一些内容发生了变化,即增加了一个必需参数workdir,请参阅托蒂的回答下面了解有关此新参数的详细描述。

我终于找到了它。我在内核源代码中找到了对它的引用,但由于某种原因,它没有出现在 kernel.org 上的 git 树中。但是!如果你像这样拉取 Ubuntu 内核源代码:apt-get source linux-image-3.0.0-16-generic你可以在 中找到它linux-3.0.0/Documentation/overlayfs.txt。它也可以在 中的 linux-doc 包中找到/usr/share/doc/linux-doc/filesystems/overlayfs.txt.gz

由于实际的帮助文档更多的是“它如何工作”而不是“如何使用它安装”,这里有一个简短的概述(内核文档中有一个例子):

mount -t overlayfs -o [mount options] overlayfs [mountpoint for merged system]

其中 [mount options] 可以是:

  • lowerdir=somedir:lowerdir 是您要放置新文件系统的目录,如果有重复,则这些目录将被 upperdir 的版本覆盖(实际上是隐藏起来)
  • upperdir=somedir:upperdir 是要覆盖 lowerdir 的目录。如果 lowerdir 和 upperdir 中存在重复的文件名,则 upperdir 的版本优先。
  • 标准安装选项。我从代码中看到的唯一选项是 ro/rw,但你可以尝试一下。

一开始让我感到困惑的一件事(所以我可能应该澄清一下)是,挂载 overlayfs 实际上并不挂载文件系统。我曾尝试使用 overlayfs 挂载来挂载 squashfs 文件系统,但事实并非如此。您必须首先将(在我的情况下是 squashfs)文件系统挂载到任意目录,然后使用 overlayfs 将挂载点(目录)和另一个目录合并到第三级目录(overlayfs 挂载点)(编辑:这个“第三级”目录实际上可以是 upperdir= 目录)。您将在第三级目录中看到合并的文件系统(或目录树 - 它很灵活)。

示例 1,覆盖根文件系统

我一直在研究 Ubuntu 混合启动盘,其中基本 Ubuntu 系统以 filesystem.squashfs 的形式存在,并且我有名为 ubuntu.overlay kubuntu.overlay xubuntu.overlay 和 lubuntu.overlay 的文件。.overlay 文件是上述系统的基本安装,其中 filesystem.squashfs 的内容已被删减(以节省空间)。然后我修改了 init 脚本,使用 overlayfs 和上述选项覆盖正确的发行版的 .overlay 文件(来自启动参数),它运行得非常好!

这些是我在初始化脚本中使用的行(一旦所有变量都被翻译):

mkdir -p /overlay
mount -t squashfs /cdrom/casper/ubuntu.overlay /overlay
mount -t overlayfs -o lowerdir=/filesystem.squashfs,upperdir=/overlay overlayfs /

请注意,上面的 filesystem.squashfs 是目录由 casper 创建,不是文件。

这三个语句创建一个/overlay目录,在该目录上挂载一个 squashfs 文件系统,然后使用 OverlayFS 来合并/overlay的内容。/overlay/

示例2、透明合并两个目录

在为每个版本重新构建实时 USB 的过程中,我使用 OverlayFS 来节省大量时间。我首先从一个名为 ubuntu-base 的目录开始,其中包含最基本的安装 ubuntu-core 映像的内容。然后我将创建名为 ubuntu、kubuntu、lubuntu 和 xubuntu 的目录。

然后,我使用 OverlayFS 使 ubuntu-base 中的文件显示在各个目录中。我会使用类似这样的方法:

mount -t overlayfs -o lowerdir=ubuntu-base,upperdir=kubuntu overlayfs kubuntu

这会使 ubuntu-base 中的文件显示在 kubuntu 文件夹中。然后,我可以chroot进入 kubuntu 文件夹并执行类似 的操作apt-get install kubuntu-desktop。在此 OverlayFS 挂载中所做的任何更改都将保留在上层目录中,在本例中为 kubuntu 文件夹。然后,一旦我卸载 OverlayFS 挂载,ubuntu-base 中实际存在但“镜像”到 kubuntu 文件夹中的文件就会消失,除非它们已被更改。这使我不必在 ubuntu-base 中拥有文件的多个副本,同时仍然可以使用它们,就像它们在每个位置都实际存在一样。

答案2

https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt

上部和下部

覆盖文件系统结合了两个文件系统 - “上层”文件系统和“下层”文件系统。当两个文件系统中都存在名称时,“上层”文件系统中的对象可见,而“下层”文件系统中的对象则隐藏,或者在目录的情况下与“上层”对象合并。

称其为上层和下层“目录树”而不是“文件系统”更为正确,因为两个目录树完全有可能位于同一个文件系统中,并且没有要求为上层或下层提供文件系统的根。

下层文件系统可以是 Linux 支持的任何文件系统,不需要可写。下层文件系统甚至可以是另一个 overlayfs。上层文件系统通常是可写的,如果是,它必须支持创建受信任的.* 扩展属性,并且必须在 readdir 响应中提供有效的 d_type,因此 NFS 不适合。

两个只读文件系统的只读覆盖可以使用任何文件系统类型。

目录

覆盖主要涉及目录。如果给定名称同时出现在上层和下层文件系统中,并且引用其中任一文件系统中的非目录,则下层对象将被隐藏 - 该名称仅引用上层对象。

当上层对象和下层对象都是目录时,会形成合并目录。

在挂载时,作为挂载选项“lowerdir”和“upperdir”给出的两个目录将合并为一个合并目录:

mount -t overlay overlay -olowerdir=/lower,upperdir=/upper,workdir=/work /merged

“workdir” 需要是与 upperdir 位于同一文件系统上的空目录。

然后,每当请求在这样的合并目录中进行查找时,都会在每个实际目录中执行查找,并将组合结果缓存在属于覆盖文件系统的 dentry 中。如果两个实际查找都找到目录,则将两个目录都存储起来并创建一个合并目录,否则只存储一个:如果存在则存储上层目录,否则存储下层目录。

仅合并目录中的名称列表。其他内容(如元数据和扩展属性)仅针对上层目录报告。下层目录的这些属性被隐藏。

答案3

最小可运行示例

# Create the filesystems.
dd if=/dev/zero of=lower.ext4 bs=1024 count=102400
mkfs -t ext4 lower.ext4
cp lower.ext4 upper.ext4
mkdir lower upper overlay
sudo mount lower.ext4 lower
sudo mount upper.ext4 upper
sudo chown "$USER:$USER" lower upper
printf lower-content > lower/lower-file
# Upper and work must be on the same filesystem.
mkdir upper/upper upper/work
printf upper-content > upper/upper/upper-file
# Work must be empty. E.g. this would be bad:
#printf work-content > upper/work/work-file
# Make the lower readonly to show that that is possible:
# writes actually end up on the upper filesystem.
sudo mount -o remount,ro lower.ext4 lower

# Create the overlay mount.
sudo mount \
  -t overlay \
  -o lowerdir=lower,upperdir=upper/upper,workdir=upper/work \
  none \
  overlay \
;

# Interact with the mount.
printf 'overlay-content' > overlay/overlay-file
ls lower upper/upper upper/work overlay

# Write to underlying directories while mounted
# gives undefined behaviour.
#printf lower-content-2 > lower/lower-file-2
#printf upper-content-2 > upper/upper-file-2

# Unmount the overlay and observe state.
sudo umount overlay
ls lower upper/upper upper/work

# Cleanup.
sudo umount upper lower

GitHub 上游

第一个ls安装的输出:

lower:
lost+found  lower-file

overlay:
lost+found  lower-file  overlay-file  upper-file

upper/upper:
overlay-file  upper-file

upper/work:
work

第二个ls没有安装的输出:

lower:
lost+found  lower-file

upper/upper:
overlay-file  upper-file

upper/work:
work

解释:

  • 较低:写入覆盖后没有变化
  • upper:接收到对 overlay 的修改
  • 覆盖:同时显示上层和下层的文件
  • 工作:包含一些work/我们不应该关心的随机内容(目录)

示例改编自:OverlayFS 使用示例

这是一个更复杂的例子,有多个较低层:Overlayfs 使用多层重新加载(从 aufs 迁移)

在 Ubuntu 18.04、Linux 内核 4.15.0 上测试。

答案4

在 fstab 中挂载 OverlayFS

以上答案解释了如何从命令行和/或脚本挂载覆盖文件系统。也可以从以下位置挂载 OverlayFS:文件系统

挂载 OverlayFS 存在固有问题。由于我们要挂载目录,因此这些目录必须存在和/或就绪。存在意味着特定目录所在的文件系统已挂载,而就绪意味着特定目录已“填充”。后者的示例是将 ISO 映像挂载到特定目录,或挂载网络共享(任何类型)。

挂载不存在的目录将会失败,但挂载尚未“填充”的目录不会失败,因为 OverlayFS 无法知道目录是否已准备就绪。

从 fstab 挂载文件系统时,这尤其成问题,因为所有挂载都是并行完成的,因此我们无法确保为 OverlayFS 做好一切都准备就绪。

但是,如果 Linux 发行版使用 systemd,则文件系统的挂载由它处理。Systemd 读取 fstab 文件,并动态创建挂载单元。之后,所有挂载都由 systemd 处理。Systemd 单元文件有选项:r需要,可用于控制fstab中定义的挂载顺序和依赖性,从而确保OverlayFS的挂载不会失败(至少不会因为顺序错误而失败)。

为了在 fstab 文件中设置挂载的顺序/依赖性,我们将声明 systemd 选项“要求“使用语法:x-systemd.require. 此选项的参数是应在给定挂载(在 fstab 中定义)之前成功挂载的挂载点。

例子:

为了展示一个例子(和语法文件系统条目),我们将展示一个案例,我们将覆盖挂载 iso 映像的目录,而这个特定的映像文件将存储在单独的硬盘上,在我们访问映像文件之前必须先挂载该硬盘。从而形成所需的事件顺序:

mount hdd -> mount iso image -> mount OverlayFS

对于给定的情况,fstab 条目将如下所示:

# 1. mount hdd partition
# 2. mount iso image from hdd partition, but only if/after hdd is mounted
# 3. overlay iso image, but only if/after iso image is mounted
#
/dev/hdb1            /mnt/hdd      ext4     errors=remount-ro                 0  2  
/mnt/hdd/linux.iso   /mnt/iso      auto     x-systemd.requires=/mnt/hdd,ro    0  0
overlay              /mnt/merged   overlay  x-systemd.requires=/mnt/iso,lowerdir=/mnt/iso,upperdir=/overlay/lower,workdir=/overlay/working  0 0
                                                                            

如果链中的任何挂载失败,则不会执行依赖的挂载。

笔记:

Arch Linux 维基有一个使用 fstab 挂载 OverlayFS 的示例,其中使用了以下选项:

noauto,x-systemd.automount

这将产生效果,覆盖文件系统将简单未安装在启动时(禁止自动选项),避免在先前的挂载尚未准备好时可能出现故障。首次访问覆盖目录时,将挂载文件系统(x-systemd.automount选项)。 这种方法有两个缺点:

  1. 如果所需的下层/上层目录尚未准备好,此挂载将失败。
  2. 即使下层/上层目录未填充,挂载也会成功(例如 ISO 未挂载)

我们可以通过添加来避免x-systemd.require到选项列表。

相关内容