![使用 docker 是否有办法确定哪些图像依赖于另一个图像](https://linux22.com/image/1524429/%E4%BD%BF%E7%94%A8%20docker%20%E6%98%AF%E5%90%A6%E6%9C%89%E5%8A%9E%E6%B3%95%E7%A1%AE%E5%AE%9A%E5%93%AA%E4%BA%9B%E5%9B%BE%E5%83%8F%E4%BE%9D%E8%B5%96%E4%BA%8E%E5%8F%A6%E4%B8%80%E4%B8%AA%E5%9B%BE%E5%83%8F.png)
通过docker
它可以识别所有命名和标记的容器并将docker images
它们列出。
我可以找出给定图像所依赖的其他图像docker inspect --format '{{.RootFS.Layers}}' _imageId_
,并且通过手动比较 SHA,我可以看到图像 B 使用了图像 A。
有什么方法可以让docker告诉我或者使用bash(或便携式shell)脚本来查找依赖于给定图像的所有命名图像。例如,在这个例子中,当我搜索依赖于A的图像时会返回B。
我一直在搜索 docker 帮助输出、在线 docker 文档、google 和 SE、SO、SU 搜索,试图找到一种现有的替代方法来手动发现依赖关系,但都没有成功。
答案1
正如问题所述,似乎没有内置方法可以做到这一点。以下docker-find-dependants 脚本在此处维护并完成工作
#!/bin/bash
# Script to determine what named images and containers are dependent on the specified image (or a containers image) from stdin or in the args
# An unmatchable input is ignored
# All of the following will be found:
# Any image name / tag / name:tag / id that has a prefix in it that matches the input
# Any other image that relies on the images specified
# Any containers (running or not) that use any of these images
set -euf -o pipefail
debugMsg() {
true
#printf "%s\n" "$@" >&2
}
specifiedParents=""
# Find all the images that need to be removed
if [ "$#" -ge "1" ]; then
# Images for removal in args
specifiedParents="$(printf " %s\n" "$@")"
else
# Images for removal to arrive via stdin
while IFS= read -r inStr; do
if [ -n "$inStr" ]; then
specifiedParents="$(printf "%s %s\n" "$specifiedParents" "$inStr")"
fi
done
fi
debugMsg "DBG:1 specifiedParents = '$specifiedParents'"
# Check there is some input
if [ -z "$specifiedParents" ]; then
printf "%s" "Nothing specified to search for; images/containers must be specified as either args or on the stdin" >&2
exit 1
fi
# Collect the container and image info
containersData="$(docker ps -a --format 'Container {{.ID}} {{.Image}} {{.Names}} {{.Labels}}' --no-trunc)"
allImagesData="$(docker images -a --format 'Image {{.ID}} {{.Repository}}:{{.Tag}} {{.Repository}} {{.Tag}}' --no-trunc | sed 's/ [^:]*:/ /')"
namedImagesData="$(docker images --format 'Image {{.ID}} {{.Repository}}:{{.Tag}}' --no-trunc | sed 's/ [^:]*:/ /')"
debugMsg "DBG:2 containersData = '$containersData'"
debugMsg "DBG:3 allImagesData = '$allImagesData'"
debugMsg "DBG:4 namedImagesData = '$namedImagesData'"
# Check to see if you can find a matching container
parents=""
while IFS= read -r aParent; do
if [ -z "$aParent" ]; then
continue
fi
# Use space to ensure matching starts at the beginning of a field
anImageId=" $(printf "%s" "$containersData" | grep -F " $aParent" | awk '{print $3}' || true)"
if [ "$anImageId" != " " ]; then
# A container matched so use the image ID
parents="$(printf "%s%s\n" "$parents" " $anImageId")"
else
# Not a container, so presumably an image
parents="$(printf "%s%s\n" "$parents" " $aParent")"
fi
done <<< $(printf "%s\n" "$specifiedParents") # Performing while inside this shell
#debugMsg "DBG:5 parents = '$parents'"
# Get the full parent image ID's
parentImageIds=""
while IFS= read -r aParent; do
debugMsg "DBG:6 aParent = '$aParent'"
# Find anything matching the parent and get it's full ID
while IFS= read -r parentImageId; do
if [ -z "$parentImageId" ]; then
continue
fi
debugMsg "DBG:7 parentImageId = '$parentImageId'"
# Add the full ID to the parentImageIds, including a space to assist matching later
parentImageIds="$(printf "%s%s\n" "$parentImageIds" " $parentImageId")"
done <<< $(printf "%s" "$allImagesData" | grep -F " $aParent" | awk '{print $2}')
done <<< $(printf "%s" "$parents") # Performing while inside this shell
debugMsg "DBG:8 parentImageIds = '$parentImageIds'"
# Stop if there are no parents
if [ -z "$parentImageIds" ]; then
exit 0
fi
# Deduplicate
parentImageIds="$(printf "%s" "$parentImageIds" | LC_ALL=C sort -u)"
debugMsg "DBG:9 parentImageIds = '$parentImageIds'"
# Find descendent images
descendentImages=""
while IFS= read -r imageData; do
anImageId="$(printf "%s" "$imageData" | awk '{print $2}')"
# Check to see if this ID is a descendent of parentImageIds by imageInfo by moving through it's lineage
areDescendents=""
imageIdsChecked=""
while true; do
# Record that anImageId is being checked; including the space at the start to assist matching later
imageIdsChecked="$(printf "%s%s\n" "$imageIdsChecked" " $anImageId")"
if printf "%s" "$descendentImages" | grep -q -F "$anImageId"; then
# Already determined that anImageId is a descendent of parentImageIds so TheImage is too
areDescendents="true"
break;
else
if printf "%s" "$parentImageIds" | grep -q -F " $anImageId"; then
# TheImage is a descendent of parentImageIds
areDescendents="true"
break;
fi
# Move onto the parent of anImageId
anImageId="$(docker inspect --format '{{.Parent}}' "$anImageId" | sed 's/.*://')"
if [ -z "$anImageId" ]; then
# Reached the end of the line; abandon all hope ye who enter here
break;
fi
fi
done
# Add descendents to the descendentImages
if [ -n "$areDescendents" ]; then
descendentImages="$(printf "%s%s\n" "$descendentImages" "$imageIdsChecked")"
fi
done <<< $(printf "%s" "$allImagesData") # Performing while inside this shell
debugMsg "DBG:10 descendentImages = '$descendentImages'"
checkIfDescendentImageFound() {
# Check to see if this is a descendent from any parent
# $1 is thisImageId
# $2 is the display text
# Using the space to ensure matching form the start of an ID
if printf "%s" "$descendentImages" | grep -q -F " $1"; then
# We've found a descendent; display it quick before it gets away
debugMsg "DBG: Found "
printf "%s\n" "$2"
fi
}
# Identify any named images that are descendents of the parentImageIds
debugMsg "DBG:11 namedImagesData = '$namedImagesData'"
printf "%s\n" "$namedImagesData" | while IFS= read -r imageData; do
thisImageId="$(printf "%s" "$imageData" | awk '{print $2}')"
checkIfDescendentImageFound "$thisImageId" "$imageData"
done
# Identify containers that rely on images that are descendents of the parentImageIds
debugMsg "DBG:12 containersData = '$containersData'"
printf "%s\n" "$containersData" | while IFS= read -r containerData; do
thisImageId="$(printf "%s" "$containerData" | awk '{print $3}')"
checkIfDescendentImageFound "$thisImageId" "$containerData"
done
例子:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f89b835ae7a0 96c117cf0a5e "/bin/sleep infinity" 12 hours ago Up 12 hours test
$ docker images -a
REPOSITORY TAG IMAGE ID CREATED SIZE
golang-build 2017-03-09T05-46GMT 96c117cf0a5e 39 hours ago 293 MB
<none> <none> 752877a5f5b1 39 hours ago 293 MB
<none> <none> cb1c86494369 39 hours ago 3.98 MB
alpine latest 4a415e366388 7 days ago 3.98 MB
$ docker-find-dependants blah
$ docker-find-dependants 752877a5f5b1
Image 96c117cf0a5ef75c6203f862ec92ae75418c1a431d86440dd71b945e5fdbff77 golang-build:2017-03-09T05-46GMT
Container f89b835ae7a08e0394c080d0e57de2020f6a9c6dd334bc078913171d4171962f 96c117cf0a5e test
答案2
不是一个狂欢解决方案 - 但对于那些最终来到这里只是想快速了解依赖关系的人来说民众图像 -包含.dev非常适合直观地探索这些信息(图像层次结构、图层、文件等)。
例如 - 查看continuumio/miniconda3:4.10.3p0图像,我很快就能看出它依赖于debian:buster-20210721-slim图像。