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
소유하고 있다고 주장 하는 종속 자식 이미지를 어떻게 얻을 수 있습니까?
해당 이미지 ID로 실행 중이거나 중지 된 컨테이너가 없습니다.
짧은 대답 : 다음은 종속 된 도커 이미지를 나열 하는 python3 스크립트 입니다.
긴 답변 : 다음과 같이 문제의 이미지 뒤에 생성 된 모든 이미지의 이미지 ID와 상위 ID를 볼 수 있습니다.
docker inspect --format='{{.Id}} {{.Parent}}' \
$(docker images --filter since=f50f9524513f --quiet)
부모 ID가 f50f9524513f로 시작하는 이미지를 찾은 다음 해당 이미지 등 의 자식 이미지를 찾을 수 있어야합니다 . 하지만 .Parent 생각하는 것은 아닙니다. , 따라서 대부분의 경우 docker images --all해당 작업을 수행하려면 위에서 지정해야하며 , 그러면 모든 중간 레이어에 대한 이미지 ID도 얻게됩니다.
다음은 docker 출력을 구문 분석하고 이미지 목록을 생성하기위한 검색을 수행하는보다 제한된 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 )
또는 위의 요점을 사용 하여 동일한 작업을 수행하십시오.
이미지가 많지 않은 경우 항상 무차별 대입 방식이 있습니다.
for i in $(docker images -q)
do
docker history $i | grep -q f50f9524513f && echo $i
done | sort -u
dockviz를 설치 하고 트리보기의 이미지 ID에서 분기를 따릅니다.
go get github.com/justone/dockviz
$(go env GOPATH)/bin/dockviz images --tree -l
I've created a gist with shell script to print out descendant tree of a docker image, should anyone be interested in bash solution:
#!/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" ""
This is what I did in order to preserve my final "image" (layer, really - which is what threw me off, as I am just getting into docker builds).
I was getting the whole "... cannot be forced..." message. I realized I couldn't delete the images I didn't need because they are not really independent images created by 'docker commit'. My issue was, I had several images (or layers) between the base image and my final, and just trying to clean up is where I met the error/warning about the child and parent.
- I exported the final image (or layer, if you will) out to a tarball.
- I then deleted all the images I wanted to, including my final - I have it saved to a tarball so, while I wasn't sure if I would be able to use it, I was just experimenting.
- I then ran
docker image load -i FinalImage.tar.gz. The output was something like:
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
Loaded image ID: sha256:82d4f8ef9ea1eab72d989455728762ed3c0fe35fd85acf9edc47b41dacfd6382
Now, when I list with 'docker image ls', I only have the original base image, and the final image I previously saved to a 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
My system is 'clean' now. I only have the images I want. I even deleted the base image without a problem.
[root@docker1 ~]# docker rmi 36540f359ca3
Untagged: centos:httpd
Untagged: centos@sha256:c1010e2fe2b635822d99a096b1f4184becf5d1c98707cbccae00be663a9b9131
Deleted: sha256:36540f359ca3b021d4b6a37815e9177b6c2bb3817598979ea55aee7ecc5c2c1f
Based on slushy and Michael Hoffman answers, if you don't have a ton of images you can use this shell function:
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}"
}
and then call it using
docker_image_desc <image-id> | awk '!x[$0]++'
Here's a solution based on the Python API (pip install docker) that recursively lists descendants together with their tags (if any), increasing the indentation according to the depth of the relationship (children, grandchildren, 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())
Example:
$ python find_dep_img.py 549afbf12931
sha256:913d0981fdc7d2d673f2c8135b7afd32ba5037755e89b00432d3460422ba99b9 []
sha256:0748dbc043b96ef9f88265c422e0267807f542e364b7a7fadf371ba5ee082b5d []
sha256:6669414d2a0cc31b241a1fbb00c0ca00fa4dc4fa65dffb532bac90d3943d6a0a []
sha256:a6441e7d9e92511608aad631f9abe8627033de41305c2edf7e03ee36f94f0817 ['foo/bar:latest']
I've made it available as a gist at https://gist.github.com/simleo/10ad923f9d8a2fa410f7ec2d7e96ad57
You can delete Docker images irrespective of parent and child relation through the below directory of Docker
/var/lib/docker/image/devicemapper/imagedb/content/sha256
In this directory you can find Docker images, so you can delete what you want.
How about:
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)
It'll print the child image id's, with the sha256: prefix.
I also had the following, which appends the names:
IMAGES=$(docker inspect --format="{{if eq \"$ID\" .Config.Image}}{{.Id}}{{.RepoTags}}{{end}}" $(docker images --filter since="$ID" -q))
ID=Gets the full id of the imageIMAGES=Gets all child images that have this image listed as anImageecho...Removes duplicates and echos the results
I cooked up this to recursively find children, their repo tags, and print what they're doing:
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
}
Don't forget to delete /tmp/dii-* if your host isn't secure.
I was also facing the same issue. Fallowed steps below to resolve the issue.
Stop all running containers
docker stop $(docker ps -aq) Remove all containers
docker rm $(docker ps -aq) Remove all images
docker rmi $(docker images -q)
참고URL : https://stackoverflow.com/questions/36584122/how-to-get-the-list-of-dependent-child-images-in-docker
'IT박스' 카테고리의 다른 글
| Lisp-1과 Lisp-2의 차이점은 무엇입니까? (0) | 2020.09.08 |
|---|---|
| REST API : 사용자 지정 HTTP 헤더와 URL 매개 변수 (0) | 2020.09.08 |
| ANTLR에서 "단편"은 무엇을 의미합니까? (0) | 2020.09.08 |
| 문자 'A'가 0x41과 비교되는 이유는 무엇입니까? (0) | 2020.09.08 |
| Google이 어떻게 그렇게 빠를 수 있습니까? (0) | 2020.09.08 |