You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何清理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给节点加个专属锁,确保同一时间只有一个任务执行清理:

  1. 安装Lockable Resources Plugin,在Jenkins全局配置里给Windows节点创建一个名为windows-docker-prune-lock的锁资源
  2. 在清理任务中先获取锁,再执行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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 20:45:43