linux - implementar - tutorial docker file
¿Cómo obtener la lista de imágenes secundarias dependientes en Docker? (11)
Estoy tratando de eliminar una imagen y obtengo:
# 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
Esta es la versión 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
pero no hay información adicional:
# 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
¿Cómo puedo obtener las imágenes de hijos dependientes que dice tener?
no hay contenedores en ejecución ni detenidos con esa identificación de imagen.
Aquí hay una solución basada en la API de Python (
pip install docker
) que enumera recursivamente descendientes junto con sus etiquetas (si las hay), aumentando la sangría de acuerdo con la profundidad de la relación (hijos, nietos, 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 __name__ == "__main__":
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("id", metavar="IMAGE_ID")
main(parser.parse_args())
Ejemplo:
$ python find_dep_img.py 549afbf12931
sha256:913d0981fdc7d2d673f2c8135b7afd32ba5037755e89b00432d3460422ba99b9 []
sha256:0748dbc043b96ef9f88265c422e0267807f542e364b7a7fadf371ba5ee082b5d []
sha256:6669414d2a0cc31b241a1fbb00c0ca00fa4dc4fa65dffb532bac90d3943d6a0a []
sha256:a6441e7d9e92511608aad631f9abe8627033de41305c2edf7e03ee36f94f0817 [''foo/bar:latest'']
Lo hice disponible como una esencia en https://gist.github.com/simleo/10ad923f9d8a2fa410f7ec2d7e96ad57
Cociné esto para encontrar recursivamente niños, sus etiquetas de repositorio e imprimir lo que están haciendo:
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
}
No olvide eliminar / tmp / dii- * si su host no es seguro.
Esto es lo que hice para preservar mi "imagen" final (capa, en realidad, que es lo que me desconcertó, ya que me estoy metiendo en las versiones de Docker).
Estaba recibiendo todo el mensaje "... no se puede forzar ...". Me di cuenta de que no podía eliminar las imágenes que no necesitaba porque no son imágenes realmente independientes creadas por ''docker commit''. Mi problema fue que tenía varias imágenes (o capas) entre la imagen base y mi final, y solo tratando de limpiar es donde encontré el error / advertencia sobre el niño y el padre.
- Exporté la imagen final (o capa, si se quiere) a un tarball.
- Luego eliminé todas las imágenes que quería, incluida mi final; lo guardé en un tarball, así que, aunque no estaba seguro de poder usarlo, solo estaba experimentando.
-
Luego ejecuté
docker image load -i FinalImage.tar.gz
. El resultado fue algo así como:
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
ID de la imagen cargada: sha256: 82d4f8ef9ea1eab72d989455728762ed3c0fe35fd85acf9edc47b41dacfd6382
Ahora, cuando enumero con ''docker image ls'', solo tengo la imagen base original y la imagen final que guardé previamente en un 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
Mi sistema está ''limpio'' ahora. Solo tengo las imágenes que quiero. Incluso eliminé la imagen base sin ningún problema.
[root@docker1 ~]# docker rmi 36540f359ca3
Untagged: centos:httpd
Untagged: centos@sha256:c1010e2fe2b635822d99a096b1f4184becf5d1c98707cbccae00be663a9b9131
Deleted: sha256:36540f359ca3b021d4b6a37815e9177b6c2bb3817598979ea55aee7ecc5c2c1f
He creado una gist con script de shell para imprimir el árbol descendiente de una imagen acoplable, si alguien está interesado en la solución 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" ""
Instale dockviz y siga las ramas desde la identificación de la imagen en la vista de árbol:
go get github.com/justone/dockviz
$(go env GOPATH)/bin/dockviz images --tree -l
Puede eliminar las imágenes de Docker independientemente de la relación principal y secundaria a través del siguiente directorio de Docker
/var/lib/docker/image/devicemapper/imagedb/content/sha256
En este directorio puede encontrar imágenes de Docker, por lo que puede eliminar lo que desee.
Qué tal si:
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)
Imprimirá la identificación de la imagen secundaria, con el prefijo
sha256:
También tenía lo siguiente, que agrega los nombres:
IMAGES=$(docker inspect --format="{{if eq /"$ID/" .Config.Image}}{{.Id}}{{.RepoTags}}{{end}}" $(docker images --filter since="$ID" -q))
-
ID=
Obtiene la identificación completa de la imagen -
IMAGES=
Obtiene todas las imágenes secundarias que tienen esta imagen listada comoImage
-
echo...
Elimina duplicados y haceecho...
los resultados
Según las respuestas de slushy y Michael Hoffman , si no tiene un montón de imágenes, puede usar esta función de 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}"
}
y luego llamarlo usando
docker_image_desc <image-id> | awk ''!x[$0]++''
Si no tiene una gran cantidad de imágenes, siempre existe el enfoque de fuerza bruta:
for i in $(docker images -q)
do
docker history $i | grep -q f50f9524513f && echo $i
done | sort -u
También estaba enfrentando el mismo problema. Pasos a continuación seguidos para resolver el problema.
Detenga todos los contenedores en funcionamiento.
docker stop $ (docker ps -aq) Eliminar todos los contenedores
docker rm $ (docker ps -aq) Eliminar todas las imágenes
docker rmi $ (imágenes de docker -q)
Respuesta corta: Aquí hay un script de python3 que enumera imágenes dependientes de acoplador.
Respuesta larga: puede ver la identificación de la imagen y la identificación principal de todas las imágenes creadas después de la imagen en cuestión con lo siguiente:
docker inspect --format=''{{.Id}} {{.Parent}}'' /
$(docker images --filter since=f50f9524513f --quiet)
Debería poder buscar imágenes con la identificación principal comenzando con f50f9524513f, luego buscar imágenes secundarias de
esas
, etc.
Pero
.Parent
no es lo que piensa.
, por lo que en la mayoría de los casos necesitaría especificar las
docker images --all
anteriores para que funcione, y luego obtendrá identificadores de imagen para todas las capas intermedias.
Aquí hay un script python3 más limitado para analizar la salida del acoplador y hacer la búsqueda para generar la lista de imágenes:
#!/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))))
Si guarda esto como
desc.py
, puede invocarlo de la siguiente manera:
docker images /
| fgrep -f <(docker inspect --format=''{{.Id}} {{.Parent}}'' /
$(docker images --all --quiet) /
| python3 desc.py f50f9524513f )
O simplemente use la esencia anterior , que hace lo mismo.