如何提取 docker 图片的所有替代标签?
How to pull all alternative tags of a docker image?
我管理一个带有构建管道的 gitlab。所有组件都封装在 docker 来自官方 gitlab 维护者的图像中。
每当我更新时——通常每周一次——我需要检查 gitlab/gitlab-runner-helper 是否仍然适用于当前最新版本的 gitlab。这只能通过执行管道来检查。如果它不起作用,日志会准确告诉我它需要什么图像,然后我继续拉取它。
有问题的图像也带有 latest
标记,由于对非易失性标记的硬依赖性,我无法使用该标记。
$docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
gitlab/gitlab-runner-helper x86_64-8af42251 1ee5a99eba5f 20 hours ago 43.7MB
gitlab/gitlab-runner-helper x86_64-latest 1ee5a99eba5f 20 hours ago 43.7MB
为了使我的更新过程自动化,我想知道如何提取带有所有替代标签的最新图像?
docker pull 的手册页说,有一个 --all-tags
选项,可以从存储库加载任何标记的图像,但这不能与标记结合使用。
据我所知,没有真正有效或内置的方法来做到这一点。相反,您需要通过 REST 查询您的注册表,首先是该存储库的标签列表:
GET http://<registry>/v2/<repository>/tags/list
然后,对于每个标签,一个清单:
GET http://<registry>/v2/<repository>/manifests/<tag>
每个清单都会有一个与其关联的散列,您应该能够从响应的 HTTP headers 中获取该散列。您甚至可以为它发出 HEAD 请求并避免清单有效载荷的其余部分,但我最近没有尝试过。
现在您有一个标签列表和清单哈希值,您只需要找到所有具有与 latest
标签相匹配的哈希值的标签。
这有点乏味,但使用 curl
和 jq
编写脚本实际上并没有那么糟糕,特别是如果您不需要担心安全问题。
脚本:
#!/bin/sh
TOKEN=`curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:gitlab/gitlab-runner-helper:pull" | jq '.token' | sed 's/"//g'`
TAGS=`curl -s https://registry.hub.docker.com/v2/gitlab/gitlab-runner-helper/tags/list -H "Authorization: Bearer $TOKEN" | jq ".tags[]" | sed 's/"//g' | grep x86_64`
for tag in $TAGS;
do
# is $tag an old entry?
if grep -Fxq $tag tags.list
then
# already processed
continue
else
echo "new tag found: $tag"
newSHA=`curl -s https://registry.hub.docker.com/v2/gitlab/gitlab-runner-helper/manifests/$tag -H "Authorization: Bearer $TOKEN" | jq ".fsLayers[] .blobSum" | sed 's/"//g'`
latestSHA=`curl -s https://registry.hub.docker.com/v2/gitlab/gitlab-runner-helper/manifests/x86_64-latest -H "Authorization: Bearer $TOKEN" | jq ".fsLayers[] .blobSum" | sed 's/"//g'`
if [ "$newSHA" = "$latestSHA" ]
then
echo "$tag is new latest version"
docker pull gitlab/gitlab-runner-helper:$tag
echo $tag >> tags.list
fi
fi
done
上面的脚本使用了一个名为 tags.list
的文件,该文件位于其旁边。此文件包含旧标签,以防止发出 500 多个 HTTP 请求。如果来自 TAGS
的标签还没有出现在文件中,这并不意味着它是最新的。有时会出现标签,最终将成为最新版本。这些标签被探测,但不会被插入到文件中。如果将这些版本作为最新版本跳过,这可能会成为未来的问题。
注意:上面的脚本只关注特定的标签子集(x86_64
)。
我管理一个带有构建管道的 gitlab。所有组件都封装在 docker 来自官方 gitlab 维护者的图像中。
每当我更新时——通常每周一次——我需要检查 gitlab/gitlab-runner-helper 是否仍然适用于当前最新版本的 gitlab。这只能通过执行管道来检查。如果它不起作用,日志会准确告诉我它需要什么图像,然后我继续拉取它。
有问题的图像也带有 latest
标记,由于对非易失性标记的硬依赖性,我无法使用该标记。
$docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
gitlab/gitlab-runner-helper x86_64-8af42251 1ee5a99eba5f 20 hours ago 43.7MB
gitlab/gitlab-runner-helper x86_64-latest 1ee5a99eba5f 20 hours ago 43.7MB
为了使我的更新过程自动化,我想知道如何提取带有所有替代标签的最新图像?
docker pull 的手册页说,有一个 --all-tags
选项,可以从存储库加载任何标记的图像,但这不能与标记结合使用。
据我所知,没有真正有效或内置的方法来做到这一点。相反,您需要通过 REST 查询您的注册表,首先是该存储库的标签列表:
GET http://<registry>/v2/<repository>/tags/list
然后,对于每个标签,一个清单:
GET http://<registry>/v2/<repository>/manifests/<tag>
每个清单都会有一个与其关联的散列,您应该能够从响应的 HTTP headers 中获取该散列。您甚至可以为它发出 HEAD 请求并避免清单有效载荷的其余部分,但我最近没有尝试过。
现在您有一个标签列表和清单哈希值,您只需要找到所有具有与 latest
标签相匹配的哈希值的标签。
这有点乏味,但使用 curl
和 jq
编写脚本实际上并没有那么糟糕,特别是如果您不需要担心安全问题。
脚本:
#!/bin/sh
TOKEN=`curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:gitlab/gitlab-runner-helper:pull" | jq '.token' | sed 's/"//g'`
TAGS=`curl -s https://registry.hub.docker.com/v2/gitlab/gitlab-runner-helper/tags/list -H "Authorization: Bearer $TOKEN" | jq ".tags[]" | sed 's/"//g' | grep x86_64`
for tag in $TAGS;
do
# is $tag an old entry?
if grep -Fxq $tag tags.list
then
# already processed
continue
else
echo "new tag found: $tag"
newSHA=`curl -s https://registry.hub.docker.com/v2/gitlab/gitlab-runner-helper/manifests/$tag -H "Authorization: Bearer $TOKEN" | jq ".fsLayers[] .blobSum" | sed 's/"//g'`
latestSHA=`curl -s https://registry.hub.docker.com/v2/gitlab/gitlab-runner-helper/manifests/x86_64-latest -H "Authorization: Bearer $TOKEN" | jq ".fsLayers[] .blobSum" | sed 's/"//g'`
if [ "$newSHA" = "$latestSHA" ]
then
echo "$tag is new latest version"
docker pull gitlab/gitlab-runner-helper:$tag
echo $tag >> tags.list
fi
fi
done
上面的脚本使用了一个名为 tags.list
的文件,该文件位于其旁边。此文件包含旧标签,以防止发出 500 多个 HTTP 请求。如果来自 TAGS
的标签还没有出现在文件中,这并不意味着它是最新的。有时会出现标签,最终将成为最新版本。这些标签被探测,但不会被插入到文件中。如果将这些版本作为最新版本跳过,这可能会成为未来的问题。
注意:上面的脚本只关注特定的标签子集(x86_64
)。