Docker在使用中,但没有任何Docker容器

338
EDIT(2/19/21):自我提出这个问题多年以来,已经过去了很长时间,我看到了自那时以来的一系列活动。 我重新选择了一个答案,我认为它与解决此问题的最本地化和安全选项一致(通常与docker-compose相关)。 虽然docker确实引入了prune命令,但通常情况下它是一种危险操作,我会谨慎使用它,因为您可能会意外地影响其他在计算机上运行的应用程序或设置。
我一直在尝试使用Docker 1.9.1删除Docker卷时遇到问题。 我已经删除了所有停止的容器,所以docker ps -a返回为空。 但是,当我使用docker volume ls时,我会得到一堆Docker容器:
docker volume ls
DRIVER              VOLUME NAME
local               a94211ea91d66142886d72ec476ece477bb5d2e7e52a5d73b2f2f98f6efa6e66
local               4f673316d690ca2d41abbdc9bf980c7a3f8d67242d76562bbd44079f5f438317
local               eb6ab93effc4b90a2162e6fab6eeeb65bd0e4bd8a9290e1bad503d2a47aa8a78
local               91acb0f7644aec16d23a70f63f70027899017a884dab1f33ac8c4cf0dabe5f2c
local               4932e2fbad8f7e6246af96208d45a266eae11329f1adf176955f80ca2e874f69
local               68fd38fc78a8f02364a94934e9dd3b5d10e51de5b2546e7497eb21d6a1e7b750
local               7043a9642614dd6e9ca013cdf662451d2b3df6b1dddff97211a65ccf9f4c6d47
#etc x 50

由于这些卷中没有包含任何重要内容,我尝试使用 docker volume rm $(docker volume ls -q) 命令删除所有的卷。

在这个过程中,大部分都被删除了,但是我收到了以下反馈:

Error response from daemon: Conflict: volume is in use
Error response from daemon: Conflict: volume is in use
Error response from daemon: Conflict: volume is in use
Error response from daemon: Conflict: volume is in use
Error response from daemon: Conflict: volume is in use

对于其中很大一部分人而言,如果我一开始没有任何容器,这些体积是如何被使用的?


12
Docker使用引用计数来检查卷是否仍在使用,所有操作都在内存中完成。这可能是某种bug或竞争条件导致容器被删除,但计数器没有被更新。重启守护进程应该可以解决这个问题,但是可能存在bug。你的设置中是否有特殊之处(例如使用docker-in-docker、Swarm等)?你是否使用脚本或工具清理容器? - thaJeztah
8
嘿,谢谢 @thaJeztah 重新启动 Docker 守护进程(sudo service docker stopsudo service docker start)清理掉了所有幽灵卷。此外,现在使用 docker rm -v 命令可以轻松删除卷,似乎没有任何问题。唯一值得注意的区别是我在 Ubuntu 15.10 上使用了 docker-compose。如果我能够复制这个问题,我会再次报告,但否则似乎只需简单地重启即可解决。谢谢! - Tkwon123
4
即使重新启动,它仍然显示Docker卷正在使用中... - holms
16
如果您使用Docker Compose,可以在下达down命令时添加“-v”来删除卷。 - Niels Bech Nielsen
6
我通过停止 Docker,然后从文件系统中删除卷并重新启动 Docker 来解决了这个问题。 service docker stop && rm -rf /var/lib/docker/volumes/你想要删除的卷的ID && service docker start - jfgrissom
显示剩余3条评论
13个回答

498

也许这个卷是通过 docker-compose 创建的?如果是这样,应该通过以下方式进行删除:get removed by:

docker-compose down --volumes

感谢Niels Bech Nielsen


10
这很有效 :) 需要注意的是,这也会删除所有容器本身。如果您更改了容器中未在永久挂载点或镜像中的文件,这可能是不想要的。 - Alexander Varwijk
7
有没有仅删除单个卷而不是所有卷的方法? - David 天宇 Wong
3
请确保您在存放 docker-compose.yaml 文件的相同文件夹中。否则它将无法找到卷名称。但是这样做可以运行 - 谢谢! - gies0r
2
如果您更改了docker compose文件中的卷名称,这可能导致孤立的容器。Docker会在控制台打印出警告,您可以添加 --remove-orphans 标志来清理,然后可以删除相关联的卷。 - Cyril Duchon-Doris
2
非常重要的警告。这将删除docker-compose中的所有图像,请确保您想要执行此操作。 - Ross W
显示剩余4条评论

266

卷可以被一个已停止的容器使用。您可以使用以下命令删除这样的容器:

docker container prune

然后您可以删除未使用的卷

docker volume prune

17
这应该是被接受的答案,不知道为什么人们喜欢给出的那个答案。 - Elger Mensonides
2
这绝对是所提出问题的答案。不过,末日脚本也很不错。 - Ron Holmes
3
是的,这应该是被接受的答案。只有这些操作也帮助了我。 - Mutatos

257

您可以使用这些函数彻底删除与Docker相关的所有内容:

removecontainers() {
    docker stop $(docker ps -aq)
    docker rm $(docker ps -aq)
}

armageddon() {
    removecontainers
    docker network prune -f
    docker rmi -f $(docker images --filter dangling=true -qa)
    docker volume rm $(docker volume ls --filter dangling=true -q)
    docker rmi -f $(docker images -qa)
}

