如何使用 docker volume prune 命令移除未使用的卷

DockerDockerBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在本次实验中,你将学习如何有效地管理 Docker 卷,重点是 docker volume prune 命令。我们将首先创建并检查各种类型的卷,包括命名卷和带有标签的卷,以了解它们的属性以及 Docker 如何管理它们。

接下来,我们将通过创建并移除一个使用卷的容器,演示卷如何与容器一起使用。这将突出显示存储在卷中的数据的持久性。最后,本实验将指导你使用 docker volume prune 命令移除未使用的卷,包括移除匿名卷、所有未使用的卷(包括命名卷),以及使用标签过滤器有选择地清理卷。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/SystemManagementGroup(["System Management"]) docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) docker(("Docker")) -.-> docker/ImageOperationsGroup(["Image Operations"]) docker(("Docker")) -.-> docker/VolumeOperationsGroup(["Volume Operations"]) docker/ContainerOperationsGroup -.-> docker/run("Run a Container") docker/ContainerOperationsGroup -.-> docker/ls("List Containers") docker/ContainerOperationsGroup -.-> docker/rm("Remove Container") docker/ContainerOperationsGroup -.-> docker/inspect("Inspect Container") docker/ImageOperationsGroup -.-> docker/pull("Pull Image from Repository") docker/VolumeOperationsGroup -.-> docker/volume("Manage Volumes") docker/SystemManagementGroup -.-> docker/prune("Remove Unused Docker Objects") subgraph Lab Skills docker/run -.-> lab-555261{{"如何使用 docker volume prune 命令移除未使用的卷"}} docker/ls -.-> lab-555261{{"如何使用 docker volume prune 命令移除未使用的卷"}} docker/rm -.-> lab-555261{{"如何使用 docker volume prune 命令移除未使用的卷"}} docker/inspect -.-> lab-555261{{"如何使用 docker volume prune 命令移除未使用的卷"}} docker/pull -.-> lab-555261{{"如何使用 docker volume prune 命令移除未使用的卷"}} docker/volume -.-> lab-555261{{"如何使用 docker volume prune 命令移除未使用的卷"}} docker/prune -.-> lab-555261{{"如何使用 docker volume prune 命令移除未使用的卷"}} end

创建并检查一些卷

在这一步中,你将学习如何创建和检查 Docker 卷。卷是持久化 Docker 容器生成和使用的数据的首选方式。虽然绑定挂载依赖于主机的目录结构,但卷完全由 Docker 管理。

首先,让我们使用 docker volume create 命令创建一个命名卷。我们将这个卷命名为 myvolume

docker volume create myvolume

你应该会在控制台看到卷的名称,这确认了它已创建成功。

现在,让我们使用 docker volume inspect 命令检查刚刚创建的卷。此命令提供有关卷的详细信息,例如它的名称、驱动程序以及在主机上的挂载点。

docker volume inspect myvolume

输出将是一个包含卷信息的 JSON 数组。查找 "Mountpoint" 字段,它显示了卷的数据在主机上的存储位置。Docker 管理这个位置,通常你应该避免直接在这个目录中修改文件。

接下来,让我们创建另一个卷,这次带有一个标签。标签对于组织和过滤 Docker 对象很有用。我们将创建一个名为 labeled_volume 的卷,并添加一个标签 app=web

docker volume create --label app=web labeled_volume

同样,卷创建成功后会打印出它的名称。

最后,让我们检查 labeled_volume 以查看我们添加的标签。

docker volume inspect labeled_volume

在 JSON 输出中,你应该能找到包含 app=web 标签的 "Labels" 字段。

创建并移除使用卷的容器

在这一步中,我们将创建一个 Docker 容器,并将上一步创建的 myvolume 卷挂载到该容器上。这将演示即使容器被移除,数据仍然可以持久化。

首先,让我们拉取 ubuntu 镜像,我们将使用该镜像来创建容器。

docker pull ubuntu

此命令会从 Docker Hub 下载 ubuntu 镜像。

现在,我们将基于 ubuntu 镜像运行一个容器,并将 myvolume 卷挂载到容器内的 /app 目录。我们还将运行一个命令,将一些数据写入挂载卷内的文件中。

docker run -d --name mycontainer -v myvolume:/app ubuntu /bin/bash -c "echo 'Hello from the container!' > /app/data.txt; sleep 30"

让我们分解一下这个命令:

  • docker run:此命令用于运行一个新容器。
  • -d:该标志使容器以分离模式运行,即容器在后台运行。
  • --name mycontainer:这将容器命名为 mycontainer,方便后续引用。
  • -v myvolume:/app:这是使用卷的关键部分。它将命名卷 myvolume 挂载到容器内的 /app 目录。
  • ubuntu:指定用于容器的镜像。
  • /bin/bash -c "echo 'Hello from the container!' > /app/data.txt; sleep 30":这是在容器内执行的命令。它使用 bash 运行两个命令:首先,将字符串 "Hello from the container!" 写入 /app 目录(即挂载的卷)下名为 data.txt 的文件中;然后,让容器休眠 30 秒,使其在短时间内保持运行状态。

你可以使用 docker ps 命令检查容器是否正在运行。

docker ps

你应该会在输出中看到 mycontainer,其状态为 "Up"。

现在,让我们移除该容器。即使我们移除了容器,写入卷的数据应该仍然存在。

docker rm -f mycontainer

-f 标志强制移除容器,即使它仍在运行。

为了验证数据是否仍然存在于卷中,我们可以运行一个新容器并挂载相同的卷,然后检查文件的内容。

docker run --rm -v myvolume:/app ubuntu cat /app/data.txt

