英文:
Docker: two images share the same image-hash, but different digests. How?
问题
我正在调试一个与Python 3.10和GitLab CI/CD相关的问题。显然,在过去的几周里,推送了一个更新的Python 3.10.12镜像,将底层操作系统从Debian 11升级到Debian 12(Bullseye)。在尝试诊断这个问题时,我遇到了以下情况:
$ docker images --digests
python <none> sha256:1435f1edde19dbe479b0ea9d358bff26726ddd391c8b6fe587624d84a68da31e 23e11cf6844c 7 days ago 1GB
python <none> sha256:a8462db480ec3a74499a297b1f8e074944283407b7a417f22f20d8e2e1619782 23e11cf6844c 7 days ago 1GB
这是如何可能的?两个镜像怎么会有相同的摘要?这不是违反了摘要的目的吗?
英文:
I am debugging a problem with python3.10 and gitlab-ci/cd. Apparently, in the last weeks, a newer image of python 3.10.12 was pushed, updating the underlying OS from debian 11 to debian 12 (bullseye). While trying to diagnose this problem, I ran into the following siutation:
$ docker images --digests
python <none> sha256:1435f1edde19dbe479b0ea9d358bff26726ddd391c8b6fe587624d84a68da31e 23e11cf6844c 7 days ago 1GB
python <none> sha256:a8462db480ec3a74499a297b1f8e074944283407b7a417f22f20d8e2e1619782 23e11cf6844c 7 days ago 1GB
How is this possible? How can two images have the same digest? Doesn't that undermine the purpose of a digest?
答案1
得分: 2
请查看此答案 https://stackoverflow.com/questions/56364643/whats-the-difference-between-a-docker-images-image-id-and-its-digest 了解镜像ID和Digest之间的区别。
有时候镜像的ID和Digest之间会不同。当您的镜像相同但更改了与镜像相关的选项,例如将平台列表(linux/386
,linux/amd64
,linux/arm64
等)添加到清单中时,就会发生这种情况。在这种情况下,镜像和ID保持相同,但Digest会发生变化。
英文:
Check this answer https://stackoverflow.com/questions/56364643/whats-the-difference-between-a-docker-images-image-id-and-its-digest to understand teh difference betweeen image ID and Digest.
It can happen that the ID and the digest are different between images.
This case happen when your images are the same but you change options related to the images, such as adding the platforms list (linux/386
, linux/amd64
, linux/arm64
, etc.) to the manifest. In this case the image, and so the ID, remains identical but the digest change.
答案2
得分: 1
以下是您要翻译的内容:
"An image consists of several components: the layers, the config, and the manifest that represents both. These are described in the OCI image-spec. Docker uses the hash of the config JSON as the image ID. This JSON contains the hashes of the uncompressed layers, so it is guaranteed to be unique for a platform specific image.
The digests are the hashes of the manifest. There are currently two types of manifest, an image manifest and a manifest list (used by multi-platform images to point to the image manifest of each platform). Those manifests also have OCI and Docker media types for at least 4 types of manifests (there are a couple more legacy ones I'll avoid getting into).
So the digest can be for a multi-platform manifest, the platform specific manifest, or a different unrelated content or a different JSON rendering of either of those (changing the JSON white space, reordering keys the map, etc, will all change the hash of the JSON). In this case, it's two different manifest lists, where the AMD64 image is unchanged, but all of the other platforms were updated:
And you can see that 23e11...
hash on the config of the AMD64 image:"
英文:
An image consists of several components: the layers, the config, and the manifest that represents both. These are described in the OCI image-spec. Docker uses the hash of the config JSON as the image ID. This JSON contains the hashes of the uncompressed layers, so it is guaranteed to be unique for a platform specific image.
The digests are the hashes of the manifest. There are currently two types of manifest, an image manifest and a manifest list (used by multi-platform images to point to the image manifest of each platform). Those manifests also have OCI and Docker media types for at least 4 types of manifests (there are a couple more legacy ones I'll avoid getting into).
So the digest can be for a multi-platform manifest, the platform specific manifest, or a different unrelated content or a different JSON rendering of either of those (changing the JSON white space, reordering keys the map, etc, will all change the hash of the JSON). In this case, it's two different manifest lists, where the AMD64 image is unchanged, but all of the other platforms were updated:
$ docker buildx imagetools inspect python@sha256:1435f1edde19dbe479b0ea9d358bff26726ddd391c8b6fe587624d84a68da31e
Name: docker.io/library/python@sha256:1435f1edde19dbe479b0ea9d358bff26726ddd391c8b6fe587624d84a68da31e
MediaType: application/vnd.docker.distribution.manifest.list.v2+json
Digest: sha256:1435f1edde19dbe479b0ea9d358bff26726ddd391c8b6fe587624d84a68da31e
Manifests:
Name: docker.io/library/python@sha256:4a1aacea636cab6af8f99f037d1e56a4de97de6025da8eff90b3315591ae3617
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/amd64
Name: docker.io/library/python@sha256:14b2ce1eda6a5685fa7be19a09dd9f47e7d497a0f25e1cf03fd7bc7edbb6225c
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/arm/v5
Name: docker.io/library/python@sha256:6220f606209088b68d4572fca6c280085f79b8757bb00d40e308dbcd7219b5c1
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/arm/v7
Name: docker.io/library/python@sha256:5e7192c06de51ff1164ea123aa7ef71c85886339078cea09aaa5671bc9015eab
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/arm64/v8
Name: docker.io/library/python@sha256:8bc1f0da01b11fba3152f43cfdd6e60be09de0f9e4ff722b8c59777301a47ca7
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/386
Name: docker.io/library/python@sha256:a034324572d801a0626d98ef681748510dd721ca15104864f761477cf98b6e1f
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/ppc64le
Name: docker.io/library/python@sha256:480ad5c174411791a08b614e2ecf587b4a52d514725924729d71a7ee3e22613f
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/s390x
$ docker buildx imagetools inspect python@sha256:a8462db480ec3a74499a297b1f8e074944283407b7a417f22f20d8e2e1619782
Name: docker.io/library/python@sha256:a8462db480ec3a74499a297b1f8e074944283407b7a417f22f20d8e2e1619782
MediaType: application/vnd.docker.distribution.manifest.list.v2+json
Digest: sha256:a8462db480ec3a74499a297b1f8e074944283407b7a417f22f20d8e2e1619782
Manifests:
Name: docker.io/library/python@sha256:4a1aacea636cab6af8f99f037d1e56a4de97de6025da8eff90b3315591ae3617
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/amd64
Name: docker.io/library/python@sha256:04f58351f4387ae9f23df91d2174777e02c9110de0845dfc02abf3675bafda37
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/arm/v5
Name: docker.io/library/python@sha256:8fed3b37d3954ca556604db5b7e7b2f1856efaa5625d0ef763c31efd1f106fbd
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/arm/v7
Name: docker.io/library/python@sha256:5e7192c06de51ff1164ea123aa7ef71c85886339078cea09aaa5671bc9015eab
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/arm64/v8
Name: docker.io/library/python@sha256:411d4ffa2d620de28120e2d363386f9ccd992ff11c4f7f7f4abbdce04d3d90b6
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/386
Name: docker.io/library/python@sha256:864a650024d6f6f93ba042c5667bb598dcb3f68311825a98b47fd6a00490a088
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/ppc64le
Name: docker.io/library/python@sha256:b0fe9eab552b92321f5bc4a4f060efcf52282b58fb871b09434fe0c2b33fff92
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/s390x
And you can see that 23e11...
hash on the config of the AMD64 image:
$ regctl manifest get python@sha256:4a1aacea636cab6af8f99f037d1e56a4de97de6025da8eff90b3315591ae3617
Name: python@sha256:4a1aacea636cab6af8f99f037d1e56a4de97de6025da8eff90b3315591ae3617
MediaType: application/vnd.docker.distribution.manifest.v2+json
Digest: sha256:4a1aacea636cab6af8f99f037d1e56a4de97de6025da8eff90b3315591ae3617
Total Size: 375.313MB
Config:
Digest: sha256:23e11cf6844c334b2970fd265fb09cfe88ec250e1e80db7db973d69d757bdac4
MediaType: application/vnd.docker.container.image.v1+json
Size: 7530B
Layers:
Digest: sha256:bba7bb10d5baebcaad1d68ab3cbfd37390c646b2a688529b1d118a47991116f4
MediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
Size: 49.552MB
Digest: sha256:ec2b820b8e87758dde67c29b25d4cbf88377601a4355cc5d556a9beebc80da00
MediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
Size: 24.031MB
Digest: sha256:284f2345db055020282f6e80a646f1111fb2d5dfc6f7ee871f89bc50919a51bf
MediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
Size: 64.112MB
Digest: sha256:fea23129f080a6e28ebff8124f9dc585b412b1a358bba566802e5441d2667639
MediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
Size: 211.003MB
Digest: sha256:7c62c924b8a6474ab5462996f6663e07a515fab7f3fcdd605cae690a64aa01c7
MediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
Size: 6.389MB
Digest: sha256:c48db0ed1df2d2df2dccd680323097bafb5decd0b8a08f02684b1a81b339f39b
MediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
Size: 17.146MB
Digest: sha256:f614a567a40341ac461c855d309737ebccf10a342d9643e94a2cf0e5ff29b6cd
MediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
Size: 243B
Digest: sha256:00c5a00c6bc24a1c23f2127a05cfddd90865628124100404f9bf56d68caf17f4
MediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
Size: 3.080MB
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论