【Docker】知识三

目录

一、UnionFS:容器分层存储的核心思想

[1. 核心分层架构](#1. 核心分层架构)

2.四大核心特性

(1)分层合并与视图统一

[(2)写时复制(Copy-On-Write, COW)](#(2)写时复制(Copy-On-Write, COW))

(3)层优先级覆盖

(4)底层隔离与资源节省

[二、Docker中的AUFS 与OverlayFS /Overlay2](#二、Docker中的AUFS 与OverlayFS /Overlay2)

[1. AUFS(Advanced UnionFS):Docker 早期核心存储驱动](#1. AUFS(Advanced UnionFS):Docker 早期核心存储驱动)

(1)核心工作逻辑

[(2)核心技术机制:Whiteout 与 Opaque​](#(2)核心技术机制:Whiteout 与 Opaque)

(3)逐步被淘汰的核心原因​

[2. OverlayFS/Overlay2:Docker 当前默认存储驱动​](#2. OverlayFS/Overlay2:Docker 当前默认存储驱动)

[(1)核心架构:四目录极简模型(对比 AUFS)​](#(1)核心架构:四目录极简模型(对比 AUFS))

[(2)Overlay2 对 OverlayFS 的核心优化​](#(2)Overlay2 对 OverlayFS 的核心优化)

[(3)Docker 中 Overlay2 的实际应用](#(3)Docker 中 Overlay2 的实际应用)

[3.AUFS 与 Overlay2 核心差异汇总](#3.AUFS 与 Overlay2 核心差异汇总)

[三、UnionFS 的跨领域应用场景​](#三、UnionFS 的跨领域应用场景)


在 Docker 容器技术体系中,镜像分层是其核心特性之一,而支撑这一特性实现的底层技术,正是UnionFS(联合文件系统)。从早期的 AUFS 到如今 Docker 默认的 Overlay2,UnionFS 通过 "联合挂载" 的思想,解决了容器镜像存储、数据隔离与高效复用的核心难题。

一、UnionFS:容器分层存储的核心思想

UnionFS 并非某一个具体的文件系统,而是一种文件系统抽象理念,核心通过"联合挂载(Union Mount)"技术实现:将多个物理 / 逻辑独立的 "层(Layer)" 按指定规则叠加,对外呈现为一个统一、虚拟的文件系统视图。

1. 核心分层架构

UnionFS 将存储层分为两类,各司其职,实现资源共享与数据隔离的统一:

1.底层分支(只读层,Image Layers):对应 Docker 镜像的底层层(如基础镜像层、依赖安装层);

2.上层分支(可写层,Container Layer):对应 Docker 容器的运行时层(容器内修改仅作用于此层)。

3.虚拟挂载点:用户 / 进程仅能看到合并后的统一目录,无法直接感知底层分层,简化了使用复杂度。

核心价值是用分层思想实现资源共享与数据隔离,既提升存储效率,又保障容器环境的独立性。

2. 四大核心特性

(1)分层合并与视图统一

将多个只读层(镜像层)与一个可写层(容器层)合并,对外呈现为单一文件系统。

创建layer1(含 file1、file2)、layer2(含 file1、file3)两个只读层,通过mount -t aufs -o br:upperlayer:layer1:layer2 none mountedfs挂载后,mountedfs目录中能看到 file1(来自 layer1)、file2(来自 layer1)、file3(来自 layer2),即 "合并后视图"。

(2)写时复制(Copy-On-Write, COW)

对合并视图中的文件进行修改、创建、删除时,不会直接修改底层只读层,仅将操作作用于上层可写层,避免底层数据污染。

示例 1(创建文件):在 AUFS 的mountedfs目录创建 file4,实际文件会写入upperlayer(可写层),layer1/layer2(只读层)无变化;

示例 2(删除文件):删除mountedfs中的 file1 时,AUFS 会在upperlayer创建/.wh.file1(whiteout 文件)标记 "隐藏底层 file1",而非删除layer1中的原始 file1;若后续重新创建 file1,/.wh.file1会被删除,新 file1 直接写入upperlayer。

(3)层优先级覆盖

当不同层存在同名文件 / 目录时,左侧层(优先级更高)的内容会覆盖右侧层,确保上层修改能 "屏蔽" 底层静态数据。

示例:AUFS 挂载时指定分支顺序upperlayer:layer1:layer2,layer1和layer2均有 file1,最终mountedfs中显示layer1的 file1 内容;若调整顺序为upperlayer:layer2:layer1,则会显示layer2的 file1 内容。

(4)底层隔离与资源节省

各层独立存储,相同基础层可被多个容器共享(如多个 Docker 容器共用同一个 Nginx 基础镜像层),无需重复存储,大幅节省磁盘空间。

Docker 镜像的 "分层构建" 机制(每条 Dockerfile 指令生成一个只读层)正是基于 UnionFS 的共享特性,例如多个容器基于python:3.12-slim镜像构建时,仅需存储一份基础镜像层,容器运行时仅新增一个可写层。

二、Docker中 AUFS 与OverlayFS /Overlay2

UnionFS 有多种落地实现(如 AUFS、OverlayFS、UnionFS-FUSE 等),其中 Docker 生态中最具代表性的是早期使用的 AUFS,以及当前默认的 OverlayFS/Overlay2。二者均遵循 UnionFS 核心理念,但在内核支持、性能表现、功能扩展性上存在显著差异。

1. AUFS(Advanced UnionFS):Docker 早期核心存储驱动

AUFS 是 UnionFS 技术规范的增强实现,也是 Docker 初期在 Debian、Ubuntu 等系统上的默认存储驱动,完美支撑了早期容器分层构建、多容器共享镜像的核心需求。

(1)核心工作逻辑

AUFS 以"分支(Branches)"为核心分层单位,将所有存储节点划分为两类分支,分工明确、互不干扰:

只读分支(Read-Only Branches):对应 Docker 镜像的所有底层分层,包括基础操作系统层、应用依赖安装层等,一旦生成便不可修改,多个容器可共用同一组只读分支,大幅节省存储资源;

可写分支(Read-Write Branch):专门对应 Docker 容器的运行时分层,容器启动后,所有文件新增、修改、删除操作,均仅在该分支内执行,不会对只读分支的原始数据造成任何影响。

bash 复制代码
# 1. 创建分层目录(2个只读层+1个可写层+1个挂载点)

mkdir aufs-test && cd aufs-test

mkdir layer1 layer2 upperlayer mountedfs



# 2. 向只读层写入测试文件(layer1和layer2有同名file1)

echo "content for file1 in layer1" > layer1/file1

echo "content for file1 in layer2" > layer2/file1

echo "content for file2 in layer1" > layer1/file2

echo "content for file3 in layer2" > layer2/file3



# 3. 挂载AUFS:指定分支顺序(upperlayer可写层在前,layer1/layer2只读层在后)

mount -t aufs -o br:upperlayer:layer1:layer2 none mountedfs



# 4. 验证合并结果:file1来自layer1(优先级高),file2来自layer1,file3来自layer2

cd mountedfs && cat file1  # 输出"content for file1 in layer1"
(2)核心技术机制:Whiteout 与 Opaque​

为了实现"不修改只读层却能隐藏底层文件/目录"的效果,AUFS 设计了两种特殊标记文件,这也是其核心技术亮点:​

Whiteout(文件隐藏标记):当删除合并视图中的某个文件时,AUFS 不会删除只读分支中的原始文件,而是在可写分支中创建一个名为 .wh.文件名 的空文件,以此标记"该文件在合并视图中隐藏",底层原始文件仍完整保留;​

Opaque(目录隐藏标记):若删除合并视图中的某个目录,AUFS 会在可写分支中创建 .wh..wh.opaque 文件,标记"该目录及旗下所有子内容在合并视图中隐藏",避免底层目录内容意外暴露。​

(3)逐步被淘汰的核心原因​

随着 Docker 普及和容器场景复杂化,AUFS 的局限性逐渐凸显,最终被 Overlay2 取代,核心短板有三点:​

内核兼容性差:AUFS 并非 Linux 内核原生支持的文件系统,需要额外安装内核补丁才能使用,仅适配 Ubuntu、Debian 等少数发行版,CentOS、RHEL 等主流服务器系统无原生支持;​

性能损耗明显:作为用户态文件系统,AUFS 的文件查找、读写操作需要经过用户态与内核态的多次切换,当镜像分层超过 10 层时,延迟会显著增加;​

功能扩展性弱:最多仅支持 127 个分层,无法适配复杂镜像的分层需求,且不支持目录重命名等基础操作,灵活性不足。​

2. OverlayFS/Overlay2:Docker 当前默认存储驱动​

OverlayFS 是 Linux 内核原生支持的 UnionFS 实现(自 Linux 3.18 版本引入),专门解决了 AUFS 兼容性差、性能弱的问题;Overlay2 是其改进版本,自 Docker 17.06 版本起成为默认存储驱动,也是目前生产环境中最推荐的选择。

(1)核心架构:四目录极简模型(对比 AUFS)​

相比 AUFS 复杂的分支管理,OverlayFS 的分层模型更简洁,核心仅包含四类目录,与 AUFS 的对应关系清晰,便于理解和维护:

|--------------|-----------------------------------------------------|----------------------------------------|
| OverlayFS 目录 | 核心作用(对应 Docker 场景) | 与 AUFS 的对应关系 |
| lowerdir | 存放所有只读层的集合(即 Docker 镜像的全部底层分层),可包含多个只读目录,用冒号分隔 | 对应 AUFS 的所有只读分支(ro-layer1、ro-layer2 等) |
| upperdir | 专门存放容器运行时的所有修改数据,即 Docker 容器的可写层,仅对当前容器生效 | 对应 AUFS 的可写分支(rw-layer) |
| workdir | 临时工作目录,用于 OverlayFS 内部处理文件重命名、删除等操作,必须为空目录,用户无需手动操作 | AUFS 无对应独立目录,同类操作依赖可写分支完成 |
| merged | 分层合并后的虚拟视图,也是 Docker 容器内部看到的根文件系统,屏蔽所有底层分层细节 | 对应 AUFS 的挂载点(mount-point) |

bash 复制代码
# 1. 创建分层目录(2个只读层+1个可写层+1个工作目录+1个挂载点)

mkdir overlay-test && cd overlay-test

mkdir layer1 layer2 upperlayer workdir mountedfs



# 2. 写入测试文件(同AUFS实验,layer1和layer2有同名file1)

echo "content for file1 in layer1" > layer1/file1

echo "content for file1 in layer2" > layer2/file1

echo "content for file2 in layer1" > layer1/file2

echo "content for file3 in layer2" > layer2/file3



# 3. 挂载OverlayFS:指定lowerdir(只读层,优先级左高右低)、upperdir(可写层)、workdir(临时目录)

mount -t overlay -o lowerdir=layer1:layer2,upperdir=upperlayer,workdir=workdir overlay mountedfs



# 4. 验证合并结果:与AUFS一致,file1来自layer1,且修改仅作用于upperdir

cd mountedfs && echo "new file4" > file4 && ls ../upperlayer  # file4存在于upperdir
(2)Overlay2 对 OverlayFS 的核心优化​

原生 OverlayFS 存在明显短板------仅支持"1 个可写层 + 1 个只读层",无法满足 Docker 镜像多分层(通常超过 10 层)的实际需求。Overlay2 作为改进版,重点解决了这一问题,同时优化了性能:​

分层数量突破:通过"链式分层"技术,将多个只读层组织成链式结构,每层记录前一层的引用关系,最终实现 128 个只读层的合并,完全适配复杂 Docker 镜像;​

性能大幅提升:引入"原生 Overlay Diff"机制,减少文件元数据的重复计算和存储,在多分层场景下,读写延迟比 AUFS 降低 30%~50%,接近原生文件系统性能;​

兼容性全面升级:Linux 4.0 及以上内核默认支持 Overlay2,无需安装任何补丁,可完美适配 Ubuntu、CentOS、RHEL、统信 UOS 等所有主流 Linux 发行版,部署成本极低。​

(3)Docker 中 Overlay2 的实际应用

作为 Docker 当前默认存储驱动,Overlay2 已深度融入 Docker 容器的运行机制,核心应用细节如下:​

验证默认驱动:通过简单命令即可查看 Docker 当前使用的存储驱动,确认是否为 Overlay2:

bash 复制代码
docker info | grep "Storage Driver" -A5

# 输出结果(文档示例):

# Storage Driver: overlay2

# Backing Filesystem: extfs

# Supports d_type: true

# Using metacopy: false

# Native Overlay Diff: true

# userxattr: false

存储路径规范:Docker 容器的 Overlay2 所有分层数据,均存储在 /var/lib/docker/overlay2/ 目录下,每个容器对应一个以"容器 ID"命名的子目录;

目录结构对应:每个容器子目录内,包含 diff(对应可写层 upperdir)、work(对应临时工作目录 workdir)、merged(对应合并视图 merged)三个核心目录;

层关联机制:容器子目录下的 mount-id 文件,记录了该容器与 /var/lib/docker/overlay2/ 中只读分层目录的关联关系,确保容器启动时能精准找到对应的所有只读层,完成分层合并。

3.AUFS 与 Overlay2 核心差异汇总

|-------------|---------------------------|--------------------------------|
| 对比维度 | AUFS | Overlay2 |
| 内核支持情况 | 非原生,需额外安装补丁,仅适配少数发行版 | 原生支持(Linux 4.0+),适配所有主流发行版 |
| 最大支持分层数 | 127 层,无法适配复杂镜像 | 128 层,链式分层适配多分层场景 |
| 性能表现 | 用户态实现,多分层场景延迟高、损耗大 | 内核态实现,多分层场景性能优异,延迟低 |
| 临时目录需求 | 无独立临时目录,依赖可写分支处理内部操作 | 必须指定空的 workdir 临时目录,操作更高效 |
| 写时复制机制 | 依赖 Whiteout/Opaque 标记文件实现 | 直接在 upperdir 写入/覆盖,删除时标记隐藏,更简洁 |
| Docker 支持状态 | deprecated(逐步淘汰),仅旧版环境兼容 | 默认推荐,生产环境首选,持续迭代优化 |

三、UnionFS 的跨领域应用场景​

容器镜像分层:Docker 镜像的分层构建、增量传输核心,基础镜像层共享,仅差异层存储,大幅节省空间;​

容器运行时:K8s、Docker 容器的根文件系统基于 UnionFS,实现环境隔离+轻量运行;​

嵌入式系统:路由器、智能设备固件采用"只读固件层+可写配置层",既防篡改,又支持用户自定义配置;​

Live CD/USB:系统镜像只读加载,可写层存放用户操作,重启后恢复初始状态,保障系统安全。

简言之,没有 UnionFS,容器镜像的轻量级与可移植性便无从谈起 ------ 它正是容器分层存储思想在文件系统层面的核心落地。

相关推荐
小明_GLC2 小时前
Docker 构建镜像一直卡在下载 Python?
python·docker·容器
JY.yuyu2 小时前
Docker搭建Web安全渗透测试靶场
运维·docker·容器
En^_^Joy2 小时前
Docker入门:快速安装与实战指南
运维·docker·容器
70asunflower2 小时前
Docker 镜像的完整内容解析
运维·docker·容器
hnxaoli2 小时前
通信小程序(九)快捷键自动改名
linux·python·小程序
API开发2 小时前
apiSQL网关 for Docker 离线安装和升级教程
运维·docker·容器·api·api网关·apisql·替代graphql
木子欢儿2 小时前
探索 OpenMediaVault 安装
linux·运维·服务器
Linux运维技术栈2 小时前
运维安全: SSH 公钥认证算法加固
linux·运维·安全
小钻风33662 小时前
Docker入门基础知识(一)
运维·docker·容器