通过 HTTP API 在 Docker 集线器上列出 Docker 图像的标签

Listing the tags of a Docker image on a Docker hub through the HTTP API

我想通过其 HTTP 接口列出 Docker 图片官方 Docker 集线器的标签,但我有点困惑。因为它们似乎有两个版本:

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

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

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

随着这个全新版本的出现,带来了新的身份验证系统,因此 v1.0 的基本身份验证将不再有效。

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

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

这里有一个 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:-}
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 )
        [ -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

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 参数。

私有图像存储库,v2 API

与私有和 public 存储库一起使用的版本,用 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=""; shift
if [ -z "$image" ] || [ "$image" == "--help" ]; then
    echo "Usage: [=11=] 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 "" | awk -v f="" 'BEGIN {RS=","; FS="=\"|\"$";} ( == f) { print ; }'
}
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[]'

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

手头的案例,对于开放 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 清单以通过以下方式获取匹配的摘要响应 header Docker-Content-Digest。我除非在有很多标签的情况下错过了对我的用例不可用的东西,所以我只是使用 regular dockerhub API 来获取所有标签和它们的详细信息和组这些标签由图像摘要。

(
  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,如有任何评论或建议,我们将不胜感激。

感谢 Neale Picket 的脚本。 它不适用于私人存储库,所以我对其进行了一些编辑(并且还修复了 headers 检测时区分大小写的问题)

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

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