Docker在输出中缺少图层ID

时间:2016-02-10 08:36:02

标签: ubuntu docker

我刚刚使用官方指南在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显示,其余的是"缺少"。我尝试在连接到不同网络的另一台Ubuntu机器上进行安装,对于我下载的任何图像都有同样的问题。

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

谢谢

1 个答案:

答案 0 :(得分:22)

正如您issue 20131中所述,这可能是新docker 1.10 content addressability migration

的后果

来自Docker blog post

  

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

这就是thaJeztah评论的原因:

  

我认为这是预期的;内容可寻址存储不再使用" parent"图像将图像层链接在一起。
  新推出的图像也不再显示中间图像(这些"缺失"图像仅针对主机上存在的图像显示,但已迁移到新存储中)

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

Nigel Brown 有一篇关于那些"缺失"的详细文章。图像。

Explaining Docker Image IDs

  

一层或者一个'差异'在Docker镜像构建过程中创建,并在命令在容器中运行时生成结果,该容器生成新的或修改的文件和目录。
  这些新的或修改过的文件和目录已经被提交了#39;作为一个新的层。

     

历史上(前Docker v1.10),每次由于提交操作而创建新图层时,Docker还会创建相应的图像,该图像由随机生成的256位UUID标识,通常称为图像ID

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

  

改变的一个重要驱动因素来自缺乏检测图像内容在推送或从注册表中拉出时是否被篡改的方法,作为Docker Hub。这导致整个社区的 robust criticism ,并导致一系列更改,最终导致内容可寻址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  
  

<missing>字段中IMAGE字段除了图像的其中一个图层以外的所有值都是误导性的,有点不幸。它传达了错误的建议,但没有错误,因为图层不再是相应图像和ID的同义词
  我认为将字段留空会更合适。

     

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

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

  

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

     

但是,如果在本地Docker主机上构建映像期间提交了一个图层,那么“&#39;图像同时创建
  与所有其他图像一样,它具有配置项,该配置项是要作为图像的一部分合并的层摘要的列表,并且其ID或摘要包含配置对象的散列。中间图像没有用名称标记,但是,他们确实有一个“父母”。 key,包含父图像的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用于图层差异的摘要&#39;在Docker主机上,包含差异的tar存档内容的sha256哈希   在将图层作为推送的一部分上载到注册表之前,会对其进行压缩以提高带宽效率。还会创建清单来描述图像的内容,并且它包含压缩图层的摘要内容。 因此,清单中图层的摘要与未压缩状态下生成的摘要不同。