如何在Docker Hub上查看Docker镜像层?

15

我知道可以使用docker history命令查看Docker镜像的层,但如何在不拉取镜像的情况下查看Docker Hub上的镜像呢?这样我才能在下载之前了解镜像上有什么。

例如,对于Tomcat仓库(https://registry.hub.docker.com/_/tomcat/),该网页似乎没有显示镜像上的内容。我必须查看Github上的Dockerfile才能找到信息。

更新 我发现这个仓库https://registry.hub.docker.com/u/tutum/tomcat/有更多的选项卡。" Dockerfile "选项卡显示如何创建镜像,但似乎仅显示最新版本。是否没有查看其他标签版本的文件的选项?


docker images --tree 已经不再可用。 - Arun Gupta
@ArunGupta 你知道它的替代品是什么吗? - stackoverflower
4
docker history 命令可以清楚地展示出镜像的创建过程。 - Arun Gupta
今天也无法使用/tutum/tomcat/ - Nam G VU
4个回答

18

Docker Hub目前相当有限,没有提供您所要求的功能。

当一个镜像在Docker Hub上被配置为从源代码构建(一种自动化构建),您可以看到其中包含了什么,但如果它是预构建上传的,则没有任何信息。


4

1
链接无法使用。 - romkadj
谢谢,链接已更新。 - Jethro

4

3
您可以使用注册表API获取任何注册表的此信息。在镜像清单中,有一个指向图像配置的指针,该配置是一个JSON blob,其中包括历史步骤。请注意,这个历史记录不是权威的,并且根据构建工具的不同,可能会报告与实际用于构建图像层的命令不同的命令。
使用Docker Hub的auth的shell脚本版本如下:
#!/bin/sh

ref="${1:-library/ubuntu:latest}"
repo="${ref%:*}"
tag="${ref##*:}"
token=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:${repo}:pull" \
        | jq -r '.token')
digest=$(curl -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
              -H "Authorization: Bearer $token" \
              -s "https://registry-1.docker.io/v2/${repo}/manifests/${tag}" \
         | jq -r .config.digest)
curl -H "Accept: application/vnd.docker.container.image.v1+json" \
     -H "Authorization: Bearer $token" \
     -s -L "https://registry-1.docker.io/v2/${repo}/blobs/${digest}" | jq .history

幕后发生的是,注册表首先将任何清单列表解析为默认架构的单个清单,但您也可以手动拉取任何架构。
$ regctl image manifest --list localhost:5000/library/alpine:latest --format '{{jsonPretty .}}'
{
  "manifests": [
    {
      "digest": "sha256:69704ef328d05a9f806b6b8502915e6a0a4faa4d72018dc42343f511490daf8a",
      "mediaType": "application\/vnd.docker.distribution.manifest.v2+json",
      "platform": {
        "architecture": "amd64",
        "os": "linux"
      },
      "size": 528
    },
    {
      "digest": "sha256:18c29393a090ba5cde8a5f00926e9e419f47cfcfd206cc3f7f590e91b19adfe9",
      "mediaType": "application\/vnd.docker.distribution.manifest.v2+json",
      "platform": {
        "architecture": "arm",
        "os": "linux",
        "variant": "v6"
      },
      "size": 528
    },
...

然后该平台特定的清单文件包括配置和图层:
$ regctl image manifest localhost:5000/library/alpine@sha256:69704ef328d05a9f806b6b8502915e6a0a4faa4d72018dc42343f511490daf8a --format '{{jsonPretty .}}'
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
  "config": {
    "mediaType": "application/vnd.docker.container.image.v1+json",
    "size": 1471,
    "digest": "sha256:14119a10abf4669e8cdbdff324a9f9605d99697215a0d21c360fe8dfa8471bab"
  },
  "layers": [
    {
      "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
      "size": 2814446,
      "digest": "sha256:a0d0a0d46f8b52473982a3c466318f479767577551a53ffc9074c9fa7035982e"
    }
  ]
}

拉取配置块会显示所有内容,你可能会从历史和检查命令中认识到其中的一些内容:
$ regctl blob get localhost:5000/library/alpine sha256:14119a10abf4669e8cdbdff324a9f9605d99697215a0d21c360fe8dfa8471bab | jq .
{
  "architecture": "amd64",
  "config": {
    "Hostname": "",
    "Domainname": "",
    "User": "",
    "AttachStdin": false,
    "AttachStdout": false,
    "AttachStderr": false,
    "Tty": false,
    "OpenStdin": false,
    "StdinOnce": false,
    "Env": [
      "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    ],
    "Cmd": [
      "/bin/sh"
    ],
    "Image": "sha256:d3e0b6258ec2f725c19668f11ae5323c3b0245e197ec478424ec6a87935690eb",
    "Volumes": null,
    "WorkingDir": "",
    "Entrypoint": null,
    "OnBuild": null,
    "Labels": null
  },
  "container": "330289c649db86f5fb1ae5bfef18501012b550adb0638b9193d4a3a4b65a2f9b",
  "container_config": {
    "Hostname": "330289c649db",
    "Domainname": "",
    "User": "",
    "AttachStdin": false,
    "AttachStdout": false,
    "AttachStderr": false,
    "Tty": false,
    "OpenStdin": false,
    "StdinOnce": false,
    "Env": [
      "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    ],
    "Cmd": [
      "/bin/sh",
      "-c",
      "#(nop) ",
      "CMD [\"/bin/sh\"]"
    ],
    "Image": "sha256:d3e0b6258ec2f725c19668f11ae5323c3b0245e197ec478424ec6a87935690eb",
    "Volumes": null,
    "WorkingDir": "",
    "Entrypoint": null,
    "OnBuild": null,
    "Labels": {}
  },
  "created": "2021-08-27T17:19:45.758611523Z",
  "docker_version": "20.10.7",
  "history": [
    {
      "created": "2021-08-27T17:19:45.553092363Z",
      "created_by": "/bin/sh -c #(nop) ADD file:aad4290d27580cc1a094ffaf98c3ca2fc5d699fe695dfb8e6e9fac20f1129450 in / "
    },
    {
      "created": "2021-08-27T17:19:45.758611523Z",
      "created_by": "/bin/sh -c #(nop)  CMD [\"/bin/sh\"]",
      "empty_layer": true
    }
  ],
  "os": "linux",
  "rootfs": {
    "type": "layers",
    "diff_ids": [
      "sha256:e2eb06d8af8218cfec8210147357a68b7e13f7c485b991c288c2d01dc228bb68"
    ]
  }
}

上述的 regctl 命令来自我的 regclient 项目,但我相信您可以使用 skopeo 和 crane 进行类似的命令。与 curl 命令相比,这些工具的优点在于处理不同注册表之间的身份验证(来自 Hub 的 bearer token 在其他注册表中无法使用)。
最后,使用 regctl 的一行答案是一个格式化的镜像配置命令,它执行所有上述步骤而不需要 jq:
$ regctl image config localhost:5000/library/alpine:latest --format '{{jsonPretty .History}}'
[
  {
    "created": "2021-08-27T17:19:45.553092363Z",
    "created_by": "/bin/sh -c #(nop) ADD file:aad4290d27580cc1a094ffaf98c3ca2fc5d699fe695dfb8e6e9fac20f1129450 in / "
  },
  {
    "created": "2021-08-27T17:19:45.758611523Z",
    "created_by": "/bin/sh -c #(nop)  CMD [\"/bin/sh\"]",
    "empty_layer": true
  }
]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接