本笔记的内容包含:如何删除本地 Docker 镜像;如何删除远程 Docker 镜像;在删除过程中出现的常见问题的处理;还涉及了一些 Docker 镜像存储方式方面的内容。
删除远程镜像
在镜像仓库(如 Docker Hub 中)中的镜像,目前不能通过命令删除,要在镜像仓库中删除。通过单击按钮来完成删除操作,不涉及特别复杂的内容,所以简单略过。
# 08/08/2019 今天在 Docker v19.03 (current) 看到了 docker registry rmi 命令,可以从Registry中移除镜像,目前出于实验性质。
删除本地镜像
删除单个或多个镜像
使用 docker rmi 与 docker image rm 命令来删除本地镜像(只能删除本地镜像,不能删除在镜像仓库中的镜像):
# 通过 Image ID 删除 docker rmi fd484f19954f # 下面这两个是等价的,因为 latest 是默认的标签 docker rmi test1:latest docker rmi test1 # 还可以通过 DIGEST 来删除。在 REPOSITORY 与 DIGEST之间,使用 @ 分隔。 # 因为使用 DIGEST 拉取的镜像是没有 TAG 的,所以会用到这种方法。 docker rmi test/busybox@sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf
1)如果镜像具有多个标签,并且将标签作为删除参数,则命令仅删除标签;
2)如果镜像具有唯一标签,命令将删除标签,然后删除镜像;
删除被容器使用的镜像
如果镜像具有正在使用的容器,则无法删除,需要使用 -f 选项,将删除容器与镜像:
docker image rm --force "REPOSITORY:TAG"
删除所有镜像
如果要删除所有镜像可以使用如下命令(可以使用 docker images 的 --filter 选项进行高级过滤):
# 下面的两个命令是等价的 docker image rm $(docker image ls -a -q) docker rmi $(docker images -a -q) # 删除有容器的镜像 docker image rm -f $(docker image ls -a -q)
删除 IMAGE ID 相同的所有镜像
当镜像具有多个标签时,如果使用 IMAGE ID 删除(docker rmi fd484f19954f),会产生如下错误:
Error: Conflict, cannot delete image fd484f19954f because it is tagged in multiple repositories, use -f to force 2013/12/11 05:47:16 Error: failed to remove one or more images
方法一、此时可以使用 -f 选项时,这将删除所有标签并删除镜像:
docker rmi --force fd484f19954f
方法二、使用命令 grep 进行过滤,将结果作为 docker rmi 参数以进行删除。
方法三、使用 docker inspect 命令,命令输出的 RepoTags 字段将显示相关标签,以用于删除。
常见错误处理
# image has dependent child images
Find the dependent child images on Docker
问题描述:
在删除某个镜像(docker rmi a990d6e2b083)的时候,提示如下错误:
Error response from daemon: conflict: unable to delete d86795370e7b (cannot be forced) - image has dependent child images
问题原因:
该错误提示删除的镜像有依赖的子镜像。
解决办法:
################################################################################ # 一个简单的做法 ################################################################################ docker image inspect --format='{{.Id}} {{.Parent}}' \ $(docker image ls --all --filter since=a990d6e2b083 -q) | grep a990d6e2b083 # 上述命令: #1 (docker image ls)找到a990d6e2b083之后的镜像 #2 (docker image inspect)然后获取这些镜像的父镜像 #3 (grep)通过过滤父镜像,找到的就是引用该镜像的子镜像。 ################################################################################ # 然而,问题从来就不是这么简单的 ################################################################################ # 最大的问题在于:子镜像还有子镜像,慢慢找??? # 其实你要做的事情很简单。通常这个问题是由于有悬空镜像引用了该镜像,所以删除所有“悬空”的镜像即可。 # 「悬空镜像」可以放心的删除 docker rmi $(docker images --filter "dangling=true" -q --no-trunc) ################################################################################ # 但是,真正正确的做法是这样的 # 找到要删除镜像的子镜像的子镜像的子镜像…………(不多删,也不少删除) # https://stackoverflow.com/questions/38118791/can-t-delete-docker-image-with-dependent-child-images/38119847#38119847#answer-53037893 ################################################################################ recursive_remove_image() { for image in $(docker images --quiet --filter "since=${1}") # 找到这个镜像之后的镜像。因为子镜像是在这之后的。 do if [ $(docker history --quiet ${image} | grep ${1}) ] # 查看这个子镜像的构建历史,是否包含了这镜像。如果是,那就应该删除。 then recursive_remove_image "${image}" # 进行递归,删除应用这个镜像的子镜像。 fi done # 执行删除 echo "Removing: ${1}" docker rmi -f ${1} } recursive_remove_image "<image-id>"
参考文献
- WikiNotes/删除镜像
- Find the dependent child images on Docker
- docker image rm
- docker rmi
- docker images
- Can’t delete image with children
- Can’t delete docker image with dependent child images
- How To Remove Docker Images, Containers, and Volumes
- How to remove multiple docker images with the same imageID?