【问题标题】:Docker Registry: How do I get the list of digest of an image layers?Docker Registry:如何获取图像层的摘要列表?
【发布时间】:2023-01-25 07:52:32
【问题描述】:

我正在尝试列出加载到 docker 注册表的图像(例如:ubuntu)的层摘要。我基本上是在为 docker registry 寻找 docker manifest inspect --verbose <image-name> 的等价物,它给出了类似的输出:

从托管注册表的服务器,我成功运行以下命令以列出注册表中的图像:

curl -k -X GET -u admin:root https://docker.registry.url/v2/_catalog | python -mjson.tool

我还可以运行以下命令来查看图像的标签:

curl -k -X GET -u admin:root https://docker.registry.url/v2/ubuntu/tags/list | python -mjson.tool

但是当我尝试使用以下命令(如here)列出摘要时:

curl -k -v -s -X GET -u admin:root https://docker.registry.url/v2/ubuntu/manifests/latest -H 'Accept: application/vnd.docker.distribution.manifest.v2+json' | python -mjson.tool

...我收到以下两条消息:

  • “未找到 HTTP/1.1 404”
  • “错误:”代码“:”MANIFEST_UNKNOWN“

根据以下输出:

* About to connect() to docker.registry.url port 443 (#0)
*   Trying <server-ip-address>...
* Connected to docker.registry.urll (<server-ip-address>) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* skipping SSL peer certificate verification
* SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate:
*       subject: CN=docker.registry.url
*       start date: Oct 22 13:15:18 2021 GMT
*       expire date: Oct 21 13:00:19 2031 GMT
*       common name: docker.registry.url
*       issuer: CN=docker.registry.url
* Server auth using Basic with user 'admin'
> GET /v2/ubuntu/manifests/latest HTTP/1.1
> Authorization: Basic YWRtaW46QWlyc3BhbjEyMw==
> User-Agent: curl/7.29.0
> Host: docker.registry.url
> Accept: application/vnd.docker.distribution.manifest.v2+json
>
< HTTP/1.1 404 Not Found
< Server: nginx/1.21.3
< Date: Tue, 08 Mar 2022 15:00:36 GMT
< Content-Type: application/json; charset=utf-8
< Content-Length: 187
< Connection: keep-alive
< Docker-Distribution-Api-Version: registry/2.0
< X-Content-Type-Options: nosniff
<
{ [data not shown]
* Connection #0 to host docker.registry.url left intact
{
    "errors": [
        {
            "code": "MANIFEST_UNKNOWN",
            "detail": {
                "Name": "ubuntu",
                "Revision": "sha256:9c152418e380c6e6dd7e19567bb6762b67e22b1d0612e4f5074bda6e6040c64a"
            },
            "message": "manifest unknown"
        }
    ]
}

1- 为什么会出现上述错误?

2- 如何从 docker registry 获取图像的清单列表?

【问题讨论】:

  • 标签列表是否显示 latest 作为标签名称?清单是单一平台 docker 清单,而不是多平台清单或 OCI 清单吗?
  • @BMitch:是的。这是
  • 您在错误中得到摘要这一事实让我认为它可能是一个多平台清单,并且注册表中缺少单个平台清单。尝试在您的接受标头列表中包含 application/vnd.docker.distribution.manifest.list.v2+json
  • 您可能还想尝试 regclient、crane 或 skopeo,它们都比 curl 命令容易得多。 regclient 包含一个 -v debug 选项,因此您可以看到发生的各种 API 请求。免责声明,我是作者。
  • @BMitch:新标头出现相同的错误

标签: docker hash docker-registry container-image


【解决方案1】:

解决方法:

不确定这个答案是否与实际问题 100% 相关,但我需要删除注册表中的图像;使用 registry:2.8.1,跟随 this 但即使是垃圾收集器也没有为我清除图像,因此作为一种解决方法,我通过不将图像安装为卷来清除图像 - 并重新启动整个注册表;如果我需要单独清除一组不同的图像,我可以在不同的端口上设置第二个注册表,并且不使用已安装的卷。

但如果它适用于其他人,这里还有一些其他命令:

1 获取摘要

docker inspect example.com:5000/myimage

应该有这个部分:

"RepoDigests": [
"my.docker.registry.com:5000/ubuntu@sha256:74a1b5f5c5d771cf3570fa0f050e0c827538b7fe1873bc88b85d56818df3f2bc"
]

2 运行垃圾收集器

docker exec registry bin/registry garbage-collect --dry-run /etc/docker/registry/config.yml

docker exec registry bin/registry garbage-collect --help /etc/docker/registry/config.yml

3 删除

curl -X DELETE -u username:password https://example.com:5000/v2/my_image/manifests/<digest> -H 'Accept: application/vnd.docker.distribution.manifest.v2+json'

【讨论】:

  • 我本来打算对自己的答案投反对票,我认为我建议的这种解决方法实际上并不是那么好,因为它引入了很多复杂性,或者至少引入了代码和逻辑的重组以应对每个环境的不同端口,但它是可行的,但我也跑了进入 docker-compose 和 --profiles 的问题。 docker-compose down --profile 忽略了配置文件,所以我无法协调基本注册表不应该用单个 docker-compose.yaml 文件停止,这是一个持续存在的问题:github.com/docker/compose/issues/8139
【解决方案2】:

我有一种情况,我想查看存储库中的最新图像是否与当前在我的机器上运行的图像相同。我试图使用 curl 命令并遇到问题,但 skopeo 在 Raspbian 上“正常工作”:

apt install -y skopeo
skopeo  inspect  docker://zwavejs/zwave-js-ui:latest | jq -r  '.Digest'

【讨论】:

    【解决方案3】:

    鉴于错误消息,注册管理机构理解标签,并试图提取特定的摘要但找不到它。最常见的原因之一是由于 longstanding bug with the GC design 而使用多平台映像在注册表上运行 GC。

    在命令中:

    curl -k -v -s -X GET -u admin:root 
      https://docker.registry.url/v2/ubuntu/manifests/latest 
      -H 'Accept: application/vnd.docker.distribution.manifest.v2+json' 
      | python -mjson.tool
    

    您正在请求单一平台清单,因此注册表将自动取消引用多平台图像清单。检查来自 Hub 的摘要,显示如下:

    $ regctl manifest get 
      ubuntu@sha256:9c152418e380c6e6dd7e19567bb6762b67e22b1d0612e4f5074bda6e6040c64a 
      --format '{{jsonPretty .}}'
    {
      "schemaVersion": 2,
      "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
      "config": {
        "mediaType": "application/vnd.docker.container.image.v1+json",
        "size": 1463,
        "digest": "sha256:2b4cba85892afc2ad8ce258a8e3d9daa4a1626ba380677cee93ef2338da442ab"
      },
      "layers": [
        {
          "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
          "size": 28565751,
          "digest": "sha256:7c3b88808835aa80f1ef7f03083c5ae781d0f44e644537cd72de4ce6c5e62e00"
        }
      ]
    }
    

    您可以通过允许额外的媒体类型来拉取清单列表来更好地了解发生了什么:

    curl -k -v -s -X GET -u admin:root 
      https://docker.registry.url/v2/ubuntu/manifests/latest 
      -H 'Accept: application/vnd.docker.distribution.manifest.v2+json' 
      -H 'Accept: application/vnd.docker.distribution.manifest.list.v2+json' 
      | python -mjson.tool
    

    一个例子如下:

    $ regctl manifest get ubuntu --format 'body' | jq .
    {
      "manifests": [
        {
          "digest": "sha256:965fbcae990b0467ed5657caceaec165018ef44a4d2d46c7cdea80a9dff0d1ea",
          "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
          "platform": {
            "architecture": "amd64",
            "os": "linux"
          },
          "size": 529
        },
        {
          "digest": "sha256:ea8f467d512068a1e52494d5b2d959a9307a35682633d0b5d481e79c914c627f",
          "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
          "platform": {
            "architecture": "arm",
            "os": "linux",
            "variant": "v7"
          },
          "size": 529
        },
        {
          "digest": "sha256:e77aa65a8a2bccbc47b96b4256995dd7ff447024ed5319527040f7cc465f6511",
          "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
          "platform": {
            "architecture": "arm64",
            "os": "linux",
            "variant": "v8"
          },
          "size": 529
        },
        {
          "digest": "sha256:48d0b40359f8789f1c5d6065bf0d2a00c8d0d4913ac61670215b2debedd483e6",
          "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
          "platform": {
            "architecture": "ppc64le",
            "os": "linux"
          },
          "size": 529
        },
        {
          "digest": "sha256:f31546bc71659c643837d57f09a161f04e866b59da4f418e064082a756c4c23a",
          "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
          "platform": {
            "architecture": "riscv64",
            "os": "linux"
          },
          "size": 529
        },
        {
          "digest": "sha256:4e3c33035b808801fc84ba48d5a779cd572167956f5123d846d7e1cbafe9e785",
          "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
          "platform": {
            "architecture": "s390x",
            "os": "linux"
          },
          "size": 529
        }
      ],
      "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
      "schemaVersion": 2
    }
    

    由于您的注册表处于损坏状态,您最好删除图像并重新开始,而无需 GC 过程。但是您可以通过摘要将单个图像复制回服务器:

    $ regctl image copy 
      ubuntu@sha256:9c152418e380c6e6dd7e19567bb6762b67e22b1d0612e4f5074bda6e6040c64a 
      docker.registry.url/ubuntu@sha256:9c152418e380c6e6dd7e19567bb6762b67e22b1d0612e4f5074bda6e6040c64a
    

    我什至为此设置了标志 --force-recursive,因为我经常看到它发生:

    $ regctl image copy --help
    ...
    
    Flags:
          --digest-tags        Include digest tags ("sha256-<digest>.*") when copying manifests
          --force-recursive    Force recursive copy of image, repairs missing nested blobs and manifests
      -h, --help               help for copy
          --include-external   Include external layers
          --referrers          Include referrers
    ...
    
    $ regctl image copy --force-recursive 
      ubuntu:latest docker.registry.url/ubuntu:latest
    

    上面显示的是我自己的 regclient/regctl 工具,但还有 crane、scopeo,我敢肯定还有其他几种工具,包括您自己首先用来复制图像的任何工具。除了演示之外,我会避免使用 curl 自己拉取图像,因为您最终会遇到其他媒体类型或令牌身份验证的场景,这使得围绕 curl 命令的脚本编写非常复杂(在决定它是更容易编写regclient)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-24
      • 1970-01-01
      • 1970-01-01
      • 2021-07-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多