【问题标题】:How to determine the Docker image ID for a tag via Docker Hub API?如何通过 Docker Hub API 确定标签的 Docker 镜像 ID?
【发布时间】:2017-06-08 02:31:39
【问题描述】:

给定一个标签 `latest`,我们想在 Docker Hub 上找出另一个具有相同镜像 ID 的标签。

这里是如何使用 Docker Hub API v2 找出 repo 的所有标签:

TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${UNAME}'", "password": "'${UPASS}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)
curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/fluent/fluentd/tags/?page_size=100 | jq

(见gist.github.com/kizbitz

不幸的是,它不包含图像 ID,但该键始终为 `null` 值:

$ curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/fluent/fluentd/tags/?page_size=100 | jq
{
  "count": 36,
  "next": null,
  "previous": null,
  "results": [
...
    {
      "name": "v0.14.11",
      "full_size": 11964464,
      "id": 7084687,
      "repository": 219785,
      "creator": 2923,
      "last_updater": 2923,
      "last_updated": "2016-12-27T07:16:41.294807Z",
      "image_id": null,
      "v2": true,
      "platforms": [
        5
      ]
    },
...

很遗憾,图片 ID 与上述 JSON 中的 `id` 不同。

$ docker images | grep fluent
docker.io/fluent/fluentd                  v0.14.11            1441d57beff9        3 weeks ago         38.25 MB

理论上,应该可以通过此 Docker Registry 调用访问 Docker Manifests 和映像 ID,但它也无济于事:

$ curl -s -H "Authorization: JWT ${TOKEN}" "https://registry.hub.docker.com/v2/fluent/fluentd/manifests/latest"
{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"repository","Name":"fluent/fluentd","Action":"pull"}]}]}

