如何使用 docker image prune 命令删除未使用的镜像

DockerDockerBeginner
立即练习

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

简介

在这个实验中,你将学习如何使用 docker image prune 命令删除未使用的 Docker 镜像,从而有效地管理磁盘空间。我们将首先了解该命令的用途,以及它所针对的不同类型的未使用镜像,特别是悬空镜像(dangling images)和所有未使用的镜像。

通过实践练习,你将练习删除悬空镜像,然后进一步扩展到删除所有未使用的镜像。此外,你将探索如何在 docker image prune 中使用过滤选项,根据创建时间和标签等条件有选择地删除镜像,从而让你对镜像清理过程进行精细控制。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ImageOperationsGroup(["Image Operations"]) docker(("Docker")) -.-> docker/SystemManagementGroup(["System Management"]) docker(("Docker")) -.-> docker/DockerfileGroup(["Dockerfile"]) docker/ImageOperationsGroup -.-> docker/pull("Pull Image from Repository") docker/ImageOperationsGroup -.-> docker/rmi("Remove Image") docker/ImageOperationsGroup -.-> docker/images("List Images") docker/SystemManagementGroup -.-> docker/prune("Remove Unused Docker Objects") docker/DockerfileGroup -.-> docker/build("Build Image from Dockerfile") subgraph Lab Skills docker/pull -.-> lab-555158{{"如何使用 docker image prune 命令删除未使用的镜像"}} docker/rmi -.-> lab-555158{{"如何使用 docker image prune 命令删除未使用的镜像"}} docker/images -.-> lab-555158{{"如何使用 docker image prune 命令删除未使用的镜像"}} docker/prune -.-> lab-555158{{"如何使用 docker image prune 命令删除未使用的镜像"}} docker/build -.-> lab-555158{{"如何使用 docker image prune 命令删除未使用的镜像"}} end

理解 docker image prune 的用途

在这一步中,我们将了解 docker image prune 命令的用途。在使用 Docker 时,你的系统上不可避免地会积累一些未使用的镜像。这些镜像会占用大量的磁盘空间。docker image prune 命令用于删除这些未使用的镜像,帮助你释放磁盘空间。

docker image prune 主要针对两种类型的未使用镜像:

  1. 悬空镜像(Dangling images):这些是没有标签且没有被任何容器引用的镜像。它们本质上是不再需要的中间层。
  2. 所有未使用的镜像:这包括悬空镜像,以及即使有标签但没有被任何容器引用的镜像。

让我们先创建一些悬空镜像,来看看 docker image prune 是如何工作的。我们将拉取几个不同版本的 ubuntu 镜像,然后基于其中一个版本构建一个新的镜像。这个过程通常会留下一些悬空镜像。

首先,拉取 ubuntu:latestubuntu:18.04 镜像。

docker pull ubuntu:latest
docker pull ubuntu:18.04

你应该会看到显示镜像正在被拉取的输出信息。

现在,让我们基于 ubuntu:latest 构建一个简单的镜像。在你的 ~/project 目录下创建一个名为 Dockerfile 的文件,内容如下:

FROM ubuntu:latest
RUN echo "Hello, Docker!" >/app/hello.txt

这个 Dockerfile 只是从 ubuntu:latest 镜像开始,然后在 /app 目录下添加一个名为 hello.txt 的文件。

现在,使用 docker build 命令构建镜像。我们不会给这个镜像打标签,这有助于创建一个悬空镜像。

docker build -t my-ubuntu-app ~/project

你应该会看到显示构建过程的输出信息。构建完成后,让我们列出所有镜像,包括中间层镜像,看看是否有悬空镜像。

docker images -a

查找 REPOSITORYTAG 列中显示 <none> 的镜像。这些就是悬空镜像。

docker image prune 命令默认用于删除这些悬空镜像。在下一步中,我们将使用这个命令清理刚刚创建的悬空镜像。

使用 docker image prune 删除悬空镜像

