Docker Registry 2.0 - 如何删除未使用的图像?

问题描述 投票:49回答:7

我们将私有docker注册表更新为官方Registry 2.0。此版本现在可以删除由标签标识的docker图像(请参阅https://docs.docker.com/registry/spec/api/#deleting-an-image),但我仍然没有看到清理旧图像的方法。

由于我们的CI服务器不断生成新图像,我需要一种方法来删除私有注册表中不再由命名标记标识的所有图像。

如果没有内置的方法来实现这一点,我认为自定义脚本可能有效,但我没有看到v2 API方法列出图像的所有存储的标签。

如何保持我的私人注册表清洁?任何提示?

docker docker-registry
7个回答
45
投票

删除图像(您可以保留10个最新版本,就像我在CI中一样)分三步完成:

  1. 通过设置环境变量REGISTRY_STORAGE_DELETE_ENABLED: "true"并将其传递给docker-registry来启用映像删除
  2. 在脚本下运行(它将删除所有图像和标签,但保留最近10个版本) registry.py -l user:pass -r https://example.com:5000 --delete --num 10
  3. 运行垃圾收集(你可以将它放入你的日常cron任务) docker-compose -f [path_to_your_docker_compose_file]运行注册表bin / registry garbage-collect /etc/docker/registry/config.yml

registry.py可以从下面的链接下载,它还允许列出图像,标签和图层,以及删除特定的图像和/或标签。

https://github.com/andrey-pohilko/registry-cli

在垃圾收集之前,我的注册表文件夹是7 Gb,在我运行上述步骤后,它缩小到1 Gb。


19
投票

这是可行的,虽然很难看。您需要运行(我认为)注册表2.3或更高版本,并已启用删除(REGISTRY_STORAGE_DELETE_ENABLED=True env var或等效)。下面的示例命令假设/srv/docker-registry中有一个本地文件存储,但是如果某些东西不能用于其他存储后端,我会感到惊讶。

对于您希望整理的每个存储库,您需要枚举不再需要的摘要引用。最简单的方法是使用per-tag,在这种情况下使用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方法来枚举与给定标签相关的所有摘要,因为没有API方法可以在后端存储中使用,但这就是cookie崩溃的方式。


14
投票

关于你的问题:

我需要一种方法来删除私有注册表中不再由命名标记标识的所有图像

distribution/registry:master中新版本的docker注册表具有这个不错的功能!但是,您将无法从API触发它。

无论如何,您将能够清理注册表中所有未标记的清单,这意味着每个覆盖的标记都不会在注册表中留下旧的清单和blob。 Registry Garbage Collectior将清理每个“未使用”的图层。

你只需要运行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。它以新的API设计取代了docker/docker-registry项目,专注于安全性和性能......

我今天确实使用了此功能并恢复了89%的注册表空间(5.7 GB与55 GB)。然后我换回稳定的registry


6
投票

有一些讨论正在进行设计 - 目前,没有层清理工具/端点。

我鼓励你去:

和/或在#docker-distribution上与Freenode IRC联系以获取更多信息。


4
投票

我拼凑了这个线程的各个部分并在bash中创建了一个易于使用的清理脚本你可以在这个gist中查看它cleanup.sh


3
投票

我在注册表v2 api中寻找相同的功能,但只找到soft deleting,这不是我想要的。在研究时,我发现了Github项目delete-docker-registry-image,它通过bash脚本从已安装的卷中删除实际文件。未测试它可能有用......


2
投票

我在来自qazxsw poi的名为qazxsw poi的docker容器中托管注册表

我只是用docker-registry_registry_1运行image: registry:2

garbage-collect
© www.soinside.com 2019 - 2024. All rights reserved.