Docker缺less输出中的图层ID

我刚刚在Ubuntu上使用官方指南进行了全新的Docker安装: https : //docs.docker.com/engine/installation/linux/ubuntulinux/

当我使用“sudo docker pull ubuntu”然后“sudo docker history ubuntu”来拖动图像时,它将返回列中缺失的图层ID。 使用文档示例( https://docs.docker.com/engine/reference/commandline/history/ )我的输出是:

IMAGE CREATED CREATED BY SIZE COMMENT 3e23a5875458 8 days ago /bin/sh -c #(nop) ENV LC_ALL=C.UTF-8 0 B "missing" 8 days ago /bin/sh -c dpkg-reconfigure locales && loc 1.245 MB "missing" 8 days ago /bin/sh -c apt-get update && apt-get install 338.3 MB 

等等。 只有基础层ID显示,其余的是“失踪”。 我尝试在另一台连接到不同networking的Ubuntu机器上进行安装,并且对于我下载的任何图像都有同样的问题。

有人知道是什么原因造成的,还是能够帮助我解决这个问题? 我依靠这个图层ID,因为我正在收集关于图层的可重用性的一些统计信息,所以我需要这个ID来正确显示。

谢谢

如您在20131号问题中提到的,这可能是新Docker 1.10内容可寻址性迁移的结果

从Docker博客文章 :

从v1.10开始,我们彻底改变了Docker解决磁盘映像数据的方式。
以前,每个图像和图层都使用随机分配的UUID。
在1.10中,我们基于图像和图层数据的安全散列,使用ID实现了内容可寻址方法。

这就是为什么thaJeztah评论:

我认为这是预料之中的; 内容寻址存储不再使用“父”图像将图像层链接在一起。
新拉的图像也不再显示中间图像(这些“丢失”的图像将只显示在主机上,但已被迁移到新的存储的图像)


2016年6月更新(3个月后)

奈杰尔布朗有一个关于那些“失踪”图像的详细文章。

解释Docker镜像ID

在Docker镜像构建过程中会创建一个图层或“diff”,并在命令在容器中运行时生成新的或已修改的文件和目录。
这些新的或修改过的文件和目录作为一个新层“提交”。

从历史上看(Docker v1.10版本),每次创建新图层时,Docker也会创建一个相应的图像,这个图像由一个随机生成的256位UUID来标识,通常被称为图像ID

http://www.windsock.io/content/images/2016/06/Historical_Image.png

其中一个重要的驱动力来自于缺乏检测图像内容是否在从注册表 (例如Docker Hub) 推入或拉出的过程中被篡改的手段 。 这引起了整个社区的强烈批评 ,导致了一系列变化,最终导致了内容可寻址ID。

从Docker v1.10开始,一般来说, 图像和图层不再是同义词
相反,图像直接引用一个或多个最终有助于派生容器的文件系统的图层。

图层现在通过一个摘要进行标识,其形式算法如下:hex;

一个Docker镜像现在由一个配置对象组成,其中包含一个层次摘要的有序列表,它使Docker引擎能够参照层摘要而不是父图像组装一个容器的文件系统。

http://www.windsock.io/content/images/2016/06/Content_Addressable_Image-2.png

所以,当一个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>值对于IMAGE中除图层之外的所有图层都是有误导性的,有点不幸。 它表达了一个错误的建议,但没有错误,因为层不再是对应的图像和ID的同义词
我觉得把这个领域留空是比较合适的

此外,图像ID似乎与最上层相关联,但实际上,图像ID不属于任何层。 相反,这些图层共同属于图像,并提供其文件系统定义。

但是(本地和远程图像):

Docker主机上本地构建的映像处理方式稍有不同
本地构建的图像的通用内容保持不变 – 它是一个包含配置项目的配置对象,包括图层摘要的有序列表。

但是,如果在本地Docker主机上构建图像期间提交图层,则会同时创建“中间”图像
就像所有其他图像一样,它有一个配置项,它是要作为图像一部分合并的图层摘要列表,其ID或摘要包含配置对象的哈希值。 中间图像没有标记名称,但是它们有一个“父”键,其中包含父图像的ID。

中间图像的目的和对父图像的引用是为了方便使用Docker的构建缓存

 $ 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指令FROM debian )。

我们可以使用docker inspect命令来查看与图像关联的图层摘要:

docker history命令显示图像有四层,但docker inspect建议只有三层。
这是因为两个CMD指令为图像产生元数据,不添加任何内容,因此“差异”是空的。
摘要5f70bf18a08a是空白图层的SHA256哈希,并且被所讨论的两个图层共享。

当本地构建的图像被推送到注册表时,它只是与其组成层一起上传的叶形图像,而由另一个Docker主机进行的后续拉动将不会产生任何中间父图像

这是因为一旦图像通过注册表提供给不同Docker主机上的其他潜在用户,它就会变得只读,支持构建缓存的组件不再需要。
<missing>插入到历史输出中,而不是图像ID。

最后:

Docker在Docker主机上使用层“差异”的摘要包含diff的tar归档内容的sha256散列。
在将图层作为推送的一部分上载到注册表之前,会将其压缩以提高带宽效率。 还会创建一个清单来描述图像的内容,并包含压缩图层内容的摘要。 因此,清单中各层的摘要与其未压缩状态中生成的摘要不同。