如何在Docker中获取依赖子图像列表?

nic*_*sar 93 linux containers docker

我正在尝试删除图像,我得到:

# docker rmi f50f9524513f  
Failed to remove image (f50f9524513f): Error response from daemon: conflict: unable to delete f50f9524513f (cannot be forced) - image has dependent child images
Run Code Online (Sandbox Code Playgroud)

这是docker版本:

# docker version
Client:
 Version:      1.10.3
 API version:  1.22
 Go version:   go1.5.3
 Git commit:   20f81dd
 Built:        Thu Mar 10 21:49:11 2016
 OS/Arch:      linux/amd64

Server:
 Version:      1.10.3
 API version:  1.22
 Go version:   go1.5.3
 Git commit:   20f81dd
 Built:        Thu Mar 10 21:49:11 2016
 OS/Arch:      linux/amd64
Run Code Online (Sandbox Code Playgroud)

但没有额外的信息:

# docker images --format="raw" | grep f50f9524513f -C3

repository: debian
tag: 8
image_id: f50f9524513f
created_at: 2016-03-01 18:51:14 +0000 UTC
virtual_size: 125.1 MB

repository: debian
tag: jessie
image_id: f50f9524513f
created_at: 2016-03-01 18:51:14 +0000 UTC
virtual_size: 125.1 MB
Run Code Online (Sandbox Code Playgroud)

如何获得它声称具有的依赖子图像

没有带有该图像ID的正在运行或已停止的容器.

小智 72

如果你没有大量的图像,总会有蛮力的方法:

for i in $(docker images -q)
do
    docker history $i | grep -q f50f9524513f && echo $i
done | sort -u
Run Code Online (Sandbox Code Playgroud)

  • 我认为这是“最佳”解决方案。您可以将其扩展一点,并通过将 `echo $1` 更改为更丑陋的(但仍然是蛮力的)`docker images | 使其更加清晰。grep $i`(在 docker 版本中比对 Image Id 使用 `--filter` 标志更便携) (2认同)

Ary*_*rog 42

简短回答: 这是一个列出相关docker镜像的python3脚本.

答案很长: 您可以使用以下内容查看在相关图像之后创建的所有图像的图像ID和父ID:

docker inspect --format='{{.Id}} {{.Parent}}' \
    $(docker images --filter since=f50f9524513f --quiet)
Run Code Online (Sandbox Code Playgroud)

您应该能够查找父ID以f50f9524513f开头的图像,然后查找那些图像的子图像等. .Parent 不是您的想法.,因此在大多数情况下,您需要指定docker images --all上面的工作,然后您将获得所有中间层的图像ID.

这是一个更有限的python3脚本来解析docker输出并进行搜索以生成图像列表:

#!/usr/bin/python3
import sys

def desc(image_ids, links):
    if links:
        link, *tail = links
        if len(link) > 1:
            image_id, parent_id = link
            checkid = lambda i: parent_id.startswith(i)
            if any(map(checkid, image_ids)):
                return desc(image_ids | {image_id}, tail)
        return desc(image_ids, tail)
    return image_ids


def gen_links(lines):
    parseid = lambda s: s.replace('sha256:', '')
    for line in reversed(list(lines)):
        yield list(map(parseid, line.split()))


if __name__ == '__main__':
    image_ids = {sys.argv[1]}
    links = gen_links(sys.stdin.readlines())
    trunc = lambda s: s[:12]
    print('\n'.join(map(trunc, desc(image_ids, links))))
Run Code Online (Sandbox Code Playgroud)

如果你保存它,desc.py你可以调用它,如下所示:

docker images \
    | fgrep -f <(docker inspect --format='{{.Id}} {{.Parent}}' \
        $(docker images --all --quiet) \
        | python3 desc.py f50f9524513f )
Run Code Online (Sandbox Code Playgroud)

或者只是使用上面的要点,它做同样的事情.

  • 如果它们都没有以期望字符开头怎么办?这表明可能存在错误吗?我在Docker for Mac beta,FWIW,所以这不会让我感到惊讶. (2认同)
  • 这并没有真正回答原来的问题.这显示了在相关图像之后创建的内容,这可能会或可能不会取决于海报试图删除的图像.Simon Brady的答案可以解决这个问题,至少是小样本的图像. (2认同)
  • @penguincoder这就是python脚本的用途. (2认同)

mmo*_*oya 10

安装dockviz并按照树视图中图像ID的分支:

go get github.com/justone/dockviz
$(go env GOPATH)/bin/dockviz images --tree -l
Run Code Online (Sandbox Code Playgroud)

  • 在 macOS 上可通过“brew install dockviz”使用 (3认同)

小智 6

我已经用shell脚本创建了一个要点,以打印出docker映像的后代树,如果有人对bash解决方案感兴趣的话:

#!/bin/bash
parent_short_id=$1
parent_id=`docker inspect --format '{{.Id}}' $1`

get_kids() {
    local parent_id=$1
    docker inspect --format='ID {{.Id}} PAR {{.Parent}}' $(docker images -a -q) | grep "PAR ${parent_id}" | sed -E "s/ID ([^ ]*) PAR ([^ ]*)/\1/g"
}

print_kids() {
    local parent_id=$1
    local prefix=$2
    local tags=`docker inspect --format='{{.RepoTags}}' ${parent_id}`
    echo "${prefix}${parent_id} ${tags}"

    local children=`get_kids "${parent_id}"`

    for c in $children;
    do
        print_kids "$c" "$prefix  "
    done
}

print_kids "$parent_id" ""
Run Code Online (Sandbox Code Playgroud)


Max*_*lov 5

根据slushyMichael Hoffman 的答案,如果你没有大量图像,你可以使用这个 shell 函数:

docker_image_desc() {
  for image in $(docker images --quiet --filter "since=${1}"); do
    if [ $(docker history --quiet ${image} | grep ${1}) ]; then
      docker_image_desc "${image}"
    fi
  done
  echo "${1}"
}
Run Code Online (Sandbox Code Playgroud)

然后使用调用它

docker_image_desc <image-id> | awk '!x[$0]++'
Run Code Online (Sandbox Code Playgroud)


wis*_*cky 5

这是获取依赖于父图像的子图像列表的简单方法:

image_id=123456789012

docker images -a -q --filter since=$image_id |
xargs docker inspect --format='{{.Id}} {{.Parent}}' |
grep $image_id
Run Code Online (Sandbox Code Playgroud)

这将生成一个子/父图像 ID 列表,例如(为了简洁而被截断):

sha256:abcdefghijkl sha256:123456789012
Run Code Online (Sandbox Code Playgroud)

左侧是子图像 ID,右侧是我们要删除的父图像 ID,但它显示“图像具有依赖的子图像”。这告诉我们,abcdefghijkl孩子是依赖的123456789012。所以我们需要先做docker rmi abcdefghijkl,然后你就可以了docker rmi 123456789012

现在,可能存在一系列依赖的子图像,因此您可能必须不断重复才能找到最后一个子图像。

  • ..并且链条可能比您使用此逐步方法的时间“长得多”:) (2认同)