Docker在输出中缺少图层ID [英] Docker missing layer IDs in output

查看:134
本文介绍了Docker在输出中缺少图层ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚在Ubuntu上使用官方指南完成了Docker的全新安装:


变化的主要驱动力来自缺少检测图像的内容是否在从注册表推送或从注册表中拉扯的情况下被篡改的方式,例如


所以,当一个Docker的图像从一个注册表中被拉出来,并且docker history命令被用来显示它的内容时,输出提供类似的东西:




  $ docker history swarm 
由SIZE COMMENT创建的IMAGE CREATED创建
c54bba046158 9天前/ bin / sh -c#(nop)CMD [ - -help] 0 B
< missing> 9天前/ bin / sh -c#(nop)ENTRYPOINT& {[/ swarm]} 0 B
< missing> 9天前/ bin / sh -c#(nop)VOLUME [/.swarm] 0 B
< missing> 9天前/ bin / sh -c#(nop)EXPOSE 2375 / tcp 0 B
< missing> 9天前/ bin / sh -c#(nop)ENV SWARM_HOST =:2375 0 B
< missing> 9天前/ bin / sh -c#(nop)COPY dir:b76b2255a3b423981a 0 B
< missing> 9天前/ bin / sh -c#(nop)COPY文件:5acf949e76228329d 277.2 kB
< missing> 9天前/ bin / sh -c#(nop)COPY文件:a2157cec2320f541a 19.06 MB




IMAGE 中的< missing> 值,除了一个形象,误导,有点不幸。它传达了一个错误的建议,但是没有错误,因为图层不再是相应的图像和ID 的代名词。

我认为这会更多适合将该字段留空



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


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

$ b $在Docker主机上的b

本地构建的映像的处理方式略有不同

本地构建的映像的通用内容保持不变 - 它是一个包含配置项的配置对象,包括层次摘要的有序列表。



但是,当在本地Docker主机上构建映像期间提交图层时,中间图像同时创建

就像所有其他图像一样,它具有一个配置项,它是要作为图像一部分并入的图层摘要的列表,其ID或摘要包含配置对象的散列。中间图像没有标记名称,但它们确实有一个父键,其中包含父图像的ID。



中间体的目的图像和对父图像的引用,是便于使用Docker的构建缓存




  $ docker history jbloggs / my_image:最新
图像创建由SIZE注释
26cca5b0c787 52秒前/ bin / sh -c#(nop)CMD [/ bin / sh-c/ bin / b 0 B
97e47fb9e0a6 52秒前/ bin / sh -c apt-get更新&& apt-get inst 16.98 MB
1742affe03b5 13天前/ bin / sh -c#(nop)CMD [/ bin / bash] 0 B
< missing> 13天前/ bin / sh -c#(nop)ADD文件:5d 8521419ad6cfb695 125.1 MB




在这个例子中,本地图像构建,而底层来自构建的基本图像(例如, Dockerfile指令 FROM debian )。



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



docker history 命令将图像显示为四层,但 docker inspect 建议只有三层。

这是因为两个 CMD 指令为图像生成元数据,不要添加任何内容,因此 diff'为空。

摘要 5f70bf18a08a 是空层的SHA256散列,由相关的两个层共享。 p>

将本地制作的图像推送到注册表时,只有与其组成图层一起上传的叶子图像,以及另一个Docker主机的后续拉不会产生任何中间父图片



这是因为一旦图像通过注册表向不同Docker主机上的其他潜在用户提供,它有效地变为只读,并且不再需要支持构建缓存的组件。

而不是图像ID,< missing> 被插入历史输出中。


最后:


Docker在Docker主机上用于图层diff的摘要包含diff的tar存档内容的sha256哈希值。

在图层作为推送的一部分上传到注册表之前,它被压缩以实现带宽效率。还创建了一个清单来描述图像的内容,并且包含压缩图层内容的摘要。 因此,清单中的图层的摘要与在未压缩状态下生成的摘要不同。



I just did a fresh install of Docker on Ubuntu using the official guidelines: https://docs.docker.com/engine/installation/linux/ubuntulinux/

