如何提取docker映像的所有其他标签?

时间:2018-10-23 06:22:06

标签: docker gitlab gitlab-ci-runner

我通过构建管道管理gitlab。所有组件都封装在官方gitlab维护者的docker映像中。

每当我更新时(通常每周一次),我需要检查gitlab / gitlab-runner-helper是否仍然适用于最新版本的gitlab。这只能通过执行管道来检查。如果它不起作用,则日志会准确地告诉我它需要什么图像,然后我将其拉出。

由于对非易失性标签的依赖性强,该图像还被标记有最新标签,我无法使用。

$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选项,用于从存储库中加载任何已标记的图像,但这不能与标签结合使用。

1 个答案:

答案 0 :(得分:1)

据我所知,并没有真正有效或内置的方式来做到这一点。相反,您需要通过REST查询注册表,首先是该存储库的标记列表:

GET http://<registry>/v2/<repository>/tags/list

然后,为每个标签添加一个清单:

GET http://<registry>/v2/<repository>/manifests/<tag>

每个清单都会有一个与之关联的哈希,您应该能够从响应的HTTP标头中获取该哈希。您甚至可以为此请求HEAD并避免其他清单有效负载,但是我最近没有尝试过。

现在您有了标签和清单哈希的列表,您只需要查找具有与latest标签匹配的哈希的所有标签即可。

这有点乏味,但是使用curljq编写脚本实际上并不那么糟糕,尤其是在您不必担心安全性的情况下。


脚本:

#!/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)。