Jenkins FAQ
内容:
- Jenkins 基础概念
- Jenkins 架构与集群
- Jenkins Pipeline(Declarative/Scripted)
- Jenkins 运维与优化
- Jenkins 与 Git、Docker、Kubernetes、DevOps 场景
Jenkins 是一个开源的 CI/CD 自动化系统,用于持续集成、持续交付、自动化构建、测试、部署等各种任务。
核心特点:
- 插件丰富(1800+)
- 支持 Pipeline
- 分布式构建(Master/Agent 模式)
- 支持多种 SCM(Git、SVN、GitHub/GitLab 等)
- 丰富的触发方式(Webhook、定时、手动、多分支)
- Jenkins Master(Controller)
- 负责 UI、任务调度、插件管理、集群管理
- Jenkins Agent(Node)
- 真正执行构建任务
- Executor
- 每个 Agent 内的执行线程数
- Plugin 插件系统
- Job / 项目
- Pipeline(Jenkinsfile)
| Job 类型 | 用途 | 特点 |
|---|---|---|
| Freestyle Project | 传统 Job | 配置简单,但扩展性差 |
| Pipeline | Jenkinsfile 驱动 | 支持完整 CI/CD 代码化 |
| Multibranch Pipeline | 自动扫描多分支 | 支持 Git Flow |
| Folder | 组织 Job | 结构化管理 |
| GitHub Organization | 自动管理整个 GitHub org | 大型团队常用 |
现在大多数企业都采用 Multibranch Pipeline + Jenkinsfile。
| CI/CD | 优点 | 缺点 |
|---|---|---|
| Jenkins | 灵活、插件多、自建、安全性强 | 需要运维、插件兼容问题 |
| GitLab CI | 内置在 GitLab 中、无需复杂运维 | 整体性能受 GitLab 影响 |
| GitHub Actions | 自带 GitHub、简单易用、事件驱动 | 私有 Runner 需要运维 |
简而言之:
- 大型企业 -> Jenkins
- 中型团队 -> GitLab CI
- GitHub 社区项目 -> GitHub Actions
通过 Master(Controller)+ Agent(Node) 模式:
Agent 连接方式:
- SSH(最常用)
- JNLP
- Docker Agent
- Kubernetes Agent(Cloud)
优势:
- 分担构建压力
- 使用不同环境(Linux/Windows/macOS)
- 扩大横向扩容能力
- 使用 Master + 多 Agent
- 使用 Kubernetes 动态 Agent(企业最佳方案)
- 独立构建资源,避免 Master 执行任务
- 通过 NFS/对象存储存放构建缓存
- 使用 nginx 做反向代理
- 使用 CasC(Configuration as Code)自动化管理 Jenkins
常见方案:
-
Active-Backup(最常用)
- 两台 Jenkins Master
- 共享 NFS(JENKINS_HOME)
- Keepalived + VIP
-> 主挂了,备立刻接管
-
Kubernetes + StatefulSet + RWO PVC
-> 集群自动重建
-
拆分 Master 与 Agents
-
使用 CasC 自动恢复配置
- Job 配置(config.xml)
- Jenkins 全局配置
- 插件 & 插件配置
- 构建记录
- 凭据(Credentials)
- Script Console 脚本
备份 Jenkins = 备份 JENKINS_HOME。
| 类型 | Declarative | Scripted |
|---|---|---|
| 结构 | 强结构,固定字段 | 灵活、Groovy 脚本 |
| 难度 | 简单 | 较难 |
| 企业常用 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
Declarative 例子:
pipeline {
agent any
stages {
stage('Build') {
steps {
echo "Hello"
}
}
}
}
Scripted 例子:
node {
stage('Build') {
echo "Hello"
}
}
-
手动触发
-
Cron:
triggers { cron('H 2 * * *') } -
GitHub Webhook
-
Poll SCM
-
input 手动确认
withCredentials([string(credentialsId: 'token', variable: 'TK')]) {
sh "echo $TK"
}
SSH Key:
sshagent(['github-ssh']) {
sh 'git pull'
}
when {
branch 'main'
}
或:
when {
anyOf {
branch 'main'
branch pattern: "release/.*", comparator: "REGEXP"
}
}
timeout(time: 5, unit: 'MINUTES') {
// your steps
}
或:
catchError(buildResult: 'FAILURE') {
sh "make test"
}
最简单:
- 停止 Jenkins
- 压缩 $JENKINS_HOME
企业级:
- 备份 JENKINS_HOME
- CasC 备份配置
- 使用 NFS / S3 后端
- 使用 Jenkins Backup 插件
-
禁止 Master 执行 Job(0 executors)
-
减少不必要插件(特别是 Blue Ocean、Build Pipeline View)
-
定期清理老构建记录
-
优化 JVM 参数例如:
-Xms2G -Xmx4G -XX:+UseG1GC -
使用 Kubernetes 动态 Agent
-
使用外部缓存(Maven/Gradle 缓存)
从 3 个方向:
- Jenkins 本身
- CPU/内存不足
- 插件过多
- Agent 性能问题
- IO、CPU、网络
- 构建任务本身
- Docker Pull 很慢
- Maven 下载依赖慢(换源)
Webhook:主动推送
Jenkins 立即执行
Poll SCM:轮询拉取
- 每几分钟去 GitHub 拉一次 -> 容易被 GitHub 限制
企业统一使用 Webhook。
Docker Pipeline:
docker.build("repo/app:${env.BUILD_NUMBER}")
推送镜像:
withCredentials([usernamePassword(credentialsId: 'dockerhub', usernameVariable: 'USER', passwordVariable: 'PASS')]) {
sh "docker login -u $USER -p $PASS"
sh "docker push repo/app:${env.BUILD_NUMBER}"
}
最简示例:
sh "kubectl apply -f k8s/deployment.yaml"
使用 kubeconfig:
withCredentials([file(credentialsId: 'kubeconfig', variable: 'KCFG')]) {
sh "kubectl --kubeconfig=$KCFG apply -f k8s/"
}
- Blue/Green
- Canary
- K8s 分批滚动(RollingUpdate)
- 利用 istio/nginx 实现流量切换
示例(K8s):
sh "kubectl rollout restart deployment app"