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

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

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


当前回答

几周前移除旧容器。

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

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

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

其他回答

如果你想删除X个月前的图片,你可以尝试下面的例子,删除三个月前创建的图片:

three_months_old_images=`docker images | grep -vi "<none>" | tr -s ' ' | cut -d" " -f3,4,5,6 | grep "3 months ago" | cut -d" " -f1`
docker rmi $three_months_old_images

请参阅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 rmi $(docker images | grep "^<none>" | awk "{print $3}")

如果你自己构建这些修剪过的映像(从其他一些较旧的基础映像),请谨慎使用上述基于docker image prune的可接受解决方案,因为该命令是生硬的,并将尝试删除最新映像所需的所有依赖关系(该命令可能应该重命名为docker image*s* prune)。

我为我的docker映像构建管道(其中有每日构建和标签=日期YYYYMMDD格式)提出的解决方案是:

# carefully narrow down the image to be deleted (to avoid removing useful static stuff like base images)
my_deleted_image=mirekphd/ml-cpu-py37-vsc-cust

# define the monitored image (tested for obsolescence), which will be usually the same as deleted one, unless deleting some very infrequently built image which requires a separate "clock"
monitored_image=mirekphd/ml-cache

# calculate the oldest acceptable tag (date)
date_week_ago=$(date -d "last week" '+%Y%m%d')

# get the IDs of obsolete tags of our deleted image
# note we use monitored_image to test for obsolescence
my_deleted_image_obsolete_tag_ids=$(docker images --filter="before=$monitored_image:$date_week_ago" | grep $my_deleted_image | awk '{print $3}')

# remove the obsolete tags of the deleted image
# (note it typically has to be forced using -f switch)
docker rmi -f $my_deleted_image_obsolete_tag_ids

首先,运行docker images查看图像列表,并将IMAGE HASH ID复制到剪贴板中。

运行docker rmi -f <镜像>

记住选项-f是强制删除。