Linux OverlayFS详解

Linux OverlayFS详解

OverlayFS 是 Linux 内核自带的联合挂载(Union Mount)文件系统:把多个目录叠成一个统一目录树,读写在逻辑上像操作普通文件夹,底层却可区分「只读基底」与「可写覆盖层」。Docker 镜像分层、Live 系统、测试回滚、增量备份背后,常见都有它的影子。

速览

  • 四要素lowerdir(只读层)+ upperdir(读写层)+ workdir(内部工作目录)→ 挂载到 merged 视图。
  • :先 upper ,再按优先级查 lower
  • :修改 lower 上已有文件 → 写时复制(CoW) 到 upper 再改;新建直接写在 upper。
  • 删 lower 文件 :在 upper 建 whiteout 标记,不删 lower 实体。
  • 依赖 :upper/work 须在支持 xattr 的文件系统上(如 ext4、xfs),且 同一文件系统
text 复制代码
merged(用户看到的统一视图)
  ↑ mount overlay
lowerdir(只读,可多目录) + upperdir(可写) + workdir(临时)

目录

一、概念与结构

  • [1. OverlayFS 是什么](#1. OverlayFS 是什么)
  • [2. 四层目录角色](#2. 四层目录角色)

二、读写与合并规则

  • [3. 读取路径](#3. 读取路径)
  • [4. 写入与写时复制 CoW](#4. 写入与写时复制 CoW)
  • [5. 删除与 whiteout](#5. 删除与 whiteout)
  • [6. 目录合并与 opaque](#6. 目录合并与 opaque)

三、使用与场景

  • [7. 挂载命令与示例](#7. 挂载命令与示例)
  • [8. 典型应用场景](#8. 典型应用场景)
  • [9. 实战案例提要](#9. 实战案例提要)

四、运维

  • [10. 性能与选型注意](#10. 性能与选型注意)
  • [11. 速查卡](#11. 速查卡)

1. OverlayFS 是什么

特点 说明
联合挂载 多个目录合并为一个逻辑文件系统视图
非块设备 FS 不直接管理磁盘块,叠在 ext4、xfs、btrfs 等已有 FS 之上
内核原生 Linux 3.18+ 主线;容器生态广泛使用
与 UnionFS 思路相近;现代 Linux 上 OverlayFS 是主流实现

底层文件系统
Overlay 层
用户视角
merged 挂载点

统一目录树
upperdir 可写
lowerdir 只读

可多层
workdir 内部
ext4 / xfs / ...


2. 四层目录角色

目录 别名 读写 作用
lowerdir 下层 / 只读层 只读 基底内容;可多个 ,逗号分隔;左侧优先级高于右侧
upperdir 上层 / 读写层 读写 所有变更(新建、修改、删除标记)落在这里
workdir 工作目录 内核用 必须为空 ;CoW 等操作的临时空间;必须与 upperdir 同一文件系统
merged 合并视图 / 挂载点 用户访问 mount 后对外呈现的路径
text 复制代码
lowerdir=A:B:C     (只读;查找时 **A 优先于 B 优先于 C**,最左优先级最高)
upperdir=U         (唯一可写)
workdir=W          (空目录,与 U 同 FS)
merged=M           (mount 目标)

Docker 对应关系(概念)

Overlay Docker
lowerdir 多层 镜像层(只读)
upperdir 容器可写层
merged 容器内 / 所见根文件系统

3. 读取路径

是文件/目录



访问 merged 下路径
upperdir

存在?
返回 upper 内容
按优先级扫描 lowerdir

左 → 右
找到?
返回 lower 内容
不存在

规则 说明
文件 upper 有则用 upper;否则在 lower 链中找第一个命中
目录 同名目录 合并 展示(见 §6)
whiteout upper 上的特殊标记表示「下层文件已删除」,读时 不可见

4. 写入与写时复制 CoW

操作 行为
在 merged 新建文件/目录 直接创建在 upperdir
修改 upper 已有文件 直接写 upper
修改 lower 已有文件 CoW :先复制到 upper,再改 upper 副本;lower 原文件不变

workdir upperdir lowerdir merged 应用 workdir upperdir lowerdir merged 应用 lower 中 foo 不变 写 lower 已有文件 foo CoW: 复制 foo 到 upper(用 workdir 辅助) 修改 upper/foo

CoW 的价值

  • 多实例 共享只读 lower (如镜像层)→ 省磁盘
  • 容器 秒级启动(不必复制整镜像);
  • 回滚测试环境 → 删掉 upper 即可恢复 lower 视图。

代价 :首次修改大文件时有一次 完整复制 I/O;频繁改大量小文件时 元数据与 CoW 压力 上升(见 §10)。


5. 删除与 whiteout

删除对象 实际行为
upper 中的文件 直接从 upper 删除
仅存在于 lower 的文件 在 upper 创建 whiteout (特殊字符设备或 xattr 标记),merged 视图中该路径 消失 ,lower 实体 仍保留
目录 规则类似;可能配合 opaque(§6)
text 复制代码
lower:  /bin/app  (只读镜像里)
用户:   rm merged/bin/app
upper:  出现 whiteout 标记(不是真删 lower)
merged: /bin/app 不可见

whiteout 让「逻辑删除」与「物理只读层」共存,是镜像分层的基础机制之一。


6. 目录合并与 opaque

6.1 目录合并

上下层 同名目录 在 merged 中 合并列出:upper 与 lower 中的条目一起呈现(子项仍遵循「文件优先 upper、否则 lower」)。

text 复制代码
lower/foo:  a.txt  b.txt
upper/foo:  c.txt
merged/foo: a.txt  b.txt  c.txt   (合并视图)

6.2 opaque 目录

若在 upper 某目录设置 opaque 属性(依赖 xattr):

  • merged 中该目录 不再合并 lower 同名目录内容;
  • 表现为 upper 目录 完全遮蔽 lower 侧同名树。

用于「上层整棵替换下层子树」的语义。


7. 挂载命令与示例

7.1 基本语法

bash 复制代码
mount -t overlay overlay \
  -o lowerdir=<lower>[,<lower2>...],upperdir=<upper>,workdir=<work> \
  <mountpoint>
选项 含义
lowerdir 一个或多个只读目录,逗号分隔,左优先
upperdir 可写层
workdir 空目录,与 upper 同 FS
<mountpoint> merged 挂载点(需已存在)

7.2 最小实验

bash 复制代码
mkdir -p /tmp/ovl/{lower,upper,work,merged}

echo "from lower" > /tmp/ovl/lower/hello.txt

mount -t overlay overlay \
  -o lowerdir=/tmp/ovl/lower,upperdir=/tmp/ovl/upper,workdir=/tmp/ovl/work \
  /tmp/ovl/merged

cat /tmp/ovl/merged/hello.txt          # from lower
echo "from upper" > /tmp/ovl/merged/new.txt
ls /tmp/ovl/upper/new.txt              # 新文件只在 upper

echo "modified" >> /tmp/ovl/merged/hello.txt
# CoW 后 upper/hello.txt 存在,lower/hello.txt 仍为 from lower

umount /tmp/ovl/merged

7.3 多层 lower

bash 复制代码
mount -t overlay overlay \
  -o lowerdir=/layer2:/layer1,upperdir=/upper,workdir=/work \
  /merged

layer2 中同名文件优先于 layer1

7.4 常用挂载参数(选读)

参数 说明
index=on/off 是否用索引优化硬链接等;部分场景 index=off 降开销
xino=on 跨层 inode 编号展示(调试/兼容)
redirect_dir=on 目录重命名优化(较新内核)

具体以当前内核 Documentation/filesystems/overlayfs.txt 为准。


8. 典型应用场景

场景 lower upper 收益
Docker / K8s 容器 镜像层(只读) 容器层 共享镜像、隔离可写、快速创建
Live CD / 只读根 系统只读分区 U 盘或缓存分区 系统完整性 + 会话内可写
软件测试 / 升级 稳定系统快照 测试 upper 失败则 删 upper 回滚
增量备份 全量备份目录 当日变更 upper 只备份 upper ≈ 增量

增量备份
全量 lower
每日 upper
容器
镜像层 lower
容器 A upper
容器 B upper


9. 实战案例提要

9.1 Docker 分层

  • 镜像各层只读叠加为 lower 链
  • docker run 创建 容器可写层 = upper;
  • 容器内 echoapt install 写入 upper;删除容器常删除 upper 层数据。

查看(宿主机,路径因存储驱动而异):

bash 复制代码
docker inspect <container> --format '{{.GraphDriver.Data}}'
# overlay2: LowerDir, UpperDir, WorkDir, MergedDir

9.2 Live USB

  • 系统镜像作 lower,用户数据分区作 upper 或独立挂载;
  • 重启后保留 upper 中 home 等变更(需正确分区与挂载脚本)。

9.3 测试与升级回滚

text 复制代码
lower = 当前稳定根文件系统快照(只读挂载)
upper = /test-upper
merged = 挂载后在此 chroot 或容器内测试

测试失败: umount merged && rm -rf /test-upper/*

9.4 增量备份与恢复

text 复制代码
1. 全量 rsync → /backup/base        (作 lower)
2. 每日变更 overlay upperdir=/backup/inc-20260526
3. 备份任务只同步 upper             (增量体积小)
4. 恢复: overlay 挂载 base + 各日 upper 或合并策略还原视图

具体脚本因备份产品而异,核心是 lower 稳定 + upper 存差量


10. 性能与选型注意

注意项 说明
CoW 开销 首次改大文件复制整文件;海量小文件频繁写 → IOPS 与延迟敏感
upper 文件系统 xattr (opaque、部分 whiteout);推荐 ext4、xfs
workdir 必须空目录 ;与 upperdir 同一文件系统
优化思路 测试环境 upper 用 tmpfs ;评估 index=off;避免在 overlay 上再叠复杂 FS
权限与 SELinux 容器场景注意挂载标签、--security-opt;upper 权限需与进程匹配
NFS 作 upper 可行但 xattr/锁语义需验证,生产常本机块设备更稳
现象 可能原因
mount 失败 invalid argument workdir 非空、upper/work 不同 FS、lower 路径不存在
修改不生效 写的是 lower 只读挂载点而非 merged
空间暴涨 CoW 复制大文件 + upper 累积未清理

11. 速查卡

text 复制代码
┌─────────────────────────────────────────────────────────┐
│ 读:  upper → lower(左优先)                             │
│ 写:  新文件→upper;改 lower 文件→CoW 到 upper 再改       │
│ 删:  upper 文件直接删;lower 文件→upper whiteout         │
│ 目录: 合并;upper opaque → 屏蔽 lower 同名树             │
├─────────────────────────────────────────────────────────┤
│ mount -t overlay overlay -o lowerdir=,upperdir=,workdir= │
│ workdir: 空;与 upper 同 FS;upper 需 xattr(ext4/xfs)    │
├─────────────────────────────────────────────────────────┤
│ Docker: 镜像=lower 链  容器层=upper  视图=merged         │
└─────────────────────────────────────────────────────────┘

落地注意

  • 生产容器多通过 overlay2 存储驱动使用 OverlayFS,路径与手工 mount 示例不同,但 lower/upper/work/merged 语义一致
  • 内核与 util-linux 版本差异会导致挂载选项略有不同,部署前在目标环境做一次 mount 实验
  • 嵌入式/Android 等场景若涉及只读 system + 可写 data,需结合 dm-verity、AVB 等安全机制,不能仅靠 Overlay 理解全盘方案。

一句话OverlayFS只读 lower + 可写 upper 叠出统一视图,靠 CoW 与 whiteout 实现省空间、快启动、易回滚------搞懂四层目录与读写规则,就抓住了 Docker 分层与大量「基底 + 差量」系统设计的底层逻辑。

相关推荐
武子康3 分钟前
Java-07 深入浅出 MyBatis数据库一对多关系模型实战:表结构设计与查询实现
java·后端
Bruce_kaizy6 分钟前
c++ linux环境编程——文件io介绍以及open 、write 、read 三剑客深度详解
linux·服务器·c++·ubuntu·操作系统·文件io
亦良Cool22 分钟前
VMware虚拟机ubuntu瘦身,解决虚拟机越用越大
linux·运维·ubuntu
星辰&与海2 小时前
KVM + QEMU虚拟化方案
linux·运维
宋浮檀s2 小时前
应急响应——恶意流量&攻击行为识别
linux·运维·网络·网络安全·应急响应
Royzst2 小时前
xml知识点
java·服务器·前端
zizle_lin3 小时前
WSL的系统安装和部分环境配置(按需操作)
运维
lwx9148523 小时前
Linux系统中用户锁定后如何解锁
linux·运维·服务器
鱼鳞_3 小时前
苍穹外卖-Day08(缓存套餐)
java·redis·缓存