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

时间:2015-04-22 15:28:06

标签: docker docker-registry

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

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

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

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

8 个答案:

答案 0 :(得分:44)

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

  1. 通过设置环境变量REGISTRY_STORAGE_DELETE_ENABLED: "true"并将其传递给docker-registry

  2. 来启用图像删除
  3. 运行以下脚本(它将删除所有图像和标签,但保留最后10个版本)

      

    registry.py -l user:pass -r https://example.com:5000 --delete --num 10

  4. 运行垃圾收集(您可以将其放入日常的cron任务中)

      

    docker-compose -f [path_to_your_docker_compose_file]运行注册表bin / registry garbage-collect /etc/docker/registry/config.yml

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

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

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

答案 1 :(得分:18)

虽然很难看,但这是可行的。您需要运行(我认为)注册表2.3或更高版本,并已启用删除( function cardsTimeout(id, time, card) { if (id in timeouts) { clearTimeout(timeouts[id]); } timeouts[id] = setTimeout(function () { var c = card.classList; var newTime = randomNum(timeMin, timeMax) * 2000; c.contains("flipped") === true ? c.remove("flipped") :c.add("flipped"); cardsTimeout(id, newTime, card); }, time); } env var或等效项。下面的示例命令假设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

最后,你需要进行GC运行,因为注册表实现了&#34;软删除&#34;,它实际上没有删除任何东西,只是让它不可用:

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

是的,这一切都很混乱,在后端存储中徘徊,因为没有API方法来枚举与给定标签相关的所有摘要,但这就是cookie崩溃的方式。

答案 2 :(得分:12)

关于你的问题:

  

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

标识的所有图像

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。自2018-02-23开始,它已与distribution/registry合并并标记为master。它取代了docker/docker-registry 项目采用新的API设计,侧重于安全性和性能......

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

答案 3 :(得分:6)

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

我鼓励你去:

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

答案 4 :(得分:4)

我拼凑了这个线程的各个部分,并在bash中创建了一个易于使用的清理脚本 您可以在这个要点cleanup.sh

中查看

答案 5 :(得分:3)

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

答案 6 :(得分:2)

我在docker-registry_registry_1的名称为image: registry:2的Docker容器中托管重载

我刚刚通过garbage-collect运行-m

docker exec docker-registry_registry_1 bin/registry garbage-collect /etc/docker/registry/config.yml -m

答案 7 :(得分:1)

要删除未处理的图像,请按以下顺序手动执行三个步骤:

  1. docker rmi -f **imageid**

  2. rm -Rf /home/**homedirectory**/docker-registry/data/docker/registry/v2/repositories/**yoursystemname**/**yourimagename**/_manifests/tags/**image version**/

  3. docker exec $(docker ps -q) bin/registry garbage-collect /etc/docker/registry/config.yml -m

*请注意:

**您必须在测试环境中执行这些命令(上面),因为如果您犯了任何错误或不了解任何步骤,则不会损坏生产环境。

**您可以使用crontab作为根目录调度这些命令(上方)。在步骤3)中,您必须执行删除“ -it”的操作,结果是:docker exec $(docker ps -q)bin / registry垃圾收集/etc/docker/registry/config.yml -m`。

它对我有效超过6个月。