同一个 tag 为什么会指向不同的内容?这篇用本机构建的镜像实际看:镜像 ID 和 digest 是什么关系,docker tag 和重新 docker build 对旧镜像的处理有什么不同,name@digest 在本机什么时候找得到,以及“同一个 Dockerfile 是不是同一个镜像”。
构建 v1 并命名 bwlab-c13:a:ID = f5b5f81ecbb1…(完整形式 sha256: 加 64 位十六进制,共 71 个字符) .Id 和 .Descriptor.digest 相同吗?True(这个镜像存储里镜像 ID 就是顶层 manifest 的摘要) RepoDigests = ["bwlab-c13@sha256:f5b5f81ecbb1c4b918634afedde042d92d3a5c90e3dee4cccf1bb082bc27f516"](没有推送过) 再构建 v2 命名为 bwlab-c13:b:ID = 1d96e82a084a…
构建 v1 命名为 bwlab-c13:a,.Id 与 .Descriptor.digest 是同一个值;RepoDigests 里即使没推送过也有一项 bwlab-c13@sha256:…。这是 containerd 镜像存储下的表现;换成经典的存储驱动,ID 的含义是否一样,本文没有测。
docker tag bwlab-c13:b bwlab-c13:a → 退出码 0 现在 bwlab-c13:a 的 ID = 1d96e82a084a…,和 bwlab-c13:b 相同吗?True docker image ls -a 里出现的 <untagged> 镜像:['f5b5f81ecbb1'](旧 v1 的 ID 是 f5b5f81ecbb1) 按旧 ID 运行 docker run --pull=never f5b5f81ecbb1 → 退出码 0;输出:v1
docker tag bwlab-c13:b bwlab-c13:a 之后,两个名字指向同一个 ID;原来 a 指向的 v1 变成 <untagged>,但镜像还在,docker run --pull=never 加上旧 ID 能跑出 v1。同一个 tag 在不同时间指向不同内容,就是这么来的。
docker run --pull=never bwlab-c13@sha256:f5b5f81ecbb1… → 退出码 125;docker: Error response from daemon: No such image: bwlab-c13@sha256:f5… docker run --pull=never bwlab-c13@sha256:1d96e82a084a… → 退出码 0;输出:v2 引用一个不存在的摘要 → 退出码 125;docker: Error response from daemon: No such image: bwlab-c13@sha256:000000000000000000000000000000000000000000
被挪走名字的 v1,用 bwlab-c13@sha256:f5b5… 引用,--pull=never 下报 No such image(退出码 125);当前叫 bwlab-c13 的 v2 用它自己的摘要引用就能运行。本机的 name@digest 解析要求这个镜像此刻还带着这个名字。摘要在仓库里“钉住”内容的作用,本文没有实验(需要 registry)。
同一个 tag bwlab-c13:c 先后构建两次:ID 8656f6b6bd5f → 1c31d8e2e739 按第一次的 ID 运行 → 退出码 125;docker: Error response from daemon: No such image: 8656f6b6bd5f:latest docker image ls -a 里的 <untagged>:['f5b5f81ecbb1']
重新构建同一个 tag 和 docker tag 挪名字不一样:这个环境里旧镜像没有留下 <untagged>,按旧 ID 运行也找不到。我没有查是哪一层把它删掉的,只记录观察到的结果。
两次构建的镜像 ID:886d739dd530 和 cfd9225cfd6e;相同吗?False RootFS.Layers 共 2 层;alpine 基础层相同吗?True;RUN 产生的那层相同吗?False
两次 --no-cache 构建同样的 Dockerfile,镜像 ID 不同,alpine 基础层相同,RUN 产生的层不同。要得到可复现的构建,需要额外控制时间戳之类的输入(本文没有测怎么做)。
默认(带 provenance 证明):三次构建的 ID = ['f36ba2a729ba', '2ef9bec6124a', '4ddb08e30de0'];ID 互不相同的有 3 个;层(RootFS.Layers)都相同吗?True --provenance=false --sbom=false:三次构建的 ID = ['af13472dcb8a', 'af13472dcb8a', 'af13472dcb8a'];ID 互不相同的有 1 个;层(RootFS.Layers)都相同吗?True
三次全缓存的构建,默认得到 3 个不同的镜像 ID,但层完全一致;加上 --provenance=false --sbom=false 后三次 ID 相同。结合之前 c11 看到的 attestation manifest,我推测是附带的构建证明让顶层摘要变了,没有单独验证是 provenance 还是 sbom 起作用。想用摘要比较两个镜像“内容是否相同”时,这点要小心。