在上一步中,我们通过构建一个没有特定标签的镜像创建了一些悬空镜像。在这一步,我们将使用 docker image prune 命令来删除这些悬空镜像。

默认情况下,docker image prune 仅删除悬空镜像。这是清理未使用镜像层的最安全方法,可避免意外删除你可能仍需要的镜像,即使这些镜像当前未与正在运行的容器关联。

要删除悬空镜像,只需运行 docker image prune 命令:

docker image prune

当你运行此命令时,Docker 会显示一个它将删除的悬空镜像列表,并要求你确认。

WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N]

输入 y 并按回车键以继续删除操作。

命令执行完成后,它会报告回收的总磁盘空间。

现在,让我们再次列出所有镜像,包括中间层镜像,以确认悬空镜像已被删除。

docker images -a

你应该不会再看到 REPOSITORYTAG 列中显示 <none> 的镜像,这些镜像是在运行 docker image prune 之前存在的。ubuntu:latestubuntu:18.04my-ubuntu-app 镜像应该仍然存在,因为它们不是悬空镜像。

这展示了使用 docker image prune 删除悬空镜像的基本用法。定期执行此操作是释放 Docker 主机磁盘空间的良好实践。

使用 docker image prune -a 删除所有未使用的镜像

在上一步中,我们学习了如何使用 docker image prune 删除悬空镜像。虽然删除悬空镜像很有帮助,但你的系统上可能还有其他未被任何容器使用但并非悬空的镜像(即它们有标签)。要删除这些镜像,你可以在 docker image prune 命令中使用 -a(或 --all)标志。

docker image prune -a 命令会删除所有未使用的镜像,而不仅仅是悬空镜像。这是一种更激进的清理方式,使用时需要谨慎,因为它会删除任何当前未与正在运行的容器关联的镜像。

让我们看看这是如何工作的。首先,列出我们当前拥有的镜像。

docker images

你应该会看到 ubuntu:latestubuntu:18.04my-ubuntu-app。这些镜像当前没有被任何正在运行的容器使用,但它们不是悬空镜像,因为它们有标签。

现在,运行 docker image prune -a 命令:

docker image prune -a

与上一步类似,Docker 会显示一个它将删除的镜像列表,并要求你确认。

WARNING! This will remove all images without at least one container associated to them.
Are you sure you want to continue? [y/N]

输入 y 并按回车键继续操作。

命令执行完成后,它会报告回收的总磁盘空间。

现在,再次列出镜像,看看哪些镜像还保留着。

docker images

你应该会看到所有未与正在运行的容器关联的镜像都已被删除。如果你有正在运行的容器,这些容器所使用的镜像不会被删除。

使用 docker image prune -a 是释放大量磁盘空间的有效方法,但请记住,它会删除所有当前未使用的镜像。

根据创建时间过滤要清理的镜像

除了删除所有未使用的镜像之外,docker image prune 还允许你根据各种条件过滤要清理的镜像。一个有用的过滤条件是基于镜像的创建时间。这使你能够删除在特定时间点之前创建的镜像。

--filter 标志用于应用过滤条件。要根据创建时间进行过滤,你可以使用 until 过滤器。until 过滤器接受一个时间戳或一个时间段作为其值。在指定时间 之后 创建的镜像将被保留,而在指定时间 之前或当时 创建的镜像将被考虑清理。

首先,让我们拉取几个不同创建时间的镜像。我们将拉取 alpine:latestcentos:latest

docker pull alpine:latest
docker pull centos:latest

现在,让我们列出这些镜像并查看它们的创建时间。

docker images

注意每个镜像的 CREATED 列。

为了演示按时间过滤,我们需要一个参考点。假设我们要删除 5 分钟之前创建的镜像。我们可以使用 5m 这样的时间段来指定 until 过滤器。

docker image prune -a --filter "until=5m"

这个命令将考虑删除所有在 5 分钟之前创建的未使用镜像。Docker 在执行之前会再次要求你确认。

WARNING! This will remove all images without at least one container associated to them.
Are you sure you want to continue? [y/N]