你可以将这些内容添加到你的~/Xrc文件中,其中X是你的shell解释器 (~/.bashrc如果你使用的是bash),然后通过执行 source ~/Xrc重新加载它们。此外,你也可以直接复制粘贴到控制台中,然后(不论你之前采取的选项如何准备函数),只需运行:

armageddon

它也可以用于普通的Docker清理。请注意,这也会删除您的镜像,不仅是运行或未运行的容器以及各种卷。


3
根据问题描述,“docker volume rm”命令执行失败。从评论中可以看出,解决方案似乎是重新启动docker守护进程以修复引用计数。 - BMitch
2
@BMitch如果您仔细阅读评论,就会发现那不是解决此问题的方法:“即使重新启动后,它仍然显示docker卷正在使用中..” - David González Ruiz
1
Holms似乎有一个不同的问题,并不是发布这个问题的人。请查看上面的一条评论。 - BMitch
13
"Gonsales"是函数名称,但实际上应该拼写为"armageddon"。请将其翻译成中文。 - Joseph Sheedy
7
这并没有解决我的问题。不过,使用 docker-compose down --volumes 确实解决了(正如 @Robert K. Bell 建议的那样)。 - BiAiB
显示剩余5条评论

69

我对Docker比较新手。我在清理一些初始测试数据时,无法删除一个卷。我已经停止了所有正在运行的实例,并执行了 docker rmi -f $(docker image ls -q),但仍然收到了 Error response from daemon: unable to remove volume: remove uuid: volume is in use 的错误信息。

然后我执行了docker system prune,它清除了需要删除最后一个卷的东西:

[0]$ docker system prune
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all build cache
Are you sure you want to continue? [y/N] y
Deleted Containers:
... about 15 containers UUID's truncated

Total reclaimed space: 2.273MB
[0]$ docker volume ls
DRIVER              VOLUME NAME
local              uuid
[0]$ docker volume rm uuid
uuid
[0]$

docker system prune

要使用此命令,客户端和守护程序 API 都必须至少为 1.25 版本。请在客户端上使用 docker version 命令检查您的客户端和守护程序 API 版本。


由于某些原因,在操作两次之后才成功。 - mameluc
3
我必须执行 "docker system prune",然后执行 "docker volume rm volume_name"。由于某种原因,prune 删除了我已经删除的容器。困惑 - Matthew Rideout

22

只要卷与容器相关联(无论其是否正在运行),它们就不能被删除。

您必须运行

docker inspect <container-id>/<container-name>

在可能安装了此卷的每个正在运行/未运行的容器上。

如果该卷被安装到任何一个容器上,您应该在检查命令输出的“挂载”部分中看到它。类似于这样:

"Mounts": [
            {
                "Type": "volume",
                "Name": "user1",
                "Source": "/var/lib/docker/volumes/user1/_data",
                "Destination": "/opt",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],

找出责任容器后,执行以下命令来删除正在运行的容器:

docker rm -f container-1 container-2 ...container-n

如果容器未在运行,则执行以下命令:

docker rm container-1 container-2 ...container-n

以从主机完全删除容器。

然后尝试使用以下命令删除卷:

docker volume remove <volume-name/volume-id>


1
为了得到一个有用的答案,这个回复需要被扩展。添加关于如何检查这个问题的信息。 - Jeroen Heier
5
我打赌在大多数情况下,使用docker container prune命令就足够了。 - x-yuri

17
  1. 首先使用以下命令修剪不需要的容器:

docker container prune

确保您真的想要删除所有容器

在删除所有不需要的容器后,还可以使用以下命令清理卷:

docker volume prune

12

目前,您可以使用Docker现在提供的通用和更完整的清理功能:

docker system prune

如果您想删除所有停止的容器和所有未使用的镜像(不仅仅是悬空镜像),请在命令中添加-a标志:

docker system prune -a

5

您必须先删除使用该卷的容器。 按名称列出所有容器,即使是已存在的容器:

docker ps --all --format '{{.Names}}'  

删除一个容器:

docker rm NAME

在删除容器后,您可以同时删除卷。 列出卷:

docker volume ls

移除卷:

docker volume remove VOLUME_NAME

有时候,为什么在“docker-compose --volumes”之后这个方法仍然有效的原因是:因为通过“docker compose run”意外地创建了一个短暂的容器。 - tjb
不错,但我发现只运行 docker ps --all 更加有用。 - xCovelus

4

一行简洁的文字,提供所需信息:

docker inspect `docker ps -aq` | jq '.[] | {Name: .Name, Mounts: .Mounts}' | less

搜寻投诉的容量时,您需要知道容器名称。

如果没有容器,即“docker ps -aq”没有返回任何内容,那么我们该如何找到挂载路径? - Manoj Kumar
docker volume inspect $(docker volume ls -q) | jq '.[] | {Name: .Name, Mountpoint: .Mountpoint}' 将会给你展示所有卷的路径,无论它们是否被容器使用... - Case Larsen

3

我相信这些卷实际上已经挂载在您的系统上了。在/proc/mounts中查看,您会在那里看到它们。您可能需要使用sudo umount <path>sudo umount -f -n <path>命令。您应该能够在/proc/mounts或通过docker volume inspect获取挂载路径。


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