Как получить список зависимых дочерних изображений в 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
Как я могу получить зависимые дочерние образы, которые он утверждает?
нет запущенных или остановленных контейнеров с этим идентификатором изображения.
Ответы
Ответ 1
Краткий ответ: вот скрипт на python3, в котором перечислены зависимые образы докеров.
Длинный ответ: Вы можете увидеть идентификатор изображения и идентификатор родителя для всех изображений, созданных после рассматриваемого изображения, со следующим:
docker inspect --format='{{.Id}} {{.Parent}}' \
$(docker images --filter since=f50f9524513f --quiet)
Вы должны иметь возможность искать изображения с родительским идентификатором, начинающимся с f50f9524513f, а затем искать дочерние изображения для них и т.д. Но .Parent
не то, что вы думаете. , так что в большинстве случаев вам понадобится указать docker images --all
выше, чтобы это работало, тогда вы также получите идентификаторы изображений для всех промежуточных слоев.
Вот более ограниченный скрипт python3 для анализа вывода докера и выполнения поиска для генерации списка изображений:
#!/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 )
Или просто используйте суть выше, которая делает то же самое.
Ответ 2
Если у вас нет большого количества изображений, всегда есть подход грубой силы:
for i in $(docker images -q)
do
docker history $i | grep -q f50f9524513f && echo $i
done | sort -u
Ответ 3
Установите dockviz и следуйте ветвям с идентификатора изображения в древовидном представлении:
go get github.com/justone/dockviz
$(go env GOPATH)/bin/dockviz images --tree -l
Ответ 4
Я создал гистологию со сценарием оболочки для распечатки дерева-потомка образа докера, если кому-то интересно решение 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" ""
Ответ 5
Вы можете удалить изображения Docker независимо от родительского и дочернего отношений через нижележащую директорию Docker
/var/lib/docker/image/devicemapper/imagedb/content/sha256
В этом каталоге вы можете найти изображения Docker, чтобы вы могли удалить то, что хотите.
Ответ 6
Это то, что я сделал, чтобы сохранить свое окончательное "изображение" (действительно, слой - это то, что сбило меня с толку, так как я только начинаю сборку докеров).
Я получаю сообщение "... не может быть принудительно...". Я понял, что не могу удалить ненужные мне изображения, потому что они не являются действительно независимыми изображениями, созданными с помощью 'docker commit'. Моя проблема заключалась в том, что у меня было несколько изображений (или слоев) между базовым изображением и моим финальным, и я просто пытался очистить, где я встретил ошибку/предупреждение о ребенке и родителе.
- Я экспортировал окончательное изображение (или слой, если хотите) в тарбол.
- Затем я удалил все изображения, которые хотел, в том числе и мой финал - я сохранил его в тарбол, поэтому, хотя я не был уверен, смогу ли я его использовать, я просто экспериментировал.
- Затем я запустил
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.
[[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
Моя система "чиста" сейчас. У меня есть только изображения, которые я хочу. Я даже удалил базовое изображение без проблем.
[[email protected] ~]# docker rmi 36540f359ca3
Untagged: centos:httpd
Untagged: [email protected]:c1010e2fe2b635822d99a096b1f4184becf5d1c98707cbccae00be663a9b9131
Deleted: sha256:36540f359ca3b021d4b6a37815e9177b6c2bb3817598979ea55aee7ecc5c2c1f
Ответ 7
Как насчет:
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)
Он напечатает идентификаторы дочерних изображений с префиксом sha256:
.
У меня также было следующее, которое добавляет имена:
IMAGES=$(docker inspect --format="{{if eq \"$ID\" .Config.Image}}{{.Id}}{{.RepoTags}}{{end}}" $(docker images --filter since="$ID" -q))
-
ID=
Получает полный идентификатор изображения -
IMAGES=
Получает все дочерние изображения, которые имеют это изображение в качестве Image
-
echo...
удаляет дубликаты и выводит результаты
Ответ 8
Я сделал это, чтобы рекурсивно найти детей, их метки репо и напечатать, что они делают:
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
}
Не забудьте удалить /tmp/dii- *, если ваш хост не защищен.
Ответ 9
Я также столкнулся с той же проблемой. Следуйте приведенным ниже инструкциям, чтобы решить проблему.
Остановите все работающие контейнеры
docker stop $ (docker ps -aq) Удалить все контейнеры
docker rm $ (docker ps -aq) Удалить все изображения
docker rmi $ (изображения докера -q)