Docker 镜像的存储核心就两个关键词:分层存储(UnionFS) + 写时复制(CoW),这是 Docker 轻量、高效、复用性强的根本原因。
我用最直白的方式,一步步给你讲透。

一、先搞懂:镜像不是一个大文件,而是多层堆叠
你可以把 Docker 镜像想象成千层蛋糕:
每一层都是一个只读的文件 / 目录增量
层与层之间通过 UnionFS(联合文件系统) 无缝叠加
最终看起来就是一个完整的、统一的文件系统
举个最经典的例子(Ubuntu + Nginx 镜像)
# 层1:基础镜像 Ubuntu(底层)
FROM ubuntu:22.04
# 层2:更新 apt 源
RUN apt-get update
# 层3:安装 Nginx
RUN apt-get install -y nginx
# 层4:暴露端口
EXPOSE 80
这个镜像最终会生成 4 层只读层:
1. Ubuntu 系统基础层
2. apt 更新文件层
3. Nginx 安装文件层
4. 配置端口层
Docker 会把它们透明叠加,你使用时完全感觉不到分层。
二、核心原理:UnionFS 联合文件系统
Docker 默认用 Overlay2(最主流)作为存储驱动,它的能力是:
把多个目录,合并成一个目录展示给用户
下层:只读镜像层(所有基础层、软件层)
上层:容器读写层(运行时修改的内容)
用户视角:只有一个完整的文件系统
三、最重要的特性:写时复制(Copy-on-Write)
这是 Docker 镜像极省空间、极快启动的关键。
规则
1. 所有镜像层都是只读的,永远不会被修改
2. 当容器要修改一个文件时:
Docker 会自动把该文件从镜像层复制到容器读写层
之后所有修改只作用于副本
底层原始镜像层完全不变
好处
多个容器可以共享同一个底层镜像,不重复占用磁盘
启动极快:不需要复制完整文件系统
镜像体积小:层可以跨镜像复用
四、容器运行时的存储结构(必看)
当你用镜像启动一个容器时:
[ 容器读写层(可写,容器删除就丢失) ]
↓
[ 镜像只读层1 ]
[ 镜像只读层2 ]
[ 镜像只读层3 ]
只读层:镜像本身,所有容器共享
读写层:每个容器独一份,临时存在
你在容器里新建、修改、删除文件,都在这里
容器删除,读写层直接丢失
这就是为什么:容器不持久化数据,数据要放数据卷!
五、镜像分层的巨大优势
1. 存储空间极大节省
100 个 Ubuntu 容器,共享 1 个 Ubuntu 基础层
不需要 100 份完整系统拷贝
2. 构建 / 分发速度极快
构建镜像:只上传 / 下载变化的层
比如只改了代码,基础系统层不用重新传输
3. 复用性极强
所有镜像都可以复用官方基础层(Ubuntu、Alpine、Node 等)
六、磁盘上真实长什么样?
Docker 默认存储路径:
/var/lib/docker/overlay2/
里面全是层目录:
每个目录对应镜像的一层
包含 diff(实际文件)、link(层关系)
你不用手动改这里,Docker 自动管理。
七、用命令看镜像分层(实操)
# 查看镜像的所有层
docker image inspect nginx
# 更直观查看层大小和内容
docker history nginx
你会看到每一层的大小、执行的命令,非常清晰。
总结(一句话版)
Docker 镜像 = 多个只读层 + UnionFS 合并 + 写时复制
镜像只读、分层、可共享
容器运行时加一层读写层
修改只影响容器,不影响镜像
高效、省空间、快启动
核心关键点回顾
1. 镜像 = 多层只读文件,靠 UnionFS 合并成一个整体
2. 写时复制:修改文件时才复制到容器层,底层不变
3. 容器读写层临时,删除容器数据丢失(需用卷持久化)
4. 分层让 Docker 轻量、复用、高效
需求留言: