核心是精准识别并清理无引用、超期或标记临时的镜像快照,通过api/cli验证引用关系,结合白名单、保留窗口、预检模式和日志记录实现安全可控的自动化清理。

直接用脚本定时清理测试环境里长期不用的镜像快照,核心是识别“无用”——即没被任何活跃节点引用、超过保留期限、或明确标记为临时的快照。关键不在删得多,而在删得准,避免误删正在使用的快照。
确认快照归属与引用关系
多数云平台(如 OpenStack、VMware、Proxmox)或容器运行时(如 Docker、Podman)都提供 API 或 CLI 查询快照是否被当前虚拟机/容器引用。例如:
- OpenStack:用
openstack image list --property status=active筛出活跃镜像,再用openstack server show <vm-id> --format value | grep image</vm-id>查哪些 VM 还在用哪些镜像 ID;快照若不在任何 VM 的 image_id 或 backup_id 中,且创建时间早于阈值,就可判定为闲置 - Docker:
docker image ls --filter "dangling=true" -q可列出悬空镜像(无 tag 且未被容器引用),但注意这不等于“快照”,需结合docker system df和docker ps -a判断是否被历史容器依赖 - 自建 KVM + libvirt:通过
virsh list --all获取所有域,再用virsh dumpxml <domain> | grep "source file"</domain>提取磁盘镜像路径,比对快照文件名是否出现在任意路径中
设置安全删除策略
不建议无条件按时间删除,而应分层控制:
- 加白名单:把用于 CI 基础镜像、标准测试模板的快照 ID 或名称正则写入配置文件(如
keep_list.txt),脚本跳过匹配项 - 设保留窗口:只清理创建时间早于 7 天且无引用的快照;新创建的快照即使未被引用也暂不处理,留出调试缓冲期
- 启用预检模式:首次运行加
--dry-run参数,只打印将删的快照 ID 和理由,人工核对后再去除非干跑开关 - 记录操作日志:每条删除动作记下快照名、ID、引用检查结果、执行时间,便于回溯
编写轻量可维护的清理脚本
用 Bash 或 Python 都可以,重点是逻辑清晰、依赖少、易读易改。示例 Bash 片段逻辑:
- 获取全部快照列表(含创建时间、状态、关联 VM/容器 ID)
- 遍历每条,调用引用检查函数,返回 true 表示“无引用”
- 若无引用且创建时间
$(( $(date +%s) - 7*24*3600 )),加入待删队列 - 逐个执行删除命令前,先
echo "[DRY] deleting $snap_id" | logger -t snapshot-cleaner(真实运行时替换为实际删除命令) - 失败时中断并报错,不静默跳过
集成进运维生命周期
清理不是孤立任务,要嵌入现有流程:
- 绑定到 CI 流水线末尾:每次测试任务成功后,触发一次快照清理,只扫本次 Job 创建的临时快照(可通过 Job ID 或命名前缀标识)
- 加入 crontab 定时任务:每天凌晨 2 点执行全量扫描,但限制单次最多删 50 个,防 IO 冲突
- 对接监控告警:若某次清理发现异常高数量待删快照(如单次 >200),发企业微信/钉钉提醒,可能意味着测试脚本未正确清理资源
- 配合权限管控:脚本用最小权限账号运行,仅授予快照查询和删除权限,不赋予 VM 创建或网络配置权











