介绍
在这个实验中,你将学习如何使用 docker image rm 命令有效地管理 Docker 镜像。首先,我们会列出系统上现有的镜像,让你了解自己拥有哪些镜像。
接下来,我们将探讨不同的镜像删除场景,包括尝试删除带有多个标签的镜像、按标签删除镜像、使用强制选项按 ID 删除镜像,最后按摘要(digest)删除镜像。通过这个实践操作,你将掌握清理无用或不需要的 Docker 镜像所需的技能。
列出现有镜像
在这一步中,你将学习如何列出系统上当前可用的 Docker 镜像。Docker 镜像是容器的构建基础,它们是用于创建容器的只读模板。
要列出镜像,你可以使用 docker images 命令。该命令会显示 Docker 在你的机器上下载或构建的所有镜像列表。
让我们来试试看。打开终端并运行以下命令:
docker images
你应该会看到类似以下的输出(具体的镜像和详细信息可能会因你之前使用 Docker 的操作而有所不同):
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 270000000000 2 weeks ago 77.8MB
hello-world latest d00000000000 2 months ago 13.3kB
输出提供了每个镜像的一些信息:
REPOSITORY:镜像的名称。TAG:镜像的特定版本。如果未指定标签,latest是默认标签。IMAGE ID:镜像的唯一标识符。CREATED:镜像创建的时间。SIZE:镜像的大小。
了解你拥有的镜像,是管理它们的第一步。在接下来的步骤中,我们将探讨如何删除镜像。
尝试删除带有多个标签的镜像
在这一步中,我们将探讨当你尝试删除一个有多个标签指向同一镜像 ID 的 Docker 镜像时会发生什么。当你用不同的版本号或名称为镜像打标签时,这是一种常见的情况。
首先,让我们拉取一个镜像并为其添加一个额外的标签。在这个例子中,我们将使用 hello-world 镜像。如果你已经有这个镜像,拉取过程会非常快。
docker pull hello-world
现在,让我们使用 docker tag 命令为这个镜像添加另一个标签。语法是 docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]。我们将为 hello-world:latest 镜像添加一个名为 hello-world:mytag 的新标签。
docker tag hello-world:latest hello-world:mytag
现在,让我们再次列出镜像,查看新标签。
docker images
你应该会看到 hello-world 有两条记录,一条是 latest 标签,另一条是 mytag 标签,但它们的 IMAGE ID 是相同的。
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 270000000000 2 weeks ago 77.8MB
hello-world latest d00000000000 2 months ago 13.3kB
hello-world mytag d00000000000 2 months ago 13.3kB
现在,让我们尝试使用 docker rmi 命令,通过其中一个标签(例如 hello-world:latest)来删除该镜像。
docker rmi hello-world:latest
你会注意到,Docker 实际上并没有删除镜像数据本身。相反,它删除了你指定的特定标签。输出会显示为“Untagged”。
Untagged: hello-world:latest
如果你再次列出镜像,你会发现 hello-world:latest 记录已消失,但 hello-world:mytag 记录(具有相同的 IMAGE ID)仍然存在。
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 270000000000 2 weeks ago 77.8MB
hello-world mytag d00000000000 2 months ago 13.3kB
这表明,当一个镜像有多个标签时,删除单个标签只会删除对该镜像数据的特定引用。只有当指向该镜像数据的最后一个标签被删除,或者你通过其 ID 显式删除它时(我们稍后会介绍),镜像数据本身才会被删除。
按标签删除镜像
在上一步中,我们了解到如果还有其他标签或容器引用该镜像,删除标签只会移除该标签。在这一步,我们将删除 hello-world 镜像的最后一个剩余标签,这将导致镜像数据被删除。
目前,我们有一个带有 mytag 标签的 hello-world 镜像。让我们通过列出镜像来确认这一点:
docker images
你应该会看到 hello-world:mytag 这一项。
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 270000000000 2 weeks ago 77.8MB
hello-world mytag d00000000000 2 months ago 13.3kB
现在,让我们使用 docker rmi 命令,通过 mytag 标签来删除 hello-world 镜像:
docker rmi hello-world:mytag
这一次,由于 mytag 是引用该镜像 ID 的唯一标签,Docker 将同时删除该标签和底层的镜像数据。输出会显示先“Untagged”(取消标签),然后“Deleted”(删除)。
Untagged: hello-world:mytag
Deleted: sha256:d0000000000000000000000000000000000000000000000000000000000000000
Deleted: sha256:0000000000000000000000000000000000000000000000000000000000000000
... (more Deleted lines)
让我们再次列出镜像,确认 hello-world 镜像已被删除:
docker images
hello-world 镜像应该不再出现在列表中。
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 270000000000 2 weeks ago 77.8MB
这展示了在镜像没有被任何容器使用且只有一个标签时,删除镜像的标准方法。
使用强制选项按 ID 删除镜像
在这一步中,你将学习如何使用镜像 ID 删除 Docker 镜像,特别是在必要时如何使用强制选项(-f 或 --force)。按 ID 删除镜像在你需要精确指定要删除的镜像时非常有用,尤其是当多个标签指向同一个镜像时。
首先,拉取一个后续可以按 ID 删除的镜像。这里使用 ubuntu 镜像。如果你已经有该镜像,拉取过程会很快完成。
docker pull ubuntu
现在,列出镜像以获取 ubuntu 镜像的 ID。
docker images
在输出中找到 ubuntu 镜像,并记录其 IMAGE ID。这是一个由十六进制字符组成的长字符串。通常,你只需要前几个字符(通常 3 个或更多)就可以唯一标识该镜像。
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 270000000000 2 weeks ago 77.8MB
首先,尝试在不使用强制选项的情况下,使用镜像 ID 删除该镜像。将 YOUR_IMAGE_ID 替换为你从 docker images 输出中记录的实际镜像 ID。
docker rmi YOUR_IMAGE_ID
如果该镜像没有被任何正在运行或已停止的容器使用,此命令可能会成功删除该镜像。但是,如果有基于此镜像的容器,你将收到一条错误消息,提示该镜像正在被容器使用,无法删除。
为了演示强制选项的使用,首先基于 ubuntu 镜像运行一个容器。
docker run -d ubuntu sleep 3600
此命令以分离模式(-d)运行一个 Ubuntu 容器,并使其运行一小时(sleep 3600)。
现在,再次尝试在不使用强制选项的情况下,按 ID 删除 ubuntu 镜像。
docker rmi YOUR_IMAGE_ID
你应该会收到类似以下的错误消息:
Error response from daemon: conflict: unable to remove repository reference "ubuntu:latest" (must force) - image is referenced by one or more containers: 000000000000 (created ...)
此错误是因为有容器正在使用该镜像。要删除正在被容器使用的镜像,你需要使用强制选项(-f)。
现在,使用强制选项和镜像 ID 删除该镜像。将 YOUR_IMAGE_ID 替换为实际的镜像 ID。
docker rmi -f YOUR_IMAGE_ID
强制选项会告知 Docker 即使镜像正在被容器使用,也要删除该镜像。Docker 会先停止并删除所有使用该镜像的容器,然后再删除镜像本身。输出会显示该镜像及其层已被删除。
Untagged: ubuntu:latest
Deleted: sha256:2700000000000000000000000000000000000000000000000000000000000000
Deleted: sha256:0000000000000000000000000000000000000000000000000000000000000000
... (more Deleted lines)
再次列出镜像,确认 ubuntu 镜像已被删除。
docker images
ubuntu 镜像应该不再出现在列表中。
使用强制选项时要谨慎,因为它会在没有进一步确认的情况下停止并删除容器。
按摘要(digest)删除镜像
在最后这一步,你将学习如何使用镜像的摘要(digest)来删除 Docker 镜像。镜像摘要是对镜像内容进行加密安全标识的一种方式。无论镜像的标签如何,它都能唯一地标识镜像的确切层和配置。
首先,拉取一个后续可以按摘要删除的镜像。在这个示例中,我们使用 alpine 镜像。
docker pull alpine
现在,若要查看镜像的摘要,可以使用 docker images --digests 命令。
docker images --digests
在输出中找到 alpine 镜像。你会看到有一个 DIGEST 列,其值以 sha256: 开头。这就是镜像的摘要。
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
ubuntu latest <none> 270000000000 2 weeks ago 77.8MB
alpine latest sha256:0000000000000000000000000000000000000000000000000000000000000000 000000000000 3 weeks ago 5.59MB
要按摘要删除镜像,你需要使用 docker rmi 命令,后面跟上镜像名称和摘要,格式为 REPOSITORY@DIGEST。将 YOUR_ALPINE_DIGEST 替换为你在上一步输出中找到的实际摘要。
docker rmi alpine@YOUR_ALPINE_DIGEST
输出会显示该镜像已被删除。
Deleted: sha256:0000000000000000000000000000000000000000000000000000000000000000
Deleted: sha256:0000000000000000000000000000000000000000000000000000000000000000
... (more Deleted lines)
再次列出镜像,确认 alpine 镜像已被删除。
docker images
alpine 镜像应该不再出现在列表中。
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest <none> 270000000000 2 weeks ago 77.8MB
按摘要删除镜像是删除镜像最精确的方式,能确保你删除的是由该摘要所标识的镜像的确切版本。
总结
在本次实验中,你学习了如何使用 docker images 和 docker rmi 命令来管理 Docker 镜像。首先,你通过列出现有镜像,了解了它们的仓库、标签、ID、创建时间和大小。
接着,你探索了删除镜像的过程。你尝试删除带有多个标签的镜像,发现如果其他标签仍引用该镜像,docker rmi 命令只会删除指定的标签,而不会删除底层的镜像 ID。你成功地通过指定标签删除了镜像,还演示了如何通过镜像 ID 删除镜像,包括在必要时使用强制标志(-f)。最后,你学习了如何使用镜像的摘要(digest)来删除镜像,摘要为镜像内容提供了唯一且不可变的标识符。



