如何清理一周未使用的Docker对象,保留近期使用的资源?
按最后使用时间清理Docker资源的方案
docker system prune的until过滤是基于创建时间,而非最后使用时间,所以无法直接满足你的需求。要实现保留近期使用的资源,需要针对容器、镜像、卷、网络分别处理:
1. 清理停止运行超过一周的容器
运行中的容器属于活跃使用状态,无需清理。对于停止的容器,我们只删除那些停止时间超过一周的:
# 获取所有停止时间超过168小时(一周)的容器ID并删除 docker container ls -a --filter "status=exited" -q | while read cid; do stopped_at=$(docker inspect --format='{{.State.FinishedAt}}' "$cid") stopped_unix=$(date -d "$stopped_at" +%s) now_unix=$(date +%s) if [ $((now_unix - stopped_unix)) -gt $((168 * 3600)) ]; then docker rm "$cid" fi done
2. 清理未被近期使用的镜像
保留两类镜像:正在运行的容器引用的镜像,以及最近一周内被用来创建过容器的镜像。其余镜像可以删除:
# 获取所有活跃使用的镜像ID(运行容器+一周内创建的容器引用的镜像) active_images=$( # 运行中容器引用的镜像 docker ps -q | xargs docker inspect --format='{{.Image}}' | sort -u # 一周内创建的容器引用的镜像 docker container ls -a --filter "since=$(date -d '1 week ago' +%Y-%m-%dT%H:%M:%SZ)" -q | xargs docker inspect --format='{{.Image}}' | sort -u ) | sort -u # 删除不在活跃列表中的非悬空镜像 docker image ls --filter "dangling=false" -q | grep -v -F -f <(echo "$active_images") | xargs docker image rm -f
3. 清理一周未使用的卷
卷的prune命令支持按最后使用时间过滤,直接使用:
docker volume prune -f --filter "until=168h"
4. 清理未被使用的网络
网络一般只有被容器引用时才会被使用,直接清理所有未被使用的网络即可:
docker network prune -f
整合脚本
可以把上述命令整合成一个脚本,方便一键执行:
#!/bin/bash # 清理停止超过一周的容器 echo "清理停止超过一周的容器..." docker container ls -a --filter "status=exited" -q | while read cid; do stopped_at=$(docker inspect --format='{{.State.FinishedAt}}' "$cid") stopped_unix=$(date -d "$stopped_at" +%s) now_unix=$(date +%s) if [ $((now_unix - stopped_unix)) -gt $((168 * 3600)) ]; then docker rm "$cid" fi done # 获取活跃镜像列表 echo "获取活跃镜像列表..." active_images=$( docker ps -q | xargs docker inspect --format='{{.Image}}' 2>/dev/null | sort -u docker container ls -a --filter "since=$(date -d '1 week ago' +%Y-%m-%dT%H:%M:%SZ)" -q | xargs docker inspect --format='{{.Image}}' 2>/dev/null | sort -u ) | sort -u # 清理不活跃镜像 echo "清理不活跃镜像..." docker image ls --filter "dangling=false" -q | grep -v -F -f <(echo "$active_images") | xargs docker image rm -f 2>/dev/null # 清理一周未使用的卷 echo "清理一周未使用的卷..." docker volume prune -f --filter "until=168h" # 清理未使用的网络 echo "清理未使用的网络..." docker network prune -f echo "清理完成!"
注意:
- 脚本中的
date命令参数在Linux和macOS下可能略有差异,macOS需要使用gdate(通过brew install coreutils安装)替换date,或者调整日期格式。 - 执行前可以先去掉
-f参数,查看会被删除的资源,确认无误后再添加-f执行删除。
内容的提问来源于stack exchange,提问作者Daniele Ricci
相关产品推荐
相关产品推荐

