Docker镜像清理是围绕空间、安全、可维护性构建的持续机制,需区分悬空镜像、未被引用命名镜像和历史版本镜像三类目标,按语义版本或时间戳策略保留,结合脚本自动化、CI/CD集成、定时任务与监控审计执行。

清理Docker镜像不是“删掉不用的”,而是围绕空间、安全、可维护性构建的一套持续机制。关键在于区分镜像类型(悬空、未被引用、过期标签)、设定明确策略(如保留最近N个、按时间/语义版本筛选),并避免误删正在运行容器依赖的镜像。
识别真正可清理的镜像类型
盲目执行 docker image prune -a 风险高,需先精准识别三类安全目标:
-
悬空镜像(dangling):无标签且未被任何容器或镜像引用的中间层,ID为
<none>:<none>,可放心清理; -
未被引用的命名镜像:有仓库名和标签,但本地无容器、构建缓存或其它镜像基于它,需结合
docker system df -v和docker image ls --format "{{.ID}}: {{.Repository}}:{{.Tag}} {{.Size}}" | grep -v "<none>"辅助判断; -
历史版本镜像:如
myapp:v1.2.0,myapp:v1.2.1,myapp:v1.3.0,应按语义版本规则(如只留 latest + 最近2个 patch 版本)或时间戳(如7天内最新3个)筛选保留。
用脚本实现按策略自动过滤与清理
纯命令行难以满足复杂保留逻辑,推荐用轻量 Bash 脚本封装判断逻辑,例如:
- 提取所有匹配项目(如
myapp:开头的镜像),按标签解析语义版本,调用sort -V排序后用tail -n +4跳过最新3个,对剩余镜像执行docker rmi; - 对带时间戳标签(如
20240520-1423)的镜像,用awk '{print $2}' | sort -r | tail -n +6保留最近5次构建; - 清理前强制检查是否被运行中容器使用:
docker ps --format "{{.Image}}" | grep "^${IMAGE_ID}\|^${REPO}:${TAG}$" | wc -l,结果为0才允许删除。
集成进CI/CD与宿主机定时任务
自动化清理必须脱离人工触发,嵌入真实运维链路:
- 在 CI 流水线末尾(如 GitHub Actions 的
post-build步骤)运行镜像清理脚本,仅清理本次流水线生成的临时镜像(如带build-前缀或sha256-标签的); - 在 Docker 主机部署
cron,每天凌晨执行docker image prune -f --filter "until=168h"清理7天前创建且未被引用的镜像; - 配合
docker system prune -f --filter "label=auto-prune=true",要求构建时通过--label auto-prune=true主动标记可清理镜像,提升可控性。
监控清理效果并防止误删
自动化带来效率也放大风险,必须配套可观测性:
- 每次清理前记录镜像列表到日志文件,包含时间、镜像ID、仓库、标签、大小、引用状态;
- 用
docker system df定期输出镜像、容器、卷占用趋势,设置阈值告警(如镜像层总量超30GB); - 禁止在生产节点直接运行
prune -a,所有清理操作需经配置文件定义策略(如keep_latest: 3,keep_days: 7),脚本读取配置而非硬编码逻辑。
不复杂但容易忽略。核心是把“哪些能删”变成可表达、可验证、可审计的规则,再让机器忠实地执行它。

















