既然你提到了AUFS(Advanced Multi-Layered Unification Filesystem,高级多层联合文件系统),那我们的视线就要从刚才的“手机闪存”瞬间拉回“Docker 容器的核心黑科技”了。
如果说Namespace解决了容器的视线隔离(让进程以为自己独占系统),那么AUFS解决的就是容器的身材管理(让几百个容器共享一份硬盘数据,却互不干扰)。
大白话来说,AUFS 就是一个“高效的图层复用魔术师”。
1. 痛点:如果没有 AUFS,容器会胖成什么样?
假设你用 Docker 启动了 100 个 Ubuntu 容器。
- 虚拟机的做法:复制 100 份 Ubuntu 镜像,每份2 GB2\text{ GB}2GB,总共吃掉200 GB200\text{ GB}200GB的硬盘空间。
- 容器的想法:这 100 个容器的底层系统明明一模一样,我能不能让它们共享同一个核心文件,只在各自需要修改的时候才占用新空间?
AUFS 就是为了实现这个想法而生的联合文件系统(Union FS)。它可以把物理上位于不同地方的多个目录(在 Docker 里叫“层”,Layer),挂载并融合成同一个虚拟目录呈现给你。
2. 大白话原理:PS 里的“图层”概念
理解 AUFS 最简单的方式,就是联想Photoshop(PS)的图层,或者小时候玩的透明塑料胶片画。
在 AUFS 的世界里,一个 Docker 镜像被拆成了好几个“只读层”和一个“读写层”,它们像叠罗汉一样叠在一起:
- 底层(只读层/Read-Only):比如最下面是 Ubuntu 基础系统(Layer 1),上面叠了一个装了 Python 的环境(Layer 2)。这些层是绝对不许修改的。
- 顶层(读写层/Read-Write):当你启动容器时,AUFS 会在最上面轻轻盖上一张透明的空白胶片。你在容器里干的所有脏活、累活、写的新数据,全都在这张透明胶片上。
- 用户视角:当你从上往下看时,所有的图层融合成了一个完整的、可读可写的正常文件系统。
3. 核心大招:Copy-on-Write(写时复制)
这时候你可能会问:“那如果我想修改底层只读文件里的东西,该怎么办?”
AUFS 掏出了它的看家本领 ——CoW(Copy-on-Write,写时复制)。我们用大白话模拟一下容器里的操作:
- 你读取一个文件(比如
/etc/config):AUFS 会从顶层开始往下找。既然顶层(透明胶片)没有,它就继续往下翻,在底层的“只读层”里找到了。它把内容拿给你看,速度极快,完全是共享读取。 - 你修改一个文件(比如要把
/etc/config里的参数改了):这就很有意思了。因为底层是只读的,AUFS不允许你直接改它。相反,内核会默默做一件事:把底层的这个文件“复制一份”,拷贝到最上面的“读写层”(你的透明胶片上),然后你在顶层对这个副本进行修改。
因为顶层的图层遮挡住了底层,下一次你再读取这个文件时,AUFS 在顶层就找到了修改后的版本,底层的那个原始文件就被“隐藏”了。
总结:AUFS 让容器“轻”在哪里?
正因为有了 AUFS(以及后来更主流的替代者Overlay2):
- 硬盘省到极致:100 个容器共享同一个几百兆的只读底层,每个容器的读写层刚启动时大小为0 B0\text{ B}0B。
- 启动快到飞起:启动一个新容器,不需要去硬盘里复制几十 GB 的文件,只需要在最上层创建一个几秒钟就能搞定的“空白透明胶片(读写层)”,容器瞬间就启动了。
所以,Namespace让进程戴上了墨镜(看不见别人),而AUFS给进程发了一张透明胶片(大家共享底片,各自在胶片上画画)。这就是容器比虚拟机轻量、高效的完整底层逻辑了!