如何使用 docker system prune 命令回收磁盘空间

DockerDockerBeginner
立即练习

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

简介

在这个实验中,你将学习如何有效使用 docker system prune 命令,通过删除未使用的 Docker 数据来回收磁盘空间。首先,我们会了解 docker system prune 默认会删除哪些内容,其中包括已退出的容器、悬空镜像(dangling images)和悬空网络(dangling networks),但不包括卷(volumes)。

接下来,你将探索如何在删除未使用的 Docker 数据时特别排除卷,然后学习如何删除所有未使用的数据,包括匿名卷。最后,你将了解如何结合使用过滤器与 docker system prune 命令,从而更精细地控制要删除的数据。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) docker(("Docker")) -.-> docker/ImageOperationsGroup(["Image Operations"]) docker(("Docker")) -.-> docker/VolumeOperationsGroup(["Volume Operations"]) docker(("Docker")) -.-> docker/SystemManagementGroup(["System Management"]) docker/ContainerOperationsGroup -.-> docker/ps("List Running Containers") docker/ImageOperationsGroup -.-> docker/images("List Images") docker/VolumeOperationsGroup -.-> docker/volume("Manage Volumes") docker/SystemManagementGroup -.-> docker/system("Manage Docker") docker/SystemManagementGroup -.-> docker/prune("Remove Unused Docker Objects") subgraph Lab Skills docker/ps -.-> lab-555250{{"如何使用 docker system prune 命令回收磁盘空间"}} docker/images -.-> lab-555250{{"如何使用 docker system prune 命令回收磁盘空间"}} docker/volume -.-> lab-555250{{"如何使用 docker system prune 命令回收磁盘空间"}} docker/system -.-> lab-555250{{"如何使用 docker system prune 命令回收磁盘空间"}} docker/prune -.-> lab-555250{{"如何使用 docker system prune 命令回收磁盘空间"}} end

了解 docker system prune 默认删除的内容

在这一步中,我们将探究 docker system prune 命令,并了解它默认会删除哪些类型的未使用 Docker 数据。该命令可通过删除悬空或未使用的对象来清理磁盘空间。

首先,让我们创建一些未使用的 Docker 对象。我们将运行一个简单的容器,然后停止它。这样会留下一个已退出的容器,如果该镜像未被其他任何容器使用,还可能会产生一个悬空镜像(dangling image)。

在 LabEx 环境中打开终端。默认目录是 ~/project

运行一个简单的 hello-world 容器:

docker run hello-world

你应该会看到输出,表明 Docker 守护进程拉取了 hello-world 镜像并运行了容器。容器在打印完消息后会立即退出。

现在,列出所有容器,包括已退出的容器:

docker ps -a

你会看到 hello-world 容器的状态为“Exited”。

接下来,让我们列出镜像:

docker images

你应该会看到 hello-world 镜像。

现在,让我们在不使用任何选项的情况下运行 docker system prune 命令。这将删除悬空镜像、悬空容器和悬空网络。默认情况下,它 不会 删除卷(volumes)。

docker system prune -f

我们使用 -f 标志来强制删除,而无需确认提示。

运行该命令后,你会看到输出,表明哪些内容已被删除。

现在,让我们再次检查容器:

docker ps -a

已退出的 hello-world 容器应该已经消失。

再次检查镜像:

docker images

如果 hello-world 镜像不被视为“悬空”(例如,如果它是最近拉取的),则可能仍然存在。但是,如果你有其他悬空镜像,它们应该已经被删除。

这里的关键要点是,docker system prune 默认会清理已退出的容器、悬空镜像和悬空网络。除非你明确要求,否则它 不会 删除卷。

在不删除卷的情况下清理未使用的 Docker 数据

在上一步中,我们了解到 docker system prune 默认不会删除卷(volumes)。卷用于持久保存 Docker 容器生成和使用的数据。无意删除卷可能会导致数据丢失。

在这一步中,我们将演示 docker system prune 在不删除卷的情况下是如何工作的。我们将创建一个卷,运行一个使用该卷的容器,停止该容器,然后清理系统。我们会观察到清理后卷仍然存在。

首先,让我们创建一个命名卷(named volume)。命名卷由 Docker 显式创建和管理。

docker volume create myvolume

你应该会看到创建的卷的名称作为输出。

现在,让我们运行一个使用这个卷的简单容器。我们将使用 ubuntu 镜像。如果你本地没有该镜像,Docker 会拉取它。

docker run -d --name mycontainer -v myvolume:/app ubuntu sleep 60

此命令以分离模式(-d)运行一个 ubuntu 容器,将其命名为 mycontainer,将 myvolume 挂载到容器内的 /app 目录,并使用 sleep 60 命令让容器运行 60 秒。

检查容器是否正在运行:

docker ps

你应该会看到 mycontainer 被列出。

现在,停止容器:

docker stop mycontainer

容器将停止,但它仍会以已退出状态存在。

验证容器已停止:

docker ps -a

你应该会看到 mycontainer 的状态为“Exited”。

现在,让我们列出卷:

docker volume ls

你应该会看到 myvolume 被列出。

