为什么父容器镜像 SHA 没有列在子层中?

Why is a parent container image SHA not listed in the layers of the child?

考虑一个容器镜像,我们称之为 BaseContainerImage。我基于 docker 集线器上的容器映像构建了这个容器映像(如果重要的话,.Net Core 3.1 运行 时间)。 “基于”是指 FROM 引用 docker 中心图像。

当我构建它时,它的 SHA 为:sha256:9ec7b7481feee3eb141f7321be1df353b1ab8b6bdf0d871717b6f7e90e6ed0f6。 (通过检查容器镜像清单的 config.digest 找到。)

然后我去制作一个新的容器镜像,我们称之为ApplicationContainerImage。它基于 BaseContainerImage,使用引用上述 SHA 的标签。构建之后,我查看容器镜像的清单。

我希望 layers 部分包含“父”容器映像的 SHA。 但事实并非如此。

当我比较两者的图层时,BaseContainerImage 的所有图层都在 ApplicationContainerImage 中。所以我知道 FROM 有效。但我只是不明白为什么 BaseContainerImage 的 SHA 被排除在 ApplicationContainerImage.

的层之外

为什么 BaseContainerImage 的 SHA 没有列在 ApplicationContainerImage 的层中?

后期笔记:
当我去从远程存储库下载 BaseContainerImage 时,它告诉我(作为 PULL 命令输出的一部分摘要是 Digest: sha256:a1dd2dfdfc51e7abba1d2db319ba457e7b72f7258f5cefca0ee6ec6845f564b6 这显然与上面的摘要不匹配。但是当我 运行 docker manifest inspect 完全相同的图像时, config.digestsha256:9ec7b7481feee3eb141f7321be1df353b1ab8b6bdf0d871717b6f7e90e6ed0f6,与我之前得到的相匹配。

为什么会有两个不同的 SHA 值?一个只是为了拉动作吗?

您混淆了不同对象的摘要。注册表中的图像包括:

  • 清单:这是顶层,有自己的摘要,但通常由标签引用
  • 配置:清单指向这个,它包括您在检查 docker 图像时看到的默认设置
  • 层:每一层都有自己的摘要,在注册表中通常是 tar+gzip,在本地拉取时 tar(未压缩)

清单摘要是最常用的摘要,用于固定要拉取的图像。请注意,您可以有一个指向多个平台特定清单的清单列表,并且每个清单都有自己的摘要。

不应将配置摘要与本地任何内容进行比较,它需要从注册表中提取配置 blob,但它不直接与层摘要相关联,也不是清单摘要。

层摘要有时会混淆,因为当您从在注册表上压缩到在本地解压缩时它们会发生变化。

什么是摘要?它只是内容上的 sha256sum。该文件作为 blob 或清单被推送到注册表。由于清单如何包含其他文件的摘要,您最终会得到一个有向无环图 (DAG)。

要查看图层重用,请查看图像清单中的实际图层。或者您可以查看配置 blob 的图层部分(这些摘要会有所不同,因为配置中的图层摘要位于未压缩的图层上)。


下面是层重用的示例,查看 docker 集线器上的两个图像:

$ regctl image manifest alpine:3.13
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
  "config": {
    "mediaType": "application/vnd.docker.container.image.v1+json",
    "size": 1472,
    "digest": "sha256:6dbb9cc54074106d46d4ccb330f2a40a682d49dda5f4844962b7dce9fe44aaec"
  },
  "layers": [
    {
      "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
      "size": 2811969,
      "digest": "sha256:540db60ca9383eac9e418f78490994d0af424aab7bf6d0e47ac8ed4e2e9bcbba"
    }
  ]
}

$ regctl image manifest redis:alpine
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
  "config": {
    "mediaType": "application/vnd.docker.container.image.v1+json",
    "size": 6390,
    "digest": "sha256:1690b63e207f6651429bebd716ace700be29d0110a0cfefff5038bb2a7fb6fc7"
  },
  "layers": [
    {
      "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
      "size": 2811969,
      "digest": "sha256:540db60ca9383eac9e418f78490994d0af424aab7bf6d0e47ac8ed4e2e9bcbba"
    },
    {
      "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
      "size": 1258,
      "digest": "sha256:29712d301e8c43bcd4a36da8a8297d5ff7f68c3d4c3f7113244ff03675fa5e9c"
    },
    {
      "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
      "size": 384200,
      "digest": "sha256:8173c12df40f1578a7b2dfbbc0034a4fbc8ec7c870fd32b9236c2e5e1936616a"
    },
    {
      "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
      "size": 7692532,
      "digest": "sha256:8cc52074f78e0a2fd174bdd470029cf287b7366bf1b8d3c1f92e2aa8789b92ae"
    },
    {
      "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
      "size": 135,
      "digest": "sha256:aa7854465cce07929842cb49fc92f659de8a559cf521fc7ea8e1b781606b85cd"
    },
    {
      "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
      "size": 412,
      "digest": "sha256:6ab1d05b49730290d3c287ccd34640610423d198e84552a4c2a4e98a46680cfd"
    }
  ]
}

从中您可以看到配置 blob 完全不同(如预期的那样,它们不是同一图像),但是 alpine 图像的层与 redis:alpine 图片.

这里显示的 regctl 工具是 available from github。免责声明,我是作者。