我有一个docker映像,我想找出它是从哪个映像创建的。当然有多层,但是我想找出最后一张图像(dockerfile中该图像的FROM语句)?
我尝试使用/var/www/html
和docker image history
,但我在那里找不到此信息。
我尝试使用以下命令,但它给我一条错误消息
docker image inspect
这是我收到的错误消息
alias dfimage="sudo docker run -v /var/run/docker.sock:/var/run/docker.sock --rm xyz/mm:9e945ff"
dfimage febae8978318
答案 0 :(得分:4)
使用简便的方法
docker image history deno
以上命令将为您提供这样的输出
然后仅查看IMAGE列,并获取位于第一个a24bb4013296
上方的图像<missing>
的图像ID
然后就做
对于Linux
docker image ls | grep a24bb4013296
对于Windows
docker image ls | findstr a24bb4013296
这将为您提供基本图像名称
答案 1 :(得分:1)
您可以使用此答案中建议的方法: https://stackoverflow.com/a/53841690/3691891
首先,拉动chenzj/dfimage
:
docker pull chenzj/dfimage
获取图像的ID:
docker images | grep <IMAGE_NAME> | awk '{print $3}'
用图像名称替换<IMAGE_NAME>
。将此ID用作
chenzj/dfimage
的参数:
docker run -v /var/run/docker.sock:/var/run/docker.sock --rm chenzj/dfimage <IMAGE_ID>
如果您觉得太难了,只需拉chenzj/dfimage
图像,然后
使用以下docker-get-dockerfile.sh
脚本:
#!/usr/bin/env sh
if [ "$#" -lt 1 ]
then
printf "Image name needed\n" >&2
exit 1
fi
image_id="$(docker images | grep "^$1 " | awk '{print $3}')"
if [ -z "$image_id" ]
then
printf "Image not found\n" >&2
exit 2
fi
docker run -v /var/run/docker.sock:/var/run/docker.sock --rm chenzj/dfimage "$image_id"
您需要传递图像名称作为参数。用法示例:
$ ./docker-get-dockerfile.sh alpine
FROM alpine:latest
ADD file:fe64057fbb83dccb960efabbf1cd8777920ef279a7fa8dbca0a8801c651bdf7c in /
CMD ["/bin/sh"]
答案 2 :(得分:0)
这些信息实际上并不存在。图像将包含其父级的层,但没有简单方法可以将层摘要反转回 FROM
语句,除非您碰巧拥有(或能够弄清楚) ) 包含这些图层的图像。
如果您手头有父图像(或可以找到它们),您可以通过交叉引用图层来推断您的图像用于其 FROM 语句(或祖先)的哪些图像。
>假设您的图像 FOO
包含图层 1 2 3 4 5 6
。如果您的系统上有另一个图像 BAR
包含层 1 2 3
,您可以推断图像 BAR
是图像 FOO
的祖先——即FROM BAR
将在其层次结构中的某个点使用)。
进一步假设您有另一个图像 BAZ
,其中包含图层 1 2 3 4 5
。您可以推断图像 BAZ
在其祖先中具有图像 BAR
,并且图像 A
继承自图像 BAZ
(因此间接来自 BAR
)。>
由此,您可以推断出这些图像的 dockerfiles 的信息可能如下所示:
# Dockerfile of image BAR
FROM scratch
# layers 1 2 and 3
COPY ./one /
COPY ./two /
COPY ./three /
# Dockerfile of Image BAZ
FROM BAR
RUN echo "this makes layer 4" > /four
RUN echo "this makes layer 5" > /five
# Dockerfile of image FOO
FROM BAZ
RUN echo "this makes layer 6" > /six
您可以通过查看每个图像的 docker image history
来获得确切的命令。
然而,这里要记住的一件重要事情是 docker 标签是可变的;维护者制作新图像并将标签移动到这些图像上。因此,如果您今天使用 FROM python:3.8.1
构建了一个映像,它所包含的层将与几周前您使用相同的 FROM
行构建的映像不同。您需要 SHA256 摘要以确保您使用的是完全相同的图像。
现在我们了解了识别图像及其基础背后的理论,让我们用一个真实的例子来实践它。
注意:因为我使用的标签会随着时间的推移而改变(参见上面的 RE:标签可变性),我将使用 SHA256 摘要来提取本示例中的图像,以便此答案的查看者可以复制它。< /p>
假设我们有一个特定的图像,我们想找到它的基础。我们将在此处使用官方 maven
图像。
首先,我们来看看它的层。
# maven:3.6-jdk-11-slim at time of writing, on my platform
IMAGE="docker.io/maven@sha256:55f1c145a04e01706233d68fe0b6b20bf76f765ab32f3fe6e29c8ef933917af6"
docker pull $IMAGE
docker image inspect $IMAGE | jq -r '.[].RootFS.Layers[]'
这将输出层:
sha256:6e06900bc10223217b4c78081a857866f674c462e4f90593b01894da56df336d
sha256:eda2f4da9b1e70500ac340d40ee039ef3877e8be13b9a24cd345406bf6693412
sha256:6bdb7b3c3e226bdfaa911ba72a95fca13c3979cd150061d570cf569e93037ce6
sha256:ce217e530345060ca0973807a3288560e1e15cf1a4eeec44d6aa594a926c92dc
sha256:f256c980a7d17a00f57fd42a19f6323fcc2341fa46eba128def04824cafa5afa
sha256:446b1af848de2dcb92bbd229ca6ecaabf2f48dab323c19f90d02622e09a8fa67
sha256:10652cf89eaeb5b5d8e0875a6b1867b5cf92c509a9555d3f57d87fab605115a3
sha256:d9a4cf86bf01eb170242ca3b0ce456159fd3fddc9c4d4256208a9d19bae096ca
现在,从这里,我们可以尝试找到具有这些层的(严格)子集的其他图像。假设您手头有图像,您可以通过交叉引用磁盘上的图像层来找到它们,例如,使用 docker image inspect
。
在这种情况下,我只是碰巧知道这些图像是什么并且手头有它们(稍后我将讨论如果手头没有图像你会怎么做) 所以我们将继续提取这些图像并查看层。
如果你想跟着:
# openjdk:11.0.10-jdk-slim at time of writing, on my platform
OPENJDK='docker.io/openjdk@sha256:fe6a46a26ff7d6c31b258e07b3d53f0c42fe68f55f646cc39d60d0b17cbc827b'
# debian:buster-20210329-slim at time of writing on my platform
DEBIAN='docker.io/debian@sha256:088be7d6017ad3ae98325f47707112e1f61687c371be1865e55d5e5531ca97fd'
docker pull $OPENJDK
docker pull $DEBIAN
如果我们检查这些图像并将它们与我们在 docker image inspect
的输出中看到的 maven
图像的层进行比较,我们可以确认来自 openjdk
和 {{1 }} 出现在我们的原始 debian
图像中。
maven
如前所述,因为这 5 层是来自 maven 图像的 8 层的严格子集,我们可以得出结论,$ docker image inspect $DEBIAN | jq -r '.[].RootFS.Layers[]'
sha256:6e06900bc10223217b4c78081a857866f674c462e4f90593b01894da56df336d
$ docker image inspect $OPENJDK | jq -r '.[].RootFS.Layers[]'
sha256:6e06900bc10223217b4c78081a857866f674c462e4f90593b01894da56df336d
sha256:eda2f4da9b1e70500ac340d40ee039ef3877e8be13b9a24cd345406bf6693412
sha256:6bdb7b3c3e226bdfaa911ba72a95fca13c3979cd150061d570cf569e93037ce6
sha256:ce217e530345060ca0973807a3288560e1e15cf1a4eeec44d6aa594a926c92dc
和 openjdk
图像至少都在debian
图像。
我们可以进一步推断,最后 3 层最有可能来自 maven
图像本身(或者可能来自某些未知图像)。
现在,当然,以上仅适用于我手头上的所有图像。因此,您要么需要拥有图像,要么能够通过层摘要定位它们。
您仍然可以使用可从 Docker Hub 等注册表或您自己的私有存储库中获得的信息来解决这个问题。
对于官方图像,docker-library/repo-info 包含有关官方图像的历史信息,包括过去几年编目的各种标签的层摘要。例如,您可以将其用作图层信息的来源。
如果你能把它想象成一个层摘要数据库,你至少可以推断出这些官方图像的血统。
需要注意的一个重要警告是,当您在本地检查图像的层摘要时,您将获得层的内容摘要。如果您正在查看注册表清单中的层摘要(如 docker-library/repo-info 项目中出现的内容),您将获得压缩的 distribution 摘要,并且无法比较层摘要有内容。
因此您只能比较摘要 maven
OR local <--> local
。
假设我想做同样的事情,但我想关联远程存储库中的图像并找到它的基础。我们可以通过查看远程清单中的层来做同样的事情。
您可以找到有关如何为您的特定注册表执行此操作的参考资料,例如 dockerhub https://stackoverflow.com/a/57878742/5747944
使用上述示例中的相同图像,我们会发现分布层摘要也以相同的方式匹配。
remote <--> remote