无法删除具有相关子映像的Docker映像


163

我在尝试

docker rmi c565603bc87f

错误:

守护程序的错误响应:冲突:无法删除c565603bc87f(无法强制执行)-图像具有相关的子图像

因此,即使使用-f标志,我也无法删除图像。然后如何删除图像及其所有子级?

Linux和docker版本:

uname -a Linux goracio-pc 4.4.0-24-generic#43-Ubuntu SMP Wed Jun 8 19:27:37 UTC 2016 x86_64 x86_64 x86_64 GNU / Linux

docker版本客户端:版本:1.11.2 API版本:1.23 Go版本:go1.5.4 Git提交:b9f10c9内置:Wed Jun 1 22:00:43 2016 OS / Arch:linux / amd64

服务器:版本:1.11.2 API版本:1.23 Go版本:go1.5.4 Git提交:b9f10c9内置:Wed Jun 1 22:00:43 2016 OS / Arch:linux / amd64



2
按标签从最新到最旧删除。如果它们位于存储库中,则在任何Dockerfile需要它们的情况下将它们拉出。
rafaelbattesti

您应该接受Nguyen提供的(非常好)答案
jpw

Answers:


119

在删除图像之前,您应该尝试删除不必要的图像:

docker rmi $(docker images --filter "dangling=true" -q --no-trunc)

之后,运行:

docker rmi c565603bc87f

12
没有任何悬空的映像... docker images -f dangling = true-> Nothing
Roman

39
这个答案回答了另一个问题“如何删除悬空的图像?” OP的问题是“如何删除相关映像?”
tu-Restate Monica-dor duh,2016年

6
要移除悬挂图片,只需使用prune
德清

17
该命令不再起作用:> "docker rmi" requires at least 1 argument.
samayo

2
@samayo如果遇到该错误,请尝试将过滤器部分更改为:--filter=dangling=true。如果仍然出现该错误,则意味着您没有任何悬挂的图像,因此内置命令的结果为空字符串。
HammerN'Songs,

100

在某些情况下(例如我的情况),您可能试图通过指定图像ID来删除图像,该图像ID包含多个您没有意识到的标签,而其中一些标签可能会被其他图像使用。在这种情况下,您可能不想删除图像

如果您有一个此处所述的冗余标签,则不要在冗余标签上docker rmi <image_id>使用,而是docker rmi <repo:tag>要删除它。


11
docker rmi <repo:tag>为我工作。您的解决方案在这些答案中非常简单,谢谢。
张世和

对于我的偏远较旧的golang图像而言,这应该是正确的方法
寺庙

谢谢,这是我的票。Untagged: drud/ddev-webserver:20200301_leymannx_apache-junk-built
rfay

如果有人安装了Microsoft的eShopOnContainers示例,则您绝对必须以这种方式删除每个示例,repo:tag因为它会创建八个标记的图像,这些图像仅共享两个图像ID。甚至Visual Studio也不会在其容器管理窗口中删除它们...
mdisibio

该命令docker rmi <repo:tag>取消标记,不一定删除图像。如果引用该图像的标签不止一个,或者存在另一个问题,例如OP指出的问题,则该图像仍将存在。您可以使用命令检查图像是否仍然存在docker images ls --all
twan163

49

