跳到正文

Docker 镜像分层分析

Docker Image Explorer

打开导出的镜像 tar 包,逐层显示构建命令、大小,以及这一层增删了哪些文件。

打开一个导出的 Docker 或 OCI 镜像,显示每一层实际包含什么——它的大小、产生它的 Dockerfile 步骤、它添加的文件,以及它从下层删除的文件。这就是你弄清一个镜像为什么有三百 MB 的办法。

🔒 完全在你的浏览器里运行dockerocilayersinspect

放进导出的镜像(.tar)

来自 `docker save image:tag -o image.tar` 或 podman save。在这个标签页里解析,不会上传任何东西。

既能打开 docker save 的 tar,也能打开 OCI 镜像布局,并按配置里的 history 把每一层对上它的 Dockerfile 步骤(标着 empty_layer 的步骤——ENV、CMD、LABEL——不产生层,会单独列出)。删除按 OCI 的 whiteout 约定来读:一条 .wh.name 记录会把下面各层里的 name 去掉——文件其实还在下层,字节也照样占着。

怎么用

  1. 导出镜像

    `docker save image:tag -o image.tar`,或者等价的 `podman save`。OCI 镜像布局也可以。

  2. 把 tar 拖进来

    它在这个标签页的 worker 里解析。什么都不上传,这很要紧,因为镜像 tar 里装着你整个文件系统。

  3. 打开大的层

    每一行用一根条显示它的大小和 Dockerfile 步骤。展开一行会列出它添加的最大文件,并分别列出它删除了什么、隐藏了什么。

常见问题

我在后面的 RUN 里删了文件——为什么镜像还是那么大?

因为删除本身就是一层。OCI 的 whiteout 约定写一个 `.wh.name` 条目把下层的 `name` 藏起来;原文件还在,还在被分发,还在被计入。在创建它的同一个 `RUN` 里删除,或者用多阶段构建。

为什么有些 Dockerfile 步骤没有层?

ENV、CMD、LABEL、EXPOSE 之类只改配置,不改文件系统,所以镜像历史把它们标为 `empty_layer`。这里把它们单独列出来,这样层的编号仍然和真正占字节的东西对得上。

它能直接从仓库打开镜像吗?

不能——它只读本地的 tar。拉取意味着这个页面要向你的镜像仓库认证,那是一个威胁模型不同的另一种工具。`docker save` 就是一条命令的事。

这里的大小和 `docker images` 对不上。

它们量的是不同的东西。`docker images` 报告存储驱动去重共享层之后的磁盘占用;这里报告的是导出文件里每一层未压缩的内容。两者都是真的;第二个才是告诉你一次 `docker pull` 要传多少的那个。

可以从这些接进来

接下来

这些工具吃得下当前工具的产出,结果可以直接送过去。