让我们分解一下这个命令:

  • docker run:运行一个新容器。
  • --rm:该标志使容器在退出时自动移除。
  • -v myvolume:/app:将 myvolume 卷挂载到新容器的 /app 目录。
  • ubuntu:使用 ubuntu 镜像。
  • cat /app/data.txt:这是在容器内执行的命令。它使用 cat 命令显示 /app 目录下 data.txt 文件的内容。

你应该会在控制台看到 "Hello from the container!",这证实了即使原始容器被移除,数据仍然存在于卷中。

清理未使用的匿名卷

在这一步中,你将学习如何移除未使用的匿名卷。当你在将卷挂载到容器时没有显式地为其命名,就会创建匿名卷。通常,创建这些匿名卷的容器被移除时,它们也会被移除,但有时它们可能会保留下来。清理操作有助于清除这些未使用的卷。

首先,让我们创建一个带有匿名卷的容器。我们将运行一个简单的容器,该容器会立即退出。

docker run --rm -v /data ubuntu ls /data

下面来分解一下这个命令:

  • docker run:运行一个新容器。
  • --rm:该标志会使容器在退出时自动被移除。
  • -v /data:这会创建一个匿名卷,并将其挂载到容器内的 /data 目录。由于我们在冒号前没有指定名称,Docker 会为该卷生成一个随机名称。
  • ubuntu:使用 ubuntu 镜像。
  • ls /data:在容器内执行的命令,用于列出 /data 目录的内容。

尽管由于 --rm 标志容器被移除了,但如果 Docker 没有显式清理该匿名卷,它可能仍然存在。

要查看所有卷,包括匿名卷,你可以使用 docker volume ls 命令。

docker volume ls

你应该会看到前几步创建的 myvolumelabeled_volume,还可能会看到一个或多个看起来很长且随机的卷名。这些就是匿名卷。

现在,让我们使用 docker volume prune 命令清理未使用的匿名卷。默认情况下,此命令只会移除当前没有被任何容器使用的匿名卷。

docker volume prune

Docker 在执行操作前会要求你确认。输入 y 并按回车键。

输出会显示哪些卷被移除了。你应该会看到未使用的匿名卷被移除。

让我们再次列出卷,以确认匿名卷已被移除。

docker volume ls

现在,你应该只会在列表中看到命名卷(myvolumelabeled_volume)。

清理所有未使用的卷,包括命名卷

在上一步中,我们清理了未使用的匿名卷。在这一步,你将学习如何清理所有未使用的卷,包括当前未挂载到任何容器的命名卷。

首先,让我们列出现有的卷,看看都有哪些。

docker volume ls

你应该会看到 myvolumelabeled_volume 被列出。这些是命名卷,默认的 docker volume prune 命令不会移除它们,因为它们是命名卷。

要清理所有未使用的卷,包括命名卷,我们需要在 docker volume prune 命令中使用 --all-a 标志。

docker volume prune --all

Docker 会再次要求你确认。输入 y 并按回车键。

输出会显示哪些卷正在被移除。由于 myvolumelabeled_volume 当前没有被任何容器使用,它们将被移除。

让我们再次列出卷,以确认所有未使用的卷都已被移除。

docker volume ls

现在你应该会看到一个空列表,这表明所有未使用的卷,包括匿名卷和命名卷,都已被移除。

使用标签过滤器清理卷

在最后这一步,你将学习如何根据标签来清理卷。这是一种强大的方法,可选择性地移除符合特定条件的卷,而不影响其他卷。

首先,让我们创建几个带有不同标签的新卷,以便进行过滤操作。

docker volume create --label env=dev dev_volume
docker volume create --label env=prod prod_volume
docker volume create --label type=data data_volume

我们创建了三个新卷:带有标签 env=devdev_volume、带有标签 env=prodprod_volume 以及带有标签 type=datadata_volume

让我们列出所有卷,查看新创建的卷。

docker volume ls

你应该会在列表中看到 dev_volumeprod_volumedata_volume

现在,让我们仅清理带有标签 env=dev 的卷。我们可以在 --filter 标志中使用 label 键。

docker volume prune --filter label=env=dev

Docker 会要求你确认。输入 y 并按回车键。

输出会显示 dev_volume 已被移除。

让我们再次列出卷,确认只有 dev_volume 被移除了。

docker volume ls

现在你应该会看到 prod_volumedata_volume 仍保留着。

我们还可以过滤掉不包含特定标签的卷。例如,让我们清理不带有标签 type=data 的卷。

docker volume prune --filter label!=type=data

Docker 会要求你确认。输入 y 并按回车键。

输出会显示 prod_volume 已被移除。

让我们最后一次列出卷,看看还剩下哪些。

docker volume ls

现在你应该只会看到 data_volume 还保留着。

这展示了你如何根据自身需求使用标签过滤器来选择性地清理卷。

总结

在本次实验中,你学习了如何管理 Docker 卷,它是持久化容器数据的首选方法。首先,你使用 docker volume createdocker volume inspect 创建并检查了命名卷和带有标签的卷。这让你了解了卷是如何创建的,并查看了它们的详细信息,包括挂载点和关联的标签。

随后,你通过创建一个使用命名卷的容器,然后移除该容器,展示了数据的持久性。这凸显了在容器被移除后,卷及其数据仍然保持完整。最后,你探索了 docker volume prune 命令,学习了如何默认移除未使用的匿名卷,如何使用 --all 标志移除所有未使用的卷(包括命名卷),以及如何使用 --filter 选项根据标签选择性地清理卷。这些步骤为你清理未使用的卷以释放磁盘空间提供了实践经验。