Docker 29.5.3 是一个小版本更新,但修了一个让不少用户头疼的问题——在使用 containerd 镜像存储时,一边清理镜像一边跑 docker system df,容易触发错误。如果你已经在用 Docker 的 containerd 镜像存储后端,这个版本值得尽快升级。
containerd 镜像存储是什么,为什么这个 bug 影响大
Docker 默认的镜像存储后端是经典的 V2 格式(overlay2 + layer store)。从 Docker 25 开始,官方逐步引入了 containerd 镜像存储作为可选后端,它的核心优势:
- 镜像和容器共享底层快照,同一镜像跑多个容器时磁盘占用更少
- 与 containerd 原生兼容,Kubernetes 和 Docker Desktop 可以共用同一套镜像缓存
- 支持
docker build的 lazy pulling 等新特性
但这个后端目前仍标记为实验性,并发操作下的稳定性是主要短板。这次修复的 moby/moby#52672 就是一个典型场景:当你执行 docker image prune 或 docker rmi 清理镜像的同时,另一个终端跑 docker system df 查看磁盘占用,两个操作争抢同一份镜像元数据,导致 system df 输出报错甚至崩溃。
对于 CI/CD 管线或自动化运维脚本来说,这种并发冲突并不少见——清理任务和监控采集往往同时运行。
修复了什么
根据 PR 描述,修复集中在两个层面:
docker system df在镜像清理期间不再报错——元数据读取加了更安全的并发处理,清理过程中的中间状态不会暴露给df命令。- 镜像清理本身的并发错误减少——多个清理操作同时触发时,不再出现冲突导致的失败。
此外,打包层面将 containerd 静态二进制文件更新到 v2.2.4,这是 containerd 近期的稳定版本,包含自身的多项修复。
实操:启用 containerd 镜像存储并验证清理行为
如果你还没用过 containerd 镜像存储后端,可以这样开启(Docker 25+ 支持):
# 编辑 Docker daemon 配置
sudo tee /etc/docker/daemon.json <<'EOF'
{
"storage-driver": "overlay2",
"features": {
"containerd-snapshotter": true
}
}
EOF
# 重启 Docker
sudo systemctl restart docker
# 验证后端已切换
docker info --format '{{.DriverStatus}}'
# 输出中应能看到 "driver-type" = "io.containerd.snapshotter.v1.overlayfs"
启用后,拉取镜像并做一次并发清理测试:
# 拉取几个小镜像
docker pull alpine:3.18
docker pull busybox:1.36
docker pull nginx:alpine
# 查看当前磁盘占用
docker system df
# 并发测试:一个终端清理,另一个终端同时查 df
# 终端 A:
docker image prune -a -f
# 终端 B(在 prune 执行期间立刻运行):
docker system df
# 在 29.5.3 之前,这里大概率报错;
# 在 29.5.3 之后,应正常输出,不会因并发而中断
如果你在 CI 脚本中同时做清理和监控,可以这样写一个简单的健壮性检查:
#!/bin/bash
# ci-cleanup-and-report.sh
# 并发清理 + 磁盘报告,验证 containerd 后端稳定性
cleanup() {
docker image prune -a -f --filter "until=24h"
echo "清理完成"
}
report() {
sleep 1 # 稍微延迟,确保与清理操作重叠
docker system df
echo "报告完成"
}
# 并发执行
cleanup &
report &
wait
echo "全部完成,无报错"
在 29.5.3 之前,这个脚本大概率在 report 阶段报错;升级后应能稳定跑完。
升级建议
| 场景 | 建议 |
|---|---|
| 已启用 containerd 镜像存储 | 尽快升级到 29.5.3,并发清理和监控不再冲突 |
| 使用默认 V2 存储后端 | 升级优先级不高,但 containerd v2.2.4 的打包更新仍有安全价值 |
CI/CD 中有定时清理 + system df 采集 |
升级后可去掉脚本中为规避并发错误而加的 sleep 或重试逻辑 |
需要注意,containerd 镜像存储后端仍是实验性特性。生产环境启用前,建议在测试环境跑一轮完整的镜像拉取、构建、清理流程,确认行为符合预期。如果你依赖第三方工具(如 skopeo、harbor 镜像同步脚本)直接操作 Docker 的本地存储目录,切换后端后这些工具可能需要适配,因为镜像元数据的磁盘布局发生了变化。