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

咨询:私有Docker Registry仅4个标签却有大量Manifests和Blobs的原因

问题:私有Docker Registry仅4个标签却存在大量未被回收的Manifests和Blobs

我维护一个私有Docker Registry,执行垃圾回收(garbage-collection)无法释放存储空间。当前镜像仅包含4个标签,但运行garbage-collection --dry-run时,发现大量manifests和blobs被标记,且没有任何资源符合删除条件。

标签输出:

1   "0.0.18"
4   "0.0.16"
5   "0.0.19-SNAPSHOT"
6   "0.0.17"

垃圾回收输出(部分省略):

first-image
first-image: marking manifest sha256:0097c9845b15c656fce4641342e2b326e876552e3ef62d2d00c60c3e60cdc1a5 
first-image: marking blob sha256:a3d9a3da71d2604e1ea5b79aaeaaf11b3fc8bbd433cbb145df13342f4691fc88
first-image: marking blob sha256:9d19ee268e0d7bcf6716e6658ee1b0384a71d6f2f9aa1ae2085610cf7c7b316f
first-image: marking blob sha256:aa5b63dfa01646dce4380e03beced61802400b00a00eb6c41a45612e6fb57e96
first-image: marking manifest sha256:00d35e06b03f5c1858f0f961de3d5f8a47af57b16c0a3d122ba3b8bd9da69b06 
...(省略大量条目)
30151 blobs marked, 0 blobs and 0 manifests eligible for deletion

实际约有70个manifest条目,旧的SNAPSHOT标签已删除但manifests仍留存;另有第二个镜像已删除所有标签,但垃圾回收仍显示存在无法删除的manifests和blobs。


原因分析与解决方案

核心原因

1. 存在未断链的Manifest引用

Docker Registry垃圾回收仅清理无任何引用链的资源。即使删除标签,以下情况会让Manifest持续被引用:

  • 多架构镜像的manifest list(索引清单)会引用单个架构的具体manifest,这些被引用的manifest不会被标记为废弃。
  • 覆盖推送同名标签时,旧manifest不会自动删除,若被其他manifest(如manifest list)引用,就会被保留。
  • 共享blob:只要有一个留存的manifest引用某个blob,该blob就会被标记为需保留。

2. 未清理的Manifest List

如果镜像曾推送过多架构版本,生成的manifest list会持续引用底层的架构manifest和blob。即使删除了标签,manifest list本身未被删除的话,所有关联资源都无法被回收。

3. 无标签Manifest未被标记为废弃

手动删除标签后,对应的manifest不会立即被标记为废弃(默认未启用自动清理)。这些"僵尸"manifest若被其他资源引用,会一直占用存储空间。

解决步骤

1. 排查并删除无引用的Manifest

通过Registry API列出所有无标签的manifest:

# 替换为你的Registry地址和镜像名
REGISTRY_URL="your-registry-domain"
IMAGE_NAME="first-image"

# 获取所有manifest的digest列表
curl -u username:password https://$REGISTRY_URL/v2/$IMAGE_NAME/manifests/list | jq '.manifests[].digest'

# 逐个检查manifest是否关联标签
for digest in $(curl -u username:password https://$REGISTRY_URL/v2/$IMAGE_NAME/manifests/list | jq -r '.manifests[].digest'); do
  curl -u username:password https://$REGISTRY_URL/v2/$IMAGE_NAME/tags/list | jq '.tags' | grep -q $(curl -u username:password https://$REGISTRY_URL/v2/$IMAGE_NAME/manifests/$digest | jq -r '.config.digest') || echo "无引用Manifest: $digest"
done

确认无引用后,手动删除这些manifest:

curl -u username:password -X DELETE https://$REGISTRY_URL/v2/$IMAGE_NAME/manifests/<目标digest>

2. 执行带删除标记的垃圾回收

先停止Registry服务(避免读写干扰),再执行完整回收:

docker stop registry-container-name
docker run --rm -v /path/to/registry/data:/var/lib/registry registry:latest garbage-collect /etc/docker/registry/config.yml --delete-untagged

--delete-untagged参数会删除所有无标签且无其他引用的manifest及关联blob。

3. 启用自动清理机制

在Registry的config.yml中添加以下配置,开启定期自动清理:

garbagecollect:
  enabled: true
  interval: 24h
  dry-run: false
  delete-untagged: true

重启Registry后,会按配置自动清理废弃资源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 17:58:13