什么是 overlayfs

什么是 overlayfs

如果你使用过 Docker,可能听过 aufs,与之一样,overlayfs 也是一个用于为 Linux 文件系统实现联合挂载的一种文件系统。它的核心概念是堆叠,把多个文件夹按照次序堆叠起来。

不知道你有没有遇到过需要合并文件夹的场景,如果你之前没有接触过类似的文件系统,那么你应该是通过 拷贝 覆盖来完成的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

overlayfs 的特点:

  • 上层文件优先
  • 挂载合并零拷贝
  • 底层文件系统只读

我们合并多个文件夹,就按照 Upper -> Lower 的次序一次堆叠起来,最终用户看到的就是 MergedDir。从上到下,用户只能看到最上层的文件,而无法越过它。这就是实现了一种类似文件夹合并的策略。用一句话理解就是 上层文件优先

它是零拷贝的,它的速度非常快,只需要执行一次 mount 操作就能实现。

另外,你可能注意到了,在用户看到的最终文件系统层下,有一个 UpperDir,这是你在此文件系统中唯一可以操作变动的层,你的所有 增加、修改、删除 操作都是在这一层上完成的,不会有任何记录留在 LowerDir 中,这可以保证你的操作不会污染到原文件夹,即使你看起来是删除的是来自于 LowerDir 的文件。

如何使用

挂载 overlayfs 的基本命令如下:

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

lower1:lower2:lower3是指定lower层的目录,越前面越优先,lower1>lower2>lower3。这里需要注意,lower层可以指定非常多,但是在 overlay1 版本中,最多支持 128 层,在 overlayfs2 中添加了更多层的支持。

使用 overlayfs 非常的简单:

# mkdir lower1
# mkdir lower2
# mkdir upper
# mkdir worker
# mkdir merged
# touch lower1/lower1.txt
# touch lower2/lower2.txt
# touch upper/upper.txt
  • lower1、lower2、upper 三个文件夹,这个三个文件夹是用来合并的
  • 一个空的 worker 文件夹,这文件夹不能有任何内容
  • 最后需要一个 merged 文件夹,用来作为给用户呈现的最终文件夹

worker 文件夹是一个空文件夹,它是作为中间临时文件夹而存在,需要和 upperdir 是同一个文件系统

它最终展示的效果应该是这样: 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

接下来实操一次:

# mount -t overlay overlay -olowerdir=./lower1:./lower2,upperdir=./upper,workdir=./worker ./merged

通过 ls 命令看一下:

# ls ./merged/
lower1.txt  lower2.txt  upper.txt

表现一直,非常完美。接下来我们可以尝试一下增加删除修改

增加文件

# touch ./merged/merged.txt
# ls ./merged/
lower1.txt  lower2.txt  merged.txt  upper.txt
# ls ./upper/
merged.txt  upper.txt

可以看到,增加文件是直接添加到了 upper 文件夹中,

删除文件

# rm -f ./merged/lower1.txt
# ls ./merged/
lower2.txt  merged.txt  upper.txt
# ls ./lower1/
lower1.txt

可以看到,删除文件之后,下面的 lower 文件夹里的内容并没有被真正的删除,但是上面的 merged 文件夹表现是确实已经被删除了。

我们可以直接去查看 upper 文件夹下面的内容:

# ls -al ./upper/
总用量 8
drwxr-xr-x 2 root root 4096 926 19:13 .
drwxr-xr-x 7 root root 4096 926 18:55 ..
c--------- 1 root root 0, 0 926 19:13 lower1.txt
-rw-r--r-- 1 root root    0 926 19:10 merged.txt
-rw-r--r-- 1 root root    0 926 18:56 upper.txt

多了一个 c 类型的文件,名字刚好为 lower1.txt,它表示此文件已经被删除了,会将下层的该文件直接忽略。

修改文件

