一、为什么Jenkins会磁盘空间不足?
Jenkins作为持续集成工具,每天都会产生大量的构建产物、工作空间文件和日志。如果不及时清理,这些文件会像滚雪球一样越积越多。想象一下你的电脑C盘变红的样子,Jenkins服务器也会遇到同样的问题。
常见占用空间的大户包括:
- 构建产物(比如编译生成的jar包、apk文件)
- 工作空间(每次构建时拉取的代码和生成的文件)
- 构建日志(特别是长时间运行的构建任务)
二、手动清理的局限性
很多团队最初会采用手动删除的方式:
# 进入Jenkins工作目录
cd /var/lib/jenkins/workspace/
# 删除30天前的构建目录
find . -type d -mtime +30 -exec rm -rf {} \;
但这种做法有三个明显问题:
- 容易误删重要文件
- 需要人工定期操作
- 无法针对不同项目设置不同策略
三、自动化清理方案设计
3.1 使用Jenkins内置功能
Jenkins其实已经提供了不错的清理机制,只是很多人没充分利用:
// Jenkinsfile示例 - 保留最近5次构建
pipeline {
options {
buildDiscarder(logRotator(numToKeepStr: '5'))
}
// 其他构建步骤...
}
这个配置会自动保留最近5次构建,删除更早的构建。但要注意:
- 只适用于流水线项目
- 不会清理工作空间
- 对日志文件无效
3.2 使用Disk Clean插件
安装"Disk Clean"插件后可以这样配置:
// 在Jenkins全局配置中添加定期清理任务
node {
// 删除超过30天的构建记录
cleanWs(deleteDirs: true, patterns: [[pattern: '.gitignore', type: 'INCLUDE']])
// 删除超过50次的旧构建
buildDiscarder(logRotator(numToKeepStr: '50'))
}
这个插件更强大之处在于:
- 可以设置多种清理条件组合
- 支持正则表达式匹配文件
- 能生成清理报告
3.3 自定义Shell脚本方案
对于需要精细控制的场景,可以编写定时任务:
#!/bin/bash
# 清理脚本示例 - 技术栈:Linux Shell
# 配置变量
JENKINS_HOME="/var/lib/jenkins"
MAX_DAYS=30 # 保留最近30天
DRY_RUN=false # 测试模式
# 主清理函数
clean_old_builds() {
find "$JENKINS_HOME/jobs" -name "builds" -type d | while read build_dir; do
echo "处理目录: $build_dir"
find "$build_dir" -mindepth 1 -maxdepth 1 -type d -mtime +$MAX_DAYS | while read old_build; do
if [ "$DRY_RUN" = true ]; then
echo "[模拟] 将删除: $old_build"
else
echo "删除: $old_build"
rm -rf "$old_build"
fi
done
done
}
# 执行清理
clean_old_builds
这个脚本的特点:
- 支持模拟运行(dry run)模式
- 可以灵活调整保留天数
- 递归处理所有项目的构建目录
四、进阶清理策略
4.1 按项目重要性分级清理
重要的核心项目和生产环境构建应该保留更长时间:
// 分级清理策略示例
def cleanupStrategy = [
'core-service': [buildsToKeep: 20, daysToKeep: 60],
'test-project': [buildsToKeep: 5, daysToKeep: 7],
'default': [buildsToKeep: 10, daysToKeep: 30]
]
pipeline {
options {
// 根据项目名称应用不同策略
buildDiscarder(logRotator(
artifactDaysToKeepStr: cleanupStrategy[env.JOB_NAME]?.daysToKeep ?: cleanupStrategy.default.daysToKeep,
artifactNumToKeepStr: cleanupStrategy[env.JOB_NAME]?.buildsToKeep ?: cleanupStrategy.default.buildsToKeep
))
}
// 构建步骤...
}
4.2 日志文件单独处理
构建日志往往比构建产物占用更多空间:
#!/bin/bash
# 日志清理专用脚本
# 保留最近100MB的日志
LOG_DIR="/var/log/jenkins"
MAX_SIZE=100000 # 单位KB
# 计算当前日志大小
current_size=$(du -sk $LOG_DIR | awk '{print $1}')
if [ $current_size -gt $MAX_SIZE ]; then
echo "当前日志大小: ${current_size}KB > ${MAX_SIZE}KB阈值"
# 按修改时间排序,删除最旧的日志
find $LOG_DIR -type f -name "*.log" -printf "%T@ %p\n" | sort -n | \
while read -r line; do
file=$(echo "$line" | awk '{print $2}')
rm "$file"
current_size=$(du -sk $LOG_DIR | awk '{print $1}')
[ $current_size -le $MAX_SIZE ] && break
done
fi
五、注意事项与最佳实践
- 清理前备份:设置自动清理前,确保关键构建产物有备份
- 监控效果:添加磁盘空间监控,验证清理策略是否有效
- 白名单机制:对特殊构建设置排除规则
- 清理频率:建议每天执行,避开构建高峰期
- 通知机制:清理重要文件前发送通知
六、完整方案示例
结合上述所有策略的完整方案:
// 完整清理方案 - 技术栈:Jenkins Pipeline
pipeline {
agent any
triggers {
// 每天凌晨2点自动执行清理
cron('0 2 * * *')
}
stages {
stage('清理构建') {
steps {
script {
// 保留最近10次构建
buildDiscarder(logRotator(numToKeepStr: '10'))
// 清理工作空间(排除.git目录)
cleanWs(
deleteDirs: true,
patterns: [
[pattern: '.git/**', type: 'EXCLUDE'],
[pattern: '*.log', type: 'INCLUDE']
]
)
}
}
}
stage('清理日志') {
steps {
sh '''
#!/bin/bash
# 保留最近7天的Jenkins系统日志
find /var/log/jenkins -name "*.log" -mtime +7 -exec rm -f {} \;
# 但保留关键错误日志
find /var/log/jenkins -name "ERROR*.log" -mtime +30 -exec rm -f {} \;
'''
}
}
}
post {
always {
// 发送清理报告
emailext body: "磁盘清理已完成,当前可用空间:${sh(returnStdout: true, script: 'df -h /var/lib/jenkins').trim()}",
subject: "Jenkins磁盘清理报告",
to: 'devops@example.com'
}
}
}
七、方案评估与选择
方案对比表:
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 手动清理 | 简单直接 | 容易出错,效率低 | 临时应急 |
| 内置功能 | 无需额外插件 | 功能有限 | 基础需求 |
| Disk Clean插件 | 功能全面 | 需要安装插件 | 大多数项目 |
| 自定义脚本 | 完全可控 | 维护成本高 | 特殊需求 |
推荐选择路径:
- 中小团队:内置功能 + Disk Clean插件
- 大型集群:分级策略 + 自定义脚本
- 特殊环境:结合文件系统快照功能
八、总结
Jenkins磁盘空间管理就像整理你的电脑硬盘:
- 定期"大扫除"比等到空间不足再处理更有效
- 不同"房间"(构建、日志、工作空间)需要不同的整理策略
- 设置好"自动保洁"规则后就能一劳永逸
记住三个关键数字:
- 构建保留次数:5-20次(根据项目重要性)
- 日志保留天数:7-30天
- 检查频率:至少每周一次
通过合理的自动化策略,可以让Jenkins保持"轻盈"状态,避免因磁盘问题导致的构建失败,让CI/CD流程更加顺畅。
评论