Docker 联合文件系统(UnionFS/Overlay2)深度详解
(底层原理 + 分层镜像 + 写时复制 + 实战表现,面试+理解Docker必看)
- 为什么 Docker 镜像下载这么快?
- 为什么容器启动秒开?
- 为什么容器修改文件不影响镜像?
- Overlay2 到底怎么工作?
一、一句话核心(背下来)
Docker 联合文件系统(Union Filesystem)
= 多层文件“叠”在一起,对外看起来是一个完整目录
= 只读分层(镜像)+ 读写层(容器)
= 共享底层、按需复制、极致节省空间
二、联合文件系统核心 3 大特性
1. 分层(Layer)
镜像不是一个大文件,而是N 层文件叠起来。
例如:
centos → yum install java → copy jar → 启动脚本
会变成 4 层。
2. 只读共享
下层永远只读,所有容器共享底层层。
100 个容器启动,只占一份底层镜像空间。
3. 写时复制(Copy-On-Write,COW)
你不改,我就共享;你一改,我立刻复制一份给你用。 (只会复制修改的文件) 不修改就不占空间,修改才复制,极致高效。
三、Docker 当前默认驱动:Overlay2(必须懂)
CentOS7、Ubuntu 全部默认用 Overlay2。
它把文件系统分成 4 个角色:
1. lowerDir 下层(只读=镜像层)
可以有多层,全部是镜像的层。
不能写!不能改!
2. upperDir 上层(读写=容器层)
容器运行时唯一可写层。
所有修改、新增、删除都在这里。
3. mergedDir 合并目录(用户看到的目录)
把 lower + upper 叠在一起,容器内部看到的就是这个。
4. workDir 工作目录
内部临时目录,你不用管。
四、最通俗图解(一眼看懂)
[容器里看到的目录 / ]
↑
[ merged 合并视图 ]
↑ ↑
[ lower层 ] [ upper层 ]
(镜像只读) (容器可写)
- 读文件:
没有修改 → 直接读 lower
修改过 → 读 upper - 写文件:
第一次写 → 从 lower 复制到 upper,再修改
之后直接写 upper
五、写时复制(COW)到底是什么?
你在容器里修改一个文件:
- 文件在镜像层(只读)
- Docker 发现你要改
- 自动复制一份到容器读写层
- 你修改的是复制出来的副本
- 原镜像文件完全不动
这就是:
不改不复制,一改才复制。
优点:
- 极快
- 极省空间
- 容器互不影响
六、文件查找顺序(超级重要)
当你在容器里访问文件:
先看 upperDir(容器层)有没有
→ 有,直接用
→ 没有,去 lowerDir(镜像层)找
**删除文件?**在 upperDir 里创建一个 whiteout 隐藏文件
看起来删了,其实原文件还在镜像里。
七、为什么 Docker 这么快?(原理答案)
- 分层共享
100 个容器共享同一底层镜像 - 写时复制
启动不复制任何文件,秒启动 - 下载分层
已经有的层不会重复下载 - 构建缓存
Dockerfile 构建复用层,极快
八、面试标准答案(可直接入库)
tags: #Docker #UnionFS #Overlay2 #面试
题型:原理深度题
题目:请解释Docker联合文件系统Overlay2原理。
精简答案:
1.联合文件系统将多个只读镜像层(lowerDir)和一个读写容器层(upperDir)透明合并。
2.对外展示统一目录(merged)。
3.采用写时复制(Copy-On-Write):不修改则共享,修改时复制到容器层。
4.多层只读共享,节省空间、提升启动速度、保证容器隔离。
5.当前默认驱动是Overlay2,性能最高、最稳定。
九、你最关心的 4 个问题(秒懂)
1. 容器删除,数据去哪了?
upperDir(容器层)被删除,数据丢失。
→ 所以要挂载数据卷。
2. 为什么镜像小?
因为分层共享,不重复存储。
3. 为什么容器启动 1 秒?
因为不复制文件,只是叠层。
4. 为什么多个容器不互相影响?
因为修改都在自己的 upperDir。
关联文档
- Dockerfile 构建原理 + 镜像分层优化 — 镜像构建
- ../linux/system/Linux — Linux 文件系统