overlay2 是 docker 默认且推荐的存储驱动,基于内核 overlayfs 实现分层与联合挂载,通过 lowerdir(只读镜像层)、upperdir(容器可写层)、merged(统一视图)和 workdir(原子操作临时区)协同工作,采用 copy-on-write 和 whiteout 机制保障高效、安全的文件操作。

Overlay2 是 Docker 默认且推荐的存储驱动,它基于 Linux 内核的 OverlayFS 联合文件系统实现,核心思想是用“分层+联合挂载”来高效管理镜像和容器的文件系统。它不复制数据,而是通过目录叠加和按需读写,让多个容器共享镜像层、各自维护独立变更。
四个关键目录各司其职
每个容器运行时,Overlay2 会在 /var/lib/docker/overlay2/ 下为其分配一组目录,主要包括:
-
lowerdir:只读层,对应镜像的多个只读层(可能有多个路径,用冒号分隔)。它们是构建镜像时每条
RUN、COPY等指令生成的静态快照,所有容器可共享,不可修改。 -
upperdir:可写层,仅属于当前容器。容器内所有新增、修改、删除操作都发生在这里。例如你执行
echo "hi" > /app/log.txt,文件实际写入upperdir/app/log.txt,不影响底层镜像。 -
merged:用户看到的“真实根文件系统”。它是
lowerdir和upperdir动态合并后的统一视图,挂载到容器的/。你ls /bin看到的是 lowerdir 的内容;ls /app看到的可能是 upperdir 新增的内容。 - workdir:OverlayFS 内部必需的临时工作区,用于保障文件操作(如重命名、unlink)的原子性。它对用户完全透明,不能直接访问或修改,挂载后内容会被清空。
读、写、删操作背后的机制
Overlay2 不直接修改只读层,所有变更都通过 Copy-on-Write(写时复制)和 Whiteout(白条)机制处理:
-
读文件:先查
upperdir;命中则返回;未命中则从最上层的lowerdir开始向下查找,直到找到为止。 -
写文件(已存在):若文件在
lowerdir中,Overlay2 先将该文件完整拷贝到upperdir(即 Copy-on-Write),再修改副本。原镜像层始终不变。 -
删文件:不在
upperdir创建空文件,而是生成一个特殊隐藏文件(如.wh.filename),称为 Whiteout,用于“屏蔽”lowerdir中同名文件,使其在merged视图中不可见。
镜像层与容器层如何组织
拉取一个镜像(如 nginx)时,Docker 把它拆成若干只读层,每个层对应一个 /var/lib/docker/overlay2/<layer-id></layer-id> 目录,含 diff/(实际文件)、link(短名软链,规避 mount 参数长度限制)、lower(记录它依赖的下层 ID)等。容器启动时,Docker 将这些只读层作为 lowerdir,再新建一个空 upperdir,加上 workdir,一起挂载为 merged。
你可以用 docker inspect <container-id></container-id> 查看具体路径,也能用 mount | grep overlay 看到类似这样的挂载项:overlay on /var/lib/docker/overlay2/<id>/merged type overlay (rw,relatime,lowerdir=...,upperdir=...,workdir=...)</id>
为什么推荐 overlay2 而不是 overlay
原始 overlay 驱动存在稳定性缺陷,比如长期运行后触发 “too many links” 错误,或 inode 泄漏。overlay2 在内核 4.0+ 中重构,支持最多 128 层叠加、优化了 inode 复用、修复了并发问题,并原生兼容 d_type=1 的 XFS 或启用 dir_index 的 ext4。只要满足内核版本(≥4.0 或 RHEL/CentOS ≥3.10.0-514)和文件系统要求,就应坚持使用 overlay2。











