You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker overlay2目录数据泄漏:通用可扩展排查方法咨询

定位Docker Overlay2未被CLI识别的数据泄漏的通用调试方法

问题背景

修改Jenkins流水线中的Docker构建脚本或升级Docker后,出现严重的镜像数据泄漏:/var/lib/docker/overlay2目录大小持续增长,远超Docker CLI(如docker system df)可识别并清理的镜像大小。繁忙的构建服务器上每日泄漏约1TB数据,常规docker system prune等命令无法清理,只能手动删除整个/var/lib/docker目录。

典型现象

执行docker system prune -af后立即查看,磁盘占用与CLI统计完全不符:

$ sudo du -sch /var/lib/docker/overlay2; echo ""; docker system df

68G     /var/lib/docker/overlay2
68G     total

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          0         0         0B        0B
Containers      0         0         0B        0B
Local Volumes   0         0         0B        0B
Build Cache     0         0         0B        0B

几乎所有无法被识别的泄漏文件都位于diff子目录,但该目录同时存储有效镜像层,无法直接区分:

$ find /var/lib/docker/overlay2 | grep diff | wc -l
989599
# vs.
$ find /var/lib/docker/overlay2 | grep -v diff | wc -l
792

泄漏目录的内容无异常,多为编译源码或预编译库文件:

./268713830f68824c1f6f5b21aad89055c18e8c0e6f1751654ec82ca4caf5bba9/diff/opt/conda/lib/python3.11/site-packages/sklearn/ensemble/_weight_boosting.py
./268713830f68824c1f6f5b21aad89055c18e8c0e6f1751654ec82ca4caf5bba9/diff/opt/conda/lib/python3.11/site-packages/sklearn/ensemble/_gradient_boosting.cpython-311-x86_64-linux-gnu.so
./268713830f68824c1f6f5b21aad89055c18e8c0e6f1751654ec82ca4caf5bba9/diff/opt/conda/lib/python3.11/site-packages/sklearn/ensemble/tests/test_gradient_boosting.py
./268713830f68824c1f6f5b21aad89055c18e8c0e6f1751654ec82ca4caf5bba9/diff/opt/conda/lib/python3.11/site-packages/sklearn/ensemble/tests/__pycache__/test_gradient_boosting.cpython-311.pyc
./268713830f68824c1f6f5b21aad89055c18e8c0e6f1751654ec82ca4caf5bba9/diff/opt/conda/lib/python3.11/site-packages/sklearn/ensemble/tests/__pycache__/test_weight_boosting.cpython-311.pyc
./268713830f68824c1f6f5b21aad89055c18e8c0e6f1751654ec82ca4caf5bba9/diff/opt/conda/lib/python3.11/site-packages/sklearn/ensemble/tests/test_weight_boosting.py
./268713830f68824c1f6f5b21aad89055c18e8c0e6f1751654ec82ca4caf5bba9/diff/opt/conda/lib/python3.11/site-packages/scipy/special/tests/data/boost.npz
./268713830f68824c1f6f5b21aad89055c18e8c0e6f1751654ec82ca4caf5bba9/diff/opt/conda/lib/python3.11/site-packages/scipy/special/tests/test_boost_ufuncs.py

Docker BuildX场景下的问题表现

升级为Docker BuildX(v0.15.1 1c1dbb2)后,初期overlay2大小稳定,但清理后无法回收存储,长期仍会耗尽空间:

$ sudo du -sch /var/lib/docker/overlay2; echo ; docker system df                                                                                                 build-srv-3-fi: Sun Jul 28 14:43:42 2024

117G    /var/lib/docker/overlay2
117G    total

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          0         0         0B        0B
Containers      0         0         0B        0B
Local Volumes   0         0         0B        0B
Build Cache     0         0         0B        0B

常规清理方式(先删镜像再清缓存、docker system prune)无改善。

注:场景不限于Docker Compose部署的Jenkins,并行数十个带层重叠、多阶段关联的流水线,每个业务容器构建需4个额外服务容器。

补充验证:排除分层文件系统计数干扰

