如何清理Jenkins中断后Windows节点上的Docker未完成镜像?
清理Windows Jenkins节点遗留无标签Docker镜像的实用思路
针对你遇到的问题,分享几个实际可行的清理方案:
1. 构建前后镜像快照对比清理
在Windows构建任务的前置阶段,先记录当前节点上的所有有效镜像ID,构建结束(无论成功、失败还是被中断)后,对比新增的无标签镜像并删除:
- 前置阶段执行:
# 把当前非悬空镜像ID写入临时文件 docker images -q --filter "dangling=false" > .pre-build-images.txt - 在
post always阶段执行清理:
这种方式精准清理单次构建产生的垃圾,不会误删其他任务的镜像。# 获取当前所有悬空(无标签)镜像ID $currentDanglingImgs = docker images -q --filter "dangling=true" # 读取构建前的镜像列表 $preBuildImgs = Get-Content .pre-build-images.txt # 只删除本次构建新增的悬空镜像,不影响其他任务的镜像 foreach ($img in $currentDanglingImgs) { if ($img -notin $preBuildImgs) { docker rmi $img 2>&1 | Out-Null } } # 清理临时文件 Remove-Item .pre-build-images.txt -Force
2. 给构建中的镜像加临时唯一标签
修改docker build流程,先给构建过程中的镜像打上包含任务ID、构建号的临时标签,避免构建中断后变成无标签镜像:
- 构建时先打临时标签:
# 用Jenkins环境变量生成唯一临时标签 $tempTag = "jenkins-build-$env:JOB_NAME-$env:BUILD_NUMBER" docker build -t $tempTag . # 构建完成后替换为正式标签 docker tag $tempTag mytag:myname docker rmi $tempTag - 在
post always阶段强制删除临时标签的镜像:
哪怕构建中途被中断,镜像也有明确的临时标签,后续清理不会遗漏。$tempTag = "jenkins-build-$env:JOB_NAME-$env:BUILD_NUMBER" docker rmi $tempTag 2>&1 | Out-Null
3. 给节点的prune操作加全局互斥锁
既然Windows节点不能并行执行docker prune,用Jenkins的Lockable Resources Plugin给节点加个专属锁,确保同一时间只有一个任务执行清理:
- 安装
Lockable Resources Plugin,在Jenkins全局配置里给Windows节点创建一个名为windows-docker-prune-lock的锁资源 - 在清理任务中先获取锁,再执行prune:
node('windows-node') { lock('windows-docker-prune-lock') { bat 'docker system prune -af --filter "until=24h"' } }
这样可以避免并行prune的报错,还能把清理频率改成每天低峰时段,比每周一次更及时。
4. 磁盘阈值触发的按需清理
给Windows节点加个磁盘监控任务,当磁盘使用率超过阈值(比如80%)时自动触发带锁的prune操作:
- 用Jenkins的
Disk Usage Plugin监控节点磁盘,结合Pipeline脚本实现:
这种方式是按需清理,既不会浪费资源做无用的定时清理,又能及时防止磁盘被占满。node('windows-node') { def nodeInfo = jenkins.model.Jenkins.instance.getNode('windows-node') def diskUsagePercent = (nodeInfo.rootSpace.totalSpace - nodeInfo.rootSpace.freeSpace) * 100 / nodeInfo.rootSpace.totalSpace if (diskUsagePercent > 80) { lock('windows-docker-prune-lock') { bat 'docker system prune -af --filter "until=12h"' } } }
内容的提问来源于stack exchange,提问作者JenyaKh
相关产品推荐
相关产品推荐