# echo 'hello' > ./merged/lower2.txt
# cat ./merged/lower2.txt
hello
# ls -al ./upper/
总用量 12
drwxr-xr-x 2 root root 4096 926 19:13 .
drwxr-xr-x 7 root root 4096 926 19:16 ..
c--------- 1 root root 0, 0 926 19:13 lower1.txt
-rw-r--r-- 1 root root    6 926 19:17 lower2.txt
-rw-r--r-- 1 root root    0 926 19:10 merged.txt
-rw-r--r-- 1 root root    0 926 18:56 upper.txt
# cat ./lower2/lower2.txt

当文件修改后,我们查看上层的 upper 文件夹,会发现,多了一个 lower2.txt。而底层的 lower2.txt 仍然没有内容变化。依此可以推断出,其实修改文件是将下层的文件复制到上层来之后再进行修改的。

好了,overlay 的使用非常简单,接下来我们来聊聊它的实现原理。

实现原理

overlayfs 最开始并不是作为 Linux 内核实现的,而是在成熟之后,于 Linux 内核 3.18 版本才合并进来的。

通过上面的操作,其实可以大概推断出来了。首先,需要一套规则,能够实现上层文件优先。这个能力非常的简单:

当查找目录时,如果一个名称在多个层中存在:

  • 如果是文件,则优先级高的文件是可见的,而优先级低的层此文件将被隐藏。
  • 如果是目录,则合并中所有内容(如果内部文件名相同参考上一条)。

添加文件非常的简单,只需要在 upper 上添加就行。

删除文件或文件夹时,会在 upper 中添加一个同名的 c 标示的文件,这个文件叫 whiteout 文件。当扫描到此文件时,会忽略此文件名。

此时又会产生一个特殊情况,如果删除文件,再新增此文件,只覆盖 whiteout 文件即可,这没有问题,但是如果是删除一个文件夹,又再新增此文件夹,如果只覆盖 whiteout。则底层目录里的原文件又会被显示出来,这显然是不可接受的,为此,引入了一个新的属性,叫 Opaque

# mkdir ./lower1/lower1dir
# ls ./merged/
lower1dir  lower2.txt  merged.txt  upper.txt
# rm -rf ./merged/lower1dir/
# ls -al ./upper/
总用量 12
drwxr-xr-x 2 root root 4096 926 19:44 .
drwxr-xr-x 7 root root 4096 926 19:16 ..
c--------- 1 root root 0, 0 926 19:44 lower1dir
c--------- 1 root root 0, 0 926 19:13 lower1.txt
-rw-r--r-- 1 root root    6 926 19:17 lower2.txt
-rw-r--r-- 1 root root    0 926 19:10 merged.txt
-rw-r--r-- 1 root root    0 926 18:56 upper.txt
# mkdir ./merged/lower1dir
# ls -al ./upper/
总用量 16
drwxr-xr-x 3 root root 4096 926 19:48 .
drwxr-xr-x 7 root root 4096 926 19:16 ..
drwxr-xr-x 2 root root 4096 926 19:48 lower1dir
c--------- 1 root root 0, 0 926 19:13 lower1.txt
-rw-r--r-- 1 root root    6 926 19:17 lower2.txt
-rw-r--r-- 1 root root    0 926 19:10 merged.txt
-rw-r--r-- 1 root root    0 926 18:56 upper.txt
# getfattr -n "trusted.overlay.opaque" ./upper/lower1dir
trusted.overlay.opaque="y"

getfattr 指令在centos/debian下可以通过安装 attr 包来使用。

可以看到增加了一个 trusted.overlay.opaque 属性。它表示这是一个当前层的目录,需要隐藏下层的内容。而为了支持修改这个属性,就需要 upper 层所在的文件系统支持 xattr 扩展属性。

修改文件内容时,实际上就是将文件复制到 upper 层再进行写入,这就是写时复制的特性,不仅是内容,事实上你对文件的任何修改,例如rename、修改属性、带写方式打开文件、修改权限等等,都会导致文件发生复制。

总结

overlayfs 被广泛用于容器中,例如镜像构建,容器运行,都会用到相应的技术。你可以在服务器上执行 mount -t overlay 看到所有你挂载的容器所在使用的文件系统,

你应该了解它,它可以被用作容器,也可以用来做非常多的事情,技术无价,只有你想不到,没有你做不到。