When I pull an image using "sudo docker pull ubuntu" and then "sudo docker history ubuntu" it returns missing layer IDs in the columns. Using the documentation example ( https://docs.docker.com/engine/reference/commandline/history/ ) my output is:

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

and so on. Only the base layer ID shows, the rest is "missing". I tried installing on another Ubuntu machine connected to a different network and it has the same problem for any image that I download.

Does someone know what's causing this or able to help me fix it? I rely on this layer ID since I'm gathering some statistics on the reusability of layers so I need this ID to show correctly.

Thank you

解决方案

As mentioned in your issue 20131, this could be the consequence of the new docker 1.10 content addressability migration

From the Docker blog post:

Starting from v1.10 we completely change the way Docker addresses the image data on disk.
Previously, every image and layer used a randomly assigned UUID.
In 1.10 we implemented a content addressable method using an ID, based on a secure hash of the image and layer data.

That is why thaJeztah comments:

I think this is expected; the content-addressable storage no longer uses "parent" images to chain the image-layers together.
Newly pulled images also no longer will show the intermediate images (these "missing" images will only be shown for images that were present on the host, but have been migrated to the new storage)


Update June 2016 (3 months later)

Nigel Brown has a detailed article about those "missing" images.

Explaining Docker Image IDs

A layer or 'diff' is created during the Docker image build process, and results when commands are run in a container, which produce new or modified files and directories.
These new or modified files and directories are 'committed' as a new layer.

Historically (pre Docker v1.10), each time a new layer was created as a result of a commit action, Docker also created a corresponding image, which was identified by a randomly generated 256-bit UUID, usually referred to as an image ID

One of the big drivers for change, came from the lack of a means of detecting whether an image's contents had been tampered with during a push to or pull from a registry, such as the Docker Hub. This led to robust criticism from the community at large, and led to a series of changes, culminating in content addressable IDs.

Since Docker v1.10, generally, images and layers are no longer synonymous.
Instead, an image directly references one or more layers that eventually contribute to a derived container's filesystem.

Layers are now identified by a digest, which takes the form algorithm:hex;

A Docker image now consists of a configuration object, which (amongst other things) contains an ordered list of layer digests, which enables the Docker Engine to assemble a container's filesystem with reference to layer digests rather than parent images.

So, when a Docker image is pulled from a registry, and the docker history command is used to reveal its contents, the output provides something similar to:

$ 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  

The <missing> value in the IMAGE field for all but one of the layers of the image, is misleading and a little unfortunate. It conveys the suggestion of an error, but there is no error as layers are no longer synonymous with a corresponding image and ID.
I think it would have been more appropriate to have left the field blank.

Also, the image ID appears to be associated with the uppermost layer, but in fact, the image ID doesn't 'belong' to any of the layers. Rather, the layers collectively belong to the image, and provide its filesystem definition.

But (local vs. remote images):

locally built images on a Docker host are treated slightly differently.
The generic content of an image built locally remains the same - it is a configuration object containing configuration items, including an ordered list of layer digests.

However, when a layer is committed during an image build on a local Docker host, an 'intermediate' image is created at the same time.
Just like all other images, it has a configuration item which is a list of the layer digests that are to be incorporated as part of the image, and its ID or digest contains a hash of the configuration object. Intermediate images aren't tagged with a name, but, they do have a 'Parent' key, which contains the ID of the parent image.

The purpose of the intermediate images and the reference to parent images, is to facilitate the use of Docker's 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  

In this example, the top two layers are created during the local image build, whilst the bottom layers came from the base image for the build (e.g. Dockerfile instruction FROM debian).

We can use the docker inspect command to review the layer digests associated with the image:

The docker history command shows the image as having four layers, but docker inspect suggests just three layers.
This is because the two CMD instructions produce metadata for the image, don't add any content, and therefore the 'diff' is empty.
The digest 5f70bf18a08a is the SHA256 hash of an empty layer, and is shared by both of the layers in question.

When a locally built image is pushed to a registry, it is only the leaf image that is uploaded along with its constituent layers, and a subsequent pull by another Docker host will not yield any intermediate parent images.

This is because once the image is made available to other potential users on different Docker hosts via a registry, it effectively becomes read-only, and the components that support the build cache are no longer required.
Instead of the image ID, <missing> is inserted into the history output in its place.

Finally:

The digests that Docker uses for layer 'diffs' on a Docker host, contain the sha256 hash of the tar archived content of the diff.
Before the layer is uploaded to a registry as part of a push, it is compressed for bandwidth efficiency. A manifest is also created to describe the contents of the image, and it contains the digests of the compressed layer content. Consequently, the digests for the layers in the manifest are different to those generated in their uncompressed state.

这篇关于Docker在输出中缺少图层ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