现场是这样的。内网 CentOS 7.9 上跑 registry:2,数据目录 /data/registry 已经 180G,按文档删了仓库目录再重启,du 一点没变,registry 日志里也没有报错,磁盘使用率还是 92%。

中间走过弯路,把「配置里开了 delete 但服务没重新加载,删除请求被忽略」当成主因,改完现象没变。

排查方向其实有限,先把可能性排一排。直接删目录只删掉了索引,blob 还留在 _layers 下面;没有跑 registry garbage-collect,元数据里仍然引用旧层;多个仓库共享同一层,单独删一个仓库不会释放共享 blob。

上来先确认删除功能是否真的开启

grep -A3 delete /etc/docker/registry/config.yml

随后用 API 删 manifest 而不是删目录

curl -X DELETE -u user:pass http://registry.local:5000/v2/app/manifests/sha256:xxxx

接着停掉 registry 后跑一次垃圾回收

docker run --rm -v /data/registry:/var/lib/registry registry:2 garbage-collect --delete-untagged /etc/docker/registry/config.yml

回收完再核对 blob 占用

du -sh /data/registry/docker/registry/v2/blobs

那几天正好在做别的变更,先把时间线对齐才敢动手。

恢复的判定其实很直接。blobs 目录从 180G 降到 60G 左右,registry 启动后能正常 pull 已有镜像,push 新 tag 也没问题。

GC 必须在 registry 停止或只读时跑,边推边回收可能把刚上传还没写完的层删掉,镜像会直接损坏。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。

作者 9823189