<think>我们正在讨论OverlayFS的使用指南和配置问题。根据提供的引用,我们可以总结以下关键点:1.**OverlayFS的基本确认**:通过`df`命令查看挂载点,如果某个分区(如根目录`/`)的挂载类型显示为`overlay`,则表明OverlayFS正在工作(引用[^1])。2.**containerd对OverlayFS的支持**:containerd使用OverlayFS作为默认的文件系统快照器(引用[^2])。3.**nerdctl配置**:nerdctl(一个与containerd兼容的容器CLI)的配置中可能涉及存储配置,其中可能包括OverlayFS的设置(引用[^3])。根据这些信息,我将提供OverlayFS的使用指南和常见配置问题的解决方法。###OverlayFS使用指南OverlayFS是一种联合挂载文件系统,它允许将一个目录(称为upper目录)覆盖在另一个目录(称为lower目录)之上,形成一个统一的视图。它常用于容器(如Docker、containerd)和只读根文件系统的场景。####基本概念-**lowerdir**:底层目录,通常是只读的。-**upperdir**:上层目录,可读写。对文件的修改会记录在这里。-**workdir**:工作目录,OverlayFS内部使用,必须和upperdir在同一个文件系统。-**merged**:合并视图目录,用户在此看到统一的文件系统。####挂载OverlayFS使用`mount`命令挂载OverlayFS:```bashsudomount-toverlayoverlay-olowerdir=/path/to/lower,upperdir=/path/to/upper,workdir=/path/to/work/path/to/merged```-注意:`workdir`必须是一个空目录,且与`upperdir`在同一文件系统。####示例:创建OverlayFS1.创建必要的目录:```bashmkdirlowerupperworkmerged```2.在`lower`目录中创建一些文件(例如`file1.txt`)。3.挂载:```bashsudomount-toverlayoverlay-olowerdir=lower,upperdir=upper,workdir=workmerged```4.现在,`merged`目录将显示`lower`和`upper`的合并内容。对`merged`的写入会反映到`upper`目录。####卸载OverlayFS```bashsudoumount/path/to/merged```###OverlayFS常见配置问题####问题1:挂载失败,提示"workdirisnotanabsolutepath"或"workdirandupperdirmustbeunderthesamemount"-**原因**:`workdir`必须是绝对路径,且与`upperdir`位于同一文件系统。-**解决**:确保使用绝对路径,并检查`upperdir`和`workdir`是否在同一设备上。####问题2:挂载失败,提示"overlayfs:missing'lowerdir'"-**原因**:未指定`lowerdir`或路径错误。-**解决**:检查`lowerdir`参数是否正确,多个lowerdir用冒号分隔(例如`lowerdir=/lower1:/lower2`)。####问题3:文件操作错误(如“Read-onlyfilesystem”)-**原因**:底层文件系统是只读的,但未正确设置`upperdir`。-**解决**:确保指定了可写的`upperdir`,并且挂载选项正确。####问题4:容器运行时(如containerd)使用OverlayFS的问题-**情况**:容器启动失败,日志提示文件系统相关问题。-**可能原因**:1.内核不支持OverlayFS:需要内核版本3.18以上。2.存储驱动配置错误:在containerd配置中,可能需要指定OverlayFS作为快照器。-**解决**:1.检查内核版本:`uname-r`2.加载OverlayFS模块:`sudomodprobeoverlay`3.确保containerd配置正确(通常在`/etc/containerd/config.toml`):```toml[plugins."io.containerd.snapshotter.v1.overlayfs"]root_path="/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs"```然后重启containerd:`sudosystemctlrestartcontainerd`###在容器中使用OverlayFS如引用[^1]所示,在树莓派等设备上,根文件系统可能已使用OverlayFS(挂载点为`/`)。在容器环境中,OverlayFS通常由容器运行时(如containerd)自动管理。引用[^2]提到containerd支持OverlayFS作为默认快照器。###配置容器运行时使用OverlayFS对于nerdctl(引用[^3]),可以通过配置文件设置存储驱动。编辑`~/.nerdctl/nerdctl.toml`:```toml#使用overlayfs作为快照器snapshotter="overlayfs"```或者通过环境变量:```bashexportCONTAINERD_SNAPSHOTTER=overlayfs```###总结OverlayFS是一种高效的文件系统层叠技术,广泛应用于容器和嵌入式系统。正确配置需要确保内核支持、路径正确以及容器运行时的配置一致。遇到问题时,检查挂载参数、文件系统权限和内核模块加载情况。§§相关问题§§1.OverlayFS和AUFS有什么区别?2.如何检查内核是否支持OverlayFS?3.在Docker中如何配置使用OverlayFS存储驱动?4.OverlayFS如何处理同名文件?</think>### OverlayFS 使用指南与配置详解 #### 一、OverlayFS 基础概念 OverlayFS 是一种联合挂载文件系统,通过**分层结构**实现文件系统的叠加: - **lowerdir**:只读的底层目录(可多个) - **upperdir**:可写的上层目录 - **merged**:合并后的统一视图 - **workdir**:内部工作目录(需与 upperdir 同文件系统) 其工作逻辑满足: $$ \text{merged 视图} = \text{upperdir} \oplus \text{lowerdir} $$ 修改文件时优先写入 upperdir,删除文件时在 upperdir 创建白名单(whiteout)。 --- #### 二、配置与挂载步骤 1. **创建目录结构**: ```bash mkdir -p {lower,upper,work,merged} ``` 2. **挂载 OverlayFS**: ```bash sudo mount -t overlay overlay \ -o lowerdir=./lower,upperdir=./upper,workdir=./work \ ./merged ``` 3. **验证挂载**: ```bash df -Th | grep overlay # 应显示 overlay 类型 ``` 成功时输出类似: ``` overlay overlay 28925547 1315493 26112465 5% / ``` [^1] --- #### 三、容器环境配置 在容器运行时中启用 OverlayFS: 1. **containerd 配置**(`/etc/containerd/config.toml`): ```toml [plugins."io.containerd.snapshotter.v1"] snapshotter = "overlayfs" # 设为默认快照器 ``` [^2] 2. **nerdctl 配置**(`~/.nerdctl/nerdctl.toml`): ```toml snapshotter = "overlayfs" # 指定存储驱动 ``` [^3] 3. **重启服务**: ```bash sudo systemctl restart containerd ``` --- #### 四、常见问题解决 1. **挂载失败:`invalid argument`** - **原因**:内核不支持 OverlayFS - **解决**: ```bash sudo modprobe overlay # 加载内核模块 grep overlay /proc/filesystems # 验证支持 ``` 2. **文件删除异常** - **现象**:删除文件后仍出现在 merged 视图 - **解决**:检查 upperdir 是否成功生成 `whiteout` 文件(以 `.wh.` 前缀标记) 3. **性能问题** - **优化方案**: - 避免 deep directory nesting(深层嵌套) - 使用 SSD 存储 upperdir - 限制 lowerdir 层数(建议 ≤3 层) 4. **容器启动失败** - **检查点**: ```bash containerd config dump | grep snapshotter # 确认配置生效 dmesg | grep overlay # 查内核日志 ``` --- #### 五、典型应用场景 1. **容器镜像分层** Docker/containerd 使用 OverlayFS 实现镜像层(lowerdir)与容器可写层(upperdir)的叠加。 2. **只读根文件系统** 嵌入式系统(如树莓派)将 OS 挂载为 lowerdir,用户数据写入 upperdir: ```bash mount -t overlay overlay -o lowerdir=/ro_root,upperdir=/rw_data,workdir=/work /new_root ``` [^1] 3. **无状态应用部署** 基础系统作为 lowerdir,应用配置和临时数据存储在 upperdir,重启后自动还原。 --- ### 相关问题 1. OverlayFS 与 AUFS 的性能对比有哪些关键差异? 2. 如何在 Kubernetes 集群中排查 OverlayFS 导致的容器启动失败问题? 3. OverlayFS 的 `redirect_dir` 功能如何解决目录合并冲突? 4. 当 upperdir 磁盘写满时,系统会产生什么异常?如何应急处理?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值