Overlay 联合文件系统详解
一、Overlay 联合文件系统的三层架构
在上一节中,我们了解到 UnionFS(联合文件系统)可以把多个目录联合到一起挂载成一个大目录给容器使用。Overlay 就是 UnionFS 的一种具体实现,它的架构主要分为三层:
| 层级 | 名称 | 别称 | 读写属性 | 作用 |
|---|---|---|---|---|
| 最底层 | lowerdir |
镜像层 | 只读 | 存放 rootfs,即基础的文件系统内容 |
| 中间层 | upperdir |
容器层 | 可读写 | 记录容器对文件的所有增删改操作 |
| 最上层 | merged |
展现层 | — | 将 lowerdir 与 upperdir 联合挂载后的合并结果 |
lowerdir(镜像层):只要某个目录被指定为lowerdir,它就变成只读的了。这一层指定的目录其实就是我们之前说的那个 rootfs,所以又称为镜像层。upperdir(容器层):只要某个目录被指定为upperdir,它就是可写的。容器执行的文件写入、修改、删除操作,结果都会体现在这一层指定的目录里,所以又称为容器层。merged(展现层):这一层本身不存放任何文件,它的内容全部来自于upperdir与lowerdir,是这两层联合挂载、合并之后的结果。我们在容器里面看到的就是merged层。
二、从上往下看的"遮挡"原理
在容器内部,我们看到的是 merged 层。理解 merged 层的关键是:从上往下看,upperdir 挡在中间。
具体规则如下:
- 查看某个文件时,先经过
upperdir,看upperdir里有没有这个文件 - 如果
upperdir里没有,就继续往下看到lowerdir(相当于没有遮挡住) - 如果
upperdir里有,就以upperdir里的为准(相当于被遮挡住了,即使lowerdir里也有同名文件)
初始状态示例
假设初始时只有 lowerdir 里有文件,upperdir 是空的:
┌─────────────────────────────────────┐
│ merged(展现层) │
│ → file1, file2, file3 │
├─────────────────────────────────────┤
│ upperdir(容器层) │
│ → (空) │
├─────────────────────────────────────┤
│ lowerdir(镜像层,只读) │
│ → file1, file2, file3 │
└─────────────────────────────────────┘
此时在 merged 层从上往下看:upperdir 里没有任何文件,没有任何遮挡,所以直接看到 lowerdir 里的 file1、file2、file3。
三、三种改动操作在 Overlay 中的体现
1. 修改文件
如果在容器内(即 merged 层)编辑修改了 file2,会发生什么?
- 不会改动
lowerdir,因为lowerdir是只读的,改不了 - 改动的结果会放到
upperdir里面,在upperdir中产生一个同名文件file2,里面是修改后的新内容
┌─────────────────────────────────────┐
│ merged(展现层) │
│ → file1, file2(已修改), file3 │
├─────────────────────────────────────┤
│ upperdir(容器层) │
│ → file2(修改后的新内容) │
├─────────────────────────────────────┤
│ lowerdir(镜像层,只读) │
│ → file1, file2(原始), file3 │
└─────────────────────────────────────┘
下次在 merged 层看 file2 时,由于 upperdir 里出现了同名的 file2,遮挡住了 lowerdir 里的 file2,所以看到的就是 upperdir 里修改后的版本。
2. 新增文件
如果在容器内新建了一个文件 file4,这也是改动操作,新增的文件会写到哪里?写到 upperdir,不会改动 lowerdir。
┌─────────────────────────────────────┐
│ merged(展现层) │
│ → file1, file2(已修改), file3, file4│
├─────────────────────────────────────┤
│ upperdir(容器层) │
│ → file2(修改后), file4(新增) │
├─────────────────────────────────────┤
│ lowerdir(镜像层,只读) │
│ → file1, file2(原始), file3 │
└─────────────────────────────────────┘
在 merged 层从上往下看,file4 在 upperdir 里有,直接被 upperdir 挡住了,所以能看到这个新文件。
3. 删除文件
如果在容器内把 file3 删掉了,会发生什么?
- 不会真正删除
lowerdir里的file3 - 而是在
upperdir里创建一个特殊的字符设备文件(whiteout 文件),文件名为file3,代表"已删除"
┌─────────────────────────────────────┐
│ merged(展现层) │
│ → file1, file2(已修改), file4 │
├─────────────────────────────────────┤
│ upperdir(容器层) │
│ → file2(修改后), file4, file3(whiteout) │
├─────────────────────────────────────┤
│ lowerdir(镜像层,只读) │
│ → file1, file2(原始), file3 │
└─────────────────────────────────────┘
联合文件系统在 merged 层往下看时,只要看到 upperdir 里有这种特殊的 whiteout 文件,就认为该文件已被删除,在 merged 层中就不再展示 file3。但实际上 file3 并没有被真正删除,它仍然存在于 lowerdir 里。
四、为什么 lowerdir 必须只读?
lowerdir 指定的目录本质就是一个镜像(rootfs),而这个镜像目录有可能同时作为其他容器的 lowerdir 来进行联合挂载。
如果在容器 1 里通过 merged 层把 file3 删了,实际就把 lowerdir 里的 file3 真删了,那其他共享这个 lowerdir 的容器里也会跟着丢失 file3——这就破坏了隔离性。所以 lowerdir 里指定的目录一定是只读的,所有改动都只发生在 upperdir 里面。
五、改动操作总结
| 操作 | Overlay 实际行为 | lowerdir 变化 |
|---|---|---|
| 修改文件 | 在 upperdir 中创建同名文件,写入修改后内容 |
不变 |
| 新增文件 | 直接在 upperdir 中创建新文件 |
不变 |
| 删除文件 | 在 upperdir 中创建 whiteout 字符设备文件标记删除 |
不变 |
六、Overlay 与 Overlay2
在 Docker 容器引擎中,Overlay 有两个版本:
- overlay:基本只能工作在两层(
lowerdir+upperdir)之上,合并成一个merged层展示 - overlay2:在 overlay 基础上做了很多优化,支持更多的层,并且对 inode 的使用做了进一步优化。现在基本都用 overlay2
使用 overlay2 有一个前提条件:内核版本必须至少在 4.0 以上。这也是为什么安装较新版本的 Docker(如 19、20 及以后的版本)时,通常要求先升级内核。
查看当前 Docker 使用的存储驱动
[root@test04 ~]# docker info | grep overlay
Storage Drive: overlay2
Network: bridge host ipvlan macvlan null overlay
可以看到,默认的 Storage Driver 就是 overlay2。新版本的 Docker 引擎默认就使用 overlay2,不需要手动修改。如果使用的是老版本且想手动指定,可以在 Docker 的配置文件中添加相应配置项来指定存储驱动。
七、本节总结与下一步
本节完整介绍了 Overlay 联合文件系统的三层架构(lowerdir → upperdir → merged)及其工作原理:
merged层只是展现层,不真正存放文件,内容来自下面两层的合并- 所有读操作遵循从上往下看的遮挡规则:优先
upperdir,其次lowerdir - 所有写操作(增、删、改)只影响
upperdir,lowerdir始终保持只读 - Docker 目前默认使用 overlay2 驱动,要求内核 4.0 以上
下一步:动手做实验,自己利用 Overlay 联合文件系统实现一次联合挂载,亲身体验联合挂载的效果。这样在后续学习 Docker 启动容器时,就能理解容器的文件系统到底是怎样通过联合挂载关联进去的。

浙公网安备 33010602011771号