现在,再次运行 docker system prune。记住,默认情况下,它不会删除卷。

docker system prune -f

观察输出。它应该表明已退出的容器已被删除,但 不应 提及删除卷。

验证容器已被删除:

docker ps -a

mycontainer 应该不再被列出。

最后,验证卷仍然存在:

docker volume ls

你应该仍然会看到 myvolume 被列出。这证实了 docker system prune 默认会保留卷。

清理所有未使用的 Docker 数据,包括匿名卷

在前面的步骤中,我们了解到 docker system prune 默认不会删除卷。然而,在某些情况下,你可能希望清理所有未使用的 Docker 数据,包括那些不再与任何容器关联的卷。这对于清理匿名卷(anonymous volumes)特别有用,匿名卷是在你不明确指定卷名而将目录挂载到容器内时创建的。

要清理所有未使用的 Docker 数据,包括卷,你可以在 docker system prune 命令中使用 -a 标志。-a 标志代表“all”,会在清理过程中包含卷。

让我们通过运行一个容器并在不指定卷名的情况下挂载一个目录来创建一个匿名卷。

docker run -d --name anothercontainer -v /data ubuntu sleep 60

此命令运行一个名为 anothercontainerubuntu 容器,并将一个匿名卷挂载到容器内的 /data 目录。

检查容器是否正在运行:

docker ps

你应该会看到 anothercontainer 被列出。

现在,停止容器:

docker stop anothercontainer

容器将停止并变为已退出状态。

验证容器已停止:

docker ps -a

你应该会看到 anothercontainer 的状态为“Exited”。

现在,列出卷:

docker volume ls

你会看到上一步创建的 myvolume 和一个新的、具有长随机生成名称的卷。这就是匿名卷。

现在,使用 -a 标志运行 docker system prune 以清理所有未使用的数据,包括卷。

docker system prune -a -f

我们使用 -a 来包含卷,使用 -f 来强制删除而无需确认提示。

仔细观察输出。它应该表明已退出的容器已被删除,并且还应列出被删除的匿名卷。上一步创建的命名卷 myvolume 也应该被删除,因为它不再被任何容器使用。

验证所有容器都已被删除:

docker ps -a

应该没有容器被列出。

最后,验证所有卷都已被删除:

docker volume ls

应该没有卷被列出。这证实了 docker system prune -a 会清理所有未使用的 Docker 数据,包括命名卷和匿名卷。

使用过滤器清理 Docker 数据

除了清理所有未使用的数据之外,docker system prune 还允许你使用过滤器来选择性地删除 Docker 对象。这让你能更精细地控制要清理的内容。

过滤器可以应用于不同类型的对象。对于 docker system prune,你可以根据对象的使用时长等条件进行过滤。

让我们创建更多的 Docker 对象来演示过滤功能。我们将运行几个容器,然后停止它们。

运行第一个容器:

docker run -d --name oldcontainer ubuntu sleep 10

这个容器将运行 10 秒,然后退出。

运行第二个容器:

docker run -d --name newcontainer ubuntu sleep 20

这个容器将运行 20 秒,然后退出。

等待两个容器都退出。你可以使用 docker ps -a 检查它们的状态。

docker ps -a

你应该会看到 oldcontainernewcontainer 的状态均为“Exited”。

现在,让我们使用一个过滤器来只删除超过特定时长的对象。我们可以使用 until 过滤器并指定一个时长。例如,要删除超过 5 秒未使用的对象,可以使用 until=5s

让我们尝试删除超过 15 秒未使用的对象。这应该会删除 oldcontainer,但保留 newcontainer(前提是你等待的时间足够让 oldcontainer 退出,但 newcontainer 还未退出)。

docker system prune -f --filter "until=15s"

观察输出。它应该表明 oldcontainer 已被删除,但 newcontainer 应该仍然存在。

验证容器状态:

docker ps -a

你应该会看到 newcontainer 被列出,但 oldcontainer 应该已被删除。

现在,让我们再次进行清理,这次删除超过 30 秒未使用的对象。这应该也会删除 newcontainer

docker system prune -f --filter "until=30s"

观察输出。它应该表明 newcontainer 已被删除。

再次验证容器状态:

docker ps -a

应该没有容器被列出。

过滤器为定制清理过程提供了强大的方法。你可以根据要清理的对象类型(容器、镜像、卷、网络)使用不同的过滤键。until 过滤器通常用于清理在特定时长内未使用的对象。

总结

在本次实验中,我们学习了如何使用 docker system prune 命令,通过删除未使用的 Docker 数据来回收磁盘空间。首先,我们了解了 docker system prune 的默认行为,它会删除已退出的容器、悬空镜像(dangling images)和悬空网络(dangling networks)。我们通过创建并删除一个已退出的容器来演示了这一点。

接着,我们探讨了如何使用 docker system prune 的选项来控制要删除的数据。我们学习了如何在不删除卷的情况下清理未使用的数据,以及如何在清理过程中包含匿名卷。最后,我们介绍了如何使用过滤器根据特定条件选择性地清理 Docker 数据。本次实验为你提供了在 Docker 环境中使用 docker system prune 有效管理磁盘空间的实践经验。