以前的所有答案都是正确的,但这是一个解决方案,它只是强制删除所有图像(使用此命令的风险自负,它将删除所有图像

docker rmi $(docker images -q) -f

在此处输入图片说明


1
这对我有用;我只是想吹走我所有的本地图像。注意,我必须进行更新才能使用我的Docker版本(18.09.7): docker image rm $(docker image ls -a -q) -f
akagixxer

40

查找在有问题的图像之后创建的所有图像的图像ID和父ID,如下所示:

docker inspect --format='{{.Id}} {{.Parent}}' $(docker images --filter since=<image_id> -q)

然后调用命令:

docker rmi {sub_image_id} 

“ sub_image_id”是从属图像的ID


删除特定图像的中间图像非常好。谢谢!!
A.Villegas '19

未知标志--filter:/
SamuraiJack

这似乎是问题的实际解决方案!
Paolo

28

对我有用的是使用REPOSITORY:TAG组合而不是IMAGE ID。

当我尝试docker rmi <IMAGE ID>使用没有与该映像关联的容器的命令删除docker映像时,出现以下消息:

$ docker rmi 3f66bec2c6bf
Error response from daemon: conflict: unable to delete 3f66bec2c6bf (cannot be forced) - image has dependent child images

使用命令后,我可以成功删除 docker rmi RPOSITORY:TAG

$ docker rmi ubuntu:18.04v1
Untagged: ubuntu:18.04v1

确实。任何解释为什么这种奇怪的行为?
RodrigoM

1
这也为我工作。就我而言,我有一个过时的Ubuntu映像,在其他任何映像中都没有将其作为父映像引用,但仍然无法删除。docker rmi 93fd78260bd1失败了,但是后来docker tag 93fd78260bd1 ubuntu:temp && docker rmi ubuntu:temp成功了。
Thomas Lobker

为我工作,还更新了过时的图像。有人知道为什么它会失败吗?
迈步

3
这并不会真正删除图像。它只是删除该图像的重复标签(因此消息Untagged: ubuntu:18.04v1)。如果这样做docker images -a,您可能3f66bec2c6bf仍会看到列表。如果图像确实被删除,您会收到消息Deleted: 3f66bec2c6bf
wisbucky

17

该命令删除了所有图像(谨慎使用)

您是否尝试过使用--force

sudo docker rmi $(sudo docker images -aq) --force

上面的代码甚至像我一样遇到魅力也一样


1
我在两个地方都放弃了sudo,这对我来说非常
有用


6

这是一个脚本,用于删除图像和所有依赖该图像的图像。

#!/bin/bash

if [[ $# -lt 1 ]]; then
    echo must supply image to remove;
    exit 1;
fi;

get_image_children ()
{
    ret=()
    for i in $(docker image ls -a --no-trunc -q); do
        #>&2 echo processing image "$i";
        #>&2 echo parent is $(docker image inspect --format '{{.Parent}}' "$i")
        if [[ "$(docker image inspect --format '{{.Parent}}' "$i")" == "$1" ]]; then
            ret+=("$i");
        fi;
    done;
    echo "${ret[@]}";
}

realid=$(docker image inspect --format '{{.Id}}' "$1")
if [[ -z "$realid" ]]; then
    echo "$1 is not a valid image.";
    exit 2;
fi;
images_to_remove=("$realid");
images_to_process=("$realid");
while [[ "${#images_to_process[@]}" -gt 0 ]]; do
    children_to_process=();
    for i in "${!images_to_process[@]}"; do
        children=$(get_image_children "${images_to_process[$i]}");
        if [[ ! -z "$children" ]]; then
            # allow word splitting on the children.
            children_to_process+=($children);
        fi;
    done;
    if [[ "${#children_to_process[@]}" -gt 0 ]]; then
        images_to_process=("${children_to_process[@]}");
        images_to_remove+=("${children_to_process[@]}");
    else
        #no images have any children. We're done creating the graph.
        break;
    fi;
done;
echo images_to_remove = "$(printf %s\n "${images_to_remove[@]}")";
indices=(${!images_to_remove[@]});
for ((i="${#indices[@]}" - 1; i >= 0; --i)) ; do
    image_to_remove="${images_to_remove[indices[i]]}"
    if [[ "${image_to_remove:0:7}" == "sha256:" ]]; then
        image_to_remove="${image_to_remove:7}";
    fi
    echo removing image "$image_to_remove";
    docker rmi "$image_to_remove";
done

6
# docker rm $(docker ps -aq)

之后,使用Nguyen建议的命令。


4

此处基于Simon Brady的蛮力方法构建,如果没有大量图像,则可以使用以下shell函数:

recursive_remove_image() {
  for image in $(docker images --quiet --filter "since=${1}")
  do
    if [ $(docker history --quiet ${image} | grep ${1}) ]
    then
      recursive_remove_image "${image}"
    fi
  done
  echo "Removing: ${1}"
  docker rmi -f ${1}
}

然后使用进行调用recursive_remove_image <image-id>


4
docker rmi <rep:tag>

例如:

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
python              3.6            60f85556d5d2        4 days ago          174MB

码头工人rmi python:3.6


3

当我想"<none>"在docker中删除一些名称未使用的图像时,我遇到了问题unable to delete a354bbc7c9b7 (cannot be forced) - image has dependent child images。因此为了解决这个问题:

须藤码头工人ps -a

CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS                         PORTS                                              NAMES
01ee1276bbe0        lizard:1                    "/bin/sh -c 'java ..."   About an hour ago   Exited (1) About an hour ago                                                      objective_lewin
49d73d8fb023        javaapp:latest              "/usr/bin/java -ja..."   19 hours ago        Up 19 hours                    0.0.0.0:8091->8091/tcp                             pedantic_bell
405fd452c788        javaapp:latest              "/usr/bin/java -ja..."   19 hours ago        Created                                                                           infallible_varahamihira
532257a8b705        javaapp:latest              "/usr/bin/java -ja..."   19 hours ago        Created                                                                           demo-default
9807158b3fd5        javaapp:latest              "/usr/bin/java -ja..."   19 hours ago        Created                                                                           xenodochial_kilby
474930241afa        jenkins                     "/bin/tini -- /usr..."   13 days ago         Up 4 days                      0.0.0.0:8080->8080/tcp, 0.0.0.0:50000->50000/tcp   myjenkins
563d8c34682f        mysql/mysql-server:latest   "/entrypoint.sh my..."   3 weeks ago         Up 4 days (healthy)            0.0.0.0:3306->3306/tcp, 33060/tcp                  mymysql
b4ca73d45d20        phpmyadmin/phpmyadmin       "/run.sh phpmyadmin"     4 weeks ago         Exited (0) 3 weeks ago                                                            phpmyadmin

您可以看到我有几个名称为javaapp:latest的图像和不同的容器名称。因此,我使用以下命令杀死并删除了“ javaapp:latest”容器的所有容器:

须藤码头工人停止“ containerName”

须藤码头工人rm“ containrName”

然后

须藤码头rmi -f“ imageId”

所以我可以删除所有带有名称的图像 "<none>"

祝好运


1

我也遇到了这个问题,可以通过以下命令解决问题。这可能是图像容器正在运行或退出的原因,因此在删除图像之前,您需要先删除容器

docker ps -a -f status = exited:此命令显示所有退出的容器,因此复制容器ID,然后在以下命令中运行以删除容器

docker rm #containerId:此命令删除容器,可能会出现以下问题:“图像具有依赖的子图像”

然后尝试使用以下命令删除图像

泊坞窗rmi #ImageId


1

我遇到了这个问题,即使在上面@tudor提到的页面中,这里的简短答案也没有用。我以为我会在这里分享我如何摆脱这些图像。我提出了一个想法,即从属图像必须大于或等于父图像的大小,这有助于识别它,因此我们可以将其删除。

我按大小列出了图像,以查看是否可以发现任何相关性:

docker images --format '{{.Size}}\t{{.Repository}}\t{{.Tag}}\t{{.ID}}' | sort -h -r | column -t

这是在docker中使用一些特殊格式来首先定位图像大小列,然后以相反的顺序运行人类可读的排序。然后,我恢复了易于阅读的列。

然后,我查看了这些<none>容器,并将列表中的第一个与类似的容器进行匹配。我docker rmi <image:tag>对该图像进行了简单的处理<none>子图像都随之处理。

所有子图像的问题图像实际上是我使用的该死的myrepo/getstarted-lab 图像我第一次开始使用docker时。这是因为我从创建链的第一个测试图像中创建了一个新图像。

希望这可以在某些时候帮助别人。


1

假设我们有一个Dockerfile

FROM ubuntu:trusty
CMD ping localhost

我们从中构建图像而无需TAG或命名

docker build .

现在,我们有一个成功报告“成功构建了57ca5ce94d04”如果我们看到docker镜像

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<none>              <none>              57ca5ce94d04        18 seconds ago      188MB
ubuntu              trusty              8789038981bc        11 days ago         188MB

我们需要先删除 docker rmi 57ca5ce94d04

其次是

docker rmi 8789038981bc

通过该图像将被删除!

根据某人的建议强行清除所有内容

docker rmi $(docker images -q) -f

1

扩展@Nguyen提供的答案-可以将该功能添加到您的.bashrcetc中,然后从命令行调用以帮助清理任何内容image has dependent child images错误...

您可以自己运行该功能,如果docker ps失败,它将使用docker命令运行sudo并提示您输入密码。

难道不是为所有正在运行的集装箱删除图像!

docker_rmi_dependants ()                                                                                                                                                         
{ 
  DOCKER=docker
  [ docker ps >/dev/null 2>&1 ] || DOCKER="sudo docker"

  echo "Docker: ${DOCKER}"

  for n in $(${DOCKER} images | awk '$2 == "<none>" {print $3}');
  do  
    echo "ImageID: $n";
    ${DOCKER} inspect --format='{{.Id}} {{.Parent}}' $(${DOCKER} images --filter since=$n -q);
  done;

  ${DOCKER} rmi $(${DOCKER} images | awk '$2 == "<none>" {print $3}')
}

我的.bashrc档案中也有这个...

docker_rm_dangling ()  
{ 
  DOCKER=docker
  [ docker ps >/dev/null 2>&1 ] || DOCKER="sudo docker"

  echo "Docker: ${DOCKER}"

  ${DOCKER} images -f dangling=true 2>&1 > /dev/null && YES=$?;                                                                                                                  
  if [ $YES -eq 1 ]; then
    read -t 30 -p "Press ENTER to remove, or CTRL-C to quit.";
    ${DOCKER} rmi $(${DOCKER} images -f dangling=true -q);
  else
    echo "Nothing to do... all groovy!";
  fi  
}

适用于:

$ docker --version 
Docker version 17.05.0-ce, build 89658be

0

强制删除图像列表(例如,不包括版本10)

泊坞窗图片| grep版本| grep -v版本10> images.txt && for img in $(awk -F“”'{print $ 3}'/root/images.txt); 做docker rmi -f $ img; 做完了


-1

您可以这样做:

➜〜须藤泊坞窗RMI 4ed13257bb55 -f删除:SHA256:4ed13257bb5512b975b316ef482592482ca54018a7728​​ea1fc387e873a68c358删除:SHA256:4a478ca02e8d2336595dcbed9c4ce034cd15f01229733e7d93a83fbb3a9026d3删除:SHA256:96df41d1ce6065cf75d05873fb1f9ea9fed0ca86addcfcec7722200ed3484c69删除:SHA256:d95efe864c7096c38757b80fddad12819fffd68ac3cc73333ebffaa42385fded


-1

图像层:存储库通常称为图像或容器图像,但实际上它们由一层或多层组成。存储库中的图像层以父子关系连接在一起。每个图像层代表自身和父层之间的变化。

docker构建模式使用继承。这意味着版本i取决于version i-1。因此,我们必须删除版本i+1才能删除version i。这是一个简单的依赖关系。

如果您想删除除最后一个(最新的)和第一个(基本的)以外的所有图像,那么我们可以使用docker save以下命令导出最后一个(最新的)。

docker save -o <output_file> <your_image-id> | gzip <output_file>.tgz

然后,如下所示,使用image-id删除所有图像。

docker rm -f <image-id i> | docker rm -f <image i-1> | docker rm -f <image-id i-2> ... <docker rm -f <image-id i-k> # where i-k = 1

现在,如下所示加载您保存的tgz图像。

gzip -c <output_file.tgz> | docker load

使用docker ps -q查看加载的图像的图像ID。它没有标签和名称。您可以按照以下步骤简单地更新标签和名称。

docker tag <image_id> group_name/name:tag
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.