ubuntu - Docker 在输出中缺少层 ID

标签 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 才能正确显示。

最佳答案

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

来自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.

这就是为什么thaJeztah评论:

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)


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

Nigel Brown 有一篇关于那些“丢失”图像的详细文章。

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

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

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.

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

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.

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

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.

最后:

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.

关于ubuntu - Docker 在输出中缺少层 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35310212/

相关文章:

docker - Ubuntu - 升级 docker-compose 版本

linux - Ubuntu Desktop 20.04 - 没有 VirtualHost 配置的 Apache2 呈现网站

caching - 无法使用 "service varnish restart"重新启动 Varnish

git - Docker镜像git clone错误 “fatal: Not a git repository”

docker - 从 Kubernetes pod 内重新启动主机节点上的 Docker 守护进程

python - 我可以使用哪个Linux发行版docker镜像连接到MySQL v8.0.12?

eclipse - 如何在Eclipse中使用 “Remote Systems” View 探索Docker容器文件系统?

c - 信号 : Segmentation fault (11) in MPI C++

image - Kubernetes 如何从外部存储库拉取镜像?图像存储在哪里?

java - Tomcat 打开文件太多错误(Ubuntu 18.04)