Leo*_*Leo 139 docker docker-registry
我运行一个私有的docker注册表,我想latest
从存储库中删除所有图像.我不想删除整个存储库,只删除其中的一些图像.该API文档不提一个办法做到这一点,但肯定这是可能的?
Kon*_*ine 105
目前,您无法使用Registry API执行该任务.它只允许您删除存储库或特定标记.
通常,删除存储库意味着删除与此存储库关联的所有标记.
删除标记意味着删除图像和标记之间的关联.
以上都不会删除单个图像.它们留在磁盘上.
对于此变通办法,您需要在本地存储docker镜像.
解决方案的解决方法是删除除最新标记之外的所有标记,从而可能删除对相关图像的引用.然后,您可以运行此脚本以删除任何标记未引用的所有图像或任何使用过的图像的祖先.
考虑这样的图像图形,其中大写字母(A
,, B
......)表示短图像ID,并且<-
表示图像基于另一图像:
A <- B <- C <- D
Run Code Online (Sandbox Code Playgroud)
现在我们为图片添加标签:
A <- B <- C <- D
| |
| <version2>
<version1>
Run Code Online (Sandbox Code Playgroud)
这里,标签<version1>
引用图像C
,标签<version2>
引用图像D
.
在你的问题中,你说你想删除
所有的图像,但
latest
.现在,这个术语不太正确.你混合了图像和标签.查看图表我认为你会同意标签<version2>
代表最新版本.事实上,根据这个问题,你可以有一个代表最新版本的标签:
A <- B <- C <- D
| |
| <version2>
| <latest>
<version1>
Run Code Online (Sandbox Code Playgroud)
由于<latest>
标签引用图像D
我问你:你真的想删除除图像以外的所有内容D
吗?可能不是!
如果您<version1>
使用Docker REST API 删除标记,您将得到以下结果:
A <- B <- C <- D
|
<version2>
<latest>
Run Code Online (Sandbox Code Playgroud)
请记住: Docker永远不会删除图像!即使它这样做,在这种情况下它也不能删除图像,因为图像C
是D
被标记的图像的祖先的一部分.
即使您使用此脚本,也不会删除任何图像.
在您可以控制何时可以拉动或推送到您的注册表的情况下(例如,通过禁用REST接口).如果没有其他图像基于图像并且没有标记引用图像,则可以从图像图形中删除图像.
请注意,在下面的图,该图像D
是没有根据C
,但对B
.因此,D
不依赖于C
.如果您删除<version1>
此图表中的标记,则C
任何图像都不会使用该图像,此脚本可以将其删除.
A <- B <--------- D
\ |
\ <version2>
\ <latest>
\ <- C
|
<version1>
Run Code Online (Sandbox Code Playgroud)
清理后,您的图像图形如下所示:
A <- B <- D
|
<version2>
<latest>
Run Code Online (Sandbox Code Playgroud)
这是你想要的吗?
byr*_*edo 57
当前v2
注册表现在支持删除viaDELETE /v2/<name>/manifests/<reference>
请参阅:https://github.com/docker/distribution/blob/master/docs/spec/api.md#deleting-an-image
工作用途:https: //github.com/byrnedo/docker-reg-tool
编辑:<reference>
可以从请求中检索上面的清单
GET /v2/<name>/manifests/<tag>
并检查Docker-Content-Digest
响应中的标头.
Yav*_*ert 57
我的注册表遇到了同样的问题,然后我从博客页面尝试了下面列出的解决方案.有用.
您可以通过调用此网址列出您的目录:
http://YourPrivateRegistyIP:5000/v2/_catalog
Run Code Online (Sandbox Code Playgroud)
回复将采用以下格式:
{
"repositories": [
<name>,
...
]
}
Run Code Online (Sandbox Code Playgroud)
您可以通过调用此网址列出目录的标记:
http://YourPrivateRegistyIP:5000/v2/<name>/tags/list
Run Code Online (Sandbox Code Playgroud)
回复将采用以下格式:
{
"name": <name>,
"tags": [
<tag>,
...
]
Run Code Online (Sandbox Code Playgroud)
}
您可以在docker注册表容器中运行此命令:
curl -v --silent -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X GET http://localhost:5000/v2/<name>/manifests/<tag> 2>&1 | grep Docker-Content-Digest | awk '{print ($3)}'
Run Code Online (Sandbox Code Playgroud)
回复将采用以下格式:
sha256:6de813fb93debd551ea6781e90b02f1f93efab9d882a6cd06bbd96a07188b073
Run Code Online (Sandbox Code Playgroud)
使用清单值运行下面给出的命令:
curl -v --silent -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X DELETE http://127.0.0.1:5000/v2/<name>/manifests/sha256:6de813fb93debd551ea6781e90b02f1f93efab9d882a6cd06bbd96a07188b073
Run Code Online (Sandbox Code Playgroud)
在docker registy容器中运行此命令:
bin/registry garbage-collect /etc/docker/registry/config.yml
Run Code Online (Sandbox Code Playgroud)
这是我的config.yml
root@c695814325f4:/etc# cat /etc/docker/registry/config.yml
version: 0.1
log:
fields:
service: registry
storage:
cache:
blobdescriptor: inmemory
filesystem:
rootdirectory: /var/lib/registry
delete:
enabled: true
http:
addr: :5000
headers:
X-Content-Type-Options: [nosniff]
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
Run Code Online (Sandbox Code Playgroud)
Lar*_*Cai 15
问题1
您提到它是您的私有docker注册表,因此您可能需要检查Registry API而不是Hub注册表API文档,这是您提供的链接.
问题2
docker注册表API是一个客户端/服务器协议,它取决于服务器是否删除后端中的图像.(我猜)
DELETE /v1/repositories/(namespace)/(repository)/tags/(tag*)
Run Code Online (Sandbox Code Playgroud)
详细说明
下面我将根据您的描述演示它的工作原理,作为我对您的问题的理解.
你运行你运行私人docker注册表,我使用默认的一个和侦听5000
端口
docker run -d -p 5000:5000 registry
Run Code Online (Sandbox Code Playgroud)
然后我标记本地图像并推入其中.
$ docker tag ubuntu localhost:5000/ubuntu
$ docker push localhost:5000/ubuntu
The push refers to a repository [localhost:5000/ubuntu] (len: 1)
Sending image list
Pushing repository localhost:5000/ubuntu (1 tags)
511136ea3c5a: Image successfully pushed
d7ac5e4f1812: Image successfully pushed
2f4b4d6a4a06: Image successfully pushed
83ff768040a0: Image successfully pushed
6c37f792ddac: Image successfully pushed
e54ca5efa2e9: Image successfully pushed
Pushing tag for rev [e54ca5efa2e9] on {http://localhost:5000/v1/repositories/ubuntu/tags/latest}
Run Code Online (Sandbox Code Playgroud)
之后,您可以使用Registry API检查它是否存在于您的私有docker注册表中
$ curl -X GET localhost:5000/v1/repositories/ubuntu/tags
{"latest": "e54ca5efa2e962582a223ca9810f7f1b62ea9b5c3975d14a5da79d3bf6020f37"}
Run Code Online (Sandbox Code Playgroud)
现在我可以使用该API删除标签!!
$ curl -X DELETE localhost:5000/v1/repositories/ubuntu/tags/latest
true
Run Code Online (Sandbox Code Playgroud)
再次检查,您的私人注册表服务器中不存在该标记
$ curl -X GET localhost:5000/v1/repositories/ubuntu/tags/latest
{"error": "Tag not found"}
Run Code Online (Sandbox Code Playgroud)
hir*_*rro 14
这真的很丑,但它有效,文本在注册表上测试:2.5.1.即使在更新配置以启用删除后,我也无法使删除工作顺利进行.该ID真的很难检索,不得不登录才能得到它,也许是一些误解.无论如何,以下工作:
登录容器
docker exec -it registry sh
Run Code Online (Sandbox Code Playgroud)定义与容器和容器版本匹配的变量:
export NAME="google/cadvisor"
export VERSION="v0.24.1"
Run Code Online (Sandbox Code Playgroud)移动到注册表目录:
cd /var/lib/registry/docker/registry/v2
Run Code Online (Sandbox Code Playgroud)删除与哈希相关的文件:
find . | grep `ls ./repositories/$NAME/_manifests/tags/$VERSION/index/sha256`| xargs rm -rf $1
Run Code Online (Sandbox Code Playgroud)删除清单:
rm -rf ./repositories/$NAME/_manifests/tags/$VERSION
Run Code Online (Sandbox Code Playgroud)登出
exit
Run Code Online (Sandbox Code Playgroud)运行GC:
docker exec -it registry bin/registry garbage-collect /etc/docker/registry/config.yml
Run Code Online (Sandbox Code Playgroud)如果完成所有操作,则会显示有关已删除blob的一些信息.
有一些客户端(在Python,Ruby等)就是这样做的.根据我的口味,在我的注册表服务器上安装运行时(例如Python)是不可持续的,只是为了保持我的注册表!
那么deckschrubber
我的解决方案是:
go get github.com/fraunhoferfokus/deckschrubber
$GOPATH/bin/deckschrubber
Run Code Online (Sandbox Code Playgroud)
超过给定年龄的图像会自动删除.年龄可以使用指定的-year
,-month
,-day
,或它们的组合:
$GOPATH/bin/deckschrubber -month 2 -day 13 -registry http://registry:5000
Run Code Online (Sandbox Code Playgroud)
删除除此之外的所有标签的要求latest
变得很复杂,因为同一个图像清单可以由多个标签指向,因此当您删除一个标签的清单时,您可能会有效地删除多个标签。
有一些选项可以使其可行。一种是跟踪最新标签的摘要,并仅删除其他摘要的清单,或者您可以使用一些不同的 API 调用来删除标签本身。
无论您如何实现这一点,首先需要将您的注册表配置为允许删除 API。对于最小的registry:2
镜像,这涉及到使用环境变量REGISTRY_STORAGE_DELETE_ENABLED=true
(或等效的 yaml 配置)来启动它。
然后,对于一个简单的脚本来循环标记并删除,有:
#!/bin/sh
repo="localhost:5000/repo/to/prune"
for tag in $(regctl tag ls $repo); do
if [ "$tag" != "latest" ]; then
echo "Deleting: $(regctl image digest --list "${repo}:${tag}") [$tag]"
regctl tag rm "${repo}:${tag}"
fi
done
Run Code Online (Sandbox Code Playgroud)
这里使用的命令regctl
来自regclient,regctl tag rm
逻辑首先尝试执行最近添加到distribution-spec 的标签删除 API 。由于大多数注册中心尚未实现该规范,因此它会退回到清单删除 API,但它首先创建一个虚拟清单来覆盖标签,然后删除该新摘要。这样做时,如果旧清单已被其他标签使用,则不会删除这些其他标签。
删除清单(指向摘要的清单除外)的脚本的替代版本latest
如下所示:
#!/bin/sh
repo="localhost:5000/repo/to/prune"
save="$(regctl image digest --list "${repo}:latest")"
for tag in $(regctl tag ls $repo); do
digest="$(regctl image digest --list "${repo}:${tag}")"
if [ "$digest" != "$save" ]; then
echo "Deleting: $digest [$tag]"
regctl manifest rm "${repo}@${digest}"
fi
done
Run Code Online (Sandbox Code Playgroud)
如果您发现自己需要创建删除策略来自动删除大量图像,我建议您regclient/regbot
从同一个存储库中查看,它允许您定义该策略并使其运行以不断修剪您的注册表。
删除映像后,在大多数使用情况下,您需要对注册表进行垃圾收集。例如,registry:2
图像如下所示:
docker exec registry /bin/registry garbage-collect \
/etc/docker/registry/config.yml --delete-untagged
Run Code Online (Sandbox Code Playgroud)
注意:垃圾收集实用程序存在一个未解决的问题,该实用程序将删除多平台映像的未标记子清单。如果您使用多平台映像,则需要确保每个特定于平台的映像都已标记,或者避免使用上述 GC 命令,直到部署版本中的问题得到解决。
归档时间: |
|
查看次数: |
206346 次 |
最近记录: |