使用du的--one-file-system参数确认是真实磁盘占用,而非分层文件系统重复计数:

$ sudo du -sch /var/lib/docker/overlay2; echo ""; sudo du -sch --one-file-system /var/lib/docker/overlay2; echo ""; docker system df

452G    /var/lib/docker/overlay2
452G    total

452G    /var/lib/docker/overlay2
452G    total

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          0         0         0B        0B
Containers      0         0         0B        0B
Local Volumes   0         0         0B        0B
Build Cache     0         0         0B        0B

极端场景数据对比

当目录过于复杂导致du无法快速执行时:

$ df -haT
Filesystem     Type         Size  Used Avail Use% Mounted on
[..]
/dev/md2       ext4         3.4T  3.2T  5.3G 100% /


$ docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          333       0         2.873TB   2.873TB (100%)
Containers      0         0         0B        0B
Local Volumes   0         0         0B        0B
Build Cache     2532      0         55.14GB   55.14GB

$ docker system prune -af
Total reclaimed space: 812.8GB

$ docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          0         0         0B        0B
Containers      0         0         0B        0B
Local Volumes   0         0         0B        0B
Build Cache     0         0         0B        0B

实际结果:docker system prune宣称回收812.8GB,但实际仅回收约0.4T,overlay2仍有大量未识别数据;docker system df预估的可回收空间与实际相差约2.5T;仅BuildX的50GB构建缓存限制基本有效(仅超出10%)。

$ df -haT
Filesystem     Type         Size  Used Avail Use% Mounted on
[..]
/dev/md2       ext4         3.4T  2.8T  400G  88% /

# 重启Docker守护进程和套接字无帮助:
$ sudo systemctl restart docker docker.socket

$ df -haT
Filesystem     Type         Size  Used Avail Use% Mounted on
[..]
/dev/md2       ext4         3.4T  2.8T  400G  88% /

通用可扩展调试步骤

步骤1:追踪Overlay2目录的元数据关联

Docker通过元数据文件跟踪overlay2的有效层,对比元数据记录与实际目录:

# 列出所有元数据中记录的层哈希
ls /var/lib/docker/image/overlay2/layerdb/sha256/ > /tmp/known_layers.txt
# 列出overlay2目录下的所有层目录(排除临时目录)
ls /var/lib/docker/overlay2 | grep -v l | grep -v merged | grep -v diff > /tmp/actual_layers.txt
# 找出不在元数据中的可疑泄漏层
comm -23 <(sort /tmp/actual_layers.txt) <(sort /tmp/known_layers.txt) > /tmp/leaked_layers.txt

步骤2:分析泄漏层的创建时间与关联进程

通过时间匹配定位泄漏层的来源:

# 查看泄漏层的创建时间
stat /var/lib/docker/overlay2/[泄漏层哈希]/
# 匹配Docker守护进程日志中的操作时间
journalctl -u docker --since "YYYY-MM-DD HH:MM:SS" --until "YYYY-MM-DD HH:MM:SS" | grep [泄漏层哈希]
# 匹配Jenkins流水线日志
grep -r [泄漏层哈希] /var/lib/jenkins/jobs/[流水线名]/builds/[构建号]/log

步骤3:验证层的引用关系

检查是否有残留的镜像、容器引用泄漏层:

# 遍历所有镜像(即使df显示0,也要检查残留元数据)
for img in $(docker images -q); do docker inspect $img | grep -A5 -B5 "Layer"; done
# 检查停止的容器残留
docker ps -a -q | xargs docker inspect | grep -A5 -B5 "Layer"

步骤4:BuildX特定调试

检查BuildX缓存与泄漏层的关联:

# 列出BuildX的构建器
docker buildx ls
# 查看构建器缓存配置
docker buildx inspect [builder-name] --bootstrap
# 模拟清理,查看将被删除的缓存
docker buildx prune -n

步骤5:排查文件句柄泄漏

检查是否有进程持有overlay2文件句柄,导致Docker无法删除:

# 查找持有overlay2文件的进程
lsof +D /var/lib/docker/overlay2

内容的提问来源于stack exchange,提问作者mirekphd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 13:29:50