Docker清理镜像

在生产环境长期运行的容器服务器,你会发现磁盘空间越来越少,例如 排查磁盘空间消耗 :

查找消耗磁盘空间最大的目录
du -Sh | sort -rh | head -5

输出类似:

查找消耗磁盘空间最大的目录输出案例(占用最大空间的的是容器镜像)
1.2G ./var/lib/containerd/io.containerd.content.v1.content/blobs/sha256
445M ./usr/bin
332M ./run/containerd/io.containerd.runtime.v2.task/k8s.io/6bd8822f911f8cbbc51826a3c2d37c0016ec44a8138c9d835fb5dbae99db269f/rootfs/usr/bin
328M ./home/huatai/z-k8s-dev
318M .

上述这是一个简单案例,实际上我在生产环境见过消耗了几百G甚至上T的镜像存储空间,大多数是因为历史上反复更新发布导致很多无用的镜像堆积在本地。

dangling image

没有使用的镜像,在英语世界有一种非常形象的动作 dangling ,也就是 悬空 。例如 how to get the dangling images using crictl

../../_images/dangling.png

dangling 就是悬空的意思

prune

docker 提供了一个非常实用的 image 子命令 prune 用于清理不再使用的镜像:

docker image prune 没有任何参数则仅删除dangling镜像(即没有任何容器使用的镜像)
docker image prune -f

这里使用了 -f 参数是为了避免交互,否则默认会提示是否进行

注意,不使用任何参数,则只会删除dangling镜像(没有任何容器使用的镜像)。如果要删除没有任何现存容器使用的所有镜像,则加上 -a 参数:

docker image prune 使用 -a 参数会删除所有没有现有容器关联的镜像,更为彻底
docker image prune -a

可以限制停止多少小时前的容器奖项:

docker image prune 指定24小时前停止容器关联镜像
docker container prune --filter "until=24h"

其他方法

其实不用 prune 也能清理镜像,就是使用 rmi ,例如:

使用 docker rmi 清理不再使用的镜像
docker images | awk '{print $1}' | tee image_list
for image in `cat image_list`;do docker rmi $image;done

这里虽然使用 rmi 删除所有镜像,但是实际上如果正在使用的 image 是不会删除的,只会提示一个无法删除信息。遮掩,实际上就完成了无效镜像的清理。

prune 一切

docker 提供了更多的清理选项,可以用来清理容器,卷,网络甚至一切:

可以使用 dockerprune 多种资源,甚至一切
# 清理容器
docker container prune
# 如果要强制完成,则增加 ``-f`` 或 ``--force`` 参数
# 可以使用过滤功能: 例如清理最近24小时前的已经停止的容器
docker container prune --filter "until=24h"

# 清理卷
docker volume prune
# 默认是删除所有没有使用的卷,可以过滤,例如有标签keep的需要保留
docker volume prune --filter "label!=keep"

# 清理网络
docker network prune
# 清理24小时以上没有使用的网络
docker network prune --filter "until=24h"

# 清理一切,默认不包括卷
docker system prune
# 清理一切,并且包括卷也清理
docker system prune --volumes

参考