按照官方文档(https://docs.docker.com/registry/spec/api/#deleting-an-image) 我已成功删除图像。正如预期的那样,删除后,无法再拉取图像,也无法通过 API 调用其清单。
我感觉我已经完成了最困难的部分,/v2/_catalog
然而问题是删除完成后,repo 仍然列在下面。我正在尝试彻底清除注册表。
这是我的注册表撰写文件:
registry:
image: registry:2.5.2
container_name: registry-test
ports:
- 5007:5000
environment:
REGISTRY_STORAGE: s3
REGISTRY_HTTP_TLS_CERTIFICATE: /etc/cert.crt
REGISTRY_HTTP_TLS_KEY: /etc/cert.key
REGISTRY_STORAGE_S3_ACCESSKEY: ******
REGISTRY_STORAGE_S3_SECRETKEY: ******
REGISTRY_STORAGE_S3_REGION: us-west-1
REGISTRY_STORAGE_S3_BUCKET: ******
REGISTRY_STORAGE_S3_SECURE: "true"
REGISTRY_STORAGE_DELETE_ENABLED: "true"
volumes:
- /dockerdata/volumes/registry-test/etc/cert.crt:/etc/cert.crt
- /dockerdata/volumes/registry-test/etc/cert.key:/etc/cert.key
restart: unless-stopped
以下是我删除图像的高级方法:
收集图像摘要:
HEAD https://myprivateregistry:5001/v2/myimage/manifests/mytag
添加"Accept: application/vnd.docker.distribution.manifest.v2+json"
到调用的标题中调用返回标头键
Docker-Content-Digest
的值,例如sha256:b57z31xyz0f616e65f106b424f4ef29185fbd80833255d79dabc73b8eb873bd
使用步骤 2 中的值,运行删除调用:
DELETE https://myprivateregistry:5001/v2/myimage/manifests/sha256:b57z31xyz0f616e65f106b424f4ef29185fbd80833255d79dabc73b8eb873bd
注册表 API 返回
202 Accepted
手动运行垃圾收集:
registry garbage-collect /etc/docker/registry/config.yml
垃圾收集器从磁盘中删除相关的 blob(这里省略了日志,但它成功删除了 blob)
此时,我可以确认 blob 已从磁盘中完全删除,并且我无法再调用图像详细信息(如上面的步骤 1 所示)所以我以为我已经完成了。
但是,运行时:/v2/_catalog
我的关联 repo 仍然列出(即使其中没有图像)!显然它不能拉动或使用,但是既然现在没有与之关联的图像,我该如何从该列表中完全删除该 repo?
我不知道该怎么做适当地在 API 文档页面上删除它。也许我遗漏了什么地方?
编辑 -
我想添加一些有关上述删除操作发生之前和之后注册表情况的更多信息。
执行上述删除操作之前:
docker/registry/v2/repositories/myimage/_manifests/revisions/...
docker/registry/v2/repositories/myimage/_manifests/tags/...
docker/registry/v2/repositories/myimage/_layers/sha256/... (5 layers listed)
docker/registry/v2/blobs/sha256/...
执行上述删除操作后:
docker/registry/v2/repositories/myimage/_layers/sha256/... (5 layers listed)
所以唯一剩下的就是_layers
列出相同 5x 层的目录。这似乎就是为什么它仍然在_catalog
当我删除myimage
文件夹(从docker/registry/v2/repositories/myimage
)时,存储库不再显示在_catalog
这似乎是将其从_catalog
列表中清除的一种方法。但是 - 如果一张图片有 2 个标签,但只删除了 1 个 - 那么_layers
在这种情况下有什么理由删除任何内容吗?如果图片有多个版本,如何处理?显然,我不能仅仅将破坏_layers
目录作为最后的方法,因为在现实世界中,图像会有许多标记版本。因此,这需要以明智的方式来完成。
我只是发现很难找到有关 Docker 注册表的维护/保养的任何文档,也找不到
_layers
子目录的架构,以及为什么垃圾收集器不像清理清单和 blob 那样清理该目录。
答案1
经过大量研究,目前没有仅通过 API 完全删除目录条目的方法。
v2 注册表不允许仅从图像中删除某些标签
这意味着整个图像被删除。标签的删除正在 Registry 未来版本的开放 PR 中(https://github.com/docker/distribution/pull/2169)
对于这个问题来说这意味着什么正确的方法是从 repo 列表中删除图像,正如您所假设的那样。将其从磁盘中删除。(例如,您通过 API 删除的图像名称在rm -r v2/repositories/myimage
哪里。)myimage
然后它将从 repo 列表中删除_catalog
,您就完成了删除过程。无需像另一个答案中提到的那样重新启动任何东西。
当添加了从注册表中删除特定标签的功能后,此过程将发生变化。目前,要么全有,要么全无。
参考:
https://forums.docker.com/t/delete-repository-from-v2-private-registry/16767/5