第十二章:故障排除

Jenkins 常见问题诊断和解决方案,包括性能问题、插件故障、网络问题。

最后更新: 2024-01-15
页面目录

故障排除

本章汇总 Jenkins 使用中的常见问题及其解决方案,帮助您快速定位和解决问题。

诊断工具

1. Jenkins 日志

# Docker 环境查看日志
docker logs jenkins

# Linux 环境日志位置
sudo tail -f /var/log/jenkins/jenkins.log

# systemd 日志
sudo journalctl -u jenkins -f

2. 脚本控制台

Jenkins → 系统管理 → 脚本命令行
// 查看系统信息
println "Jenkins Version: ${Jenkins.instance.version}"
println "Java Version: ${System.getProperty('java.version')}"
println "OS: ${System.getProperty('os.name')} ${System.getProperty('os.version')}"
println "Jenkins Home: ${Jenkins.instance.rootDir}"

// 查看插件状态
Jenkins.instance.pluginManager.plugins.each { plugin ->
    println "${plugin.shortName}: ${plugin.version} (${plugin.active ? 'active' : 'inactive'})"
}

// 查看节点状态
Jenkins.instance.computers.each { computer ->
    println "Node: ${computer.displayName}, Offline: ${computer.isOffline()}"
}

3. 系统信息

系统管理 → 系统信息
    • Java 系统属性
    • 环境变量
    • 内存信息
    • 插件列表

常见问题与解决方案

问题 1:Jenkins 启动失败

症状

Jenkins does not start

诊断步骤

# 1. 检查 Java 版本
java -version

# 2. 检查端口占用
sudo netstat -tlnp | grep 8080
# 或
sudo lsof -i :8080

# 3. 检查磁盘空间
df -h

# 4. 检查权限
ls -la /var/lib/jenkins
ls -la /var/log/jenkins

# 5. 查看启动日志
sudo cat /var/log/jenkins/jenkins.log

解决方案

# 端口被占用 - 修改端口
sudo vi /etc/default/jenkins
# 修改 HTTP_PORT=8081

