使用api从nexus注册表中删除docker映像



有一个为docker注册表运行的nexus设置。我正在努力使用API从nexus设置中删除旧的/不必要的图像。到目前为止,我知道以下可用的API。有2个要求:

  1. 删除超过30天的图像
  2. 每个图像至少保留5个标签

删除api只能使用图像的摘要进行删除;I’我不知道如何为图像的标签找到准确的标签。搜索api似乎不适用于docker图像。有人能帮忙吗?

##搜索apihttps://help.sonatype.com/repomanager3/integrations/rest-and-integration-api/search-api?_ga=2.253346826.2007475959.1640178248-1042170715.1640178248#SearchAPI-SearchComponents

##在docker寄存器下查找所有目录映像curl -u admin:adminPass -X "GET" nexus.example.com/v2/_catalog | jq

##获取图像的所有标签curl -u admin:adminPass -X "GET" nexus.example.com/v2/abc-web-service-prod/tags/list

##获取清单curl -u admin:adminPass -X "GET" "nexus.example.com/v2/abc-web-service-stage-2/manifests/5.2.6_1" | jq

##按摘要删除curl -i -u admin:adminPass -X "DELETE" "nexus.example.com/v2/abc-web-service/manifests/sha256:8829ce7278c1151f61438dcfea20e3694fee2241a75737e3a8de31a27f0014a5"

;获取清单";实例首先,如果您包含http头,您可能会得到摘要字段,或者您可以跳过jq并将结果通过管道传输到sha256sum中以获得摘要。但您还需要添加一个";接受";manifest的各种媒体类型的头,否则注册表将把它转换为旧的schema v1语法,该语法将不具有相同的摘要。下面是一个执行两种v2 docker介质类型的示例:

api="application/vnd.docker.distribution.manifest.v2+json"
apil="application/vnd.docker.distribution.manifest.list.v2+json"
curl -H "Accept: ${api}" -H "Accept: ${apil}" 
-u admin:adminPass 
-I -s "nexus.example.com/v2/abc-web-service-stage-2/manifests/5.2.6_1" 

您的保单将遇到的下一个问题是30天的要求。您可以通过提取图像配置blob(在清单中列出(来获取许多图像的创建时间,但该日期将是创建图像的时间,而不是推送或最后一次提取图像的时间。有人建议将API添加到OCI中以处理更多的元数据,但我们离这还有一段路要走,而且还需要让注册表提供商来实现它们。所以你最终会删除可能被使用的东西。如果创建了几个新标签来处理CI中的错误,并且您使当前部署在生产中的映像老化,那么即使是5标签规则也可能存在问题。

话虽如此,我所使用的一些名为regclient的工具可能会有所帮助。regctl命令提供了一种在shell中编写脚本的方法,例如:

#!/bin/sh
registry="nexus.example.com"
cutoff="$(date -d -30days '+%s')"
for repo in $(regctl repo ls "$registry"); do
# The "head -n -5" ignores the last 5 tags, but you may want to sort that list first.
for tag in $(regctl tag ls "$registry/$repo" | head -n -5); do
# This is the most likely command to fail since the created timestamp is optional, may be set to 0,
# and the string format might vary.
# The cut is to remove the "+0000" that breaks the "date" command.
created="$(regctl image config "$registry/$repo:$tag" --format '{{.Created}}' | cut -f1,2,4 -d' ')"
createdSec="$(date -d "$created" '+%s')"
# both timestamps are converted to seconds since epoc, allowing numeric comparison
if [ "$createdSec" -lt "$cutoff" ]; then
# next line is prefixed with echo for debugging, delete the echo to run the tag delete command
echo regctl tag rm "$registry/$repo:$tag"
fi
done
done

注意,我使用的是";regctl标签rm";上面,这与您在API中看到的图像清单删除不同。这将尝试首先执行OCI标记删除API,这可能不受注册表的支持。它又回到了推送一个伪清单并删除它。删除标记所指向的当前清单的另一种选择是,您可以删除比预期更多的标记(您可以有5个标记都指向同一清单(。

如果你想进一步自动化这一点,同一回购中的regbot可以让你构建一个策略,并按计划运行它,以根据你的规则不断清理旧图像。

除了regclient,还有crane和skopeo也可能在这个领域有所帮助,但它们的功能各不相同。

我找到了一个很好的解决方案。https://github.com/andrey-pohilko/registry-cli

1.使用下面的Dockerfile创建一个docker镜像[name:registry-cli:1.0.1]


ADD requirements-build.txt /
RUN pip install -r /requirements-build.txt
ADD registry.py /
ENTRYPOINT ["/registry.py"]

2.使用以下命令列出所有图像:您的私有nexus注册表中的标签docker run --rm registry-cli:1.0.1 -l admin:adminPass -r http://nexus.example.com

3.获取特定图像的所有标签docker run --rm registry-cli:1.0.1 -l admin:adminPass -r http://nexus.example.com-i <name-of-the-image1> <name-of-the-image2>

4.删除特定图像的所有旧标签,但保留最新的10个标签docker run --rm registry-cli:1.0.1 -l admin:adminPass -r http://nexus.example.com -i <name-of-the-image1> --delete

5.删除存储库中所有图像的所有旧标签,但保留每个图像的10个最新标签docker run --rm registry-cli:1.0.1 -l admin:adminPass -r http://nexus.example.com --delete

6.如果希望保留20张图像而不是10张,请使用--numdocker run --rm registry-cli:1.0.1 -l admin:adminPass -r http://nexus.example.com --delete --num 20

7.删除图像的旧标签后,运行task"删除未使用的清单和docker图像">

8.步骤后:7,运行压缩任务以回收存储

最新更新