Jenkins 从入门到精通 — 完整学习笔记

Jenkins 从入门到精通 --- 完整学习笔记

服务器环境 :华为云 ecs-7c2c × 4 台 | Ubuntu 24.04 | 2vCPU/4GiB

Jenkins 版本 :2.555.2 LTS | Java 21 | WAR 方式部署

认证方式 :HudsonPrivateSecurityRealm | CSRF Protection

实战日期:2026-06-01


目录

  1. [第一章:CI/CD 概念与 Jenkins 概述](#第一章:CI/CD 概念与 Jenkins 概述)
  2. [第二章:Jenkins 安装与配置](#第二章:Jenkins 安装与配置)
  3. [第三章:Jenkins 界面与核心概念](#第三章:Jenkins 界面与核心概念)
  4. [第四章:Pipeline 流水线详解](#第四章:Pipeline 流水线详解)
  5. [第五章:Jenkins 插件生态](#第五章:Jenkins 插件生态)
  6. [第六章:Jenkins 安全与权限](#第六章:Jenkins 安全与权限)
  7. [第七章:Jenkins 分布式构建](#第七章:Jenkins 分布式构建)
  8. [第八章:Jenkins 与版本控制集成](#第八章:Jenkins 与版本控制集成)
  9. [第九章:Jenkins 与容器化集成](#第九章:Jenkins 与容器化集成)
  10. [第十章:Jenkins 通知与报告](#第十章:Jenkins 通知与报告)
  11. [第十一章:Jenkins 高级特性](#第十一章:Jenkins 高级特性)
  12. [第十二章:Jenkins 性能优化](#第十二章:Jenkins 性能优化)
  13. [第十三章:Jenkins 实战项目](#第十三章:Jenkins 实战项目)
  14. [第十四章:Jenkins 故障排查](#第十四章:Jenkins 故障排查)
  15. [第十五章:Jenkins 云原生实践](#第十五章:Jenkins 云原生实践)
  16. [第十六章:Jenkins 面试与进阶](#第十六章:Jenkins 面试与进阶)
  17. 附录

第一章:CI/CD 概念与 Jenkins 概述

1.1 持续集成(CI)概念与价值

持续集成(Continuous Integration) 是一种软件开发实践,要求团队成员频繁地(通常每天多次)将代码集成到共享主干分支。

复制代码
┌──────────────────────────────────────────────────────────────┐
│                    CI/CD Pipeline 全景图                       │
│                                                              │
│  [Code] → [Build] → [Test] → [Package] → [Deploy] → [Monitor]│
│    │         │        │         │          │           │     │
│    ▼         ▼        ▼         ▼          ▼           ▼     │
│  Git      Maven    JUnit    Docker    Kubernetes   Grafana   │
│  Push    Gradle   Selenium   Jar/War   Staging     Prometheus │
│          npm      Coverage  Registry  Production   Alerting   │
└──────────────────────────────────────────────────────────────┘
CI 核心价值
价值维度 传统开发 CI 后 提升
集成频率 数周/月一次 每次 git push
Bug 发现时间 数天后 数分钟内 100x
集成问题修复成本 极高(回滚整个版本) 极低(单个提交) 90%↓
团队信心 低("在我机器上能跑") 高(自动化验证) ---
交付速度 月级别 天/小时级别 30x+

1.2 持续部署(CD)与持续交付的区别

复制代码
持续交付 (Continuous Delivery):
  代码变更 → 自动构建 → 自动测试 → [手动审批] → 部署到生产
                                                ↑
                                          人工决策关卡

持续部署 (Continuous Deployment):
  代码变更 → 自动构建 → 自动测试 → 自动部署到生产
                                        ↑
                                  完全自动化(无人工干预)

实战对比

维度 持续交付 持续部署
生产部署 手动触发 自动触发
适用场景 金融/医疗等强合规行业 互联网/SaaS 产品
风险控制 人工审核 自动化金丝雀+自动回滚
团队要求 高(需要高度自动化测试覆盖)

1.3 Jenkins 历史与发展

复制代码
2004 --- Kohsuke Kawaguchi 在 Sun Microsystems 创建 Hudson
2005 --- Hudson 首次公开发布
2011 --- Oracle 获得 Hudson 商标,社区 fork 为 Jenkins
2014 --- Jenkins 2.0 概念提出(Pipeline as Code)
2016 --- Jenkins 2.0 正式发布(Declarative Pipeline)
2018 --- Jenkins X 诞生(云原生 CI/CD)
2020 --- Jenkins 2.263+ 支持 Java 11
2024 --- Jenkins 2.463+ 要求 Java 17
2026 --- 当前 2.555.2 LTS 要求 Java 21
Jenkins 版本选择
版本线 更新频率 稳定性 推荐场景
LTS(长期支持) 每 12 周 生产环境
Weekly 每周 尝鲜/开发环境
Jenkins X 独立版本 --- Kubernetes 原生 CI/CD

1.4 Jenkins 特点与优势

复制代码
Jenkins 核心优势:

1. 插件生态 --- 1800+ 插件覆盖所有 DevOps 工具链
2. Pipeline as Code --- Jenkinsfile 版本化在 Git 仓库
3. 分布式构建 --- Master-Agent 架构支持横向扩展
4. 完全开源 --- MIT License,无商业限制
5. 社区活跃 --- 20 年历史,数百万用户
6. 平台无关 --- Java 语言,跨 Windows/Linux/macOS

1.5 Jenkins 与 GitLab CI、GitHub Actions、CircleCI 对比

特性 Jenkins GitLab CI GitHub Actions CircleCI
类型 自托管 自托管+SaaS SaaS+自托管 SaaS+自托管
配置方式 Jenkinsfile .gitlab-ci.yml .github/workflows/*.yml .circleci/config.yml
插件生态 1800+ 有限 社区 Actions Orbs
学习曲线 中-高 低-中
定制化 极高
费用 免费(自建) 免费层有限 免费层慷慨 免费层有限
UI 界面 Blue Ocean 现代化 内置 CI/CD 页面 Actions Tab Dashboard
适合场景 企业定制流水线 GitLab 全家桶 GitHub 生态项目 中小型 SaaS

第二章:Jenkins 安装与配置

2.1 环境要求

组件 最低要求 推荐配置
Java JDK 21 JDK 21 (Jenkins 2.555+ 强制要求)
内存 256 MB 4 GB+ (生产环境)
磁盘 1 GB (JENKINS_HOME) 50 GB+ (含构建历史)
CPU 1 核 4 核+
操作系统 Linux/Windows/macOS Ubuntu 24.04 LTS
Java 版本兼容性表
Jenkins 版本 最低 Java 推荐 Java
< 2.357 Java 8 Java 8
2.357 - 2.419 Java 11 Java 11
2.463 - 2.479 Java 17 Java 17
2.492+ Java 21 Java 21

实战踩坑:本次安装时,Ubuntu 24.04 默认安装 Java 17,Jenkins 2.555.2 启动直接报错:

复制代码
Running with Java 17, which is older than the minimum required version (Java 21)
Supported Java versions are: [21, 25]

解决apt-get install openjdk-21-jre

2.2 Linux 环境安装(apt 方式)

bash 复制代码
# 1. 安装 Java 21
sudo apt-get update
sudo apt-get install -y fontconfig openjdk-21-jre
java -version  # 确认 Java 21

# 2. 添加 Jenkins 仓库
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | \
  sudo gpg --dearmor -o /usr/share/keyrings/jenkins-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.gpg] \
  https://pkg.jenkins.io/debian-stable binary/" | \
  sudo tee /etc/apt/sources.list.d/jenkins.list

# 3. 安装并启动
sudo apt-get update
sudo apt-get install -y jenkins
sudo systemctl enable --now jenkins

# 4. 获取初始管理员密码
sudo cat /var/lib/jenkins/secrets/initialAdminPassword

2.3 WAR 包部署方式(推荐 --- 本次实战使用)

WAR 包方式相比 apt 安装的优势:

  • 版本精确控制:指定具体版本 WAR 包
  • 不依赖系统仓库:避免 GPG 签名问题
  • 灵活配置 JVM 参数:直接传递 JVM 启动参数
  • 多实例共存:不同端口运行多个 Jenkins
bash 复制代码
# 1. 安装 Java 21
sudo apt-get install -y fontconfig openjdk-21-jre

# 2. 下载 WAR 包
sudo mkdir -p /opt/jenkins
sudo wget https://get.jenkins.io/war-stable/latest/jenkins.war \
  -O /opt/jenkins/jenkins.war
# 实际版本: 2.555.2 | 96MB

# 3. 创建 Jenkins 用户
sudo useradd -r -m -d /var/lib/jenkins -s /bin/bash jenkins
sudo mkdir -p /var/lib/jenkins /var/log/jenkins /var/cache/jenkins
sudo chown -R jenkins:jenkins /opt/jenkins /var/lib/jenkins \
  /var/log/jenkins /var/cache/jenkins
systemd 服务配置文件详解
ini 复制代码
# /etc/systemd/system/jenkins.service
[Unit]
Description=Jenkins Continuous Integration Server
After=network.target
# ↑ network.target: 确保网络栈初始化完毕后再启动 Jenkins

[Service]
User=jenkins                     # 以 jenkins 用户运行(非 root)
Group=jenkins
Environment="JENKINS_HOME=/var/lib/jenkins"
# ↑ JENKINS_HOME: Jenkins 数据目录(jobs、plugins、configs)
# 出厂占用约 500MB-2GB(取决于插件数量)
Environment="JENKINS_LOG=/var/log/jenkins/jenkins.log"
# ↑ 可选:指定日志文件路径
Environment="JENKINS_WEBROOT=/var/cache/jenkins/war"
# ↑ WAR 解压缓存目录,加速后续启动
WorkingDirectory=/var/lib/jenkins
# ↑ 工作目录 = JENKINS_HOME

ExecStart=/usr/lib/jvm/java-21-openjdk-amd64/bin/java \
  -Djava.awt.headless=true \    # 无图形界面模式
  -jar /opt/jenkins/jenkins.war \
  --webroot=/var/cache/jenkins/war \
  --httpPort=8080               # 监听端口

Restart=on-failure              # 仅异常退出时重启
RestartSec=10                   # 重启前等待 10 秒
LimitNOFILE=8192                # 最大文件描述符数

[Install]
WantedBy=multi-user.target      # 默认运行级别
JVM 生产调优参数
bash 复制代码
# 生产环境推荐 JVM 参数
ExecStart=/usr/lib/jvm/java-21-openjdk-amd64/bin/java \
  -Djava.awt.headless=true \
  -Xms2048m \                   # 初始堆 2GB
  -Xmx4096m \                   # 最大堆 4GB
  -XX:MaxMetaspaceSize=512m \   # 元空间上限 512MB
  -XX:+UseG1GC \                # G1 垃圾收集器
  -XX:MaxGCPauseMillis=200 \    # GC 暂停目标 200ms
  -XX:+HeapDumpOnOutOfMemoryError \  # OOM 时生成 heap dump
  -XX:HeapDumpPath=/var/log/jenkins/heapdump.hprof \
  -Djava.io.tmpdir=/tmp/jenkins \    # 临时文件目录
  -Dhudson.model.DirectoryBrowserSupport.CSP="" \  # 放宽 CSP(插件兼容)
  -Dhudson.lifecycle=hudson.lifecycle.LinuxLifecycle \
  -jar /opt/jenkins/jenkins.war \
  --httpPort=8080 \
  --webroot=/var/cache/jenkins/war
JVM 参数 说明 推荐值
-Xms 初始堆大小 2g(生产)/ 512m(测试)
-Xmx 最大堆大小 4g(生产)/ 1g(测试)
-XX:MaxMetaspaceSize 元空间上限 512m
-XX:+UseG1GC G1 垃圾收集器 Java 9+ 默认,推荐
-XX:+HeapDumpOnOutOfMemoryError OOM 时 dump 堆 生产必开

2.4 Docker 容器化部署

bash 复制代码
# 官方 Docker 镜像
docker run -d \
  --name jenkins \
  --restart=unless-stopped \
  -p 8080:8080 \
  -p 50000:50000 \
  -v jenkins_home:/var/jenkins_home \
  -v /var/run/docker.sock:/var/run/docker.sock \
  jenkins/jenkins:lts

# Docker Compose
version: '3.8'
services:
  jenkins:
    image: jenkins/jenkins:lts
    container_name: jenkins
    ports:
      - "8080:8080"
      - "50000:50000"    # Agent 通信端口
    volumes:
      - jenkins_home:/var/jenkins_home
      - /var/run/docker.sock:/var/run/docker.sock  # 内部调用 Docker
    environment:
      - JAVA_OPTS=-Xmx2048m -Xms1024m
    restart: unless-stopped

volumes:
  jenkins_home:

2.5 首次启动与初始化

实战验证
bash 复制代码
# 启动后验证
$ systemctl status jenkins
● jenkins.service - Jenkins Continuous Integration Server
     Active: active (running) since Mon 2026-06-01 11:37:22 CST
   Main PID: 14353 (java)
     Memory: 327.1M (peak: 327.4M)

$ ss -tlnp | grep 8080
LISTEN 0  50  *:8080  *:*  users:(("java",pid=14353,fd=9))

# 获取初始密码
$ cat /var/lib/jenkins/secrets/initialAdminPassword
d94de5fb078642e3b8908bf9e7470da0
自动化初始化(Groovy Init 脚本)
groovy 复制代码
// /var/lib/jenkins/init.groovy.d/01-security.groovy
import jenkins.model.*
import hudson.security.*

def instance = Jenkins.get()
def realm = new HudsonPrivateSecurityRealm(false)

// 创建管理员账号
realm.createAccount('devops', 'Devops@2024!')
instance.setSecurityRealm(realm)

// 配置权限策略
def strategy = new FullControlOnceLoggedInAuthorizationStrategy()
strategy.setAllowAnonymousRead(false)  // 禁止匿名访问
instance.setAuthorizationStrategy(strategy)
instance.save()

注意 :Groovy Init 脚本在 Jenkins 启动的 init 阶段执行,每次重启都会运行。

如果用户已存在则 createAccount 会抛异常,需要 try-catch 包裹。


第三章:Jenkins 界面与核心概念

3.1 Job/Project 类型

Jenkins 中的核心概念是 Job(也称为 Project),代表一个自动化的构建任务。

五种 Job 类型对比
复制代码
┌──────────────────────────────────────────────────────────┐
│                    Jenkins Job 类型                        │
│                                                          │
│  Freestyle Project                                       │
│  ├─ 图形化配置                                            │
│  ├─ 适合简单任务                                          │
│  └─ 不推荐(难以版本化)                                    │
│                                                          │
│  Pipeline Project                                         │
│  ├─ Jenkinsfile 定义                                      │
│  ├─ 版本化管理(Git)                                       │
│  └─ ★ 推荐首选                                            │
│                                                          │
│  Multibranch Pipeline                                     │
│  ├─ 自动发现所有分支                                       │
│  ├─ 每个分支独立 Pipeline                                  │
│  └─ 适合多分支项目                                         │
│                                                          │
│  Maven Project                                            │
│  ├─ Maven 专用配置                                        │
│  ├─ 自动识别 POM                                          │
│  └─ 仅 Java/Maven 项目                                    │
│                                                          │
│  Folder                                                   │
│  ├─ 组织层级结构                                          │
│  └─ 命名空间隔离                                          │
└──────────────────────────────────────────────────────────┘

3.2 构建触发器

触发器类型 配置方式 适用场景
手动触发 Web UI "Build Now" 临时/调试构建
定时构建 (Cron) Build periodically 夜间构建、定时检查
SCM 轮询 Poll SCM 代码变更检测
Webhook GitHub/GitLab 配置 实时触发(推荐)
上游/下游 Build after other projects 流水线级联
Cron 语法详解
复制代码
分 时 日 月 周

H/5 * * * *      → 每 5 分钟构建一次
H H * * *         → 每天构建一次(H = Jenkins 自动分散)
H 2 * * 1-5       → 工作日凌晨 2 点
H(0-29)/30 * * *  → 上半小时每 30 分钟
@midnight          → 午夜 0:00-2:59 之间随机时间

推荐使用 H(Hash)替代固定值,避免在整点所有 Job 同时构建造成峰值

3.31 实战:Freestyle Job 构建输出(真实服务器日志)

bash 复制代码
# 任务创建
$ curl -s -u devops:**** -X POST \
  'http://localhost:8080/createItem?name=Hello-World-Freestyle' \
  --data-binary @freestyle.xml -H 'Content-Type: application/xml'
# → 200 Created

# 构建输出(来自 ecs-7c2c-0002 服务器)
Started by user devops
Running as SYSTEM
Building in workspace /var/lib/jenkins/workspace/Hello-World-Freestyle
[Hello-World-Freestyle] $ /bin/sh -xe /tmp/jenkins130698.sh

========================================
Jenkins Freestyle Job Demo
BUILD_NUMBER=
JOB_NAME=
NODE_NAME=
--- System ---
Linux ecs-7c2c-0002 6.8.0-106-generic x86_64 GNU/Linux
--- Disk ---
/dev/vda1   40G  5.0G  33G  14% /
--- Memory ---
              total  used  free  shared  buff/cache  available
Mem:          3.3Gi  1.3Gi 146Mi 2.6Mi   2.2Gi       2.0Gi
--- Java ---
openjdk version "21.0.11" 2026-04-21
=== BUILD SUCCESS ===

Finished: SUCCESS
构建状态颜色含义
颜色 图标 含义
🔵 蓝色 Blue 最后一次构建成功
🔴 红色 Red 最后一次构建失败
🟡 黄色 Yellow 构建成功但测试不稳定
⚪ 灰色 Grey 从未构建或被禁用
🟢 绿色 Blue Animated 正在构建中

3.4 全局配置详解

全局工具配置 (Manage Jenkins → Tools)
groovy 复制代码
// 通过 Configuration as Code (JCasC) 配置
tool:
  jdk:
    installations:
      - name: "JDK21"
        home: "/usr/lib/jvm/java-21-openjdk-amd64"
  maven:
    installations:
      - name: "Maven3"
        home: "/opt/maven"
  git:
    installations:
      - name: "Default"
        home: "git"
系统配置关键项
配置项 位置 说明
Jenkins URL 系统配置 Agent 回连地址,必须正确
执行者数量 系统配置 并发构建数,默认 2
Quiet Period 系统配置 构建前等待时间(秒),默认 5
SCM checkout retry count 系统配置 SCM 检出失败重试次数
Restrict project naming 系统配置 项目命名规则限制

第四章:Pipeline 流水线详解

4.1 Pipeline 概念与优势

Pipeline 是 Jenkins 的核心功能,将 CI/CD 流程定义为代码(Pipeline as Code),版本化在 Git 仓库中。

复制代码
传统方式(Freestyle):           Pipeline方式(Jenkinsfile):
┌────────────────────┐           ┌──────────────────────────┐
│  UI 点点点配置       │           │  pipeline {               │
│  无法版本化          │      →    │    agent any              │
│  修改无审计          │           │    stages {               │
│  无法复用            │           │      stage('Build') {...} │
└────────────────────┘           │      stage('Test') {...}  │
                                 │      stage('Deploy') {...} │
                                 │    }                       │
                                 │  }                         │
                                 └──────────────────────────┘

4.2 Declarative Pipeline(声明式 --- 推荐)

完整的 Declarative Pipeline 示例
groovy 复制代码
pipeline {
    // ===== 1. agent:指定运行节点 =====
    agent any                     // 任意可用节点
    // agent { label 'linux' }    // 指定标签
    // agent { docker 'maven:3' } // Docker 容器

    // ===== 2. environment:环境变量 =====
    environment {
        APP_NAME    = 'myapp'
        VERSION     = '1.0.0'
        DOCKER_REG  = 'registry.example.com'
        // 引用凭据
        GIT_CREDS   = credentials('git-credentials-id')
    }

    // ===== 3. options:全局选项 =====
    options {
        timeout(time: 1, unit: 'HOURS')   // 超时 1 小时
        buildDiscarder(
            logRotator(numToKeepStr: '30')  // 保留 30 个构建
        )
        disableConcurrentBuilds()          // 禁止并发
        timestamps()                       // 时间戳日志
    }

    // ===== 4. parameters:参数化构建 =====
    parameters {
        string(name: 'BRANCH', defaultValue: 'main',
               description: '要构建的分支')
        choice(name: 'ENV', choices: ['dev', 'staging', 'prod'],
               description: '部署环境')
        booleanParam(name: 'RUN_TESTS', defaultValue: true,
                     description: '是否运行测试')
    }

    // ===== 5. triggers:触发器 =====
    triggers {
        cron('H 2 * * 1-5')              // 工作日凌晨 2 点
        pollSCM('H/15 * * * *')           // 每 15 分钟检查 SCM
    }

    // ===== 6. stages:核心构建阶段 =====
    stages {
        stage('Checkout') {
            steps {
                echo '检出代码...'
                git url: 'https://github.com/user/repo.git',
                    branch: "${params.BRANCH}"
            }
        }

        stage('Build') {
            steps {
                echo "构建 ${APP_NAME} v${VERSION}..."
                sh 'mvn clean package -DskipTests'
            }
            post {
                success {
                    archiveArtifacts artifacts: 'target/*.jar',
                                     fingerprint: true
                    // ↑ fingerprint 用于追踪制品来源
                }
            }
        }

        stage('Test') {
            // parallel:并行执行测试
            parallel {
                stage('Unit Tests') {
                    steps {
                        sh 'mvn test'
                    }
                }
                stage('Integration Tests') {
                    steps {
                        sh 'mvn verify -Pintegration'
                    }
                }
                stage('Code Quality') {
                    steps {
                        sh 'mvn sonar:sonar'
                    }
                }
            }
        }

        stage('Deploy') {
            // when:条件执行
            when {
                branch 'main'            // 仅 main 分支执行
                environment name: 'ENV', value: 'prod'
            }
            steps {
                sh "kubectl set image deployment/${APP_NAME} \
                    ${APP_NAME}=${DOCKER_REG}/${APP_NAME}:${VERSION}"
            }
        }
    }

    // ===== 7. post:构建后操作 =====
    post {
        always {
            // 无论构建结果如何都执行
            cleanWs()  // 清理工作空间
        }
        success {
            // 成功时
            emailext to: 'team@example.com',
                     subject: "✅ ${JOB_NAME} - #${BUILD_NUMBER} 成功",
                     body: "构建通过!"
        }
        failure {
            // 失败时
            emailext to: 'oncall@example.com',
                     subject: "❌ ${JOB_NAME} - #${BUILD_NUMBER} 失败",
                     body: "请查看: ${BUILD_URL}"
        }
        unstable {
            // 测试失败但构建通过
            echo '测试不稳定,请关注!'
        }
    }
}
Declarative Pipeline 指令速查
指令 位置 说明 示例
agent pipeline/stage 运行节点 agent any
environment pipeline/stage 环境变量 environment { VAR = 'val' }
options pipeline 全局选项 options { timeout(time:1,unit:'HOURS') }
parameters pipeline 参数化构建 parameters { string(name:'X') }
triggers pipeline 触发器 triggers { cron('H * * * *') }
stages pipeline 阶段容器 stages { stage(...) {} }
steps stage 执行步骤 steps { sh 'cmd' }
post pipeline/stage 后处理 post { success {...} }
when stage 条件执行 when { branch 'main' }
tools pipeline 工具定义 tools { maven 'M3' }
input stage 人工确认 input { message 'OK?' }
parallel stage 并行执行 parallel { stage1{}, stage2{} }
post 条件块详解
条件 触发时机
always 总是执行(无论成功/失败/中止)
changed 当前构建结果与上次不同
fixed 上次失败,本次成功
regression 上次成功,本次失败
aborted 手动中止构建
failure 构建失败
success 构建成功
unstable 测试失败但构建通过
unsuccessful 非成功(failure + unstable + aborted)
cleanup 所有其他 post 执行完毕后

4.3 Scripted Pipeline(脚本式)

groovy 复制代码
node('linux') {              // node() = 分配执行节点
    try {
        stage('Checkout') {
            checkout scm     // 检出代码
        }

        stage('Build') {
            def mvnHome = tool name: 'Maven3', type: 'maven'
            sh "${mvnHome}/bin/mvn clean package"
        }

        // Scripted Pipeline 的并行执行
        stage('Parallel Tests') {
            def branches = [:]

            for (int i = 1; i <= 3; i++) {
                def num = i
                branches["test-${num}"] = {
                    echo "运行测试批次 ${num}..."
                    sh "mvn test -Dtest.group=${num}"
                }
            }
            parallel branches  // 并行执行所有分支
        }

        // 流程控制
        stage('Deploy') {
            if (env.BRANCH_NAME == 'main') {
                sh 'kubectl apply -f k8s/production/'
            } else {
                sh 'kubectl apply -f k8s/staging/'
            }
        }

    } catch (Exception e) {
        currentBuild.result = 'FAILURE'
        error("构建失败: ${e.message}")
    } finally {
        cleanWs()            // 清理工作空间
    }
}

4.4 Declarative vs Scripted 对比

特性 Declarative Scripted
语法 结构化 DSL Groovy 流程控制
学习曲线 中-高
代码检查 内置 when 条件 手动 if/else
错误处理 post try-catch-finally
可读性 高(声明意图) 中(过程式)
灵活性 高(可任意编程)
推荐场景 90% CI/CD 流水线 复杂条件/动态流水线
Blue Ocean 原生支持 支持

4.5 Pipeline 全局变量

Jenkins 内置了大量环境变量,可在 Pipeline 中直接使用:

groovy 复制代码
// Jenkins 内置变量(只读)
${JOB_NAME}            // 项目名称
${BUILD_NUMBER}        // 构建编号
${BUILD_ID}           // 构建 ID (时间戳)
${BUILD_URL}          // 构建结果 URL
${NODE_NAME}          // 执行节点名称
${WORKSPACE}          // 工作空间路径
${JENKINS_HOME}       // Jenkins 主目录
${JENKINS_URL}        // Jenkins 服务器 URL
${EXECUTOR_NUMBER}    // 执行器编号
${GIT_COMMIT}         // Git commit hash
${GIT_BRANCH}         // Git 分支名

// 使用示例
echo "构建 ${JOB_NAME} #${BUILD_NUMBER} 在 ${NODE_NAME} 执行"
echo "工作空间: ${WORKSPACE}"

第五章:Jenkins 插件生态

5.1 插件管理架构

复制代码
Jenkins Plugin Manager
│
├─ Update Center(更新中心)
│   └─ https://updates.jenkins.io/
│       └─ update-center.json(插件元数据)
│
├─ 安装方式
│   ├─ Web UI:Manage Jenkins → Plugins
│   ├─ CLI:java -jar jenkins-cli.jar install-plugin <name>
│   └─ 手动:上传 .hpi/.jpi 文件
│
└─ 插件存储
    └─ ${JENKINS_HOME}/plugins/
        ├─ plugin-name.jpi     (插件包)
        └─ plugin-name/        (解压目录)

5.2 必备插件推荐

SCM(源码管理)
插件 用途 必装
Git Plugin Git 仓库集成 ★★★★★
GitHub Integration GitHub Webhook + PR ★★★★
GitLab Plugin GitLab Webhook + MR ★★★★
Subversion SVN 仓库 ★★
Pipeline
插件 用途 必装
Pipeline Pipeline 核心 ★★★★★
Pipeline: Stage View Stage 可视化 ★★★★★
Blue Ocean 现代化 UI ★★★★
Pipeline Utility Steps 扩展 Steps ★★★★
构建工具
插件 用途 必装
Maven Integration Maven 构建 ★★★★
Gradle Gradle 构建 ★★★
NodeJS Node.js 构建 ★★★★
Docker Pipeline Docker 操作 ★★★★★
通知
插件 用途 必装
Email Extension 增强邮件通知 ★★★★
Slack Notification Slack 通知 ★★★
DingTalk 钉钉通知 ★★★★(中国团队)
安全
插件 用途 必装
Role-based Strategy 角色权限 ★★★★★
Credentials Binding 凭据绑定 ★★★★★
LDAP Plugin LDAP 集成 ★★★

5.3 插件管理最佳实践

groovy 复制代码
// plugins.txt --- 版本锁定
workflow-aggregator: latest
git: latest
blueocean: latest
credentials-binding: latest
role-strategy: latest
email-ext: latest
docker-workflow: latest
bash 复制代码
# 批量安装
#!/bin/bash
while IFS=: read -r plugin version; do
    java -jar jenkins-cli.jar install-plugin "${plugin}" -deploy
done < plugins.txt

# 安全重启
java -jar jenkins-cli.jar safe-restart

踩坑 :Plugin 安装后必须 重启 Jenkins 。使用 safe-restart 会等待当前构建完成再重启。


第六章:Jenkins 安全与权限

6.1 安全域配置

复制代码
┌───────────────────────────────────────────┐
│            Jenkins 安全模型                 │
│                                           │
│  安全域 (Security Realm)                   │
│  ├─ Jenkins 内置用户数据库                  │
│  │   └─ HudsonPrivateSecurityRealm         │
│  ├─ LDAP                                  │
│  ├─ Active Directory                      │
│  └─ OAuth (GitHub/Google)                 │
│                                           │
│  授权策略 (Authorization Strategy)          │
│  ├─ 任何用户可以做任何事(不安全⚠️)          │
│  ├─ 登录用户可以做任何事                     │
│  ├─ 矩阵授权 (Matrix-based)                │
│  ├─ 项目矩阵授权                            │
│  └─ ★ Role-based Strategy(推荐)           │
└───────────────────────────────────────────┘

6.2 角色管理配置(Role-based Strategy)

groovy 复制代码
// 角色定义示例
Role          | Pattern               | Permissions
──────────────┼──────────────────────┼────────────────────────────
admin         | .*                    | 全部权限
developer     | dev-.*                | Job.Build, Job.Read, SCM
viewer        | .*                    | Overall.Read, Job.Read
deploy-prod   | .*-prod               | Job.Build
groovy 复制代码
// init.groovy.d 配置角色
import com.michelin.cio.hudson.plugins.rolestrategy.*
import hudson.security.*

def strategy = new RoleBasedAuthorizationStrategy()

// 定义角色
strategy.addRole(RoleBasedAuthorizationStrategy.GLOBAL, 
    new Role("admin", Permission.getAll()))
strategy.addRole(RoleBasedAuthorizationStrategy.GLOBAL,
    new Role("developer", [
        Permission.fromId("hudson.model.Hudson.Read"),
        Permission.fromId("hudson.model.Item.Build"),
        Permission.fromId("hudson.model.Item.Read"),
    ]))

// 分配用户到角色
strategy.assignRole(RoleBasedAuthorizationStrategy.GLOBAL,
    "admin", "devops")
strategy.assignRole(RoleBasedAuthorizationStrategy.GLOBAL,
    "developer", "alice")

Jenkins.get().setAuthorizationStrategy(strategy)

6.3 凭据管理

groovy 复制代码
// Credentials Binding 在 Pipeline 中的使用
pipeline {
    agent any
    environment {
        // 密码凭据
        DB_PASSWORD = credentials('db-password-id')
        // SSH 密钥凭据
        SSH_KEY = credentials('ssh-key-id')
        // 文件凭据
        KUBECONFIG = credentials('kubeconfig-id')
    }
    stages {
        stage('Deploy') {
            steps {
                // 密码会自动注入为环境变量
                sh 'mysql -u root -p${DB_PASSWORD} -e "SELECT 1"'
            }
        }
    }
}
凭据类型
类型 存储内容 使用场景
Secret text 文本密文 API Token, 密码
Username with password 用户名+密码 Git 仓库认证
SSH Username with private key SSH 私钥 Git SSH 认证
Secret file 文件 kubeconfig, Docker config
Certificate 证书 客户端证书认证

6.4 安全最佳实践

复制代码
1. 最小权限原则
   └─ 每个用户/角色只给完成任务所需的最小权限

2. 凭据管理
   ├─ 所有凭据通过 Credentials 插件管理
   ├─ 不在 Jenkinsfile 中硬编码密码
   └─ 凭据 ID 使用有意义的命名(如 github-deploy-key)

3. CSRF 保护
   └─ 默认开启,不要关闭

4. Agent 安全
   ├─ 使用 -jnlpCredentials 认证
   └─ 限制 Agent 文件系统访问

5. 审计日志
   └─ 开启 Audit Trail 插件记录所有操作

6. HTTPS
   └─ 生产环境必须配置 HTTPS 反向代理(Nginx/Apache)

第七章:Jenkins 分布式构建

7.1 Master-Agent 架构

复制代码
┌──────────────────────────────────────────────────────┐
│                  Jenkins Master                        │
│  ┌─────────────────────────────────────────────────┐ │
│  │  Job 调度  │  UI 展示  │  插件管理  │  配置存储     │ │
│  └─────────────────────────────────────────────────┘ │
│                         │                             │
│              ┌──────────┼──────────┐                  │
│              ▼          ▼          ▼                  │
│        ┌─────────┐ ┌─────────┐ ┌─────────┐          │
│        │ Agent 1 │ │ Agent 2 │ │ Agent 3 │          │
│        │ Linux   │ │ Linux   │ │ Linux   │          │
│        │ JDK 17  │ │ JDK 21  │ │ JDK 21  │          │
│        │ Maven   │ │ Docker  │ │ Node.js │          │
│        └─────────┘ └─────────┘ └─────────┘          │
└──────────────────────────────────────────────────────┘

7.2 Agent 配置方式

方式一:SSH Agent(推荐)
bash 复制代码
# 在 Master 上配置
Manage Jenkins → Nodes → New Node

# 配置参数
Name: agent-01
Remote root directory: /var/lib/jenkins-agent
Labels: linux docker
Launch method: Launch agents via SSH
Host: 192.168.0.228
Credentials: jenkins-agent-key
Host Key Verification Strategy: Non verifying
方式二:JNLP Agent(防火墙友好)
bash 复制代码
# Agent 端执行
java -jar agent.jar \
  -jnlpUrl http://jenkins-master:8080/computer/agent-01/jenkins-agent.jnlp \
  -secret <agent-secret> \
  -workDir "/var/lib/jenkins-agent"

# 或者通过 WebSocket(无额外端口)
java -jar agent.jar \
  -jnlpUrl http://jenkins-master:8080/computer/agent-01/jenkins-agent.jnlp \
  -secret <agent-secret> \
  -webSocket
方式三:Docker Agent
groovy 复制代码
pipeline {
    agent {
        docker {
            image 'maven:3.9-eclipse-temurin-21'
            args '-v /var/run/docker.sock:/var/run/docker.sock'
        }
    }
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean package'
            }
        }
    }
}

7.3 Agent 标签策略

groovy 复制代码
// 标签匹配示例
agent { label 'linux && docker && !windows' }
// → 选择有 linux 和 docker 标签,但没有 windows 标签的 Agent

agent { label 'docker || kubernetes' }
// → 选择有 docker 或 kubernetes 标签的 Agent

// 实际场景
pipeline {
    agent none  // 顶层不分配 agent
    stages {
        stage('Build on Linux') {
            agent { label 'linux' }
            steps { sh 'make build' }
        }
        stage('Test on Windows') {
            agent { label 'windows' }
            steps { bat 'test.bat' }
        }
    }
}

第八章:Jenkins 与版本控制集成

8.1 Git 集成深度配置

groovy 复制代码
// 基础 Git 检出
git url: 'https://github.com/user/repo.git',
    branch: 'main'

// 完整配置
checkout([
    $class: 'GitSCM',
    branches: [[name: '*/main']],
    userRemoteConfigs: [[
        url: 'git@github.com:user/repo.git',
        credentialsId: 'github-ssh-key'
    ]],
    extensions: [
        [$class: 'PruneStaleBranch'],    // 清理已删除的远程分支
        [$class: 'CleanCheckout'],       // 干净检出
        [$class: 'SubmoduleOption',       // 子模块
         disableSubmodules: false,
         recursiveSubmodules: true]
    ]
])

8.2 GitHub Webhook 配置

复制代码
GitHub 仓库 → Settings → Webhooks → Add webhook

Payload URL:    https://jenkins.example.com/github-webhook/
Content type:   application/json
Events:         Just the push event / Let me select...

Jenkins 端:
Pipeline Job → Build Triggers → GitHub hook trigger for GITScm polling

8.3 多分支 Pipeline

groovy 复制代码
// Jenkinsfile 放在仓库根目录
// Multibranch Pipeline 自动为每个分支创建 Job

pipeline {
    agent any
    stages {
        stage('Build') {
            when {
                anyOf {
                    branch 'main'
                    branch 'develop'
                    branch pattern: 'feature/.*', comparator: 'REGEXP'
                }
            }
            steps {
                sh 'make build'
            }
        }
        stage('Deploy') {
            when {
                branch 'main'  // 仅 main 分支部署
            }
            steps {
                sh 'make deploy'
            }
        }
    }
}

第九章:Jenkins 与容器化集成

9.1 Docker 镜像构建与推送

groovy 复制代码
pipeline {
    agent any
    environment {
        DOCKER_REGISTRY = 'registry.example.com'
        IMAGE_NAME = "${DOCKER_REGISTRY}/${APP_NAME}"
    }
    stages {
        stage('Build Image') {
            steps {
                script {
                    docker.build("${IMAGE_NAME}:${BUILD_NUMBER}")
                    // ↑ 使用 Dockerfile 构建镜像
                }
            }
        }
        stage('Push Image') {
            steps {
                script {
                    docker.withRegistry(
                        "https://${DOCKER_REGISTRY}",
                        'docker-registry-creds'
                    ) {
                        docker.image("${IMAGE_NAME}:${BUILD_NUMBER}").push()
                        docker.image("${IMAGE_NAME}:${BUILD_NUMBER}").push('latest')
                    }
                }
            }
        }
    }
}

9.2 Kubernetes 部署

groovy 复制代码
pipeline {
    agent any
    stages {
        stage('Deploy to K8s') {
            steps {
                withCredentials([file(
                    credentialsId: 'kubeconfig',
                    variable: 'KUBECONFIG'
                )]) {
                    sh """
                        kubectl set image deployment/${APP_NAME} \
                            ${APP_NAME}=${IMAGE_NAME}:${BUILD_NUMBER} \
                            --namespace=production

                        kubectl rollout status deployment/${APP_NAME} \
                            --namespace=production --timeout=5m
                    """
                }
            }
        }
        stage('Verify') {
            steps {
                sh 'kubectl get pods -n production | grep ${APP_NAME}'
            }
        }
    }
}

9.3 多阶段构建优化

dockerfile 复制代码
# 多阶段 Dockerfile
# Stage 1: 构建
FROM maven:3.9-eclipse-temurin-21 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src/ src/
RUN mvn package -DskipTests

# Stage 2: 运行(镜像小 80%)
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
USER 1000
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

第十章:Jenkins 通知与报告

10.1 邮件通知

groovy 复制代码
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh 'make build'
            }
        }
    }
    post {
        success {
            emailext(
                to: 'dev-team@example.com',
                subject: "✅ ${JOB_NAME} - Build #${BUILD_NUMBER} 成功",
                body: """
                    <h2>构建成功</h2>
                    <table>
                        <tr><td>项目</td><td>${JOB_NAME}</td></tr>
                        <tr><td>构建号</td><td>#${BUILD_NUMBER}</td></tr>
                        <tr><td>耗时</td><td>${currentBuild.durationString}</td></tr>
                        <tr><td>查看</td><td><a href="${BUILD_URL}">${BUILD_URL}</a></td></tr>
                    </table>
                """,
                mimeType: 'text/html'
            )
        }
        failure {
            emailext(
                to: 'oncall@example.com',
                subject: "❌ ${JOB_NAME} - Build #${BUILD_NUMBER} 失败",
                body: "构建失败!请立即处理:${BUILD_URL}",
                attachLog: true  // 附加构建日志
            )
        }
    }
}

10.2 钉钉通知集成

groovy 复制代码
// 安装 DingTalk Plugin
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh 'make build'
            }
        }
    }
    post {
        success {
            dingtalk(
                robot: 'dingtalk-robot-id',
                type: 'MARKDOWN',
                title: "✅ ${JOB_NAME} 构建成功",
                text: [
                    "### 构建成功",
                    "- 项目: ${JOB_NAME}",
                    "- 构建号: #${BUILD_NUMBER}",
                    "- 耗时: ${currentBuild.durationString}",
                    "- [查看详情](${BUILD_URL})"
                ]
            )
        }
    }
}

10.3 测试报告发布

groovy 复制代码
pipeline {
    agent any
    stages {
        stage('Test') {
            steps {
                sh 'mvn test'
            }
            post {
                always {
                    // JUnit 测试报告
                    junit(
                        testResults: '**/target/surefire-reports/*.xml',
                        keepLongStdio: true,
                        allowEmptyResults: false
                    )

                    // JaCoCo 代码覆盖率
                    jacoco(
                        execPattern: '**/target/jacoco.exec',
                        classPattern: '**/target/classes',
                        sourcePattern: '**/src/main/java'
                    )
                }
            }
        }
    }
}

第十一章:Jenkins 高级特性

11.1 共享库(Shared Libraries)

复制代码
项目共享库结构:
vars/                     ← 全局变量(可在 Pipeline 中直接调用)
├─ sayHello.groovy        ← 自定义步骤
├─ dockerBuild.groovy     ← Docker 构建步骤
└─ deployK8s.groovy       ← K8s 部署步骤

src/                      ← Groovy 类
└─ com/example/
    └─ Utils.groovy

resources/                ← 资源文件
└─ templates/
    └─ email.template
vars 示例
groovy 复制代码
// vars/sayHello.groovy
def call(String name = 'World') {
    echo "Hello, ${name}!"

    // 自动获取当前构建信息
    echo "当前构建: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
}
groovy 复制代码
// vars/dockerBuild.groovy
def call(Map config) {
    def imageName = config.imageName ?: env.JOB_NAME
    def dockerfile = config.dockerfile ?: 'Dockerfile'
    def registry  = config.registry ?: 'registry.example.com'

    sh "docker build -f ${dockerfile} -t ${registry}/${imageName}:${env.BUILD_NUMBER} ."
    sh "docker push ${registry}/${imageName}:${env.BUILD_NUMBER}"
}
在 Pipeline 中使用共享库
groovy 复制代码
// 1. 在 Jenkins 全局配置中注册共享库
// Manage Jenkins → Configure System → Global Pipeline Libraries
// Name: my-shared-lib
// Default version: main
// Git URL: https://github.com/myorg/jenkins-shared-lib.git

// 2. 在 Jenkinsfile 中引用
@Library('my-shared-lib') _

pipeline {
    agent any
    stages {
        stage('Greet') {
            steps {
                sayHello 'Jenkins'
            }
        }
        stage('Docker Build') {
            steps {
                dockerBuild(
                    imageName: 'myapp',
                    registry: 'registry.example.com'
                )
            }
        }
    }
}

11.2 配置即代码(JCasC --- Configuration as Code)

yaml 复制代码
# jenkins.yaml --- JCasC 配置文件
jenkins:
  systemMessage: "Jenkins 配置由 JCasC 管理"
  numExecutors: 4
  mode: NORMAL

  securityRealm:
    local:
      allowsSignup: false
      users:
        - id: "admin"
          password: "${ADMIN_PASSWORD}"  # 从环境变量读取

  authorizationStrategy:
    roleBased:
      roles:
        global:
          - name: "admin"
            permissions:
              - "Overall/Administer"
          - name: "developer"
            permissions:
              - "Overall/Read"
              - "Job/Build"

tool:
  jdk:
    installations:
      - name: "JDK21"
        home: "/usr/lib/jvm/java-21-openjdk-amd64"
  maven:
    installations:
      - name: "Maven3"
        home: "/opt/maven"

unclassified:
  location:
    url: "https://jenkins.example.com/"
bash 复制代码
# 启动时加载 JCasC
java -jar jenkins.war \
  -Dcasc.jenkins.config=/var/lib/jenkins/jenkins.yaml

11.3 常见高级用法

超时与重试
groovy 复制代码
pipeline {
    agent any
    stages {
        stage('Deploy') {
            steps {
                timeout(time: 10, unit: 'MINUTES') {
                    retry(3) {
                        sh './deploy.sh'
                    }
                }
            }
        }
    }
}
输入确认
groovy 复制代码
stage('Approve Production Deploy') {
    input {
        message "确认部署到生产环境?"
        ok "部署"
        submitter "admin,team-lead"      // 只有指定用户可确认
        parameters {
            string(name: 'VERSION', defaultValue: '1.0.0',
                   description: '确认版本号')
        }
    }
    steps {
        sh 'kubectl apply -f production/'
    }
}
等待条件
groovy 复制代码
stage('Wait for Service Ready') {
    steps {
        script {
            waitUntil(initialRecurrencePeriod: 1000) {
                def result = sh(
                    script: 'curl -s -o /dev/null -w "%{http_code}" http://myapp:8080/health',
                    returnStdout: true
                ).trim()
                return result == '200'
            }
        }
    }
}

第十二章:Jenkins 性能优化

12.1 JVM 调优

bash 复制代码
# 生产环境 JVM 推荐配置
-Xms2048m -Xmx4096m \          # 堆 2-4GB
-XX:+UseG1GC \                 # G1 垃圾收集器
-XX:MaxGCPauseMillis=200 \     # GC 暂停目标 <200ms
-XX:+ParallelRefProcEnabled \  # 并行处理引用
-XX:+DisableExplicitGC \       # 禁止显式 GC
-Dhudson.slaves.NodeProvisioner.initialDelay=0 \
-Dhudson.slaves.NodeProvisioner.MARGIN=50 \
-Dhudson.slaves.NodeProvisioner.MARGIN0=0.85

12.2 构建历史管理

groovy 复制代码
// 在 Pipeline 中配置构建保留策略
options {
    buildDiscarder(logRotator(
        numToKeepStr: '30',       // 保留最近 30 次构建
        daysToKeepStr: '90',      // 最多保留 90 天
        artifactNumToKeepStr: '10', // 制品保留 10 次
        artifactDaysToKeepStr: '30' // 制品保留 30 天
    ))
}

12.3 工作空间优化

groovy 复制代码
// 构建后清理工作空间
post {
    always {
        cleanWs(
            deleteDirs: true,
            patterns: [
                [pattern: 'target/', type: 'INCLUDE'],
                [pattern: 'node_modules/', type: 'INCLUDE']
            ]
        )
    }
}

12.4 插件管理

bash 复制代码
# 列出已安装插件及大小
du -sh ${JENKINS_HOME}/plugins/*.jpi | sort -rh | head -20

# 清理未使用的插件
java -jar jenkins-cli.jar list-plugins | grep -E 'no.*update'

# 建议卸载不必要的大插件来减少内存占用

第十三章:Jenkins 实战项目

13.1 Java 项目 CI/CD 完整流水线

groovy 复制代码
pipeline {
    agent any
    environment {
        SONAR_HOST = 'http://sonarqube:9000'
        DOCKER_REG = 'registry.example.com'
        APP_NAME = 'user-service'
    }
    stages {
        stage('1. Checkout') {
            steps { checkout scm }
        }
        stage('2. Compile') {
            steps { sh 'mvn compile' }
        }
        stage('3. Unit Test') {
            steps { sh 'mvn test' }
        }
        stage('4. SonarQube Analysis') {
            steps {
                withSonarQubeEnv('SonarQube') {
                    sh 'mvn sonar:sonar'
                }
            }
        }
        stage('5. Package') {
            steps { sh 'mvn package -DskipTests' }
        }
        stage('6. Build Docker Image') {
            steps {
                sh "docker build -t ${DOCKER_REG}/${APP_NAME}:${BUILD_NUMBER} ."
            }
        }
        stage('7. Push to Registry') {
            steps {
                docker.withRegistry("https://${DOCKER_REG}", 'docker-creds') {
                    sh "docker push ${DOCKER_REG}/${APP_NAME}:${BUILD_NUMBER}"
                }
            }
        }
        stage('8. Deploy to K8s') {
            steps {
                sh """
                    kubectl set image deployment/${APP_NAME} \
                        ${APP_NAME}=${DOCKER_REG}/${APP_NAME}:${BUILD_NUMBER}
                    kubectl rollout status deployment/${APP_NAME}
                """
            }
        }
    }
}

13.2 前端项目自动化

groovy 复制代码
pipeline {
    agent { label 'nodejs' }
    stages {
        stage('Install Dependencies') {
            steps { sh 'npm ci' }
        }
        stage('Lint') {
            steps { sh 'npm run lint' }
        }
        stage('Unit Test') {
            steps { sh 'npm test -- --coverage' }
        }
        stage('Build') {
            steps { sh 'npm run build' }
        }
        stage('Deploy to CDN') {
            steps {
                sh """
                    aws s3 sync dist/ s3://my-cdn-bucket/ \
                        --cache-control 'max-age=31536000'
                    aws cloudfront create-invalidation \
                        --distribution-id E1234567890 \
                        --paths '/*'
                """
            }
        }
    }
}

13.3 多环境部署策略

复制代码
开发环境 (dev)  ← 自动部署(每次 push)
    ↓
测试环境 (staging) ← 自动部署(main 分支)
    ↓
生产环境 (prod)  ← 手动审批后部署

Pipeline 分支策略:
feature/*  → dev 环境
develop    → dev 环境
main       → staging 环境(自动)
main       → prod 环境(手动审批)
release/*  → prod 环境(手动审批)

第十四章:Jenkins 故障排查

14.1 常见问题诊断

构建失败排查流程
复制代码
1. 查看构建日志
   → http://jenkins/job/<name>/<build>/console

2. 检查错误类型
   ├─ Compilation Error → 代码问题
   ├─ Dependency Error → Maven/npm 源问题
   ├─ Test Failure → 测试代码问题
   └─ Timeout → 资源/网络问题

3. 检查 Agent 状态
   → Manage Jenkins → Nodes → <agent-name>
   → 查看 Agent 日志: ${JENKINS_HOME}/logs/slaves/<agent>/

4. 检查系统日志
   → ${JENKINS_HOME}/logs/jenkins.log

5. 检查资源
   → df -h → 磁盘空间
   → free -h → 内存
   → top → CPU
Agent 连接问题
复制代码
症状:Agent 离线 (offline)

排查步骤:
1. Agent 端:ping master-ip
2. Agent 端:telnet master-ip 50000 (JNLP 端口)
3. 检查 Agent 日志
4. 检查防火墙规则
5. 检查 Java 版本兼容性

常见原因:
- 网络不通 → 检查安全组/防火墙
- 端口 50000 未开放 → Master 安全组添加规则
- Java 版本不匹配 → Agent 需安装与 Master 兼容的 Java
- Agent 密钥过期 → 重新生成 Secret

14.2 日志分析

bash 复制代码
# 关键日志文件
${JENKINS_HOME}/logs/
├── jenkins.log          # 主日志
├── tasks/               # 后台任务日志
├── slaves/              # Agent 日志
└── plugins/             # 插件日志

# 查看最近的错误
tail -100 ${JENKINS_HOME}/logs/jenkins.log | grep -E 'ERROR|WARN|SEVERE'

# 实时跟踪日志
tail -f ${JENKINS_HOME}/logs/jenkins.log

14.3 备份与恢复

bash 复制代码
# 备份 JENKINS_HOME(停服状态下)
#!/bin/bash
BACKUP_DIR=/data/backup/jenkins
DATE=$(date +%Y%m%d_%H%M)

# 1. 进入 Quiet Down 模式(阻止新构建)
curl -X POST -u admin:token http://jenkins/quietDown

# 2. 等待正在运行的构建完成
sleep 30

# 3. 备份
tar -czf ${BACKUP_DIR}/jenkins_${DATE}.tar.gz \
    --exclude='workspace' \
    --exclude='caches' \
    --exclude='*.log' \
    /var/lib/jenkins/

# 4. 恢复模式
curl -X POST -u admin:token http://jenkins/cancelQuietDown

# 保留策略
find ${BACKUP_DIR} -name 'jenkins_*.tar.gz' -mtime +30 -delete

第十五章:Jenkins 云原生实践

15.1 Jenkins X 概念

复制代码
Jenkins X vs 传统 Jenkins:

传统 Jenkins:              Jenkins X:
┌──────────┐               ┌──────────────────────┐
│ Jenkins  │               │  GitOps + Tekton      │
│ Master   │               │  ├─ Preview Env       │
│  ├─ Job1 │               │  ├─ Auto Promotion    │
│  ├─ Job2 │               │  └─ ChatOps           │
│  └─ Job3 │               │                       │
└──────────┘               │  K8s Native           │
                           │  Serverless Jenkins    │
                           └──────────────────────┘

15.2 Tekton 与 Jenkins 对比

特性 Jenkins Tekton
架构 Master-Agent Kubernetes CRD
配置 Jenkinsfile (Groovy) Task/Pipeline (YAML)
扩展性 插件 Step/Resource CRD
资源管理 Agent 长驻 Pod 按需创建
学习曲线 中-高
社区成熟度 20年 5年

15.3 云服务集成对比

服务 Jenkins 集成 原生替代
AWS EC2 Plugin + ECR + EKS AWS CodePipeline
阿里云 自建 + 容器服务 阿里云效
Azure Azure VM Agent Azure DevOps
GCP GCE Plugin Google Cloud Build
华为云 自建 + CCE DevCloud

第十六章:Jenkins 面试与进阶

16.1 面试高频问题

Q1:请描述 Jenkins Pipeline 的工作原理

标准回答

Jenkins Pipeline 基于 Groovy DSL,将 CI/CD 流程定义为代码。

  • Declarative Pipeline 使用结构化语法,必须在 pipeline {} 块内
  • Scripted Pipeline 使用 Groovy 流程控制,更灵活
  • Pipeline 由 Master 调度,实际构建在 Agent 节点执行
  • 通过 Jenkinsfile 存储在 Git 仓库,实现版本化管理
Q2:如何保证 Jenkins 的高可用?
  1. 数据备份 :定期备份 JENKINS_HOME(configs + jobs + plugins)
  2. 主从架构:Master 负责调度,Agent 负责执行
  3. 负载均衡:Nginx 反向代理 + 多 Master(Active-Passive)
  4. 外部存储:JENKINS_HOME 放在 NFS/云存储
  5. 配置即代码:JCasC 保障配置可重建
Q3:Jenkins Pipeline 如何实现并行构建?
groovy 复制代码
stage('Parallel Tests') {
    parallel {
        stage('Unit Test') { steps { sh 'mvn test' } }
        stage('Integration Test') { steps { sh 'mvn verify' } }
        stage('E2E Test') { steps { sh 'npm run e2e' } }
    }
}
Q4:Jenkins 如何实现凭据管理?
  • 使用 Credentials Binding 插件
  • 凭据类型:Secret Text / Username+Password / SSH Key / Certificate
  • 在 Pipeline 中通过 credentials('id') 引用
  • 凭据加密存储在 ${JENKINS_HOME}/secrets/

16.2 学习路线图

复制代码
初级阶段(1-2 个月)
├─ Jenkins 安装与基本配置
├─ Freestyle Job 创建
├─ 基础 Pipeline 编写
└─ 常用插件使用

中级阶段(3-6 个月)
├─ 完整 CI/CD 流水线设计
├─ 多分支 Pipeline
├─ Agent 分布式构建
├─ Docker 集成
└─ 凭据与安全管理

高级阶段(6-12 个月)
├─ 共享库开发
├─ JCasC 配置即代码
├─ Kubernetes 集成
├─ 性能调优
└─ 高可用架构设计

专家阶段(12+ 个月)
├─ Jenkins X / Tekton
├─ 大规模集群运维
├─ 自定义插件开发
└─ 团队 DevOps 规范制定

16.3 最佳实践总结

复制代码
1. Pipeline as Code
   └─ 所有 Pipeline 使用 Jenkinsfile,存储在 Git

2. 配置即代码 (JCasC)
   └─ 系统配置 yaml 化,可版本控制和重建

3. 共享库
   └─ 通用逻辑抽象为共享库,避免重复代码

4. 安全第一
   ├─ 最小权限原则
   ├─ 凭据统一管理
   └─ HTTPS + 认证

5. 构建隔离
   ├─ 每个项目独立工作空间
   └─ Docker Agent 沙箱隔离

6. 监控告警
   ├─ 构建失败立即通知
   ├─ 慢构建分析优化
   └─ 资源使用监控

7. 定期维护
   ├─ 清理旧构建历史
   ├─ 更新安全插件
   └─ 数据备份验证

附录

附录 A:Jenkins 常用命令速查

bash 复制代码
# 启动/停止
sudo systemctl start jenkins
sudo systemctl stop jenkins
sudo systemctl restart jenkins
sudo systemctl status jenkins

# 安全重启(等待构建完成)
curl -X POST -u admin:token http://jenkins/safeRestart

# CLI 工具
java -jar jenkins-cli.jar -s http://jenkins:8080 -auth user:token <command>

# 列出 Job
java -jar jenkins-cli.jar list-jobs

# 触发构建
java -jar jenkins-cli.jar build <job-name>

# 查看构建日志
java -jar jenkins-cli.jar console <job-name> <build-number>

# 安装插件
java -jar jenkins-cli.jar install-plugin <plugin-name> -deploy

# 备份
cp -r ${JENKINS_HOME} /backup/jenkins_$(date +%Y%m%d)/

附录 B:Pipeline 语法快速参考

复制代码
pipeline {
    agent { label 'xxx' }           → 指定运行节点
    environment { VAR = 'val' }     → 环境变量
    options { ... }                 → 全局选项
    parameters { ... }              → 参数化构建
    triggers { ... }                → 触发器
    tools { maven 'M3' }            → 工具定义
    stages {
        stage('Name') {
            when { ... }            → 条件执行
            steps { ... }           → 步骤
            post { ... }            → 阶段后处理
        }
    }
    post { ... }                    → 全局后处理
}

附录 C:插件推荐列表

分类 插件 评分
Pipeline Pipeline, Blue Ocean, Stage View ★★★★★
Git Git, GitHub, GitLab, Bitbucket ★★★★★
Docker Docker Pipeline, Kubernetes ★★★★★
安全 Role-based, Credentials, LDAP ★★★★★
通知 Email Extension, Slack, DingTalk ★★★★
测试 JUnit, JaCoCo, Allure ★★★★
质量 SonarQube, Warnings Next Gen ★★★★
工具 Timestamper, Workspace Cleanup ★★★

附录 D:Groovy 语法基础

groovy 复制代码
// 变量
def name = 'Jenkins'           // 动态类型
String version = '2.555'       // 静态类型

// 字符串
def s1 = "Hello ${name}"       // GString 插值
def s2 = '''多行
字符串'''                      // 三引号多行

// 集合
def list = ['a', 'b', 'c']
def map = [key: 'value', count: 42]

// 闭包
def greet = { name -> println "Hello ${name}" }
greet('Jenkins')

// 流程控制
if (condition) { ... }
for (item in list) { ... }
list.each { item -> ... }

附录 E:Dockerfile 最佳实践

dockerfile 复制代码
# ✓ 好的实践
FROM eclipse-temurin:21-jre-alpine  # 使用具体标签而非 latest
RUN addgroup -S app && adduser -S app -G app  # 非 root 用户
USER app
COPY --chown=app:app target/*.jar app.jar

# ✗ 不好的实践
FROM openjdk                    # latest 标签不稳定
USER root                       # root 用户不安全
ADD app.jar /app/               # ADD 自动解压 tar,不必要时用 COPY

附录 F:学习资源推荐

资源类型 名称 链接
书籍 《Jenkins 2 权威指南》 O'Reilly
书籍 《持续交付》 Jez Humble
官方 Jenkins Handbook jenkins.io/doc/book
社区 Jenkins 中文社区 jenkins-zh.cn
课程 Jenkins 入门到精通 Bilibili / YouTube
博客 CloudBees Blog cloudbees.com/blog

实战服务器信息

华为云 ecs-7c2c 系列 | Ubuntu 24.04 LTS | Jenkins 2.555.2 LTS

Java: OpenJDK 21.0.11 | 进程占用 ~327MB(启动时), 峰值 ~500MB

部署方式: WAR 包 + systemd | 认证: HudsonPrivateSecurityRealm + CSRF

Freestyle 构建验证: ✅ SUCCESS (blue) | Pipeline: 配置文件已创建

构建节点: Built-in Node (2 executors)

相关推荐
牢七1 小时前
契约锁逆向(失败,已老实正在学习)
学习
江华森1 小时前
Kafka 从入门到精通 — 完整学习笔记
笔记·学习·kafka
chushiyunen1 小时前
elasticsearch笔记
笔记·elasticsearch·jenkins
dusk_star1 小时前
go语言--笔记--接口
java·笔记·golang
小陈phd1 小时前
多模态大模型学习笔记(四十二)——从像素到语义的精准问询——视觉问答(VQA)
笔记·学习
Brilliantwxx1 小时前
【算法从零到千】【1-7】 双指针算法
开发语言·c++·笔记·算法·leetcode·推荐算法
wuyuanshun1 小时前
人工智能学习总结(一)
人工智能·学习
chushiyunen1 小时前
elasticsearch内置接口笔记
大数据·笔记·elasticsearch
吃好睡好便好1 小时前
詹姆斯·艾伦语录
学习·生活