# 磁盘空间不足 - 清理
sudo apt clean
docker system prune -a
sudo rm -rf /tmp/*

# 权限问题 - 修复权限
sudo chown -R jenkins:jenkins /var/lib/jenkins
sudo chown -R jenkins:jenkins /var/log/jenkins

# 内存不足 - 增加内存
sudo vi /etc/default/jenkins
# 添加: JAVA_OPTS="-Xmx2g -Xms1g"

问题 2:构建卡在等待中

症状

Build is queued, waiting for an available executor

诊断步骤

1. 检查系统管理 → 节点管理
2. 查看是否有可用节点
3. 检查 Executor 是否都忙碌
4. 查看构建队列长度

解决方案

// Pipeline 中优化资源使用
pipeline {
    agent {
        label 'docker'
        customWorkspace '/tmp/build-${BUILD_NUMBER}'
    }
    
    options {
        // 设置合理的超时
        timeout(time: 30, unit: 'MINUTES')
        
        // 避免并发冲突
        disableConcurrentBuilds()
    }
    
    stages {
        // 快速失败
        stage('Quick Check') {
            steps {
                script {
                    if (!fileExists('pom.xml')) {
                        error 'Build file not found'
                    }
                }
            }
        }
    }
}

问题 3:Agent 连接失败

症状

Agent is disconnected

诊断步骤

# 1. 检查 Agent 服务状态
sudo systemctl status jenkins-agent

# 2. 检查网络连通性
telnet jenkins-master 50000

# 3. 检查防火墙
sudo ufw status

# 4. 检查 Agent 日志
sudo cat /var/log/jenkins/agent.log

解决方案

# 重新注册 Agent
# 1. 生成新的 agent.jar
curl -O http://jenkins:8080/jnlpJars/agent.jar

# 2. 启动 Agent
java -jar agent.jar \
    -jnlpUrl http://jenkins:8080/computer/${NODE_NAME}/slave-agent.jnlp \
    -secret ${AGENT_SECRET} \
    -workDir "/opt/jenkins/agent"

问题 4:Git 克隆失败

症状

Failed to connect to repository
stderr: Permission denied (publickey)

诊断步骤

# 1. 测试 SSH 连接
ssh -T git@github.com
ssh -vT git@github.com  # 详细日志

# 2. 检查 SSH 密钥
ls -la ~/.ssh/

# 3. 检查 known_hosts
cat ~/.ssh/known_hosts

解决方案

# 生成新 SSH 密钥
ssh-keygen -t ed25519 -C "jenkins@server"
cat ~/.ssh/id_ed25519.pub
# 添加到 GitHub/GitLab

# 测试密钥
ssh -T git@github.com

# 检查 Jenkins 凭据
# 系统管理 → 安全 → Manage Credentials
# 验证 SSH 密钥凭据
// Pipeline 中指定凭据
pipeline {
    stages {
        stage('Checkout') {
            steps {
                git {
                    remote {
                        url 'git@github.com:org/repo.git'
                        credentialsId 'github-ssh-key'
                    }
                    branch 'main'
                }
            }
        }
    }
}

问题 5:插件安装失败

症状

Failed to install plugin

诊断步骤

# 1. 检查网络
curl -I https://updates.jenkins.io/current/

# 2. 检查磁盘空间
df -h /var/lib/jenkins

# 3. 检查权限
ls -la /var/lib/jenkins/plugins/

解决方案

# 手动安装插件
# 1. 下载插件 .hpi 文件
curl -O https://updates.jenkins.io/current/plugins/git/latest/git.hpi

# 2. 复制到插件目录
sudo cp git.hpi /var/lib/jenkins/plugins/

# 3. 重启 Jenkins
sudo systemctl restart jenkins

# 修复插件目录权限
sudo chown -R jenkins:jenkins /var/lib/jenkins/plugins/

问题 6:内存溢出 (OOM)

症状

java.lang.OutOfMemoryError: PermGen space
java.lang.OutOfMemoryError: GC overhead limit exceeded

诊断步骤

# 查看 JVM 内存使用
jstat -gc <pid>
jmap -heap <pid>

# 检查 Jenkins 日志中的 OOM
grep -i "outofmemory" /var/log/jenkins/jenkins.log

解决方案

# 增加 JVM 内存
# /etc/default/jenkins
JAVA_ARGS="-Xmx4g -Xms2g -XX:+UseG1GC -XX:MaxMetaspaceSize=512m"

# Pipeline 中优化
pipeline {
    agent {
        docker {
            image 'maven:3.8-openjdk-11'
            jvmArgs '-Xmx1g'
        }
    }
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn -M512m clean package'  # 限制 Maven 内存
            }
        }
    }
}

问题 7:构建产物无法归档

症状

'archiveArtifacts' not executed

解决方案

pipeline {
    post {
        success {
            // ✅ 在 success 或 always 中归档
            archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
        }
    }
    
    stages {
        stage('Build') {
            steps {
                // ✅ 确保产物存在
                sh '''
                    mvn clean package
                    ls -la target/*.jar
                '''
            }
        }
    }
}

问题 8:凭据无法解密

症状

Failed to decrypt credentials

诊断

// 脚本控制台
import hudson.util.Secret
import jenkins.model.Jenkins

// 测试解密
try {
    def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
        com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials.class,
        Jenkins.instance
    )
    creds.each { c ->
        println "${c.id}: ${c.username}"
    }
} catch (Exception e) {
    println "Error: ${e.message}"
}

解决方案

# 检查 secrets 目录
ls -la /var/lib/jenkins/secrets/

# 修复权限
sudo chown -R jenkins:jenkins /var/lib/jenkins/secrets/
sudo chmod 700 /var/lib/jenkins/secrets/
sudo chmod 600 /var/lib/jenkins/secrets/*

# 重启 Jenkins
sudo systemctl restart jenkins

性能问题排查

构建缓慢

// Pipeline 中添加时间戳
pipeline {
    options {
        timestamps()
    }
    
    stages {
        stage('Build') {
            steps {
                timeStamp() {
                    sh 'mvn clean package -DskipTests'
                }
            }
        }
    }
}

常见性能瓶颈

瓶颈 症状 解决方案
网络 I/O 依赖下载慢 使用 Nexus/Artifactory
磁盘 I/O 文件读写慢 使用 SSD
内存不足 GC 频繁 增加内存
CPU 过载 构建排队 增加 Executor
数据库 查询慢 使用外置数据库

调试技巧

1. 启用详细日志

系统管理 → 日志记录
    添加记录器:
        • hudson.model.Job: ALL
        • hudson.plugins.git: ALL
        • org.jenkinsci.plugins: ALL

2. Pipeline 调试

pipeline {
    stages {
        stage('Debug') {
            steps {
                script {
                    echo "Build Number: ${env.BUILD_NUMBER}"
                    echo "Workspace: ${env.WORKSPACE}"
                    echo "Branch: ${env.BRANCH_NAME}"
                    sh 'printenv | sort'
                    sh 'ls -la'
                }
            }
        }
    }
}

3. 使用 sh scriptExitCode

steps {
    script {
        def result = sh(
            script: 'mvn test',
            returnStatus: true,
            returnStdout: true
        )
        
        echo "Exit code: ${result}"
        
        if (result != 0) {
            echo "Build failed with exit code ${result}"
        }
    }
}

常见错误码

错误码 含义 解决方案
0 成功 -
1 一般错误 检查日志
126 权限不足 chmod +x
127 命令不存在 检查 PATH
137 OOM kill 增加内存
143 被信号终止 检查超时

恢复操作

Jenkins 无法启动时的紧急恢复

#!/bin/bash
# emergency-recovery.sh

set -e

echo "=== Jenkins 紧急恢复 ==="

# 1. 备份当前配置
cp -r /var/lib/jenkins /var/lib/jenkins.bak.$(date +%Y%m%d)

# 2. 检查端口
sudo netstat -tlnp | grep 8080 || echo "Port 8080 is free"

# 3. 检查 Java
java -version

# 4. 检查日志
tail -100 /var/log/jenkins/jenkins.log

# 5. 清除缓存
rm -rf /var/lib/jenkins/cache/
rm -rf /var/lib/jenkins/temp/

# 6. 重置插件(如果需要)
# mv /var/lib/jenkins/plugins /var/lib/jenkins/plugins.bak

# 7. 启动 Jenkins
sudo systemctl start jenkins

# 8. 验证
sleep 10
curl -f http://localhost:8080 || echo "Jenkins is not responding"

获取帮助

资源 链接
官方文档 https://www.jenkins.io/doc/
问题追踪 https://issues.jenkins.io/
Slack https://jenkins.io/slack/
Wiki https://wiki.jenkins-ci.org/
Stack Overflow https://stackoverflow.com/questions/tagged/jenkins

下一步

最后,让我们学习如何开发自定义 Jenkins 插件。

👉 插件开发


🔧 提示:遇到问题时,先查看日志和系统信息,通常能快速定位原因。