【问题标题】:Listing the tags of a Docker image on a Docker hub through the HTTP API通过 HTTP API 在 Docker 集线器上列出 Docker 映像的标签
【发布时间】:2016-05-23 12:18:21
【问题描述】:

我想通过它的HTTP接口列出一个Docker镜像官方Docker hub的标签,但是我有点困惑。似乎有两个版本:

我设法通过向此端点发送 GET 请求来获取它们:https://index.docker.io/v1/repositories/{my-namespace}/{my-repository}/tags 以及基本身份验证凭据。

我不确定其中是否有正确的,但我应该使用哪个?

【问题讨论】:

    标签: docker docker-registry dockerhub


    【解决方案1】:

    Docker V2 API 更新

    Docker V2 API 需要带有适当声明的 OAuth 不记名令牌。在我看来,官方文档在这个话题上相当模糊。为了让其他人不会像我一样痛苦,我提供了下面的docker-tags 函数。

    docker-tags 的最新版本可以在我的GitHubGist : "List Docker Image Tags using bash" 中找到。

    docker-tags 函数依赖于jq。如果您正在使用 JSON,那么您可能已经拥有它。

    #!/usr/bin/env bash
    docker-tags() {
        arr=("$@")
    
        for item in "${arr[@]}";
        do
            tokenUri="https://auth.docker.io/token"
            data=("service=registry.docker.io" "scope=repository:$item:pull")
            token="$(curl --silent --get --data-urlencode ${data[0]} --data-urlencode ${data[1]} $tokenUri | jq --raw-output '.token')"
            listUri="https://registry-1.docker.io/v2/$item/tags/list"
            authz="Authorization: Bearer $token"
            result="$(curl --silent --get -H "Accept: application/json" -H "Authorization: Bearer $token" $listUri | jq --raw-output '.')"
            echo $result
        done
    }
    

    例子

    docker-tags "microsoft/nanoserver" "microsoft/dotnet" "library/mongo" "library/redis"
    

    诚然,docker-tags 做了几个假设。具体来说,OAuth 请求参数大多是硬编码的。更雄心勃勃的实现会向注册表发出未经身份验证的请求,并从未经身份验证的响应中派生 OAuth 参数。

    【讨论】:

    • 您声明但不使用authz。也不需要分配和回显result,你可以让jq输出。
    【解决方案2】:

    我来晚了,我搜索了这个问题,列出了同一张图片的所有标签(了解摘要),不幸的是,大多数答案只是关于显示推送的任何图片摘要的所有可用标签。

    举个例子,对于 open jdk,同一个图像摘要通常会被标记多次:

      {
        "sha256:518f6c2137b7463272cb1f52488e914b913b92bfe0783acb821c216987959971": [
          "11",
          "11-buster",
          "11-jdk",
          "11-jdk-buster",
          "11.0",
          "11.0-buster",
          "11.0-jdk",
          "11.0-jdk-buster",
          "11.0.8",
          "11.0.8-buster",
          "11.0.8-jdk",
          "11.0.8-jdk-buster"
        ]
      },
    

    我找不到相关的 API v2,似乎 api 公开了标签,但没有详细信息,否则您需要列出每个 blob 清单以通过响应标头 Docker-Content-Digest 获得匹配的摘要。除非我在有很多标签的情况下错过了对我的用例无法使用的东西,所以我只是使用 regular dockerhub API 来获取所有标签和 teir 详细信息,并按图像摘要对这些标签进行分组。

    (
      url="https://registry.hub.docker.com/v2/repositories/library/openjdk/tags/?page_size=100" ;
      while [ -n "$url" ]; do
        >&2 echo -n ".";
        content="$(curl -s "$url")";
        url=$(jq -r '.next // empty' <<< "${content}");
        echo "$content";
      done;
      >&2 echo;
    ) | jq -s '[.[].results[]]' \
      | jq 'map({tag: .name, digest: .images[].digest}) | unique | group_by(.digest) | map(select(.[].digest) | {(.[0].digest): [.[].tag]})' \
      > openjdk-tags.json
    

    我已将此作为脚本发布在此 gist 中,任何意见或建议将不胜感激。

    【讨论】:

    • 只是想感谢你的剧本,太棒了!
    【解决方案3】:

    Docker 对注册表进行了巨大的重构:registry v2.0。

    在这个全新的版本中,带有一个新的身份验证系统,因此 v1.0 的基本身份验证将不再起作用。

    您可以在此处找到有关 v2.0 身份验证的更多详细信息:https://docs.docker.com/v1.6/registry/spec/auth/token/

    由于 v1.0 已弃用,您应该继续使用注册表 v2.0。

    【讨论】:

      【解决方案4】:

      这里有一个 Bash 脚本可以做到这一点。将其保存到名为 docker-hub-tags-list 的文件中并像这样运行它:

      docker-hub-tags-list markriggins/todowrangler
      

      但您需要先通过docker login 登录。您需要安装 JSON 工具 http://trentm.com/json/,这是一个非常酷的命令行解析 JSON 工具。

      #!/usr/bin/env bash
      
      REPOSITORY=${REPOSITORY:-$1}
      REGISTRY=${REGISTRY:-docker.io}
      
      #
      #  Docker funcs
      #
          d__docker_relative_repository_name_from_URL() {
              # Given $REGISTRY/repo/path:tag, return the repo/path
              set +o pipefail
              echo ${1-} | sed -e "s|^$REGISTRY/||" | cut -d: -f1
          }
      
          d___version_sort() {
              # Read stdin, sort by version number descending, and write stdout
              # It assumes X.Y.Z version numbers
      
              # This will sort tags like pr-3001, pr-3002 to the END of the list
              # and tags like 2.1.4 BEFORE 2.1.4-gitsha
      
              sort -s -t- -k 2,2nr |  sort -t. -s -k 1,1nr -k 2,2nr -k 3,3nr -k 4,4nr
          }
      
          d__basic_auth() {
              #
              # Read basic authentication credentials from `docker login`
              #
              cat ~/.docker/config.json | json '.auths["https://index.docker.io/v1/"].auth'
          }
      
      
          d__registry__tags_list() {
      
              # Return a list of available tags for the given repository sorted
              # by version number, descending
              #
              # Get tags list from dockerhub using the v2 API and an auth.docker token
      
              local rel_repository=$(d__docker_relative_repository_name_from_URL ${1})
              [ -z "$rel_repository" ] && return
      
              local TOKEN=$(curl -s -H "Authorization: Basic $(d__basic_auth)" \
                             -H 'Accept: application/json' \
                             "https://auth.docker.io/token?service=registry.docker.io&scope=repository:$rel_repository:pull" | json .token)
      
      
              curl -s -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" \
                      "https://index.docker.io/v2/$rel_repository/tags/list" |
                      json .tags |
                      json -a |
                      d___version_sort
          }
      
      d__registry__tags_list $REPOSITORY
      

      【讨论】:

        【解决方案5】:

        私有图像存储库,v2 API

        一个使用私有和公共存储库的版本,用 vanilla Bourne shell(包括但不限于 Bash)编写,并使用 v2 API,位于https://gist.github.com/nealey/86da928cdb5c21a4edc1be2ba7b845e3

        你可以像这样运行它:

        $ docker-tags.sh alpine
        $ docker-tags.sh ceph/daemon
        $ docker-tags.sh quay.io/coreos/dnsmasq
        

        它列出了所有版本,每行一个。

        #! /bin/sh
        
        image="$1"; shift
        if [ -z "$image" ] || [ "$image" == "--help" ]; then
            echo "Usage: $0 IMAGE"
            echo
            echo "Prints all tags associated with IMAGE in a docker repository"
            exit 1
        fi
        
        case "$image" in
            */*/*)
                host=${image%%/*/*}
                path=${image#*/}
                ;;
            */*)
                host=index.docker.io
                path=$image
                ;;
            *)
                host=index.docker.io
                path=library/$image
                ;;
        esac
        
        tags_uri=https://$host/v2/$path/tags/list
        
        ##
        ## Figure out who hands out tokens by doing an unauthenticated request
        ##
        extract () {
            # XXX: This can't handle values with commas in them
            echo -n "$2" | awk -v f="$1" 'BEGIN {RS=","; FS="=\"|\"$";} ($1 == f) { print $2; }'
        }
        auth=$(curl --silent -I $tags_uri | sed -n 's/^Www-Authenticate: Bearer //p' | tr -d '\r')
        if [ -n "$auth" ]; then
            realm=$(extract realm "$auth")
            service=$(extract service "$auth")
            scope=$(extract scope "$auth")
            ## Now fetch a token
            token=$(curl --silent --get --data-urlencode "service=$service" --data-urlencode "scope=$scope" $realm | jq  -r '.token')
            auth_header="Authorization: Bearer $token"
        fi
        
        ## Finally, list versions
        curl -s --header "$auth_header" "$tags_uri" | jq -r '.tags[]'
        

        【讨论】:

          【解决方案6】:

          感谢尼尔·皮克特的剧本。 它不适用于私人存储库,因此我对其进行了一些编辑(并且还修复了标头检测时区分大小写的问题)

          这个一开始会询问你的 Dockerhub 用户和密码,并用它来向 Dockehuv API 发出和验证请求。

          要点:https://gist.github.com/juanlb/b959354cc289dd9962e9f57dee4ac063

          【讨论】:

            猜你喜欢
            • 2017-06-08
            • 2015-04-27
            • 1970-01-01
            • 2015-04-03
            • 2021-11-02
            • 1970-01-01
            • 1970-01-01
            • 2018-01-17
            • 2022-10-08
            相关资源
            最近更新 更多