UnionFS 的“删除”是逻辑屏蔽而非物理擦除,通过白化(whiteout)机制实现:在可写层创建 .wh.xxx 标记文件遮盖下层同名项,保障只读层完整性与镜像分层不可变性。

UnionFS 中的“删除”不是真正擦除,而是一种逻辑屏蔽——通过白化(whiteout)机制实现。它保障了底层只读层的完整性,是镜像分层不可变性的关键支撑。
白化文件(whiteout)是什么
当容器内执行 rm /etc/nginx.conf 时,该文件实际仍存在于某一层镜像中。UnionFS 并不修改或删除它,而是在可写层(upperdir)中创建一个特殊标记文件,例如:.wh.nginx.conf
这个以 .wh. 开头的隐藏文件即为 whiteout 条目,表示“上层要遮盖掉下层同名项”。挂载后,用户看到的效果就是该文件“已消失”。
删除行为的三层表现
– 对用户:文件不可见、不可访问,行为符合预期
– 对镜像层:所有只读层完全未改动,哈希值不变,可被其他容器安全复用
– 对可写层:仅新增一个极小的 whiteout 文件(通常几字节),不复制原内容,节省空间
白化与修改的区别处理
– 删除操作 → 写入 .wh.xxx 标记,不拷贝原文件
– 修改操作 → 先触发 Copy-on-Write(COW):把原文件从只读层完整复制到 upperdir,再编辑副本
– 重命名/移动 → 若跨目录,可能涉及 whiteout + 新建;若同层内,多数情况下直接更新 dentry,不生成 whiteout
实际影响与注意事项
– docker diff <container> 命令会明确列出 whiteout 条目,标为 D(Deleted)类型
– 白化文件本身不可见于普通 ls,需加 ls -a 查看,且仅存在于 upperdir 目录中
– 容器删除后,whiteout 和所有可写层内容一并释放,不影响镜像层
– 真正清理磁盘空间,需执行 docker system prune 或手动清理 /var/lib/docker/overlay2 中无引用的层










