Как получить список зависимых дочерних изображений в 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

Это докер версия:

# 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

но нет никакой дополнительной информации:

# 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

как я могу получить зависит от ребенка картинки он утверждает, что есть?

нет ни запущенных, ни остановленных контейнеров с этим идентификатором изображения.

8 61

8 ответов:

короткий ответ: вот скрипт python3 это список зависимых изображений докера.

ответ: Вы можете увидеть идентификатор изображения и родительский идентификатор для всех изображений, созданных после рассматриваемого изображения со следующим:

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

вы должны быть в состоянии искать изображения с родительским идентификатором, начиная с f50f9524513f, а затем искать дочерние изображения те и т. д.. но.Parentне то, что ты думаешь., поэтому в большинстве случаев вам нужно будет указать docker images --all выше, чтобы сделать эту работу, то вы получите коды изображения для всех промежуточных слоев, а также.

вот более ограниченный скрипт 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))))

если вы сохраните его как desc.py вы можете вызвать его следующим образом:

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

или просто использовать суть выше, который делает то же самое.

Если у вас нет огромного количества картинок, всегда в лоб:

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

установить dockviz и следуйте за ветвями из идентификатора изображения в виде дерева:

go get github.com/justone/dockviz
$(go env GOPATH)/bin/dockviz images --tree -l

вы можете удалить изображения Docker независимо от родительского и дочернего отношения через нижеприведенный каталог Docker

/var/lib/docker/image/devicemapper/imagedb/content/sha256

в этом каталоге вы можете найти Докер изображений, так что вы можете удалить то, что вы хотите.

Я создал суть С помощью сценария оболочки для печати дерева потомков изображения docker, если кто-то заинтересован в решении bash:

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

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

print_kids() {
   local parent_id=
   local prefix=
   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" ""

это то, что я сделал, чтобы сохранить мой окончательный "образ" (слой, на самом деле - это то, что сбило меня с толку, так как я просто попадаю в Docker builds).

Я получал все"... его нельзя заставить..." сообщение. Я понял, что не могу удалить изображения, которые мне не нужны, потому что они не являются действительно независимыми изображениями, созданными "Docker commit". Моя проблема заключалась в том, что у меня было несколько изображений (или слоев) между базовым изображением и моим финалом, и просто пытаюсь очистить, где я встретил ошибка / предупреждение о ребенке и родителе.

  1. я экспортировал окончательное изображение (или слой, если хотите) в тарбол.
  2. затем я удалил все изображения, которые я хотел, включая мой финал - я сохранил его в tarball, поэтому, хотя я не был уверен, смогу ли я его использовать, я просто экспериментировал.
  3. Я тогда побежал docker image load -i FinalImage.tar.gz. На выходе получилось что-то вроде:

7d9b54235881: Loading layer [==================================================>]  167.1MB/167.1MB
c044b7095786: Loading layer [==================================================>]  20.89MB/20.89MB
fe94dbd0255e: Loading layer [==================================================>]  42.05MB/42.05MB
19abaa1dc0d4: Loading layer [==================================================>]  37.96MB/37.96MB
4865d7b6fdb2: Loading layer [==================================================>]  169.6MB/169.6MB
a0c115c7b87c: Loading layer [==================================================>]    132MB/132MB

идентификатор загруженного изображения: sha256:82d4f8ef9ea1eab72d989455728762ed3c0fe35fd85acf9edc47b41dacfd6382

теперь, когда я перечисляю с "docker image ls", у меня есть только исходное базовое изображение и окончательное изображение, которое я ранее сохранил в tarball.

[root@docker1 ~]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
httpd               import              82d4f8ef9ea1        3 days ago          747MB
centos              httpd               36540f359ca3        5 weeks ago         193MB

моя система теперь "чистая". У меня есть только те образы, которые я хочу. Я даже удалил базовое изображение без проблем.

[root@docker1 ~]# docker rmi 36540f359ca3
Untagged: centos:httpd
Untagged:     centos@sha256:c1010e2fe2b635822d99a096b1f4184becf5d1c98707cbccae00be663a9b9131
Deleted: sha256:36540f359ca3b021d4b6a37815e9177b6c2bb3817598979ea55aee7ecc5c2c1f

как насчет:

ID=$(docker inspect --format="{{.Id}}" "")
IMAGES=$(docker inspect --format="{{if eq \"$ID\" .Config.Image}}{{.Id}}{{end}}" $(docker images --filter since="$ID" -q))
echo $(printf "%s\n" "${IMAGES[@]}" | sort -u)

он будет печатать идентификатор дочернего изображения, с sha256: префикс.
У меня также было следующее, которое добавляет имена:

IMAGES=$(docker inspect --format="{{if eq \"$ID\" .Config.Image}}{{.Id}}{{.RepoTags}}{{end}}" $(docker images --filter since="$ID" -q))

  • ID= получает полный идентификатор изображения
  • IMAGES= получает все дочерние изображения, которые имеют это изображение в списке как Image
  • echo... удаляет дубликаты и выводит результаты

Я также столкнулся с той же проблемой. Под паром шаги ниже, чтобы решить эту проблему.

остановить все запущенные контейнеры

docker stop $(docker ps-aq) удалить все контейнеры

docker rm $(docker ps-aq) удалить все изображения

docker rmi $(docker images-q)