写时复制(CoW)机制在修改文件时先完整复制整个文件到upperdir再操作;删除则生成.wh.文件遮蔽原文件,原内容仍保留在lowerdir中。
修改文件时,docker 不会直接改动只读镜像层里的原始文件,而是靠写时复制(copy-on-write, cow)机制,在容器的可写层中生成一份副本再操作。
修改动作触发复制
只有当容器内首次对某个只读层中的文件执行写操作(如编辑、覆盖、追加、重命名或删除)时,CoW 才会被激活。此时系统会:
- 定位该文件在哪个只读层(lowerdir)中存在
- 将整个文件完整复制到 upperdir(可写层)中
- 后续所有读写都作用于 upperdir 中的这份副本,原文件保持不变且仍被其他容器共享
复制粒度是“整个文件”
CoW 按文件为单位复制,不是按字节、块或目录。哪怕你只改了 config.json 的一个字符,整个文件都会被拉上来。这意味着:
使用 Python 脚本下载 Docker 镜像并打包为 tar 文件。用户说“下载镜像”“拉取镜像”“pull xxx”“帮我下载 nginx 镜像”等时触发。支持 SOCKS5 代理直连(推荐)和国内镜像站加速两种模式。
- 大文件(如日志、数据库文件、依赖包)被修改时,upperdir 会迅速变大
- 反复修改同一文件不会重复复制——只要它已在 upperdir 中,后续操作直接在其上进行
- 未被访问或修改的文件始终零开销,仍指向底层只读层
删除操作也走 CoW 流程
执行 rm 删除一个来自只读层的文件时,并不真正擦除数据,而是:
- 在 upperdir 中创建一个 whiteout 文件(如 .wh.filename)
- merged 视图中该路径即被隐藏,表现为“已删除”
- 原文件仍保留在 lowerdir 中,继续占用磁盘空间
验证方式:查看 upperdir 内容
可通过 docker inspect 获取容器的 UpperDir 路径(通常在 /var/lib/docker/overlay2/<id>/diff),然后进入该目录观察:
- 新创建或修改的文件会真实出现在 diff 目录下
- 被删除的文件对应有 .wh.* 标记文件
- 未动过的文件在 diff 目录里找不到,说明它们仍由 lowerdir 提供

















