docker通过内容哈希识别相同层并联合文件系统叠加只读层实现存储复用,每条dockerfile指令生成唯一sha256哈希层,输入一致即复用;多镜像共享基础层与依赖层,overlay2通过lowerdir引用减少冗余;缓存复用提升构建效率并节省空间,需合理设计dockerfile顺序、避免latest标签、使用多阶段构建,并定期清理悬空层。
靠内容哈希识别相同层,再通过联合文件系统叠加只读层,是 docker 实现存储复用的核心方式。关键不在于“堆得多”,而在于“叠得准”——相同变更集只存一份,多个镜像按需引用。
分层基于指令生成,每层有唯一内容哈希
Dockerfile 中每条有效指令(如 FROM、RUN、COPY)都会生成一个新层,该层内容被计算 SHA256 哈希值作为唯一标识。只要两处构建中某一层的输入完全一致(包括基础镜像、命令文本、文件内容),生成的哈希就相同,Docker 就会复用本地已有的那一层,不再重复存储。
- FROM ubuntu:22.04 → 固定标签确保基础层哈希稳定
- RUN apt-get update && apt-get install -y curl → 命令字符串+执行结果决定哈希
- COPY package.json . → 文件内容变化即触发新层
多镜像共享底层,减少冗余占用
不同项目若都基于 alpine:3.18 或 python:3.11-slim 构建,它们的基础操作系统层和通用依赖层(如 pip install 的包)在磁盘上只保存一次。Docker 的存储驱动(如 overlay2)通过 lowerdir 引用这些共享层,无需复制。
- 运行 docker system df 可查看 “Reclaimable” 空间,反映未被任何镜像引用的“悬空层”
- 执行 docker image ls --digests 能看到各镜像最后一层的摘要,相同摘要即表示共享了该层
缓存复用提升构建效率,间接节省空间
构建时跳过已缓存层,不仅加快速度,也避免因重复执行 RUN 或 COPY 产生冗余中间层。例如将 go.mod 单独 COPY 并 RUN go mod download 放在前面,即使源码频繁变更,依赖下载层仍可复用。
- 把变动少的内容(基础镜像、依赖声明)写在 Dockerfile 上方
- 避免使用 latest 标签,防止基础镜像更新导致整条链缓存失效
- 多阶段构建中,builder 阶段的输出可通过 COPY --from 复用,不污染最终镜像层
定期清理无用层释放物理空间
虽然共享机制自动避免重复存储,但构建失败、中断或旧版本镜像残留会产生未被引用的层(dangling layers)。这些层不参与运行,却持续占用磁盘。
- docker builder prune -a 清理所有构建缓存(含中间镜像)
- docker image prune -a 删除所有未被容器或镜像引用的悬空层
- 搭配 --filter "until=24h" 可精准控制清理范围











