我试图删除图片,但我得到了:
# 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的正在运行或已停止的容器。
答案 0 :(得分:61)
如果你没有大量的图像,那么总是有蛮力的方法:
for i in $(docker images -q)
do
docker history $i | grep -q f50f9524513f && echo $i
done | sort -u
答案 1 :(得分:33)
简答: 列出相关泊坞窗图像的Here is a python3 script。
答案很长: 您可以使用以下内容查看在相关图像之后创建的所有图像的图像ID和父ID:
docker inspect --format='{{.Id}} {{.Parent}}' \
$(docker images --filter since=f50f9524513f --quiet)
您应该能够查找父ID以f50f9524513f开头的图像,然后查找那些等的子图像。但是 .Parent
{ {3}},因此在大多数情况下,您需要指定上面的docker images --all
才能使其正常工作,然后您将获得所有中间层的图像ID。
这是一个更有限的python3脚本,用于解析docker输出并进行搜索以生成图像列表:
#!/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 )
或者只使用isn’t what you think.,它可以做同样的事情。
答案 2 :(得分:9)
安装dockviz并按照树状视图中图片ID的分支:
go get github.com/justone/dockviz
$(go env GOPATH)/bin/dockviz images --tree -l
答案 3 :(得分:4)
如果有人对bash解决方案感兴趣,我已经创建了一个带有shell脚本的gist来打印一个docker图像的后代树:
#!/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" ""
答案 4 :(得分:2)
基于slushy和Michael Hoffman的答案,如果您没有大量图像,则可以使用以下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}"
}
然后使用
进行调用docker_image_desc <image-id> | awk '!x[$0]++'
答案 5 :(得分:1)
您可以通过Docker的以下目录
删除Docker镜像而不管父子关系/var/lib/docker/image/devicemapper/imagedb/content/sha256
在此目录中,您可以找到Docker图像,因此您可以删除所需内容。
答案 6 :(得分:1)
这就是我为了保留我的最终“形象”而做的事情(层,真的 - 这就是让我失望的原因,因为我刚刚进入码头工程版)。
我得到了整个“...不能强迫......”的消息。我意识到我无法删除我不需要的图像,因为它们不是'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
已加载的图片ID:sha256:82d4f8ef9ea1eab72d989455728762ed3c0fe35fd85acf9edc47b41dacfd6382
现在,当我列出'docker image ls'时,我只有原始的基本图像,以及我之前保存到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
我的系统现在“干净”了。我只有我想要的图像。 我甚至没有问题地删除了基本图像。
[root@docker1 ~]# docker rmi 36540f359ca3
Untagged: centos:httpd
Untagged: centos@sha256:c1010e2fe2b635822d99a096b1f4184becf5d1c98707cbccae00be663a9b9131
Deleted: sha256:36540f359ca3b021d4b6a37815e9177b6c2bb3817598979ea55aee7ecc5c2c1f
答案 7 :(得分:1)
这是一个基于Python API(from sqlalchemy import and_, or_
from sqlalchemy.orm import aliased
DeviceModel2 = aliased(DeviceModel)
subquery = (session
.query(DeviceModel.created_at)
.outerjoin(DeviceModel2,
and_(DeviceModel.user_uid == DeviceModel2.user_uid,
DeviceModel.created_at < DeviceModel2.created_at))
.filter(DeviceModel2.user_uid == None)
.subquery('subq'))
query = (session
.query(User, DeviceModel)
.outerjoin(DeviceModel)
.filter(or_(
DeviceModel.created_at == subquery.c.created_at,
DeviceModel.id == None)))
print(query)
results = query.all()
for row in results:
if row[1]:
print({**row.User.__dict__, **row.DeviceModel.__dict__})
else:
print(row.User.__dict__)
)的解决方案,该解决方案以递归方式列出后代及其标记(如果有的话),并根据关系的深度(子代,孙代等)增加缩进:
pip install docker
示例:
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())
我已经在https://gist.github.com/simleo/10ad923f9d8a2fa410f7ec2d7e96ad57
上提供了它的要点。答案 8 :(得分:0)
怎么样:
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:
前缀的子图像ID。
我还拥有以下名称,这些名称后面加上了
IMAGES=$(docker inspect --format="{{if eq \"$ID\" .Config.Image}}{{.Id}}{{.RepoTags}}{{end}}" $(docker images --filter since="$ID" -q))
ID=
获取图像的完整ID IMAGES=
获取所有将此图像列为Image
的子图像echo...
删除重复项并回显结果答案 9 :(得分:0)
我做了这个递归找到孩子,他们的回购标签和打印他们在做什么:
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-*。
答案 10 :(得分:0)
这是一种获取依赖于父图像的子图像列表的简单方法:
image_id=123456789012
docker images -a -q --filter since=$image_id |
xargs docker inspect --format='{{.Id}} {{.Parent}}' |
grep $image_id
这将生成一个子/父图像ID的列表,例如(为简洁起见,将其截短):
sha256:abcdefghijkl sha256:123456789012
左侧是我们要删除的子图片ID,右侧是我们要删除的父图片ID,但它的意思是“图片具有相关的子图片”。这告诉我们abcdefghijkl
是依赖123456789012
的孩子。因此,我们需要先docker rmi abcdefghijkl
,然后才能docker rmi 123456789012
。
现在,可能有一系列依赖的子图像,因此您可能必须不断重复以找到最后一个子图像。
答案 11 :(得分:-6)
我也面临同样的问题。下面的步骤可以解决问题。
停止所有正在运行的容器
docker stop $(docker ps -aq) 删除所有容器
docker rm $(docker ps -aq) 删除所有图片
docker rmi $(docker images -q)