Jenkins 磁盘写满 No space left on device 速查:构建历史、工作空间与镜像膨胀
更新时间:2026-10-24。FAQ 速查页,面向构建突然失败、日志里躺着
No space left on device,或者控制器首页直接报「磁盘空间不足」红条的同学。Jenkins 磁盘写满的本质是「只进不出」:构建历史一份一份堆、工作空间一次一次拉、镜像一层一层叠,而默认配置里没有任何自动回收。病因收敛在六根轴上:构建历史与归档产物堆积、工作空间(workspace)构建后不清理、Docker in Docker 或镜像构建把 var/lib/docker 撑爆、控制台日志与临时文件失控、JENKINS_HOME 主目录增长失控、以及磁盘还有余量但 inode 先耗尽。顺一遍基本必中。如果是磁盘没满但构建卡住不动,转 Jenkins 构建超时挂起速查。
本文要回答的问题
No space left on device报错后,第一刀应该砍向哪里?- 构建历史保留多少份合适,Discard Old Builds 怎么配?
- 工作空间什么时候清,
cleanWs()和 Ws Cleanup 插件差在哪? - Docker 构建任务把磁盘撑爆,镜像与构建缓存怎么收?
- 磁盘看着还有空间,为什么还是报写满?
一、报错原文与典型现象
磁盘类报错分散在三处:构建日志、控制器页面横幅、以及代理节点的系统日志(控制器地址以 jenkins.example.com 占位,任务路径以 /proj/demo 占位):
# 构建日志:写文件直接失败
java.io.IOException: No space left on device
# 或 shell 步骤里
tar: write failed: No space left on device# 控制器首页横幅
Jenkins 磁盘空间不足。可用空间低于阈值,
构建已被暂时禁用。
# 节点页提示
Disk space is too low. Only xxx MB left on agent-1.# 节点系统日志里的连锁反应
docker: Error response from daemon:
write /var/lib/docker/tmp/...: no space left on device读现象先分三层:构建日志里的 No space left on device 是「任务把工作目录写爆了」;控制器横幅是「JENKINS_HOME 所在分区低于阈值,Jenkins 主动熔断」;docker daemon 报错是「镜像存储分区爆了」。三层清理对象互不相同,先定性。
二、病因处置速查表
| 报错现象 / 场景 | 可能原因 | 快速验证 | 处置 |
|---|---|---|---|
| 构建里写文件报 No space left | 工作空间或构建历史堆满分区 | 登录节点 df -h 看使用率 | 清旧构建历史,配 Discard Old Builds |
| 控制器横幅提示磁盘不足 | JENKINS_HOME 增长失控 | du -sh 逐层定位大头目录 | 清 builds 目录与归档,调低保留数 |
| 每次构建后工作空间越来越大 | 构建不清理,依赖与产物残留 | 对比 workspace 前后体积 | 流水线收尾 cleanWs() 或装 Ws Cleanup |
| docker 任务报写失败 | 镜像层与构建缓存膨胀 | docker system df 看占用 | docker system prune 收悬空镜像与缓存 |
| 控制台日志巨大且越攒越多 | 大日志任务无保留策略 | 看 builds/*/log 单文件大小 | 限制日志保留份数,大日志归档外置 |
| df 显示有空间仍写失败 | inode 耗尽(海量小文件) | df -i 看 inode 使用率 | 清碎小文件,npm 缓存等迁移或精简 |
三、排查决策图
下面这张图是标准排查路线,颜色按角色区分:红是报错入口与命中的根因,蓝是排查动作,绿是通过分支,橙是修复动作,紫是防复发沉淀。
读这张图抓两步分水岭:第一步 df -h 与 df -i 同时跑——空间满与 inode 满症状一样、治法不同;第二步 du -sh 从分区根往下逐层钻,Jenkins 场景下大头几乎总落在 builds/、workspace/、/var/lib/docker 三者之一。找到大头再决定是删历史还是改保留策略,不要一上来就全量清空。
四、逐条排查展开
构建历史堆积是 JENKINS_HOME 的第一大来源。 每次构建在 jobs/<任务名>/builds/<编号>/ 下留一份完整档案:控制台日志、归档产物、测试结果、变更记录。一个每天跑几十次、每次归档几百 MB 产物的任务,一年不清理就是 TB 级。正解是配「Discard Old Builds(丢弃旧构建)」:自由风格任务在配置页勾上并填「保留天数」与「保留最大份数」;流水线在 options { buildDiscarder(logRotator(daysToKeepStr: '30', numToKeepStr: '50', artifactDaysToKeepStr: '7', artifactNumToKeepStr: '10')) } 里声明——注意产物保留与构建保留是两个独立参数,只限构建数不限产物数等于没配。历史任务立即生效:手动触发一次构建,超龄记录即被旋转删除。
工作空间不清理是代理节点磁盘的隐形漏斗。 默认行为是构建结束工作空间原样保留,下次构建复用以省拉取时间——代价是 node_modules、构建缓存、打包产物越攒越厚。处置分两档:流水线收尾加 post { always { cleanWs() } },构建完即清;不想每次都全量重拉的,装 Workspace Cleanup 插件并配置「仅失败/仅成功时清理」或按模式排除缓存目录。临时救急可以在任务页点「Wipe Out Current Workspace」手动清一次,但这只是止血。
Docker 构建任务的膨胀不在 Jenkins 目录里。 镜像构建任务的大头在节点的 /var/lib/docker:每构建一次多一层镜像,悬空镜像(dangling,标签被新构建顶掉的旧镜像)与构建缓存(build cache)只增不减。docker system df 一条命令看清镜像、容器、卷、缓存各占多少;常规回收用 docker system prune -f 清悬空镜像与停止的容器,激进一点加 --volumes 连未挂载的卷一起收。流水线化团队建议给节点挂一个定时任务,每日低峰自动 prune,并把「构建镜像打唯一标签 + 推送后删除本地镜像」写进流水线收尾步骤。
控制台日志失控常见于两类任务。 一类是编译型任务开了 verbose 输出,单份日志几百 MB;一类是测试任务把全量用例输出打进控制台。日志文件就在 builds/<编号>/log,配 buildDiscarder 即可随构建历史一起旋转;真正需要长期留档的,用 tee 把完整输出落独立文件再归档到外置存储(对象存储或制品库),控制台只留尾部摘要。
inode 耗尽是最容易被误判的一种「满」。 df -h 看着还有一半空间,df -i 已经 100%——海量小文件(npm 缓存、碎片化测试报告、上万个小产物)把 inode 表占光了,新文件照样建不出来。处置思路不是删大文件而是「减文件数」:清掉过期缓存目录、把小文件打包归档、必要的话给这类任务单独挂一块 inode 配额更宽的卷。
JENKINS_HOME 的结构性大头别漏看。 除了 builds,还有几个常驻增长点:war/ 解压目录、plugins/ 多版本残留、fingerprints/ 指纹库、以及 jobs/*/nextBuildNumber 之外的各类 XML。du -sh $JENKINS_HOME/* 排序后一目了然,大头通常还是 builds——别在边角目录上浪费时间。
五、规范做法与预防
- 保留策略是任务标配不是选配:新建任务模板里预置 Discard Old Builds(构建 30 天/50 份、产物 7 天/10 份起步),评审时无保留策略不予入库。
- 工作空间清理进流水线收尾:
post { always { cleanWs() } }或 Ws Cleanup 插件,二选一写进共享库,不依赖个人记忆。 - 镜像卫生定时化:节点每日低峰
docker system prune -f,构建流水线收尾删除本地临时镜像。 - 磁盘水位告警前置:节点与控制器的磁盘使用率接监控,80% 告警、90% 电话,别等构建报错才发现。
- 大日志外置:需要留档的完整日志
tee落文件归档对象存储,控制台只留摘要,保留策略管得住。 - JENKINS_HOME 独立分区:主目录挂独立卷,与系统盘、与 docker 存储物理隔离,一处写满不拖垮整机。
这一篇在知识体系里的位置
本篇是 Jenkins 排错速查簇的磁盘入口篇,定位「空间回收」:磁盘没满但资源争抢导致构建慢看 Jenkins 资源耗尽速查;清理后构建因缓存全失而变慢看 Jenkins 构建缓存失效速查;磁盘正常但构建卡住不动看 Jenkins 构建超时挂起速查。「df 定位分区 → du 定位大头 → 删历史止血 → 保留策略治本」这条主线对一切存储类报错通用。
一句话总结
Jenkins 磁盘写满先 df -h 加 df -i 双跑分清空间满还是 inode 满,再 du -sh 逐层定位——大头几乎总落在构建历史、工作空间、镜像存储三者之一。止血是删旧构建、清工作空间、docker system prune 收悬空镜像;治本是 Discard Old Builds(构建与产物分别限额)、流水线收尾 cleanWs()、镜像每日定时 prune。保留策略进任务模板、磁盘水位接告警,这类报错基本绝迹。