Docker镜像由按序堆叠的只读层组成,每层为构建指令产生的增量快照,依赖UnionFS(如overlay2)实现多层合并与写时复制;容器运行时 atop 可写层,共享基础层以节省空间。
Docker镜像不是单个大文件,而是一组按顺序堆叠的只读层(layers),每一层代表一次构建操作的变更。这种分层结构依赖底层存储驱动(如overlay2)提供的联合文件系统(UnionFS)能力,实现高效复用、快速启动和空间节省。
镜像层的本质:只读增量快照每次docker build中的指令(如 RUN、COPY、ADD)都会生成一个新层,该层仅保存与上一层相比的文件增删改差异(diff)。基础镜像(如 ubuntu:22.04)本身也由多个层构成,最底层通常是操作系统根文件系统的精简副本。
所有镜像层默认只读,运行容器时才在顶部叠加一个可写层(container layer)
同一基础镜像的不同衍生镜像(如 python:3.11 和 node:18)会共享底层共用层,降低磁盘占用docker history
写入新文件 → 落入可写层(copy-on-write)
修改已有文件 → 先从只读层复制到可写层再编辑(copy-on-write)
删除文件 → 在可写层放置一个“whiteout”标记,屏蔽下层同名文件(overlay2 使用 .wh.* 文件)
为什么分层会影响构建效率和镜像大小层是缓存和复用的基本单位,但也是膨胀和冗余的源头。Docker 构建过程按指令逐层提交,一旦某层变化,其后所有层均失效重建;同时,被上层删除或覆盖的文件仍物理存在于旧层中,无法自动清理。
避免在不同层重复安装/删除软件包(如 apt update + apt install + apt clean 应写在同一 RUN 中)
使用多阶段构建(multi-stage build),仅将最终需要的二进制或配置复制到轻量运行镜像,丢弃构建依赖层docker image prune -a可清理悬空层(dangling layers),但不会删除被任意镜像引用的层实际验证:查看镜像层与存储布局以本地镜像为例,可通过文件系统路径观察真实分层结构(以 overlay2 驱动为例):镜像层元数据存于/var/lib/docker/image/overlay2/imagedb/content/sha256/,记录每层 diffID 和 chainID各层实际内容在/var/lib/docker/overlay2/
