wake-up-neo.net

Wie erhalte ich die Liste der abhängigen untergeordneten Bilder in Docker?

Ich versuche ein Bild zu entfernen und bekomme:

# 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

Dies ist die Docker-Version:

# 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

es gibt jedoch keine zusätzlichen Informationen: 

# 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

Wie bekomme ich die abhängigen Kinderbilder behauptet zu haben? 

es gibt keine laufenden oder gestoppten Container mit dieser Image-ID. 

68
nicocesar

Kurze Antwort:Hier ist ein Python3-Skript , das abhängige Docker-Bilder auflistet.

Lange Antwort: Sie können die Bild-ID und die übergeordnete ID für alle Bilder anzeigen, die nach dem fraglichen Bild erstellt wurden.

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

Sie sollten in der Lage sein, nach Bildern zu suchen, deren übergeordnete ID mit f50f9524513f beginnt, und dann nach untergeordneten Bildern von diesen usw. suchen. Aber.Parentist nicht das, was Sie denken. , in den meisten Fällen müssten Sie oben docker images --all angeben, damit dies funktioniert. Dann erhalten Sie auch Bild-IDs für alle Zwischenebenen.

Hier ist ein eingeschränkteres python3-Skript, um die Dockerausgabe zu analysieren und die Liste der Bilder zu suchen:

#!/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 __== '__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))))

Wenn Sie dies als desc.py speichern, können Sie es wie folgt aufrufen:

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

Oder benutzen Sie einfach den Gist oben , der dasselbe tut.

31

Wenn Sie nicht über eine große Anzahl von Bildern verfügen, gibt es immer einen Brute-Force-Ansatz:

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

Installiere dockviz und folge den Zweigen der Image-ID in der Baumansicht:

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

Ich habe ein Gist mit Shell-Skript erstellt, um den Nachkommenbaum eines Docker-Images auszudrucken, falls sich jemand für die bash-Lösung interessiert:

#!/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" ""
3
Michal Linhard

Sie können Docker-Bilder unabhängig von der übergeordneten und untergeordneten Beziehung über das unten angegebene Verzeichnis von Docker löschen 

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

In diesem Verzeichnis finden Sie Docker-Bilder, sodass Sie löschen können, was Sie möchten.

1
Jvn

Dies ist, was ich getan habe, um mein endgültiges "Image" (wirklich Layer) zu bewahren - was mich abgewiesen hat, als ich gerade in Docker-Builds gehe.

Ich bekam die ganze Nachricht "... kann nicht gezwungen werden ...". Mir wurde klar, dass ich die Bilder nicht löschen konnte, die ich nicht brauchte, da es sich nicht wirklich um unabhängige Bilder handelt, die durch 'docker commit' erstellt wurden. Mein Problem war, ich hatte mehrere Bilder (oder Ebenen) zwischen dem Basis-Image und meinem letzten Bild, und beim Aufräumen habe ich den Fehler/die Warnung über das Kind und die Eltern getroffen.

  1. Ich habe das endgültige Bild (oder die Ebene, wenn Sie möchten) in ein Tarball exportiert.
  2. Ich habe dann alle Bilder gelöscht, die ich wollte, einschließlich meines Finales. Ich habe es in einem Tarball gespeichert. Ich war mir zwar nicht sicher, ob ich es verwenden könnte, aber ich experimentierte nur. 
  3. Ich lief dann docker image load -i FinalImage.tar.gz. Die Ausgabe war so etwas wie:

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

Geladenes Bild ID: sha256: 82d4f8ef9ea1eab72d989455728762ed3c0fe35fd85acf9edc47b41dacfd6382

Wenn ich jetzt mit 'docker image ls' liste, habe ich nur das ursprüngliche Basisbild und das endgültige Bild, das ich zuvor in einem Archiv gespeichert habe.

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

Mein System ist jetzt "sauber". Ich habe nur die Bilder, die ich will. Ich habe sogar das Basisbild problemlos gelöscht.

