web-dev-qa-db-fra.com

Comment obtenir la liste des images d'enfants dépendants dans Docker?

J'essaie de supprimer une image et je reçois:

# 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

Ceci est la version de 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

mais il n'y a pas d'informations supplémentaires: 

# 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

Comment puis-je obtenir les images de l'enfant dépendant qu'il prétend avoir? 

il n'y a pas de conteneurs en cours ni arrêtés avec cet identifiant d'image. 

68
nicocesar

Si vous n'avez pas un grand nombre d'images, il y a toujours l'approche par force brute:

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

Installez dockviz et suivez les branches à partir de l’identifiant de l’image dans l’arborescence:

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

J'ai créé un script Gist with Shell pour imprimer l’arborescence descendante d’une image de menu fixe, si une solution intéressée intéresse quelqu'un:

#!/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

Vous pouvez supprimer des images Docker indépendamment des relations parent/enfant via le répertoire ci-dessous de Docker. 

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

Dans ce répertoire, vous pouvez trouver des images Docker afin de pouvoir supprimer ce que vous voulez.

1
Jvn

C’est ce que j’ai fait afin de préserver mon "image" finale (couche, en réalité - c’est ce qui m’a jeté au loin, car je commence tout juste à me lancer dans la construction de dockers).

Je recevais tout le message "... ne peut pas être forcé ...". J'ai réalisé que je ne pouvais pas supprimer les images dont je n'avais pas besoin car ce ne sont pas vraiment des images indépendantes créées par 'docker commit'. Mon problème était, j'avais plusieurs images (ou couches) entre l'image de base et ma finale, et juste essayer de nettoyer, c'est là que j'ai rencontré l'erreur/avertissement concernant l'enfant et le parent.

  1. J'ai exporté l'image finale (ou couche, si vous voulez) vers une archive.
  2. J'ai ensuite supprimé toutes les images que je voulais, y compris ma dernière - je l'ai sauvegardée dans une archive, alors, bien que je ne sois pas sûr de pouvoir l'utiliser, je faisais juste des expériences. 
  3. J'ai ensuite couru docker image load -i FinalImage.tar.gz. La sortie était quelque chose comme:

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

Image chargée: sha256: 82d4f8ef9ea1eab72d989455728762ed3c0fe35fd85acf9edc47b41dacfd6382

Désormais, lorsque je liste avec "image fixe", je ne dispose que de l'image de base d'origine et de la dernière image enregistrée précédemment dans une archive.

[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

Mon système est «propre» maintenant. Je n'ai que les images que je veux. J'ai même supprimé l'image de base sans problème.

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

Voici une solution basée sur l'API Python (pip install docker) qui répertorie de manière récursive les descendants avec leurs balises (le cas échéant), en augmentant l'indentation en fonction de la profondeur de la relation (enfants, petits-enfants, etc.):

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())

Exemple:

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

Je l'ai rendu disponible en tant que Gist à https://Gist.github.com/simleo/10ad923f9d8a2fa410f7ec2d7e96ad57

1
simleo

J'ai préparé cela pour rechercher récursivement des enfants, leurs balises repo et imprimer ce qu'ils font:

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
}

N'oubliez pas de supprimer/tmp/dii- * si votre hôte n'est pas sécurisé.

0
android.weasel

Basé sur slushy et Michael Hoffman répond, si vous n'avez pas une tonne d'images, vous pouvez utiliser cette fonction 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}"
}

puis appelez en utilisant

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

Que diriez-vous:

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)

Cela va imprimer les identifiants de l'image enfant, avec le préfixe sha256:.
J'ai également eu ce qui suit, qui ajoute les noms:

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

  • ID= Obtient l'identifiant complet de l'image
  • IMAGES= Obtient toutes les images enfants pour lesquelles cette image est répertoriée en tant que Image.
  • echo... Supprime les doublons et renvoie les résultats
0
Justin