Skip to main content
☘️ Septvean's Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Linux UnionFS

Linux UnionFS(联合文件系统)详解。

内容:概念 -> 内核实现 -> 主流实现 -> 行为细节 -> 与容器的关系 -> 性能与陷阱 -> 最佳实践

一、UnionFS 是什么(一句话)

UnionFS 是一种“把多个目录(分支)叠加成一个统一视图”的文件系统机制。

  • 上层:可写层(upper)
  • 下层:只读层(lower)
  • 对用户呈现:一个完整目录树

📌 UnionFS ≠ OverlayFS(OverlayFS 是内核实现之一)

二、为什么需要 UnionFS(设计动机)

1️⃣ 镜像分层(容器)

应用层(可写)
---------
基础镜像层(只读)
---------
OS 层(只读)
  • 节省空间
  • 快速创建
  • 层复用

2️⃣ 系统快照 / Live CD

  • Live 系统:只读 + 内存写层
  • 回滚 / 快照

3️⃣ 只读根文件系统 + 可写覆盖

  • 嵌入式系统
  • 安全系统

三、UnionFS 的核心概念

1️⃣ Branch(分支)

每一层目录叫一个 branch

  • lower branch:只读
  • upper branch:可写

2️⃣ Whiteout(白障)

用于“在上层删除下层文件”的特殊标记

  • 删除 ≠ 真删除
  • 是创建 .wh.<filename>

📌 这是 UnionFS 的核心魔法之一

3️⃣ Copy-on-Write(写时复制)

当你:

echo hello >> /bin/ls

实际发生的是:

  1. /bin/ls 从 lower copy 到 upper
  2. 在 upper 中修改
  3. lower 不变

四、UnionFS 的内核实现演进

1️⃣ UnionFS(最早)

  • 外部模块
  • 稳定性一般
  • 已基本弃用

2️⃣ AUFS(Docker 早期)

  • 功能强大
  • 非主线内核
  • Ubuntu 曾长期使用

📌 RHEL 系列从未支持 AUFS

3️⃣ OverlayFS(主线内核)

现在事实上的标准

  • Linux 内核原生
  • Docker / Podman / CRI-O 默认
  • RHEL / AlmaLinux / Rocky 全支持

五、OverlayFS 详解(重点)

1️⃣ 基本结构

lowerdir=/layers/base:/layers/app
upperdir=/layers/write
workdir=/layers/work

挂载后:

/merged

2️⃣ 挂载命令示例

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

📌 workdir 用于原子操作(必须)

3️⃣ 文件访问逻辑(读写流程)

  1. upperdir
  2. 从上到下依次 lowerdir

  • lower -> copy 到 upper -> 写

  • 创建 whiteout

六、UnionFS 的关键行为细节(很容易踩坑)

1️⃣ inode 不稳定

  • 同一路径
  • 不同层 inode 不同

📌 影响:

  • bind mount
  • inode cache
  • 某些数据库
  • OverlayFS 对 hardlink 支持有限
  • 跨层 hardlink 基本不可用

3️⃣ rename 是“伪原子”

  • 跨层 rename 实际是:
    • copy + delete

📌 对 fsync 敏感程序危险

4️⃣ chmod / chown 行为

  • 触发 COW
  • 文件被复制到 upper

七、OverlayFS 与容器(核心关系)

1️⃣ Docker overlay2 的本质

container_rw_layer (upper)
--------------------------
image layer N
--------------------------
image layer N-1
--------------------------
base OS layer

2️⃣ 为什么容器启动快?

  • 不复制 rootfs
  • 只 mount 联合视图

3️⃣ 为什么容器磁盘 IO 抖?

  • metadata 操作多
  • copy-up 代价大
  • fsync 穿透层

八、UnionFS 不适合哪些场景?

❌ 数据库(重点)

原因:

  • fsync 不可控
  • rename 不安全
  • inode 不稳定
  • 白障文件膨胀

📌 这就是 “数据库为什么不适合跑在容器” 的底层原因之一

❌ 高 IO 小文件场景

  • Git
  • 编译缓存
  • npm / pip

九、性能关键点(OverlayFS)

1️⃣ Metadata 开销高

  • stat
  • readdir
  • lookup

2️⃣ Copy-up 成本不可忽视

  • 第一次写 = 全文件复制
  • 大文件尤其明显

3️⃣ fsync 行为复杂

  • upper + lower 组合
  • 存储栈不透明

十、UnionFS 的最佳实践

✅ 容器

  • rootfs:overlay2
  • 数据目录:bind mount / volume
-v /data/mysql:/var/lib/mysql

✅ 系统设计

  • 只读 OS + overlay
  • 日志 / 数据单独盘

❌ 禁止事项

  • ❌ overlay2 存数据库数据
  • ❌ overlay2 跑消息队列
  • ❌ overlay2 做性能 benchmark

十一、OverlayFS vs 其他方案

特性 OverlayFS bind mount tmpfs
分层
可写
性能
数据安全
适合数据库

十二、总结(记住)

UnionFS 是 “视图文件系统”,不是 “数据文件系统”。

它的使命是:

  • 镜像
  • 分层
  • 复用

不是:

  • 高一致性
  • 高 fsync 可靠性
  • 数据持久化