[[email protected] ~]# docker rmi 36540f359ca3
Untagged: centos:httpd
Untagged:     [email protected]:c1010e2fe2b635822d99a096b1f4184becf5d1c98707cbccae00be663a9b9131
Deleted: sha256:36540f359ca3b021d4b6a37815e9177b6c2bb3817598979ea55aee7ecc5c2c1f
1
Jerome Jordan

Hier ist eine Lösung basierend auf der Python-API (pip install docker), die rekursiv Nachkommen mit ihren Tags (falls vorhanden) auflistet und den Einzug entsprechend der Tiefe der Beziehung (Kinder, Enkelkinder usw.) erhöht:

import argparse
import docker

def find_img(img_idx, id):
    try:
        return img_idx[id]
    except KeyError:
        for k, v in img_idx.items():
            if k.rsplit(":", 1)[-1].startswith(id):
                return v
    raise RuntimeError("No image with ID: %s" % id)

def get_children(img_idx):
    rval = {}
    for img in img_idx.values():
        p_id = img.attrs["Parent"]
        rval.setdefault(p_id, set()).add(img.id)
    return rval

def print_descendants(img_idx, children_map, img_id, indent=0):
    children_ids = children_map.get(img_id, [])
    for id in children_ids:
        child = img_idx[id]
        print(" " * indent, id, child.tags)
        print_descendants(img_idx, children_map, id, indent=indent+2)

def main(args):
    client = docker.from_env()
    img_idx = {_.id: _ for _ in client.images.list(all=True)}
    img = find_img(img_idx, args.id)
    children_map = get_children(img_idx)
    print_descendants(img_idx, children_map, img.id)

if __== "__main__":
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("id", metavar="IMAGE_ID")
    main(parser.parse_args())

Beispiel:

$ python find_dep_img.py 549afbf12931
 sha256:913d0981fdc7d2d673f2c8135b7afd32ba5037755e89b00432d3460422ba99b9 []
   sha256:0748dbc043b96ef9f88265c422e0267807f542e364b7a7fadf371ba5ee082b5d []
     sha256:6669414d2a0cc31b241a1fbb00c0ca00fa4dc4fa65dffb532bac90d3943d6a0a []
       sha256:a6441e7d9e92511608aad631f9abe8627033de41305c2edf7e03ee36f94f0817 ['foo/bar:latest']

Ich habe es als Gist unter https://Gist.github.com/simleo/10ad923f9d8a2fa410f7ec2d7e96ad57 verfügbar gemacht.

1
simleo

Ich habe dies gekocht, um rekursiv Kinder, ihre Repo-Tags zu finden und zu drucken, was sie tun:

docker_img_tree() {
    for i in $(docker image ls -qa) ; do
        [ -f "/tmp/dii-$i"  ] || ( docker image inspect $i > /tmp/dii-$i)
        if grep -qiE 'Parent.*'$1 /tmp/dii-$i ; then
            echo "$2============= $i (par=$1)"
            awk '/(Cmd|Repo).*\[/,/\]/' /tmp/dii-$i | sed "s/^/$2/"
            docker_img_tree $i $2===
        fi
    done
}

Vergessen Sie nicht,/tmp/dii- * zu löschen, wenn Ihr Host nicht sicher ist.

0
android.weasel

Basierend auf slushy und Michael Hoffman antworten, wenn Sie nicht viele Bilder haben, können Sie diese Shell-Funktion verwenden:

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}"
}

und rufen Sie es dann mit an

docker_image_desc <image-id> | awk '!x[$0]++'
0
Maxim Suslov

Wie wäre es mit:

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

Die untergeordneten Bild-IDs werden mit dem Präfix sha256: gedruckt.
Ich hatte auch folgendes, das die Namen anfügt:

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

  • ID= Ruft die vollständige ID des Bildes ab
  • IMAGES= Ruft alle untergeordneten Bilder ab, für die dieses Bild als Image aufgeführt ist.
  • echo... Entfernt Duplikate und bestätigt die Ergebnisse
0
Justin