1. 简介
Docker 镜像在容器化应用中扮演着核心角色。但在某些情况下,由于镜像构建历史的复杂性,我们可能难以准确识别某个镜像所使用的基镜像(Base Image)。
本文将介绍几种常见的方法来查看 Docker 镜像的基镜像,包括使用 Docker Scout、dive
工具以及原生的 Docker 命令,并分析每种方法的优缺点和适用场景。
2. 使用 Docker Scout 查看基镜像
✅ Docker Scout 是一种快速、可靠地识别基镜像的方式。
如果你使用的是 Docker Engine,可能需要手动安装 Docker Scout。但如果你使用的是 Docker Desktop,则 Docker Scout 已经预装好了。
我们以 postgres:17.2
镜像为例,使用如下命令查看其基镜像:
$ docker scout quickview postgres:17.2
...
...
Target │ postgres:17.2 │ 3C 35H 16M 36L 1?
digest │ 80cbdc6c3301 │
Base image │ debian:12-slim │ 0C 0H 0M 23L
│
输出显示,postgres:17.2
的基镜像是 debian:12-slim
。
❌ 但 Docker Scout 也有局限性:它依赖于 Docker Hub 的元数据,因此对于本地构建、未上传到 Docker Hub 的镜像,它可能无法正确识别其基镜像。
3. 手动查找基镜像
当 Docker Scout 无法识别基镜像时,我们可以尝试通过分析镜像的构建历史来手动识别。
⚠️ 手动识别容易出错,因为 Docker 镜像是由多个只存储增量变化的层(Layer)组成,而这些层中并不包含关于基镜像的元信息。
识别流程大致如下:
- 使用
docker history
查看镜像构建历史 - 利用
dive
工具获取特定层的 digest - 将 digest 与本地已有镜像的 digest 进行匹配
3.1. 使用 docker history
查看构建历史
我们以 postgres:17.2
为例:
$ docker history postgres:17.2
IMAGE CREATED CREATED BY SIZE COMMENT
80cbdc6c3301 8 days ago CMD ["postgres"] 0B buildkit.dockerfile.v0
<missing> 8 days ago EXPOSE map[5432/tcp:{}] 0B buildkit.dockerfile.v0
<missing> 8 days ago STOPSIGNAL SIGINT 0B buildkit.dockerfile.v0
...
...
...
<missing> 8 days ago RUN /bin/sh -c set -eux; groupadd -r postgr… 4.32kB buildkit.dockerfile.v0
<missing> 2 weeks ago CMD ["bash"] 0B buildkit.dockerfile.v0
<missing> 2 weeks ago ADD rootfs.tar.xz / # buildkit 74.8MB buildkit.dockerfile.v0
通常,基镜像的构建会在某个 CMD
或 ENTRYPOINT
指令之前结束。因此,我们可以关注 ADD rootfs.tar.xz
这一层,作为潜在的基镜像层。
3.2. 使用 dive
获取层的 digest
我们先为 dive
创建一个别名:
$ alias dive='docker run -ti --rm -v /var/run/docker.sock:/var/run/docker.sock wagoodman/dive'
然后运行:
$ dive postgres:17.2
┃ ● Layers ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Cmp Size Command
75 MB FROM blobs
4.3 kB RUN /bin/sh -c set -eux; groupadd -r postgres --gid=999;
│ Layer Details ├───────────────────────────────────────────────────────
Tags: (unavailable)
Id: blobs
Digest: sha256:c3548211b8264f8bfa47a6727043a64f1791b82ac965a284a7ea187e9
我们得到了该层的 digest:sha256:c3548211b8264f8bfa47a6727043a64f1791b82ac965a284a7ea187e9
3.3. 匹配 digest
接下来我们遍历本地所有镜像,查找包含该 digest 的镜像:
$ for image in $(docker images -q)
do
if [[ $(docker inspect $image | grep "sha256:c3548211b8264f8bfa47a6727043a64f1791b82ac965a284a7ea187e971a95e2") ]]
then
docker images | grep $image
fi
done
输出结果中包含两个镜像:
postgres 17.2 80cbdc6c3301 8 days ago 435MB
debian 12-slim 762d928e7cfb 2 weeks ago 74.8MB
我们再检查 debian:12-slim
的 RootFS 层:
$ docker inspect debian:12-slim | jq '.[].RootFS'
{
"Type": "layers",
"Layers": [
"sha256:c3548211b8264f8bfa47a6727043a64f1791b82ac965a284a7ea187e971a95e2"
]
}
✅ 确认 debian:12-slim
是 postgres:17.2
的基镜像。
⚠️ 该方法的局限性在于:如果本地没有该基镜像,就无法匹配成功;如果多个镜像共享相同的层,也可能导致误判。
4. 小结
本文介绍了三种确定 Docker 镜像基镜像的方法:
方法 | 优点 | 缺点 |
---|---|---|
Docker Scout | 快速、准确 | 仅适用于 Docker Hub 上的镜像 |
dive + docker history + digest 匹配 |
适用于本地镜像 | 操作复杂、易出错、依赖本地镜像存在 |
原生命令组合 | 无需额外工具 | 精度低、过程繁琐 |
✅ 推荐优先使用 Docker Scout,除非你需要分析本地构建的私有镜像。
⚠️ 手动识别方式应作为最后的备选手段,因为它依赖于本地镜像存在,且容易误判。
如果你在 CI/CD 或镜像构建过程中需要自动化识别基镜像,建议在构建时显式记录基镜像信息,避免后续查找的麻烦。