镜像推送至Azure容器注册表后Docker镜像摘要不一致问题排查
本地镜像摘要与Azure容器注册表(ACR)中镜像摘要不一致的原因
问题场景
1. 本地镜像信息
mark@L-R910LPKW:~$ docker image ls --digests | grep debug MyACR.azurecr.io/argoproj/argocd debug sha256:1346c0c07913d4da45beef22165aea26a24aab1be34eb166183c3d31ac19e8b8 b2d78a6e9763 7 hours ago 398 MB mark@L-R910LPKW:~$
2. 确认ACR中无该镜像
mark@L-R910LPKW:~$ az acr repository show -n MyACR --repository argoproj/argocd 2023-05-12 00:42:56.707823 Error: repository "argoproj/argocd" is not found. Correlation ID: d5884fbd-4804-4502-bc72-e90e1843361c. mark@L-R910LPKW:~$
3. 推送镜像至ACR
mark@L-R910LPKW:~$ docker push MyACR.azurecr.io/argoproj/argocd:debug Getting image source signatures Copying blob ddf9aeed156d done Copying blob e8614160d539 done Copying blob 3ab4ff5552b4 done Copying blob cabffe0d70ef done Copying blob c5ff2d88f679 done Copying blob 734db535e151 done Copying blob ab4be5894c20 done Copying blob d4648c3c4f4e done Copying blob a1af47c16bf8 done Copying blob 647b5703dc62 done Copying blob dfb784b423af done Copying blob 2ed7c8e88b82 done Copying config b2d78a6e97 done Writing manifest to image destination Storing signatures mark@L-R910LPKW:~$
4. 查询ACR中镜像的摘要
mark@L-R910LPKW:~$ az acr repository show -n MyACR -t argoproj/argocd:debug --query digest -o tsv sha256:a54903c9c8e867b458bb6f7cb41e3b26e7abf8346b7adc7ab87ebab066b2a95b mark@L-R910LPKW:~$
此时发现本地docker image ls --digests返回的镜像摘要sha256:1346c0c07913d4da45beef22165aea26a24aab1be34eb166183c3d31ac19e8b8与ACR中的摘要不一致。
补充信息
实际使用Podman伪装Docker
mark@L-R910LPKW:~$ cat `which docker` #!/bin/sh [ -f /etc/containers/nodocker ] || \ echo "Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg." >&2 exec /usr/bin/podman "$@" mark@L-R910LPKW:~$
本地构建镜像也会显示摘要(并非仅推送后才有)
mark@L-R910LPKW:/tmp$ mkdir 1 mark@L-R910LPKW:/tmp$ cd 1 mark@L-R910LPKW:/tmp/1$ vi Dockerfile mark@L-R910LPKW:/tmp/1$ cat Dockerfile FROM busybox mark@L-R910LPKW:/tmp/1$ docker build . STEP 1/1: FROM busybox Resolved "busybox" as an alias (/etc/containers/registries.conf.d/shortnames.conf) Trying to pull docker.io/library/busybox:latest... Getting image source signatures Copying blob a58ecd4f0c86 done Copying config af2c3e96bc done Writing manifest to image destination Storing signatures COMMIT --> af2c3e96bcf af2c3e96bcf1a80da1d9b57ec0adc29f73f773a4a115344b7e06aec982157a33 mark@L-R910LPKW:/tmp/1$ docker image ls --digests |grep af2c3e96bcf docker.io/library/busybox latest sha256:9e2bbca079387d7965c3a9cee6d0c53f4f4e63ff7637877a83c4c05f2a666112 af2c3e96bcf1 3 days ago 5.09 MB mark@L-R910LPKW:/tmp/1$
原因分析
核心原因是本地显示的摘要和ACR返回的摘要,计算的对象完全不同:
- 本地Podman通过
docker image ls --digests显示的摘要,是镜像**配置文件(config)**的哈希值;如果是多架构镜像,则是manifest list的哈希。 - ACR返回的摘要,是镜像推送后存储的**镜像清单(manifest)**的哈希值。
Podman与Docker的摘要显示逻辑存在差异:Podman会提前计算并展示镜像config的哈希作为摘要,而Docker通常仅在镜像推送后才显示manifest的哈希。当镜像推送到ACR时,注册表会基于收到的manifest内容重新计算哈希——这个哈希对应manifest本身,而非本地的config文件,因此两者必然不一致。
另外,ACR作为OCI兼容的注册表,存储的manifest严格遵循OCI规范,其哈希计算基于manifest的JSON内容;而本地Podman生成的manifest格式可能与ACR存储的存在细微差异(比如字段顺序、空白字符),也会导致哈希结果不同,但本质还是计算对象的区别。
内容的提问来源于stack exchange,提问作者mark
相关产品推荐
相关产品推荐

