Docker - 无法删除已停止的容器

104

我无法删除已停止的容器,每当我重新启动Docker服务后它就会再次出现。

docker ps -a
CONTAINER ID         STATUS          
11667ef16239         Dead

那么

docker rm -f 11667ef16239

然后,当我运行了docker ps -a命令时,没有显示任何Docker容器。

docker ps -a
CONTAINER ID         STATUS

但是,当我重新启动docker服务时:

service docker restart

再次运行docker ps -a命令:

docker ps -a
CONTAINER ID         STATUS          
11667ef16239         Dead

3
你好,这仍然是一个当前问题,但目前被接受的答案不再有效,并且存在相当大的风险。有umount的答案,是一个很好的选择,如果可能的话,请接受那个答案。 - Daniel F
“umount” 的解决方案已经不可行了,因为它不允许在资源被占用时卸载。同样地,杀死负责的 pid 也无法解决问题。 - runr
26个回答

64

您也可以使用此命令删除 dead 容器

docker rm $(docker ps --all -q -f status=dead)

但是,我真的不确定为什么会创建dead容器以及它们是如何被创建的。每当我遇到dead容器时,这个错误似乎与https://github.com/typesafehub/mesos-spark-integration-tests/issues/34有关。

[更新] 有了Docker 1.13的更新,我们可以轻松删除不需要的容器和悬挂镜像。

$ docker system df #will show used space, similar to the unix tool df
$ docker system prune # will remove all unused data.

@Akvel 它可以在没有它们的情况下工作。它已经死了,所以没有依赖进程。 - sk8terboi87 ツ
7
“docker system prune”做了比预期更多的事情,但解决了问题。正如原帖中所述,“docker rm --force”无效。 - rdupz
2
正如@rdupz所提示的那样,docker system prune是危险的,请参见此评论,了解它如何在使用-a时甚至删除命名卷。它还会删除网络,这通常不是您想要的。更好的方法是在1.13+中使用docker image prunedocker volume prune - RichVel
这个命令出现了语法错误。我认为你错放了强制“-f”参数。 - VPaul

54

很可能,在守护进程试图清理容器时发生了错误,导致其现在处于“僵尸”状态。

恐怕您唯一的选择就是手动清理它:

$ sudo rm -rf /var/lib/docker/<storage_driver>/11667ef16239.../

其中 <storage_driver> 是您驱动程序的名称 (aufs, overlay, btrfsdevicemapper)。


对于像我这样在生产环境中没有sudo权限的人来说,是否可以通过发出docker命令而不是使用sudo rm ...来实现此操作的功能等效呢? - Scott Stensland
1
您可能还想尝试相反的操作:使用zfs create创建该卷,以便Docker可以愉快地删除它。 - tadman
在删除文件后,可能还需要重新启动Docker服务。 - Mauro Baraldi
具体来说:创建一个新的ZFS数据集解决了这个问题..每个容器可能需要多个数据集。 - Mitchell Currie

45

最近事情有些微妙的变化,为了摆脱那些无用的容器,您可以尝试卸载已阻塞的文件系统以释放它们。

所以如果你收到类似这样的消息:

Error response from daemon: Cannot destroy container elated_wozniak: Driver devicemapper failed to remove root filesystem 656cfd09aee399c8ae8c8d3e735fe48d70be6672773616e15579c8de18e2a3b3: Device is Busy

只需运行此命令

umount /var/lib/docker/devicemapper/mnt/656cfd09aee399c8ae8c8d3e735fe48d70be6672773616e15579c8de18e2a3b3

之后通常可以移除容器


这个感觉是最好的,最安全的! - Daniel F
我刚刚重新启动了系统,当我重新登录时,容器不见了。 - superhero
这对我有用,但是我不得不重启docker服务才能使docker ps -a的输出实际上为空。 - Daniel Quinn
1
两年后,这篇文章仍然相关。刚刚花了两个小时尝试寻找解决方案,然后发现了这个链接:https://github.com/moby/moby/issues/3786#issuecomment-33471966。要卸载所有的devicemapper容器,请使用`umount $(grep 'devicemapper' /proc/mounts | awk '{print$2}' | sort -r)`。 - AlexanderF

30

在 CentOS 7 上使用 docker 17.06.1-ce 移除已停止的容器时,我遇到了以下错误:

Error response from daemon: driver "overlay" failed to remove root filesystem for <some-id>: 
remove /var/lib/docker/overlay/<some-id>/merged: device or resource busy

以下是我解决问题的方法:

1. 检查哪些其他进程也在使用Docker资源

