Jenkins 从入门到精通 --- 完整学习笔记
服务器环境 :华为云 ecs-7c2c × 4 台 | Ubuntu 24.04 | 2vCPU/4GiB
Jenkins 版本 :2.555.2 LTS | Java 21 | WAR 方式部署
认证方式 :HudsonPrivateSecurityRealm | CSRF Protection
实战日期:2026-06-01
目录
- [第一章:CI/CD 概念与 Jenkins 概述](#第一章:CI/CD 概念与 Jenkins 概述)
- [第二章:Jenkins 安装与配置](#第二章:Jenkins 安装与配置)
- [第三章:Jenkins 界面与核心概念](#第三章:Jenkins 界面与核心概念)
- [第四章:Pipeline 流水线详解](#第四章:Pipeline 流水线详解)
- [第五章:Jenkins 插件生态](#第五章:Jenkins 插件生态)
- [第六章:Jenkins 安全与权限](#第六章:Jenkins 安全与权限)
- [第七章:Jenkins 分布式构建](#第七章:Jenkins 分布式构建)
- [第八章:Jenkins 与版本控制集成](#第八章:Jenkins 与版本控制集成)
- [第九章:Jenkins 与容器化集成](#第九章:Jenkins 与容器化集成)
- [第十章:Jenkins 通知与报告](#第十章:Jenkins 通知与报告)
- [第十一章:Jenkins 高级特性](#第十一章:Jenkins 高级特性)
- [第十二章:Jenkins 性能优化](#第十二章:Jenkins 性能优化)
- [第十三章:Jenkins 实战项目](#第十三章:Jenkins 实战项目)
- [第十四章:Jenkins 故障排查](#第十四章:Jenkins 故障排查)
- [第十五章:Jenkins 云原生实践](#第十五章:Jenkins 云原生实践)
- [第十六章:Jenkins 面试与进阶](#第十六章:Jenkins 面试与进阶)
- 附录
第一章: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 的高可用?
- 数据备份 :定期备份
JENKINS_HOME(configs + jobs + plugins) - 主从架构:Master 负责调度,Agent 负责执行
- 负载均衡:Nginx 反向代理 + 多 Master(Active-Passive)
- 外部存储:JENKINS_HOME 放在 NFS/云存储
- 配置即代码: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)