可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm trying to remove an image and I get:
# 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
This is the 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
but there is no extra information:
# 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
How can I get the dependent child images it claims to have?
there are no running nor stopped containers with that image id.
回答1:
Short answer:
Here is a python3 script that lists dependent docker images.
Long answer:
You can see the image id and parent id for all image created after the image in question with the following:
docker inspect --format='{{.Id}} {{.Parent}}' \
$(docker images --filter since=f50f9524513f --quiet)
You should be able to look for images with parent id starting with f50f9524513f, then look for child images of those, etc.. But .Parent
isn’t what you think., so in most cases you would need to specify docker images --all
above to make that work, then you will get image ids for all intermediate layers as well.
Here's a more limited python3 script to parse the docker output and do the searching to generate the list of images:
#!/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))))
If you save this as desc.py
you could invoke it as follows:
docker images \
| fgrep -f <(docker inspect --format='{{.Id}} {{.Parent}}' \
$(docker images --all --quiet) \
| python3 desc.py f50f9524513f )
Or just use the gist above, which does the same thing.
回答2:
If you don't have a huge number of images, there's always the brute-force approach:
for i in $(docker images -q)
do
docker history $i | grep -q f50f9524513f && echo $i
done | sort -u
回答3:
Install dockviz and follow the branches from the image id in the tree view:
go get github.com/justone/dockviz
$(go env GOPATH)/bin/dockviz images --tree -l
回答4:
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" ""
回答5:
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.
回答6:
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
回答7:
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 image
IMAGES=
Gets all child images that have this image listed as an Image
echo...
Removes duplicates and echos the results
回答8:
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)