简介
在这个实验中,你将学习如何使用 docker image rm
命令有效地管理 Docker 镜像。首先,我们会列出系统上现有的镜像,让你了解自己拥有哪些镜像。
接下来,我们将探讨不同的镜像删除场景,包括尝试删除带有多个标签的镜像、按标签删除镜像、使用强制选项按 ID 删除镜像,最后按摘要(digest)删除镜像。通过这个实践操作,你将掌握清理无用或不需要的 Docker 镜像所需的技能。
在这个实验中,你将学习如何使用 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 删除 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)来删除 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)来删除镜像,摘要为镜像内容提供了唯一且不可变的标识符。