Title here
Summary here
OverlayFS 是 Linux 内核提供的联合文件系统(Union Filesystem),它允许将多个目录叠加在一起,呈现为单一的文件系统视图。这是容器镜像分层存储的核心技术。
联合文件系统将多个独立的文件系统分支(branch)合并为一个统一的视图:
核心特性:
OverlayFS 由四个关键组件组成:
| 组件 | 说明 | 特性 |
|---|---|---|
| lowerdir | 只读底层 | 可以有多个,从下到上叠加 |
| upperdir | 可写上层 | 所有修改都写入这里 |
| workdir | 工作目录 | 用于原子操作,必须为空 |
| merged | 合并视图 | 挂载点,用户访问的入口 |
mount -t overlay overlay \
-o lowerdir=/lower3:/lower2:/lower1,upperdir=/upper,workdir=/work \
/merged参数说明:
-t overlay:文件系统类型lowerdir=:只读层,多个用 : 分隔,右边的在下面upperdir=:可写层workdir=:工作目录,必须和 upperdir 在同一文件系统查找顺序:从上到下
当修改一个来自 lower 层的文件时,OverlayFS 会执行 Copy-on-Write:
具体步骤:
/merged/file.txt删除 lower 层的文件时,不能直接删除(lower 是只读的),而是使用 Whiteout 文件标记:
Whiteout 文件:
.wh.<原文件名># 查看 whiteout 文件
ls -la upper/
# c--------- 1 root root 0, 0 Jan 30 10:00 .wh.deleted_file
# 手动创建 whiteout
mknod upper/.wh.file.txt c 0 0当删除并重建一个目录时,使用 Opaque 标记:
# upper 目录设置 opaque 属性
setfattr -n "trusted.overlay.opaque" -v "y" upper/new_dir
# 查看 opaque 属性
getfattr -n "trusted.overlay.opaque" upper/new_dirOpaque 目录表示:忽略 lower 层中同名目录的所有内容。
# 创建目录
mkdir -p /tmp/overlay/{lower1,lower2,upper,work,merged}
# 创建 lower1 层文件
echo "base content" > /tmp/overlay/lower1/base.txt
mkdir /tmp/overlay/lower1/config
echo "config v1" > /tmp/overlay/lower1/config/app.conf
# 创建 lower2 层文件(覆盖部分 lower1)
echo "config v2" > /tmp/overlay/lower2/config/app.conf
echo "feature.txt" > /tmp/overlay/lower2/feature.txt# 挂载(需要 root 权限)
sudo mount -t overlay overlay \
-o lowerdir=/tmp/overlay/lower2:/tmp/overlay/lower1,\
upperdir=/tmp/overlay/upper,\
workdir=/tmp/overlay/work \
/tmp/overlay/merged# 查看合并后的文件
ls -la /tmp/overlay/merged/
# base.txt # 来自 lower1
# config/ # 目录
# feature.txt # 来自 lower2
cat /tmp/overlay/merged/config/app.conf
# config v2 # 来自 lower2(覆盖了 lower1)# 修改来自 lower 的文件
echo "modified" >> /tmp/overlay/merged/base.txt
# 检查 upper 层
ls /tmp/overlay/upper/
# base.txt # Copy-on-Write 复制到 upper
cat /tmp/overlay/upper/base.txt
# base content
# modified# 删除来自 lower 的文件
rm /tmp/overlay/merged/feature.txt
# 检查 whiteout 文件
ls -la /tmp/overlay/upper/
# c--------- 1 root root 0, 0 .wh.feature.txtsudo umount /tmp/overlay/merged
rm -rf /tmp/overlayOverlayFS 支持最多 500 层 lower:
mount -t overlay overlay \
-o lowerdir=/l500:/l499:...:/l2:/l1,upperdir=/upper,workdir=/work \
/merged性能考虑:
不指定 upperdir 和 workdir 时为只读挂载:
mount -t overlay overlay \
-o lowerdir=/layer2:/layer1 \
/merged这在只读容器场景下很有用。
OverlayFS 支持 index 特性,用于:
mount -t overlay overlay \
-o lowerdir=/lower,upperdir=/upper,workdir=/work,index=on \
/mergedcontainerd 默认关闭 index 以提升性能:
-o index=off允许在 upper 层重命名 lower 层的目录:
mount -t overlay overlay \
-o lowerdir=/lower,upperdir=/upper,workdir=/work,redirect_dir=on \
/merged只复制元数据,不复制文件内容,直到真正需要时:
mount -t overlay overlay \
-o lowerdir=/lower,upperdir=/upper,workdir=/work,metacopy=on \
/merged这可以加速 Copy-on-Write 操作。
containerd 使用 Overlay Snapshotter 管理容器文件系统:
目录结构:
/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/
├── metadata.db # BoltDB 元数据
└── snapshots/
├── 1/ # 镜像层 1
│ └── fs/ # 层内容
├── 2/ # 镜像层 2
│ └── fs/
└── 3/ # 容器层
├── fs/ # upperdir
└── work/ # workdir关键代码路径:
plugins/snapshots/overlay/overlay.go| Snapshotter 概念 | OverlayFS 角色 |
|---|---|
| Committed Snapshot | lowerdir(只读层) |
| Active Snapshot | upperdir + workdir(可写层) |
| View | 只读 OverlayFS 挂载 |
# 1. 控制镜像层数
# 在 Dockerfile 中合并 RUN 指令
# 2. 将频繁修改的数据放在 volume
docker run -v /data:/app/data ...
# 3. 对于大文件,考虑使用 volume 而非 overlay
# 4. 使用 metacopy 加速(需要内核支持)
mount -t overlay ... -o metacopy=on ...| 特性 | 内核版本 |
|---|---|
| 基础 OverlayFS | 3.18+ |
| 多层 lower | 4.0+ |
| redirect_dir | 4.10+ |
| index | 4.13+ |
| metacopy | 4.19+ |
| volatile | 5.6+ |
# 可能是 lower 层文件系统不支持 d_type
# 检查文件系统是否支持
xfs_info /dev/sda1 | grep ftype
# ftype=1 表示支持# workdir 必须为空
rm -rf /path/to/work/*# upperdir 和 workdir 必须在同一文件系统
# 确保它们不在不同的挂载点
df /path/to/upper /path/to/workOverlayFS 是容器文件系统的基础:
理解 OverlayFS 原理有助于:
下一节我们将学习 OCI 规范,它定义了容器镜像和运行时的标准。