79

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

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

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

如何保持我的私人注册表清洁?有什么提示吗?

4

8 回答 8

59

删除图像(您可以保留 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 垃圾收集 /etc/docker/registry/config.yml

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

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

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

于 2016-10-15T05:32:01.297 回答
41

关于你的问题:

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

新版本的 docker 注册表distribution/registry:master具有这个不错的功能!但是,您将无法从 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 PRdistribution/registry截至 2018 年 2 月 23 日,它已与, 标记合并并可用master。它以新的 API 设计取代了该docker/docker-registry 项目,专注于安全性和性能……

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

于 2018-02-23T14:34:26.193 回答
21

这是可行的,虽然丑陋。您需要运行(我认为)注册表 2.3 或更高版本,并启用删除(REGISTRY_STORAGE_DELETE_ENABLED=Trueenv var 或等效项)。下面的示例命令假设一个本地文件存储在 中/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 方法可以枚举与给定标签关联的所有摘要,但这就是 cookie 崩溃的方式。

于 2016-06-09T03:28:04.963 回答
14

我在 docker 容器中托管 regestry,名称docker-registry_registry_1来自image: registry:2

garbage-collect我只是跑-m

docker exec docker-registry_registry_1 bin/registry garbage-collect /etc/docker/registry/config.yml -m
于 2019-04-01T13:19:13.450 回答
7

对此进行了一些讨论 - 现在,没有层清理工具/端点。

我鼓励你去:

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

于 2015-04-22T19:11:45.070 回答
4

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

于 2017-08-31T23:42:08.637 回答
3

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

于 2016-04-03T19:19:26.503 回答
1

要删除 unsed 图像,请在这些序列上手动执行三个步骤:

  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

*注意:

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

** 您可以以 root 身份使用 crontab 来安排这些命令(如上)。在步骤 3)中,您必须执行删除“-it”,结果是:docker exec $(docker ps -q) bin/registry Garbage-collect /etc/docker/registry/config.yml -m`。

它为我工作了6个多月。

于 2020-05-31T14:50:24.093 回答