在长时间运行Docker时,系统中存在大量的镜像。如何一次安全地删除所有未使用的Docker映像以释放存储空间?

另外,我还想删除几个月前拉的图片,这些图片有正确的TAG。

因此,我并不是只要求删除未标记的图像。我正在寻找一种方法来删除一般不使用的图像,其中包括未标记和其他图像,如几个月前拉正确的TAG。


当前回答

请参阅docker系统修剪的官方参考

Docker系统修剪将删除:

所有停止的集装箱 所有网络不被至少一个容器使用 所有悬挂的图像 所有构建缓存

Docker系统prune -a也会做同样的事情,但是除了删除所有悬浮图像之外,它还会更广泛地删除:

没有至少一个与之关联的容器的所有映像

什么是悬空图像?

Docker映像由多个层组成,当从Dockerfile生成整个容器映像时,这些层被包装在父“容器层”中。悬浮图像是与任何其他标记图像没有关系的层,因此在任何构建的新容器中都不会有任何用途。它们不再起作用,而是消耗磁盘空间。

例如,悬浮图像可以通过以下过程创建:

从Dockerfile中构建一个命名image my-image,不指定任何标签:

FROM ubuntu:latest
CMD ["echo", "Hello World"]

docker build -t my-image

docker images

REPOSITORY   TAG       IMAGE ID
my-image     latest    7ed6e7202eca   <--- created, not dangling
ubuntu       latest    825d55fb6340

更新Dockerfile:

FROM ubuntu:latest
CMD ["echo", "Hello, World!"]

使用以前的名称重新构建映像,不指定任何标记:

docker build -t my-image

docker images

REPOSITORY   TAG       IMAGE ID
my-image     latest    da6e74196f66   <--- replacement layer
<none>       <none>    7ed6e7202eca   <--- previous layer, now dangling
ubuntu       latest    825d55fb6340

构建创建了一个新的my-image层。正如我们所看到的,最初创建的层仍然在那里,但它的名称和标签被设置为<none>:<none>。这个层永远不可能与任何docker容器层相关联,这意味着它是“悬空的”。

没有至少一个关联容器的图像是什么?

未使用的映像意味着它没有被分配或在容器中使用。例如,docker ps -a将列出所有运行和停止的容器。这些容器使用的任何映像都是“已用映像”。

当运行docker系统prune -a时,它将删除未使用和悬挂的图像。与至少一个容器相关联的任何映像都不会受到影响。

其他回答

如何删除带标签的图像

Docker先取标签 Docker对图像进行了描述。 #可以在一个docker rmi调用中完成,例如:# Docker rmi <repo:tag> <imageid>

(2016年11月,Docker版本1.12.2)

e.g.

$ docker images 
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
usrxx/the-application   16112805            011fd5bf45a2        12 hours ago        5.753 GB
usryy/the-application   vx.xx.xx            5af809583b9c        3 days ago          5.743 GB
usrzz/the-application   vx.xx.xx            eef00ce9b81f        10 days ago         5.747 GB
usrAA/the-application   vx.xx.xx            422ba91c71bb        3 weeks ago         5.722 GB
usrBB/the-application   v1.00.18            a877aec95006        3 months ago        5.589 GB

$ docker rmi usrxx/the-application:16112805 && docker rmi 011fd5bf45a2
$ docker rmi usryy/the-application:vx.xx.xx && docker rmi 5af809583b9c
$ docker rmi usrzz/the-application:vx.xx.xx eef00ce9b81f
$ docker rmi usrAA/the-application:vx.xx.xx 422ba91c71bb
$ docker rmi usrBB/the-application:v1.00.18 a877aec95006

例:脚本删除超过2周的内容。

IMAGESINFO=$(docker images --no-trunc --format '{{.ID}} {{.Repository}} {{.Tag}} {{.CreatedSince}}' |grep -E " (weeks|months|years)")
TAGS=$(echo "$IMAGESINFO" | awk '{ print $2 ":" $3 }' )
IDS=$(echo "$IMAGESINFO" | awk '{ print $1 }' )
echo remove old images TAGS=$TAGS IDS=$IDS
for t in $TAGS; do docker rmi $t; done
for i in $IDS; do docker rmi $i; done

假设你有Docker 1.13或更高版本,你可以只使用修剪命令。对于你的问题,特别是关于删除旧图像,你想要第一个。

# Remove unused images
docker image prune

# Remove stopped containers.
docker container prune

# Remove unused volumes
docker volume prune

# Remove unused networks
docker network prune

# Command to run all prunes:
docker system prune

我建议不要习惯使用docker系统的prune命令。我认为用户会不小心删除他们不想删除的内容。就我个人而言,我将主要使用docker映像修剪和docker容器修剪命令。

要修剪所有的图像和卷以及 Docker系统剪枝-af——volumes

几周前移除旧容器。

Docker rm $(Docker ps -a | grep "weeks" | awk '{打印$1;}”)

几周前删除旧图像。小心些而已。这将删除几周前创建的基本图像,但您的新图像可能会使用这些图像。

Docker rmi $(Docker images | grep 'weeks' | awk '{打印$3;}”)

docker rm `docker ps -aq`

or

docker rm $(docker ps -q -f status=exited)