5.1 overlay2存储驱动:镜像在磁盘上的真实形态


5.1 overlay2 存储驱动:镜像在磁盘上的真实形态

摘要:存储驱动负责把镜像层与可写层拼成容器根目录,当前的事实标准是 overlay2。本节看清它在磁盘上的目录布局、回顾存储驱动混战的结局,并学会用 docker system df 与 prune 管理磁盘这本账。

能力目标

  1. 描述 Docker 存储区中层目录、可写层目录、镜像元数据的布局关系
  2. 说出 overlay2 成为默认存储驱动的两条原因
  3. 用 docker system df 分项盘点磁盘占用
  4. 安全地执行清理而不误删数据

存储驱动在整盘棋里的位置

先划清存储驱动的职责边界。它只负责一件事:把镜像层与可写层拼成容器的根目录,并处理这个过程中的读、改、删。它不管三件事:卷里的数据存放(卷直接落在宿主文件系统的管理区,不走联合挂载)、镜像在仓库中的传输格式(那是压缩层与清单的事)、容器配置(有独立的元数据)。初学者常把"容器数据问题"一股脑归到存储驱动头上,方向就偏了——数据丢失多是没用卷,性能差多是往可写层写大文件,两类问题的病根都在使用方式而非驱动本身。边界划清,后面的内容才好对号入座。

从一片混战到 overlay2 一统

联合文件系统有过一段诸侯割据的历史:aufs 是 Docker 最早用的实现,功能全但一直没能进内核主线;device-mapper 用块设备模拟层,配置复杂且性能平平;overlayfs 在 2014 年进入 Linux 内核主线,轻量、快、维护活跃。Docker 的 overlay2 驱动就是建立在 overlayfs 之上的第二代实现(第一代 overlay 只支持低层目录数有限,已淘汰)。今天的结论很简单:内核 4.0 以上、文件系统是 ext4 或 xfs(带 ftype=1),用 overlay2,不需要纠结。docker info 里的 Storage Driver: overlay2 就是健康状态。

磁盘上的真实布局

Docker 的存储区默认在 /var/lib/docker,与存储驱动相关的两块:

层目录。每个镜像层在 overlay2 目录下占一个哈希命名的目录,层内容在其 diff 子目录,另有一份 lower 文件记录它之下还有哪些层。2.1 节 inspect 出的 LowerDir 冒号串,就来自这些目录的拼接。

可写层目录。每个运行过(或创建过)的容器一个目录,同样是 diff/merged/work 三件套。容器删除,这个目录连带消失——可写层"容器删了就没"在文件系统层面就是这么直白。

镜像清单本身不在这两个目录里,而是 image/overlay2 下的层配置文件,记录"这个镜像由哪几层按什么顺序叠成"。所以"镜像"在本地=若干层目录+一份配置清单;pull 时先取清单再补缺的层,push 时按清单逐层上传。

动手看一眼(需 root):

sudo ls /var/lib/docker/overlay2 | head sudo du -sh /var/lib/docker/overlay2

第二个命令给出层总占用——一台跑久了的机器,这个数字往往比 docker images 列表的总和还大,因为被中断的构建、悬空层、停止容器的可写层都躺在里面。

磁盘账本与清理

docker system df

输出分四行:

TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 24 6 12.4GB 8.9GB (71%) Containers 9 3 890MB 612MB (68%) Local Volumes 5 3 2.1GB 402MB (18%) Build Cache 31 0 1.7GB 1.7GB (100%)

重点看 RECLAIMABLE 列:可回收的部分才是清理的目标。四类垃圾各有对应清法:

docker container prune # 清停止的容器(连带其可写层) docker image prune # 清悬空镜像(无 tag 且无容器引用) docker image prune -a # 更狠:清一切无容器引用的镜像 docker builder prune # 清构建缓存 docker volume prune # 清无容器引用的卷 ⚠️ 慎用

最后一条要单独警告:卷里装的是数据。一个停掉的数据库容器引用着卷时 prune 不会动它,但容器被 rm 之后,卷就成了"无引用",prune 会把数据一并带走。生产机器上执行 volume prune 前必须确认卷清单,或者干脆禁用这条命令的习惯养成。一次性全清的 docker system prune 同理,加上 -a --volumes 的形态是核弹级的,只在一次性测试机上用。

⚠️ 另一个磁盘黑洞是容器日志。json-file 日志驱动默认不限大小,长跑的服务日志能吃掉几十 GB,它们记在 containers 目录下每个容器的 json 日志文件里,不占 overlay2 但同属 /var/lib/docker。1.2 节配的 max-size/max-file 就是提前堵这个洞。

overlay2 的性能特征

三条实用结论:

顺序读与页缓存友好。读路径几乎无额外开销,merged 视图的查找在 dentry 缓存命中后与原生 ext4 差距很小。常规 Web 服务不必担心存储驱动拖累。

写大文件触发整文件复制(写时复制,2.1 节已拆)。在容器可写层里做数据库、日志追加这类高频写大文件的活,性能与磁盘都会遭殃——这正是必须用卷的技术理由,不是风格偏好。

目录查找深度。层数极多(几十层)时,第一次查找的代价略增,且镜像元数据协商变慢。把镜像控制在十几层内是健康线,2.2 的指令合并已经在做这件事。

本节要点回顾

  • overlay2 建于内核 overlayfs,是当前唯一值得默认选择的存储驱动
  • 镜像 = 层目录 + 配置清单,可写层目录随容器生灭
  • system df 的 RECLAIMABLE 列是清理决策的依据,四类垃圾各有对应 prune
  • volume prune 会删数据,生产机上是最危险的清理命令
  • 性能敏感的写操作离开可写层,去卷里写——下一节的主角

可写层靠不住,那数据该住哪?三种挂载方式登场。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U