(见stackoverflow.com

这里是 Docker GitHub 存储库中的一个类似问题,但我仍然无法找出解决方案:https://github.com/docker/distribution/issues/1490

P.S.:这是我尝试推送测试映像的 Docker 版本:

$ docker version
Client:
 Version:         1.12.6
 API version:     1.24
 Package version: docker-common-1.12.6-5.git037a2f5.fc25.x86_64
 Go version:      go1.7.4
 Git commit:      037a2f5/1.12.6
 Built:           Wed Jan 18 12:11:29 2017
 OS/Arch:         linux/amd64

【问题讨论】:

    标签: docker dockerhub


    【解决方案1】:

    Docker Registry API v2 使用镜像摘要而不是镜像 ID 来区分镜像身份。

    可以通过以下 API 调用从 HTTP 响应头的Docker-Content-Digest 获取图像摘要:

    $ REPOSITORY=fluent/fluentd
    
    $ TOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:$REPOSITORY:pull" | jq -r .token)
    
    $ curl -s -D - -H "Authorization: Bearer $TOKEN" -H "Accept: application/vnd.docker.distribution.manifest.v2+json" https://index.docker.io/v2/$REPOSITORY/manifests/latest
    HTTP/1.1 200 OK
    Content-Length: 1982
    Content-Type: application/vnd.docker.distribution.manifest.v2+json
    Docker-Content-Digest: sha256:eaea1edffc34cff3b5e31ee738ea56e46326f90731b4139a19948814a4f0a4db
    Docker-Distribution-Api-Version: registry/2.0
    Etag: "sha256:eaea1edffc34cff3b5e31ee738ea56e46326f90731b4139a19948814a4f0a4db"
    Date: Tue, 24 Jan 2017 13:34:53 GMT
    Strict-Transport-Security: max-age=31536000
    ...
    

    所有标签都可以通过以下API调用获取:

    $ curl -s -H "Authorization: Bearer $TOKEN" https://index.docker.io/v2/$REPOSITORY/tags/list
    {"name":"fluent/fluentd","tags":["edge-onbuild","edge","jemalloc","latest-onbuild","latest","onbuild","stable-onbuild","stable","ubuntu-base","v0.12-latest-onbuild","v0.12-latest","v0.12-onbuild","v0.12.16","v0.12.18","v0.12.19","v0.12.20","v0.12.21","v0.12.23","v0.12.24","v0.12.26-2","v0.12.26-onbuild","v0.12.26","v0.12.27-onbuild","v0.12.27","v0.12.28-onbuild","v0.12.28","v0.12.29-onbuild","v0.12.29","v0.12.30-onbuild","v0.12.30","v0.12.31-onbuild","v0.12.31","v0.12","v0.14-latest-onbuild","v0.14-latest","v0.14-onbuild","v0.14.1","v0.14.10-onbuild","v0.14.10","v0.14.11-onbuild","v0.14.11","v0.14.2","v0.14.6","v0.14.8","v0.14"]}
    

    基于上述,要找到与特定标签相同的摘要,它将是如下脚本。

    #!/bin/bash
    
    REPOSITORY=$1
    TARGET_TAG=$2
    
    # get authorization token
    TOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:$REPOSITORY:pull" | jq -r .token)
    
    # find all tags
    ALL_TAGS=$(curl -s -H "Authorization: Bearer $TOKEN" https://index.docker.io/v2/$REPOSITORY/tags/list | jq -r .tags[])
    
    # get image digest for target
    TARGET_DIGEST=$(curl -s -D - -H "Authorization: Bearer $TOKEN" -H "Accept: application/vnd.docker.distribution.manifest.v2+json" https://index.docker.io/v2/$REPOSITORY/manifests/$TARGET_TAG | grep Docker-Content-Digest | cut -d ' ' -f 2)
    
    # for each tags
    for tag in ${ALL_TAGS[@]}; do
      # get image digest
      digest=$(curl -s -D - -H "Authorization: Bearer $TOKEN" -H "Accept: application/vnd.docker.distribution.manifest.v2+json" https://index.docker.io/v2/$REPOSITORY/manifests/$tag | grep Docker-Content-Digest | cut -d ' ' -f 2)
    
      # check digest
      if [[ $TARGET_DIGEST = $digest ]]; then
        echo "$tag $digest"
      fi
    done
    

    结果如下:

    $ ./find_same_digest.sh fluent/fluentd latest
    latest sha256:eaea1edffc34cff3b5e31ee738ea56e46326f90731b4139a19948814a4f0a4db
    stable sha256:eaea1edffc34cff3b5e31ee738ea56e46326f90731b4139a19948814a4f0a4db
    v0.12.31 sha256:eaea1edffc34cff3b5e31ee738ea56e46326f90731b4139a19948814a4f0a4db
    v0.12 sha256:eaea1edffc34cff3b5e31ee738ea56e46326f90731b4139a19948814a4f0a4db
    

    如果要查看本地图片的摘要,可以通过docker images --digests获取:

    $ docker images --digests | grep fluentd
    fluent/fluentd                  latest              sha256:eaea1edffc34cff3b5e31ee738ea56e46326f90731b4139a19948814a4f0a4db   1788ee7dcfcc        14 hours ago        35.41 MB
    

    【讨论】:

    • 次要注意,因为您只希望标头使用 curl -I 来执行 HTTP HEAD。此外,-i-D - 做同样的事情。
    • 如果需要,别忘了指定library/<reponame>
    • 你可以通过只过滤掉ALL_TAGS中你关心的标签而不是检索所有标签的摘要来加快这段代码的速度。
    • 对于如今相当流行的多架构图像,您需要指定此内容类型:application/vnd.docker.distribution.manifest.list.v2+json
    【解决方案2】:

    上面的答案很棒!此外,如果您想在私有 repo 上使用它,您需要使用您的注册表用户凭据添加基本身份验证,以及附加范围参数 'account='

    (见http://www.cakesolutions.net/teamblogs/docker-registry-api-calls-as-an-authenticated-user

    【讨论】:

    • curl -u $UNAME:$UPASS "https://auth.docker.io/token?service=registry.docker.io&scope=repository:$REPOSITORY:pull&account=$UNAME"
    猜你喜欢
    • 2021-09-02
    • 1970-01-01
    • 1970-01-01
    • 2022-12-26
    • 2015-01-28
    • 1970-01-01
    • 2020-06-02
    • 1970-01-01
    • 2021-06-29
    相关资源
    最近更新 更多