输入 y 并按回车键确认。

清理完成后,再次列出镜像:

docker images

根据你拉取镜像和运行清理命令的时间间隔,可能会有一些镜像被删除。在过去 5 分钟内创建的镜像应该会保留。

你还可以使用各种格式指定具体的时间戳。例如,要删除在特定日期和时间之前创建的镜像,你可以使用 "2023-10-27T10:00:00" 这样的格式。

根据创建时间进行过滤对于自动化清理任务很有用,能确保系统上只保留相对较新的镜像。

根据标签过滤要清理的镜像

在最后这一步,我们将探索 docker image prune 的另一个强大过滤选项:基于标签进行过滤。标签是可以附加到 Docker 对象(包括镜像)上的键值对,用于添加元数据。然后,你可以使用这些标签来过滤和管理你的 Docker 资源。

使用 label 键的 --filter 标志允许你根据镜像的标签指定在清理过程中要包含或排除哪些镜像。

首先,让我们创建几个带有不同标签的镜像。我们将使用一个简单的 Dockerfile 并构建两个带有不同标签的镜像。

在你的 ~/project 目录中创建一个名为 Dockerfile.labeled 的文件,内容如下:

FROM alpine:latest
LABEL environment="development"
LABEL version="1.0"
RUN echo "This is a labeled image" >/app/info.txt

现在,从这个 Dockerfile 构建两个镜像,在构建过程中使用 --label 标志应用不同的标签。

docker build -t my-labeled-app:dev --label project=myapp --label stage=dev ~/project -f Dockerfile.labeled
docker build -t my-labeled-app:prod --label project=myapp --label stage=prod ~/project -f Dockerfile.labeled

现在我们已经构建了两个镜像,my-labeled-app:devmy-labeled-app:prod,它们都基于同一个 Dockerfile,但具有不同的 stage 标签。

让我们列出这些镜像并检查它们的标签。

docker images --filter reference="my-labeled-app*" --format "{{.Repository}}:{{.Tag}} {{.Labels}}"

你应该会看到显示镜像及其关联标签的输出。

现在,让我们使用 docker image prune 根据镜像的标签来删除镜像。假设我们要删除所有带有 stage=dev 标签的未使用镜像。我们可以使用带有 label=stage=dev--filter 标志。我们还将使用 -a 标志来考虑所有未使用的镜像,而不仅仅是悬空镜像。

docker image prune -a --filter "label=stage=dev"

Docker 会显示符合过滤条件并将被删除的镜像。输入 y 进行确认。

清理完成后,再次列出镜像:

docker images --filter reference="my-labeled-app*" --format "{{.Repository}}:{{.Tag}} {{.Labels}}"

你应该会看到 my-labeled-app:dev 镜像已被删除,而 my-labeled-app:prod 仍然存在,因为它不符合过滤条件。

你还可以使用 label!=key=value 语法来删除 具有特定标签或标签值的镜像。例如,要删除所有 具有 stage=prod 标签的未使用镜像:

docker image prune -a --filter "label!=stage=prod"

这个命令将删除 my-labeled-app:dev(如果它仍然存在)以及任何其他不具有 stage=prod 标签的未使用镜像。

根据标签进行过滤提供了一种灵活的方式,可根据你自己定义的元数据来管理和清理你的镜像。

总结

在本次实验中,我们学习了如何使用 docker image prune 命令,通过删除未使用的 Docker 镜像来管理磁盘空间。首先,我们了解了该命令的用途以及它所针对的未使用镜像类型:悬空镜像(无标签且未被引用的镜像)和所有未使用的镜像(包括有标签但未被引用的镜像)。然后,我们练习了使用基本的 docker image prune 命令来识别和删除悬空镜像。

我们进一步探索了 docker image prune 的功能,学习了如何使用 -a 标志删除所有未使用的镜像。最后,我们掌握了如何使用过滤选项,根据创建时间和标签等条件有选择地清理镜像,从而对镜像清理实现更精细的控制。