从 Docker 图片中识别 FROM 行

Identify FROM line from Docker Image

我有一张来自同事的图片,用于创建它的 Docker 文件的原始版本丢失了。

我使用 alpine/dfimage 重建了 Docker 文件中除第一行 (FROM) 之外的所有内容。

根据 Artifactory,层的摘要是

{
    "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
    "size": 2813316,
    "digest": "sha256:cbdbe7a5bc2a134ca8ec91be58565ec07d037386d1f1d8385412d224deafca08"
}

ADD 行是:

ADD file:b91adb67b670d3a6ff9463e48b7def903ed516be66fc4282d22c53e41512be49 in /

我相当有信心基础图像是从 public 存储库中提取的。我一直在尝试找到一种通过摘要搜索 Docker Hub 以查找图像的方法(就像我在 Artifactory 中所做的那样),但我还没有找到一些东西。例如,在 Docker Hub 上发布的 sha256:c74f1b1166784193ea6c8f9440263b9be6cae07dfe35e32a5df7a31358ac2060 library/apline:3.15.0 has a digest of sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300 (different from the repo digest

如果我知道名称空间和存储库,我可以简单地用 docker image pull server/namespace/repo@digest 指定摘要。不幸的是,我唯一拥有的是 Docker 文件的先前版本,那里引用的命名空间和存储库不起作用。

FROM mcr.microsoft.com/dotnet/core/runtime:2.1.11-alpine3.9

也就是说,docker image pull mcr.microsoft.com/dotnet/core/runtime@sha256:cbdbe7a5bc2a134ca8ec91be58565ec07d037386d1f1d8385412d224deafca08没有return成功。 docker image pull mcr.microsoft.com/dotnet/runtime@sha256:cbdbe7a5bc2a134ca8ec91be58565ec07d037386d1f1d8385412d224deafca08.

也没有

如有任何帮助,我们将不胜感激。在这一点上我唯一的选择就是重新发明轮子。

所以,我能够找到这个,但是 none 的数据似乎与我相关,如果实际上有任何相关数据,我欢迎对此进行讨论。

感兴趣的图像是 alpine:3.11.6,摘要为 sha256:9a839e63dad54c3a6d1834e29692c8492d93f90c59c978c1ed79109ea4fb9a54

层 blob 的摘要和图像清单的摘要是两个不同的东西,清单包含层 blob 的摘要,因此如果任何层发生更改,清单的摘要也会更改。这就是提供图像不变性的原因。检查您找到的图像:

$ regctl manifest get localhost:5000/library/alpine:3.11.6
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
  "config": {
    "mediaType": "application/vnd.docker.container.image.v1+json",
    "size": 1507,
    "digest": "sha256:f70734b6a266dcb5f44c383274821207885b549b75c8e119404917a61335981a"
  },
  "layers": [
    {
      "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
      "size": 2813316,
      "digest": "sha256:cbdbe7a5bc2a134ca8ec91be58565ec07d037386d1f1d8385412d224deafca08"
    }
  ]
}

您可以看到您的一个 blob,但要拉取图像,您需要清单摘要,不幸的是,没有办法列出指向特定 blob 的所有清单(至少现在还没有,我们可能会得到)作为 OCI 引用类型的一部分,但这还有很长的路要走)。但是,清单本身有一个摘要,与您在检查图像时看到的内容相匹配:

$ regctl manifest get localhost:5000/library/alpine:3.11.6 --format raw-body | sha256sum
39eda93d15866957feaee28f8fc5adb545276a64147445c64992ef69804dbf01  -

$ regctl manifest get localhost:5000/library/alpine:3.11.6 --list --format raw-body | sha256sum
9a839e63dad54c3a6d1834e29692c8492d93f90c59c978c1ed79109ea4fb9a54  -

至于为什么上面有两个摘要,alpine镜像是一个multi-platform镜像,所以父清单列表有一个摘要,然后每个镜像清单都有一个摘要。清单列表如下所示:

$ regctl manifest get localhost:5000/library/alpine:3.11.6 --list --format raw-body | jq .
{
  "manifests": [
    {
      "digest": "sha256:39eda93d15866957feaee28f8fc5adb545276a64147445c64992ef69804dbf01",
      "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
      "platform": {
        "architecture": "amd64",
        "os": "linux"
      },
      "size": 528
    },
    {
      "digest": "sha256:0ff8a9dffabb5ed8dcba4ee898f62683305b75b4086f433ee722db99138f4f53",
      "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
      "platform": {
        "architecture": "arm",
        "os": "linux",
        "variant": "v6"
      },
      "size": 528
    },
    {
      "digest": "sha256:19c4e520fa84832d6deab48cd911067e6d8b0a9fa73fc054c7b9031f1d89e4cf",
      "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
      "platform": {
        "architecture": "arm",
        "os": "linux",
        "variant": "v7"
      },
      "size": 528
    },
    {
      "digest": "sha256:ad295e950e71627e9d0d14cdc533f4031d42edae31ab57a841c5b9588eacc280",
      "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
      "platform": {
        "architecture": "arm64",
        "os": "linux",
        "variant": "v8"
      },
      "size": 528
    },
    {
      "digest": "sha256:b28e271d721b3f6377cb5bae6cd4506d2736e77ef6f70ed9b0c4716da8bdf17c",
      "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
      "platform": {
        "architecture": "386",
        "os": "linux"
      },
      "size": 528
    },
    {
      "digest": "sha256:e095eb9ac24e21bf2621f4d243274197ef12b91c67cde023092301b2db1e073c",
      "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
      "platform": {
        "architecture": "ppc64le",
        "os": "linux"
      },
      "size": 528
    },
    {
      "digest": "sha256:41ba0806c6113064dd4cff12212eea3088f40ae23f182763ccc07f430b3a52f8",
      "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
      "platform": {
        "architecture": "s390x",
        "os": "linux"
      },
      "size": 528
    }
  ],
  "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
  "schemaVersion": 2
}

一旦我们通过标签或摘要获得清单列表,我们就可以将结构遍历清单和包含的 blob。但是 blob 不包含父项的摘要(添加它会更改 blob 的摘要,这会更改父项的摘要,并且您会得到循环依赖)。

最近添加到 OCI standard annotations 列表中的一件事是 org.opencontainers.image.base.digestorg.opencontainers.image.base.tag,如果实现,将允许图像用户通过两个标签识别他们的基本图像和摘要,这对于确定何时需要重建图像很有用(当标签不再引用相同的摘要时)。