由于我们的CI服务器不断生产新镜像,我需要一种方法来删除私有注册表中不再由命名标签识别的所有镜像。
如果没有内置的方法来实现此目的,我认为可能可以使用自定义脚本,但是我也没有看到v2 API方法来列出镜像的所有存储的哈希标签..
如何保持私有注册表的干净整洁呢?有什么提示吗?
删除镜像(保留最后10个版本,就像我在我的CI中所做的那样)需要三个步骤:
通过设置环境变量 REGISTRY_STORAGE_DELETE_ENABLED: "true"
并传递给 docker-registry 启用镜像删除
运行下面的脚本(它会删除所有镜像和标签但保留最后10个版本)
registry.py -l user:pass -r https://example.com:5000 --delete --num 10
运行垃圾回收(您可以将其放入每日 cron 任务中)
docker-compose -f [path_to_your_docker_compose_file] run registry bin/registry garbage-collect /etc/docker/registry/config.yml
registry.py 可以从以下链接下载,它还允许列出镜像、标签和层,以及删除特定的镜像和/或标签。
https://github.com/andrey-pohilko/registry-cli
在进行垃圾回收之前,我的注册表文件夹大小为7 GB,之后运行上述步骤后,它缩小到1 GB。
registry.py
使用API(/v2/_catalog
用于存储库, - x-yuri/v2/REPO/tags/list
获取标签。但是,每个标签通常都有多个版本。可以在/var/lib/docker/volumes/registry/_data/docker/registry/v2/repositories/REPO/_manifests/tags/TAG/index
中查看这些版本。可以使用DELETE /v2/REPO/manifests/sha256:HASH
删除它们。 - x-yuri关于您的问题:
我需要一种方法来删除私有注册表中所有不再由命名标签识别的图像
一个新版本的Docker注册表在distribution/registry:master
上具有这个很好的功能!但是,您无法通过API触发它。
无论如何,您将能够清理您注册表中的所有未标记的清单,这意味着每个覆盖的标记不会在注册表中留下旧的清单和二进制文件。每个“未使用”的层都将被注册表垃圾回收器清除。
您只需要运行一个docker exec
命令:
docker exec ${container_id} registry garbage-collect \
/path/to/your/registry/config.yml \
--delete-untagged=true
看这个垃圾回收二进制文件的帮助:
Usage:
registry garbage-collect <config> [flags]
Flags:
-m, --delete-untagged=false: delete manifests that are not currently referenced via tag
-d, --dry-run=false: do everything except remove the blobs
-h, --help=false: help for garbage-collect
你可以查看github PR,它已经被合并并可用于distribution/registry
的master
标签截至2018-02-23。 它取代了docker/docker-registry
项目,具有新的API设计,重点是安全和性能...我今天使用了此功能,并恢复了注册表空间的89%(5.7 GB vs. 55 GB)。之后我切换回稳定的registry
。docker pull registry:2
,停止容器 docker-compose stop registry
,删除容器 docker-compose rm registry
并重新创建它 docker-compose up -d registry
。以上步骤适用于使用 docker-compose 并在带有 docker-compose.yml
的目录中执行,并且您的容器名称为 registry
:) - Krystiandocker exec -it <docker-registry-container-name> /bin/sh
找到了它的位置,然后执行了 find / -iname "*.yml"
,找到了该文件的位置。 - Dave我使用名称为 docker-registry_registry_1
的Docker容器托管registry:2
镜像仓库。
我刚刚运行了garbage-collect
命令,并加上了-m
选项。
docker exec docker-registry_registry_1 bin/registry garbage-collect /etc/docker/registry/config.yml -m
虽然不太美观,但是这个可行。您需要运行(我认为)注册表2.3或更高版本,并启用删除(REGISTRY_STORAGE_DELETE_ENABLED=True
环境变量或等效项)。下面的示例命令假定在/srv/docker-registry
中有一个本地文件存储,但我相信对于其他存储后端也可以找到类似的解决方案。
对于您希望整理的每个存储库,您需要枚举不再需要的摘要引用。最简单的方法是按标签进行,以此示例中的latest
为例,您可以执行以下操作:
ls -1tr /srv/docker-registry/v2/repositories/<repo>/_manifests/tags/latest/index/sha256 \
| tail -n +3
这将列出除最近三个推送到 latest
标签之外的所有摘要。或者,如果您不太关心 标签,只想保留最近几个推送的引用,可以这样操作:
ls -1t /srv/docker-registry/v2/repositories/<repo>/_manifests/revisions/sha256 \
| tail -n +3
然后,您只需删除不需要的引用即可:
for hash in $(ls -1t /srv/docker-registry/v2/repositories/<repo>/_manifests/tags/latest/index/sha256 | tail -n +3); do
curl -X DELETE https://registry:5000/v2/<repo>/manifests/sha256:$hash
done
最后,您需要进行GC运行,因为注册表实现了“软删除”,它实际上并未删除任何内容,而只是使其无法使用:
docker exec docker-registry /bin/registry \
garbage-collect /path/to/config.yml
没错,这一切都非常混乱,在后端存储区域里翻找,因为没有API方法可以枚举与给定标签关联的所有摘要,但这就是现实。
REGISTRY_STORAGE_DELETE_ENABLED
,而不是 ..._STORE_...
。更多详情请见 https://docs.docker.com/registry/configuration/#/override-specific-configuration-options。 - Dave Foster.../_manifest/tags/<tag>/index/...
。 - David Pärsson/srv/docker-registry/v2/repositories/<repo>/_manifests/tags/latest/index/sha256
的清单。 - x-yuri目前正在讨论设计此功能-现在没有图层清理工具/端点。
我鼓励您前往:
如需更多帮助,请在 Freenode IRC 上的 #docker-distribution 联系我们。
我整理了这个帖子的不同部分,并创建了一个易于使用的bash清理脚本。
你可以在这个Gist链接中查看:cleanup.sh
for hash in
循环假定仓库名称是单个字符串,而我的仓库名称为 project/repo
,因此我不得不添加另一个内部循环来导航额外的文件夹级别。2)使用 -u usr:pwd
在 curl 命令中添加身份验证。3)将 REGISTRY_STORAGE_DELETE_ENABLED=true
添加到运行注册表的环境变量中。 - foz我在查找注册表v2 api中相同的功能,但只找到了软删除,这不是我要找的。在研究过程中,我发现了Github项目delete-docker-registry-image,它通过bash脚本从挂载的卷中删除实际文件。没有测试过,也许有用...
要删除未使用的镜像,需要按照以下三个步骤:
docker rmi -f **imageid**
rm -Rf /home/**homedirectory**/docker-registry/data/docker/registry/v2/repositories/**yoursystemname**/**yourimagename**/_manifests/tags/**image version**/
docker exec $(docker ps -q) bin/registry garbage-collect /etc/docker/registry/config.yml -m
*注意事项:
** 请在测试环境中执行上述命令,以免在执行过程中出现错误或未理解某个步骤而损坏生产环境。
** 您可以使用root用户的crontab定时执行上述命令。在第3步中,您必须删除"-it",即:docker exec $(docker ps -q) bin/registry garbage-collect /etc/docker/registry/config.yml -m`。
这对我已经有效运行了6个月以上。