如何查看docker history中各镜像层的压缩大小?
关联Docker镜像构建历史与清单中压缩层大小的方法
Docker及dive等工具能展示镜像层的磁盘占用大小,但拉取镜像时层以压缩形式传输,因此更关注各层的压缩大小(即拉取所需带宽)。但docker history输出的构建步骤与镜像清单中的层并非一一对应,比如ubuntu:22.04的历史显示6个步骤,清单却只有1个层;nvcr.io/nvidia/tensorrt:24.08-py3的历史有100步,清单仅36个层,以下是原因及关联方法:
为什么两者数量不一致?
docker history展示的是镜像构建的每一步操作,包括LABEL、ARG、CMD等元数据操作,这些操作仅修改镜像配置,不会生成新的磁盘层(大小为0B),也不会出现在镜像清单的layers中;- 镜像清单的
layers仅包含实际存储数据的层(即拉取时需要传输的压缩层); - 若构建时使用
--squash参数合并层,或复用基础镜像的层,也会导致历史步骤数与清单层数差异。
实例对比
1. docker history展示的构建步骤(解压后磁盘大小)
$ docker pull --platform linux/amd64 ubuntu:22.04 $ docker history ubuntu:22.04 IMAGE CREATED CREATED BY SIZE COMMENT cc934a90cd99 11 days ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B <missing> 11 days ago /bin/sh -c #(nop) ADD file:433cf0b8353e08be3… 77.9MB <missing> 11 days ago /bin/sh -c #(nop) LABEL org.opencontainers.… 0B <missing> 11 days ago /bin/sh -c #(nop) LABEL org.opencontainers.… 0B <missing> 11 days ago /bin/sh -c #(nop) ARG LAUNCHPAD_BUILD_ARCH 0B <missing> 11 days ago /bin/sh -c #(nop) ARG RELEASE 0B
这里77.9MB是层解压后的磁盘大小,而非拉取时的压缩大小。
2. 镜像清单展示的压缩层大小
$ docker manifest inspect --verbose ubuntu:22.04 { "Ref": "docker.io/library/ubuntu:22.04@sha256:a76d0e9d99f0e91640e35824a6259c93156f0f07b7778ba05808c750e7fa6e68", "Descriptor": { "mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "sha256:a76d0e9d99f0e91640e35824a6259c93156f0f07b7778ba05808c750e7fa6e68", "size": 424, "platform": { "architecture": "amd64", "os": "linux" } }, "OCIManifest": { "schemaVersion": 2, "mediaType": "application/vnd.oci.image.manifest.v1+json", "config": { "mediaType": "application/vnd.oci.image.config.v1+json", "size": 2297, "digest": "sha256:cc934a90cd99a939f3922f858ac8f055427300ee3ee4dfcd303c53e571d0aeab" }, "layers": [ { "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", "size": 29532365, "digest": "sha256:30a9c22ae099393b0131322d7f50d8a9d7cd06c5e518cd27a19ac960a4d0aba3" } ] } }
清单中layers[0].size(约29.5MB)就是拉取该层的压缩大小。
如何关联两者?
方法1:通过docker inspect查看镜像配置的历史记录
镜像配置的History字段包含了所有构建步骤,其中带layer字段的条目对应清单中的实际层,可通过digest关联:
docker inspect ubuntu:22.04 --format '{{json .Config.History}}' | python3 -m json.tool
输出示例(截取关键部分):
[ { "created": "2024-08-01T23:27:38.612264215Z", "created_by": "/bin/sh -c #(nop) ARG RELEASE", "empty_layer": true }, { "created": "2024-08-01T23:27:38.445920515Z", "created_by": "/bin/sh -c #(nop) ADD file:433cf0b8353e08be3... in / ", "layer": "sha256:30a9c22ae099393b0131322d7f50d8a9d7cd06c5e518cd27a19ac960a4d0aba3" }, { "created": "2024-08-01T23:27:38.612264215Z", "created_by": "/bin/sh -c #(nop) CMD [\"/bin/bash\"]", "empty_layer": true } ]
这里layer字段的digest和清单中layers[0].digest完全一致,即可将docker history中的ADD步骤与清单中的压缩层关联,得到该步骤对应的拉取大小。
方法2:使用skopeo工具直接查看
skopeo可直接输出镜像的完整元数据,同时包含构建历史和层信息:
skopeo inspect --raw docker://ubuntu:22.04 | python3 -m json.tool
通过config.history找到对应步骤的layer digest,再匹配layers中的条目即可获取压缩大小。
内容的提问来源于stack exchange,提问作者sciencectn
相关产品推荐
相关产品推荐

