正如您在issue 20131 中提到的,这可能是新的docker 1.10 content addressability migration 的结果
来自Docker blog post:
从 v1.10 开始,我们彻底改变了 Docker 寻址磁盘上图像数据的方式。
以前,每个图像和图层都使用随机分配的 UUID。
在 1.10 中,我们使用 ID 实现了内容寻址方法,基于图像和图层数据的安全哈希。
这就是为什么thaJeztah cmets:
我认为这是意料之中的;内容寻址存储不再使用“父”图像将图像层链接在一起。
新拉取的图像也不再显示中间图像(这些“丢失”的图像只会显示在主机上存在但已迁移到新存储的图像)
2016 年 6 月更新(3 个月后)
Nigel Brown 有一篇关于那些“丢失”图像的详细文章。
Explaining Docker Image IDs
在 Docker 映像构建过程中创建一个层或“差异”,并在容器中运行命令时产生结果,这些命令会生成新的或修改的文件和目录。
这些新的或修改的文件和目录被“提交”为一个新层。
从历史上看(Docker v1.10 之前),每次由于提交操作而创建新层时,Docker 也会创建相应的镜像,该镜像由随机生成的 256 位 UUID 标识,通常称为图像 ID
改变的一大驱动力来自于缺乏检测图像内容在向注册表推送或从注册表拉取期间是否被篡改的方法,例如@987654328 @。这导致了整个社区的 robust criticism,并导致了一系列变化,最终形成了内容可寻址 ID。
从 Docker v1.10 开始,图像和图层通常不再是同义词。
取而代之的是,图像直接引用一个或多个层,这些层最终有助于派生容器的文件系统。
层现在由摘要标识,其形式为 algorithm:hex;
Docker 映像现在包含一个配置对象,该对象(除其他外)包含层摘要的有序列表,这使 Docker 引擎能够参考层摘要而不是父映像来组装容器的文件系统。
因此,当从注册表中提取 Docker 映像并使用 docker history 命令显示其内容时,输出会提供类似于以下内容的内容:
$ docker history swarm
IMAGE CREATED CREATED BY SIZE COMMENT
c54bba046158 9 days ago /bin/sh -c #(nop) CMD ["--help"] 0 B
<missing> 9 days ago /bin/sh -c #(nop) ENTRYPOINT &{["/swarm"]} 0 B
<missing> 9 days ago /bin/sh -c #(nop) VOLUME [/.swarm] 0 B
<missing> 9 days ago /bin/sh -c #(nop) EXPOSE 2375/tcp 0 B
<missing> 9 days ago /bin/sh -c #(nop) ENV SWARM_HOST=:2375 0 B
<missing> 9 days ago /bin/sh -c #(nop) COPY dir:b76b2255a3b423981a 0 B
<missing> 9 days ago /bin/sh -c #(nop) COPY file:5acf949e76228329d 277.2 kB
<missing> 9 days ago /bin/sh -c #(nop) COPY file:a2157cec2320f541a 19.06 MB
IMAGE 字段中的 <missing> 值用于除图像的一层之外的所有图层,具有误导性且有点令人遗憾。它传达了错误的建议,但没有错误,因为图层不再与相应的图像和 ID 同义。
我认为离开会更合适字段空白。
此外,图像 ID 似乎与最上层相关联,但实际上,图像 ID 并不“属于”任何层。相反,这些层共同属于图像,并提供其文件系统定义。
但是(本地与远程图像):
Docker 主机上本地构建的映像的处理方式略有不同。
本地构建的图像的通用内容保持不变 - 它是一个包含配置项的配置对象,包括层摘要的有序列表。
但是,当在本地 Docker 主机上构建映像期间提交层时,会同时创建一个“中间”映像。
就像所有其他图像一样,它有一个配置项,该配置项是要合并为图像一部分的层摘要列表,其 ID 或摘要包含配置对象的哈希。中间图像没有用名称标记,但它们确实有一个“父”键,其中包含父图像的 ID。
中间图像和对父图像的引用的目的是方便使用Docker的build cache。
$ docker history jbloggs/my_image:latest
IMAGE CREATED CREATED BY SIZE COMMENT
26cca5b0c787 52 seconds ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin/b 0 B
97e47fb9e0a6 52 seconds ago /bin/sh -c apt-get update && apt-get inst 16.98 MB
1742affe03b5 13 days ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B
<missing> 13 days ago /bin/sh -c #(nop) ADD file:5d8521419ad6cfb695 125.1 MB
在此示例中,顶部两层是在本地映像构建期间创建的,而底部层来自构建的基础映像(例如 Dockerfile instruction FROM debian)。
我们可以使用docker inspect 命令查看与图像相关的层摘要:
docker history 命令显示图像有四层,但docker inspect 建议只有三层。
这是因为两条CMD 指令为图像生成元数据,不添加任何内容,因此“差异”为空。
摘要 5f70bf18a08a 是一个空层的 SHA256 哈希,由两个相关层共享。
当本地构建的镜像被推送到注册表时,只有叶子镜像连同其组成层一起上传,随后由另一个 Docker 主机拉取不会产生任何中间父镜像.
这是因为一旦映像通过注册表提供给不同 Docker 主机上的其他潜在用户,它实际上变为只读,并且不再需要支持构建缓存的组件。
代替图像 ID,<missing> 被插入到历史输出中。
最后:
Docker 用于 Docker 主机上的“差异”层的摘要包含差异的 tar 归档内容的 sha256 哈希值。
在将层作为推送的一部分上传到注册表之前,它被压缩以提高带宽效率。还创建了一个清单来描述图像的内容,它包含压缩层内容的摘要。 因此,清单中各层的摘要与其未压缩状态下生成的摘要不同。