overlay2分层合并本质是路径优先级规则的实时解析:lowerdir为从左到右扫描的只读层集合,upperdir为唯一可写层并处理copy-up与whiteout,merged仅为内核动态合成的空挂载点视图。

理解镜像分层合并,关键不是数有多少层,而是看清 lowerdir 和 upperdir 如何协同呈现“一层”假象。Overlay2 的分层不是物理堆叠,而是通过目录视图叠加实现的逻辑合并——用户看到的 merged 目录,本质是内核对两个路径的实时联合解析结果。
lowerdir 是只读层的集合,不是单个目录
一个镜像可能由 5 层构成,它的 lowerdir 就是这 5 个 diff 目录用冒号拼接的路径,例如:
/var/lib/docker/overlay2/abc.../diff:/var/lib/docker/overlay2/def.../diff:...
这些目录按构建顺序从左到右排列,查找文件时 overlay2 会从左往右逐层扫描,一旦命中即返回,不会继续向后查。所以镜像层越深,open() 类操作的路径遍历开销越大。
upperdir 是唯一可写入口,也是所有变更的“落点”
容器启动后,所有新增、修改、删除操作都只发生在 upperdir 中:
• 新建文件 → 直接写入 upperdir
• 修改只读层中的文件 → 先 copy-up 整个文件到 upperdir,再改副本
• 删除文件 → 在 upperdir 创建 whiteout 文件(如 .wh.filename),屏蔽 lowerdir 中同名项
这意味着 upperdir 不仅承载运行时数据,还隐式记录了“哪些内容被覆盖或隐藏”,它是镜像与容器差异的完整快照。
merged 视图是动态合成的结果,不占用额外存储
merged 目录本身是空的挂载点,它不存数据,只提供统一访问入口。内核在访问 merged 下任意路径时,实时判断该路径应来自 lowerdir 还是 upperdir:
• 若 upperdir 存在同名常规文件 → 返回 upperdir 版本
• 若 upperdir 存在 .wh.* whiteout → 忽略 lowerdir 中对应项,表现为“已删除”
• 若 upperdir 无匹配,且 lowerdir 有 → 返回 lowerdir 版本
这种机制让镜像复用和容器隔离同时成立:多个容器可共享同一组 lowerdir,各自独立维护 upperdir。
分层合并的本质是路径优先级规则
所谓“合并”,并非把文件拷贝到一起,而是定义一套查找优先级:
upperdir > whiteout屏蔽 > lowerdir(从左到右)
Docker 构建时每条 RUN 指令生成一层,实质就是新增一个 lowerdir 路径段;而容器运行时所有写操作,都在 upperdir 中建立新路径或覆盖已有路径。最终用户看到的文件系统,是这套规则在线计算出的视图——它轻量、即时、无需预处理。