$ grep docker /proc/*/mountinfo

输出结果类似于以下内容,其中/proc/后面的数字是pid

/proc/10001/mountinfo:179...
/proc/10002/mountinfo:149...
/proc/12345/mountinfo:159 149 0:36 / /var/lib/docker/overlay/...

2. 检查上述pid的进程名称

$ ps -p 10001 -o comm=
dockerd
$ ps -p 10002 -o comm=
docker-containe
$ ps -p 12345 -o comm=
nginx   <<<-- This is suspicious!!!

所以,pid 为12345的 nginx 似乎也正在使用 /var/lib/docker/overlay/...,因此我们无法删除相关的容器并出现 device or resource busy 错误。(请参见这里讨论如何使 nginx 与 docker 容器共享相同的挂载名称空间从而防止其被删除。)

3. 停止 nginx 然后我就可以成功地删除该容器。

$ sudo service nginx stop
$ docker rm <container-id>

1
感谢您提供有关Nginx的信息,我遇到了同样的问题,这让我很烦恼,我还遇到了DNS进程(named)的同样问题,不得不执行:systemctl restart named。谢谢您的帮助。 - user1928596

13

我遇到了同样的问题,但两个答案都没有帮助。

对我有用的是创建缺少的目录然后再将它们删除:

mkdir /var/lib/docker/devicemapper/mnt/656cfd09aee399c8ae8c8d3e735fe48d70be6672773616e15579c8de18e2a3b3
mkdir /var/lib/docker/devicemapper/mnt/656cfd09aee399c8ae8c8d3e735fe48d70be6672773616e15579c8de18e2a3b3-init
docker rm 656cfd09aee399c8ae8c8d3e735fe48d70be6672773616e15579c8de18e2a3b3

11

我通过强制删除容器的方式得到了解决。

docker rm -f <id_of_the_dead_container>

注意:

请注意,此命令可能会抛出以下错误:Error response from daemon: Driver devicemapper failed to remove root filesystem <id_of_the_dead_container>: Device is Busy

尽管会出现上述错误信息,但您的死亡容器设备映射应该被移除。也就是说,您将无法再访问此路径:

/var/lib/docker/devicemapper/mnt/<id_of_the_dead_container>


9

我尝试了上述所有方法(除了重新启动docker)。

这里是关于docker rm的错误:

$ docker rm 08d51aad0e74
Error response from daemon: driver "devicemapper" failed to remove root filesystem for 08d51aad0e74060f54bba36268386fe991eff74570e7ee29b7c4d74047d809aa: remove /var/lib/docker/devicemapper/mnt/670cdbd30a3627ae4801044d32a423284b540c5057002dd010186c69b6cc7eea: device or resource busy

接着我进行了以下操作:
$  grep docker /proc/*/mountinfo | grep 958722d105f8586978361409c9d70aff17c0af3a1970cb3c2fb7908fe5a310ac
/proc/20416/mountinfo:629 574 253:15 / /var/lib/docker/devicemapper/mnt/958722d105f8586978361409c9d70aff17c0af3a1970cb3c2fb7908fe5a310ac rw,relatime shared:288 - xfs /dev/mapper/docker-253:5-786536-958722d105f8586978361409c9d70aff17c0af3a1970cb3c2fb7908fe5a310ac rw,nouuid,attr2,inode64,logbsize=64k,sunit=128,swidth=128,noquota

这个命令会给出占用资源的进程PID - 20416(在“/proc/”之后)。然后我执行了“ps -p”命令,惊讶地发现:
[devops@dp01app5030 SeGrid]$ ps -p 20416
  PID TTY          TIME CMD
20416 ?        00:00:19 ntpd

一个真正的令人惊讶的时刻。所以我和谷歌一起解决了这个问题,并找到了这个:https://github.com/docker/for-linux/issues/124

结果发现我需要重新启动ntp守护程序,这样问题就解决了!


你救了我的一天。我一直在为这个问题苦苦挣扎。即使重新启动了Docker守护进程,问题仍未解决。我相信这个答案应该被接受。谢谢。 - sat

9
  1. 删除所有已停止的容器:docker rm -f $(docker ps --all -q -f status=dead)

  2. 删除所有已退出的容器:docker rm -f $(docker ps --all -q -f status=exited)

请注意,使用-f选项是必要的。


错误:没有这个容器:2787a08aaf3c 不起作用,它显示: 错误:没有这个容器:2f13ced716af 错误:没有这个容器:48d43ea0e93f 错误:没有这个容器:ab7720dd4392 错误:没有这个容器:c81751444fad - juliangonzalez
1
我的系统出了些问题。你在两天之内第二次救了我。哈哈。 - Sebastian

6
grep 656cfd09aee399c8ae8c8d3e735fe48d70be6672773616e15579c8de18e2a3b3 /proc/*/mountinfo

然后找到656cfd09aee399c8ae8c8d3e735fe48d70be6672773616e15579c8de18e2a3b3and的pid并将其杀死。


在编程中,/proc/后面的数字就是进程ID。 - Belter

6

尝试运行以下命令。这对我总是有效的。

# docker volume rm $(docker volume ls -qf dangling=true)
# docker rm $(docker ps -q -f 'status=exited')

执行上述命令后,通过以下方式重启 Docker:

# service docker restart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接