目錄
1. 什么是Jenkins
1.1 簡單理解
1.2 技術定義
1.3 核心特點
2. 為什么需要Jenkins
2.1 傳統開發的痛點
手工發布的問題
真實場景舉例
2.2 Jenkins的解決方案
自動化CI/CD流程
3. 核心概念解析
3.1 Job(任務)
Job示例
3.2 Build(構建)
3.3 Pipeline(流水線)
3.4 Node(節點)
節點配置示例
3.5 Workspace(工作空間)
4. 安裝和初始配置
4.1 Docker安裝(推薦)
4.2 Linux系統安裝
4.3 初始配置向導
4.4 基礎配置
系統配置
5. 第一個Jenkins任務
5.1 創建自由風格項目
基礎配置
構建步驟
5.2 第一個Pipeline項目
Pipeline腳本
6. Pipeline詳解
6.1 聲明式Pipeline vs 腳本式Pipeline
聲明式Pipeline(推薦)
腳本式Pipeline(靈活)
6.2 Pipeline高級特性
并行執行
條件執行
矩陣構建
6.3 共享庫
共享庫結構
共享庫代碼
使用共享庫
7. 插件系統
7.1 必備插件推薦
基礎功能插件
質量管理插件
7.2 插件安裝和配置
通過Web界面安裝
通過命令行安裝
通過插件配置文件批量安裝
7.3 常用插件配置示例
Blue Ocean配置
SonarQube集成
Docker插件使用
8. 分布式構建
8.1 Master-Slave架構
8.2 添加Slave節點
通過SSH添加Linux節點
通過JNLP添加Windows節點
Docker動態節點
8.3 Kubernetes集成
Kubernetes插件配置
Kubernetes Pipeline示例
8.4 節點管理最佳實踐
節點標簽管理
節點監控腳本
9. 實際應用場景
9.1 微服務CI/CD流程
多服務構建Pipeline
9.2 前端項目CI/CD
React/Vue項目Pipeline
9.3 數據庫變更管理
Flyway數據庫遷移Pipeline
10. 安全管理
10.1 用戶和權限管理
基于角色的訪問控制
LDAP集成
10.2 憑據管理
安全存儲敏感信息
10.3 構建安全
安全掃描Pipeline
11. 性能優化
11.1 Jenkins性能調優
JVM參數優化
磁盤性能優化
11.2 構建性能優化
并行構建優化
緩存策略
11.3 監控和告警
性能監控Dashboard
12. 最佳實踐
12.1 Pipeline設計原則
12.1.1 可復用和模塊化
12.1.2 環境隔離
12.2 代碼管理最佳實踐
12.2.1 Git分支策略集成
12.3 監控和告警
12.3.1 構建健康度監控
12.3.2 實時告警系統
13. 問題排查和調試
13.1 常見問題診斷
13.1.1 構建失敗排查
13.2 性能問題診斷
13.2.1 構建性能分析
13.3 調試工具和技巧
13.3.1 Pipeline調試模式
總結
?? 核心收獲
?? 關鍵要點回顧
核心概念
最佳實踐
性能優化
?? 進階方向
?? 實施建議
?? 實施檢查清單
基礎設施
流程設計
質量保證
運維監控
1. 什么是Jenkins
1.1 簡單理解
想象一下你經營一家汽車工廠:
傳統方式(手工生產):
- 工人手工制造每個零件
- 手工組裝汽車
- 手工檢查質量
- 手工包裝發貨
- 效率低下,容易出錯
使用Jenkins(自動化工廠):
- 自動化生產線制造零件
- 自動化組裝流程
- 自動化質量檢測
- 自動化包裝發貨
- 高效準確,24小時不間斷
1.2 技術定義
Jenkins是一個開源的自動化服務器,用于實現持續集成(CI)和持續部署(CD)。它可以自動化軟件開發過程中的構建、測試、部署等環節。
1.3 核心特點
Jenkins的能力:構建自動化: 自動編譯代碼、運行測試部署自動化: 自動發布到不同環境流程編排: 串聯復雜的發布流程監控告警: 實時監控構建狀態插件生態: 豐富的插件擴展功能
主要優勢:
- ?? 提高效率:自動化重復性工作
- ??? 降低風險:標準化的發布流程
- ?? 快速反饋:及時發現和修復問題
- ?? 持續交付:快速響應業務需求
2. 為什么需要Jenkins
2.1 傳統開發的痛點
手工發布的問題
# 傳統手工發布流程
開發人員完成代碼 → 手工打包 → 手工測試 → 手工部署 → 手工驗證↓ ↓ ↓ ↓ ↓
容易忘記步驟 格式不統一 測試不充分 環境不一致 驗證不完整
具體痛點:
- 效率低下:每次發布需要幾小時甚至幾天
- 容易出錯:手工操作容易遺漏步驟
- 環境不一致:開發、測試、生產環境差異
- 難以回滾:出問題時難以快速回滾
- 協作困難:多人協作時容易沖突
真實場景舉例
場景:電商網站雙11大促前發布傳統方式:
周五晚上11點 → 開發提交代碼
周五晚上11:30 → 測試人員手工測試
周六凌晨1點 → 運維手工部署
周六凌晨2點 → 發現Bug,緊急回滾
周六凌晨3點 → 修復Bug,重新部署
周六凌晨4點 → 終于發布成功
結果:團隊通宵達旦,身心俱疲
2.2 Jenkins的解決方案
自動化CI/CD流程
graph LRA[代碼提交] --> B[自動構建]B --> C[自動測試]C --> D[自動部署到測試環境]D --> E[自動化測試]E --> F{測試通過?}F -->|是| G[自動部署到生產環境]F -->|否| H[通知開發人員]G --> I[自動監控]
Jenkins后的效果:
相同場景:電商網站雙11大促前發布Jenkins方式:
周五下午5點 → 開發提交代碼到Git
周五下午5:05 → Jenkins自動觸發構建
周五下午5:10 → 自動編譯、測試通過
周五下午5:15 → 自動部署到測試環境
周五下午5:20 → 自動化測試通過
周五下午5:25 → 自動部署到生產環境
周五下午5:30 → 發布完成,監控一切正常
結果:開發人員準點下班,輕松愉快
3. 核心概念解析
3.1 Job(任務)
生活比喻:Job就像工廠里的一條生產線,專門生產某種產品。
Job的類型:自由風格項目: 最靈活的任務類型,可以執行任何腳本Pipeline項目: 使用代碼定義的復雜工作流多配置項目: 在多個環境中同時執行的任務Maven項目: 專門用于Java Maven項目的任務
Job示例
// 一個簡單的Job配置
job('my-first-job') {description('我的第一個Jenkins任務')// 源碼管理scm {git('https://github.com/username/project.git')}// 構建觸發器triggers {scm('H/5 * * * *') // 每5分鐘檢查一次代碼變更}// 構建步驟steps {shell('echo "開始構建..."')shell('mvn clean package') // Maven打包shell('echo "構建完成!"')}// 構建后操作publishers {archiveArtifacts('target/*.jar') // 歸檔構建產物emailext {subject('構建完成: ${JOB_NAME} - ${BUILD_NUMBER}')body('構建已完成,請查看詳情。')to('developer@company.com')}}
}
3.2 Build(構建)
生活比喻:Build就像一次生產過程,把原材料(代碼)加工成產品(可部署的軟件)。
# 構建過程示例
Build #1: 開始時間: 2024-01-15 10:00:00狀態: 成功 ?耗時: 3分鐘Build #2:開始時間: 2024-01-15 14:30:00狀態: 失敗 ?耗時: 1分鐘失敗原因: 單元測試失敗Build #3:開始時間: 2024-01-15 15:00:00狀態: 成功 ?耗時: 3分鐘
3.3 Pipeline(流水線)
生活比喻:Pipeline就像汽車組裝流水線,每個工位(Stage)完成特定工作。
pipeline {agent anystages {stage('準備工作') {steps {echo '獲取代碼...'git 'https://github.com/username/project.git'}}stage('編譯構建') {steps {echo '開始編譯...'sh 'mvn clean compile'}}stage('運行測試') {steps {echo '運行單元測試...'sh 'mvn test'}post {always {junit 'target/surefire-reports/*.xml'}}}stage('打包應用') {steps {echo '打包應用...'sh 'mvn package'archiveArtifacts artifacts: 'target/*.jar'}}stage('部署應用') {steps {echo '部署到測試環境...'sh './deploy.sh test'}}}post {success {echo '?? 構建成功!'emailext (subject: "構建成功: ${env.JOB_NAME} - ${env.BUILD_NUMBER}",body: "恭喜!構建成功完成。",to: "team@company.com")}failure {echo '?? 構建失敗!'emailext (subject: "構建失敗: ${env.JOB_NAME} - ${env.BUILD_NUMBER}",body: "構建失敗,請及時處理。",to: "team@company.com")}}
}
3.4 Node(節點)
生活比喻:Node就像工廠里的車間,每個車間都可以執行生產任務。
節點類型:Master節點: - Jenkins的大腦,負責調度和管理- 運行Jenkins Web界面- 分配任務給Slave節點Slave節點:- 執行具體的構建任務- 可以是物理機、虛擬機、Docker容器- 可以根據需要動態創建和銷毀
節點配置示例
// Docker節點配置
node('docker') {stage('在Docker中構建') {docker.image('maven:3.8.1-jdk-11').inside {sh 'mvn --version'sh 'mvn clean package'}}
}// Windows節點配置
node('windows') {stage('在Windows中構建') {bat 'echo %PATH%'bat 'dotnet build'}
}// Linux節點配置
node('linux') {stage('在Linux中構建') {sh 'uname -a'sh 'make build'}
}
3.5 Workspace(工作空間)
生活比喻:Workspace就像工人的工作臺,存放當前正在處理的材料和工具。
# 工作空間目錄結構
/var/jenkins_home/workspace/my-project/
├── src/ # 源代碼
├── target/ # 編譯輸出
├── Jenkinsfile # Pipeline定義文件
├── pom.xml # Maven配置文件
└── README.md # 項目說明
4. 安裝和初始配置
4.1 Docker安裝(推薦)
最簡單快捷的安裝方式:
# 1. 拉取Jenkins鏡像
docker pull jenkins/jenkins:lts# 2. 創建數據目錄
mkdir -p /var/jenkins_home
sudo chown 1000:1000 /var/jenkins_home# 3. 啟動Jenkins容器
docker run -d \--name jenkins \-p 8080:8080 \-p 50000:50000 \-v /var/jenkins_home:/var/jenkins_home \-v /var/run/docker.sock:/var/run/docker.sock \jenkins/jenkins:lts# 4. 查看初始管理員密碼
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
4.2 Linux系統安裝
# CentOS/RHEL安裝
sudo wget -O /etc/yum.repos.d/jenkins.repo \https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
sudo yum upgrade
sudo yum install jenkins java-11-openjdk# Ubuntu/Debian安裝
wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb https://pkg.jenkins.io/debian-stable binary/ > \/etc/apt/sources.list.d/jenkins.list'
sudo apt-get update
sudo apt-get install jenkins# 啟動Jenkins
sudo systemctl start jenkins
sudo systemctl enable jenkins
4.3 初始配置向導
1. 首次訪問設置:打開瀏覽器訪問: http://localhost:80802. 解鎖Jenkins:輸入初始管理員密碼(從日志中獲取)3. 安裝插件:選擇"安裝推薦插件"(適合新手)或者"選擇要安裝的插件"(高級用戶)4. 創建管理員用戶:用戶名: admin密碼: ********全名: Jenkins Administrator郵箱: admin@company.com5. 實例配置:Jenkins URL: http://localhost:8080/6. 開始使用Jenkins!
4.4 基礎配置
系統配置
// 在 Manage Jenkins → Configure System 中配置// 全局工具配置
configure {// JDK配置jdk {name('JDK-11')home('/usr/lib/jvm/java-11-openjdk')}// Maven配置maven {name('Maven-3.8')home('/usr/share/maven')}// Git配置git {name('Default')path('/usr/bin/git')}
}// 郵件配置
emailext {smtpServer('smtp.company.com')smtpPort(587)useSsl(true)charset('UTF-8')defaultSubject('Jenkins構建通知: ${JOB_NAME} - ${BUILD_NUMBER}')defaultBody('''構建狀態: ${BUILD_STATUS}項目名稱: ${JOB_NAME}構建編號: ${BUILD_NUMBER}構建URL: ${BUILD_URL}構建日志: ${BUILD_LOG}''')
}
5. 第一個Jenkins任務
5.1 創建自由風格項目
讓我們創建一個簡單的"Hello World"項目:
1. 點擊"新建任務"
2. 輸入任務名稱: hello-world
3. 選擇"構建一個自由風格的軟件項目"
4. 點擊"確定"
基礎配置
任務配置:描述: 我的第一個Jenkins任務,用于學習基礎操作源碼管理:Git倉庫: https://github.com/username/hello-world.git分支: main構建觸發器:GitHub hook trigger: ?定時構建: H/15 * * * * (每15分鐘檢查一次)構建環境:刪除工作空間: ?超時時間: 10分鐘
構建步驟
# 添加構建步驟 → 執行shell
#!/bin/bashecho "========================================="
echo "?? 開始執行Jenkins構建任務"
echo "========================================="# 顯示環境信息
echo "?? 構建時間: $(date)"
echo "??? 構建編號: ${BUILD_NUMBER}"
echo "?? 工作目錄: ${WORKSPACE}"
echo "?? Git分支: ${GIT_BRANCH}"
echo "?? 任務名稱: ${JOB_NAME}"# 檢查代碼
echo "?? 檢查項目文件:"
ls -la# 如果是Java項目
if [ -f "pom.xml" ]; thenecho "? 檢測到Maven項目,開始構建..."mvn clean compilemvn testmvn packageecho "? Maven構建完成"
fi# 如果是Node.js項目
if [ -f "package.json" ]; thenecho "?? 檢測到Node.js項目,開始構建..."npm installnpm testnpm run buildecho "? Node.js構建完成"
fi# 如果是Python項目
if [ -f "requirements.txt" ]; thenecho "?? 檢測到Python項目,開始構建..."pip install -r requirements.txtpython -m pytestecho "? Python測試完成"
fiecho "========================================="
echo "?? Jenkins構建任務完成!"
echo "========================================="
5.2 第一個Pipeline項目
創建一個更現代的Pipeline項目:
1. 新建任務 → Pipeline
2. 任務名稱: my-first-pipeline
3. 在Pipeline配置中選擇"Pipeline script"
Pipeline腳本
pipeline {agent any// 環境變量environment {APP_NAME = 'my-awesome-app'VERSION = '1.0.0'ENVIRONMENT = 'development'}// 參數化構建parameters {choice(name: 'DEPLOY_ENV',choices: ['dev', 'test', 'prod'],description: '選擇部署環境')string(name: 'BUILD_VERSION',defaultValue: '1.0.0',description: '構建版本號')booleanParam(name: 'SKIP_TESTS',defaultValue: false,description: '是否跳過測試')}stages {stage('?? 準備階段') {steps {script {echo "?? 開始構建 ${APP_NAME} v${BUILD_VERSION}"echo "?? 目標環境: ${params.DEPLOY_ENV}"echo "? 構建時間: ${new Date().format('yyyy-MM-dd HH:mm:ss')}"// 清理工作空間cleanWs()}}}stage('?? 代碼檢出') {steps {echo '正在檢出代碼...'git branch: 'main', url: 'https://github.com/username/project.git'script {// 獲取Git信息env.GIT_COMMIT_SHORT = sh(script: 'git rev-parse --short HEAD',returnStdout: true).trim()echo "?? 當前提交: ${env.GIT_COMMIT_SHORT}"}}}stage('?? 代碼質量檢查') {parallel {stage('語法檢查') {steps {echo '正在進行語法檢查...'sh 'echo "語法檢查通過 ?"'}}stage('安全掃描') {steps {echo '正在進行安全掃描...'sh 'echo "安全掃描通過 ??"'}}}}stage('?? 編譯構建') {steps {echo '開始編譯項目...'script {if (fileExists('pom.xml')) {sh 'mvn clean compile'} else if (fileExists('package.json')) {sh 'npm install'sh 'npm run build'} else {echo '未找到構建配置文件,跳過編譯步驟'}}}}stage('?? 運行測試') {when {not { params.SKIP_TESTS }}steps {echo '開始運行測試...'script {try {if (fileExists('pom.xml')) {sh 'mvn test'} else if (fileExists('package.json')) {sh 'npm test'}echo '? 所有測試通過!'} catch (Exception e) {echo '? 測試失敗!'currentBuild.result = 'FAILURE'error("測試階段失敗: ${e.getMessage()}")}}}post {always {// 發布測試報告script {if (fileExists('target/surefire-reports/*.xml')) {junit 'target/surefire-reports/*.xml'}}}}}stage('?? 打包應用') {steps {echo '開始打包應用...'script {if (fileExists('pom.xml')) {sh 'mvn package -DskipTests'archiveArtifacts artifacts: 'target/*.jar', fingerprint: true} else if (fileExists('package.json')) {sh 'npm run package'archiveArtifacts artifacts: 'dist/**/*', fingerprint: true}}echo '?? 應用打包完成!'}}stage('?? 部署應用') {steps {script {echo "正在部署到 ${params.DEPLOY_ENV} 環境..."switch(params.DEPLOY_ENV) {case 'dev':sh './deploy.sh dev'env.APP_URL = 'http://dev.myapp.com'breakcase 'test':sh './deploy.sh test'env.APP_URL = 'http://test.myapp.com'breakcase 'prod':// 生產環境需要額外確認input message: '確認部署到生產環境?', ok: '確認部署'sh './deploy.sh prod'env.APP_URL = 'http://www.myapp.com'break}echo "?? 部署完成!訪問地址: ${env.APP_URL}"}}}stage('? 驗證部署') {steps {echo '正在驗證部署結果...'script {// 健康檢查sh """echo "等待應用啟動..."sleep 30echo "檢查應用健康狀態..."curl -f ${env.APP_URL}/health || exit 1echo "應用部署驗證成功!?""""}}}}post {always {echo '?? 構建后清理工作...'script {// 計算構建時長def duration = currentBuild.durationdef durationString = "${Math.round(duration/1000)}秒"echo "?? 總構建時長: ${durationString}"}}success {echo '?? 構建成功!'script {// 發送成功通知emailext (subject: "? 構建成功: ${env.JOB_NAME} #${env.BUILD_NUMBER}",body: """<h2>?? 構建成功通知</h2><p><strong>項目:</strong> ${env.JOB_NAME}</p><p><strong>構建編號:</strong> ${env.BUILD_NUMBER}</p><p><strong>部署環境:</strong> ${params.DEPLOY_ENV}</p><p><strong>應用地址:</strong> <a href="${env.APP_URL}">${env.APP_URL}</a></p><p><strong>構建時間:</strong> ${new Date().format('yyyy-MM-dd HH:mm:ss')}</p><p><strong>Git提交:</strong> ${env.GIT_COMMIT_SHORT}</p><p>構建詳情請查看: <a href="${env.BUILD_URL}">點擊查看</a></p>""",mimeType: 'text/html',to: 'team@company.com')}}failure {echo '? 構建失敗!'script {// 發送失敗通知emailext (subject: "? 構建失敗: ${env.JOB_NAME} #${env.BUILD_NUMBER}",body: """<h2>? 構建失敗通知</h2><p><strong>項目:</strong> ${env.JOB_NAME}</p><p><strong>構建編號:</strong> ${env.BUILD_NUMBER}</p><p><strong>失敗階段:</strong> ${env.STAGE_NAME}</p><p><strong>構建時間:</strong> ${new Date().format('yyyy-MM-dd HH:mm:ss')}</p><p>請及時處理構建問題。</p><p>構建詳情請查看: <a href="${env.BUILD_URL}">點擊查看</a></p><p>控制臺日志: <a href="${env.BUILD_URL}console">查看日志</a></p>""",mimeType: 'text/html',to: 'team@company.com')}}unstable {echo '?? 構建不穩定!'// 處理不穩定狀態的邏輯}}
}
6. Pipeline詳解
6.1 聲明式Pipeline vs 腳本式Pipeline
聲明式Pipeline(推薦)
// 聲明式Pipeline - 結構化、易讀
pipeline {agent anytools {maven 'Maven-3.8'jdk 'JDK-11'}environment {MAVEN_OPTS = '-Xmx1024m'}stages {stage('Build') {steps {sh 'mvn clean compile'}}stage('Test') {steps {sh 'mvn test'}post {always {junit 'target/surefire-reports/*.xml'}}}}
}
腳本式Pipeline(靈活)
// 腳本式Pipeline - 更靈活,但復雜
node {try {stage('Checkout') {checkout scm}stage('Build') {if (isUnix()) {sh 'mvn clean compile'} else {bat 'mvn clean compile'}}stage('Test') {if (env.BRANCH_NAME == 'main') {sh 'mvn test'junit 'target/surefire-reports/*.xml'} else {echo 'Skipping tests for feature branch'}}} catch (Exception e) {currentBuild.result = 'FAILURE'throw e} finally {cleanWs()}
}
6.2 Pipeline高級特性
并行執行
pipeline {agent nonestages {stage('Parallel Testing') {parallel {stage('Unit Tests') {agent { label 'linux' }steps {sh 'mvn test'}post {always {junit 'target/surefire-reports/*.xml'}}}stage('Integration Tests') {agent { label 'docker' }steps {sh 'mvn verify -Pintegration-tests'}}stage('Security Scan') {agent anysteps {sh 'sonar-scanner'}}}}stage('Deploy') {steps {echo 'All tests passed, deploying...'}}}
}
條件執行
pipeline {agent anystages {stage('Build') {steps {sh 'mvn clean package'}}stage('Deploy to Dev') {when {branch 'develop'}steps {sh './deploy.sh dev'}}stage('Deploy to Staging') {when {branch 'main'}steps {sh './deploy.sh staging'}}stage('Deploy to Production') {when {allOf {branch 'main'environment name: 'DEPLOY_TO_PROD', value: 'true'}}steps {input message: 'Deploy to production?', ok: 'Deploy'sh './deploy.sh production'}}stage('Weekend Deployment') {when {// 只在工作日部署not { anyOf {expression { return Date.parse("EEE", new Date().format("EEE")) in ["Sat", "Sun"] }}}}steps {echo 'Deploying on weekday'}}}
}
矩陣構建
pipeline {agent nonestages {stage('Build Matrix') {matrix {axes {axis {name 'JAVA_VERSION'values '8', '11', '17'}axis {name 'OS'values 'linux', 'windows', 'mac'}}excludes {exclude {axis {name 'JAVA_VERSION'values '8'}axis {name 'OS'values 'mac'}}}stages {stage('Build') {agent {label "${OS}"}tools {jdk "JDK-${JAVA_VERSION}"}steps {sh "java -version"sh "mvn clean package"}}}}}}
}
6.3 共享庫
創建可重用的Pipeline代碼:
共享庫結構
jenkins-shared-library/
├── vars/
│ ├── buildJavaApp.groovy
│ ├── deployApp.groovy
│ └── sendNotification.groovy
├── src/
│ └── com/
│ └── company/
│ └── jenkins/
│ └── Utils.groovy
└── resources/├── scripts/│ └── deploy.sh└── templates/└── email.html
共享庫代碼
// vars/buildJavaApp.groovy
def call(Map config) {pipeline {agent anytools {maven config.mavenVersion ?: 'Maven-3.8'jdk config.jdkVersion ?: 'JDK-11'}stages {stage('Checkout') {steps {git url: config.gitUrl, branch: config.branch ?: 'main'}}stage('Build') {steps {sh 'mvn clean compile'}}stage('Test') {steps {sh 'mvn test'}post {always {junit 'target/surefire-reports/*.xml'publishHTML([allowMissing: false,alwaysLinkToLastBuild: true,keepAll: true,reportDir: 'target/site/jacoco',reportFiles: 'index.html',reportName: 'Coverage Report'])}}}stage('Package') {steps {sh 'mvn package -DskipTests'archiveArtifacts artifacts: 'target/*.jar'}}stage('Deploy') {when {expression { config.deploy == true }}steps {deployApp([environment: config.environment,artifact: 'target/*.jar'])}}}post {always {sendNotification([status: currentBuild.result,recipients: config.notifications])}}}
}// vars/deployApp.groovy
def call(Map config) {script {def environment = config.environmentdef artifact = config.artifactecho "Deploying ${artifact} to ${environment}"switch(environment) {case 'dev':sh "./deploy.sh dev ${artifact}"breakcase 'staging':sh "./deploy.sh staging ${artifact}"breakcase 'production':input message: 'Deploy to production?', ok: 'Deploy'sh "./deploy.sh production ${artifact}"breakdefault:error "Unknown environment: ${environment}"}}
}// vars/sendNotification.groovy
def call(Map config) {script {def status = config.status ?: currentBuild.resultdef recipients = config.recipients ?: 'team@company.com'def subject = "Jenkins Build ${status}: ${env.JOB_NAME} - ${env.BUILD_NUMBER}"def body = """Build ${status}!Job: ${env.JOB_NAME}Build Number: ${env.BUILD_NUMBER}Build URL: ${env.BUILD_URL}Console Output:${env.BUILD_URL}console"""if (status == 'SUCCESS') {body = "? " + body} else {body = "? " + body}emailext(subject: subject,body: body,to: recipients)}
}
使用共享庫
// Jenkinsfile
@Library('jenkins-shared-library') _buildJavaApp([gitUrl: 'https://github.com/company/my-app.git',branch: 'main',mavenVersion: 'Maven-3.8',jdkVersion: 'JDK-11',deploy: true,environment: 'staging',notifications: 'team@company.com'
])
7. 插件系統
7.1 必備插件推薦
基礎功能插件
Git插件:- Git: Git倉庫集成- GitHub: GitHub集成- GitLab: GitLab集成- Bitbucket: Bitbucket集成構建工具插件:- Maven Integration: Maven項目支持- Gradle: Gradle項目支持- NodeJS: Node.js項目支持- Docker: Docker容器支持通知插件:- Email Extension: 增強郵件通知- Slack Notification: Slack集成- DingTalk: 釘釘通知- WeChat Work: 企業微信通知
質量管理插件
代碼質量:- SonarQube Scanner: 代碼質量檢查- Checkstyle: Java代碼風格檢查- FindBugs: Java靜態分析- PMD: 代碼質量分析測試報告:- JUnit: 單元測試報告- TestNG Results: TestNG測試報告- Coverage: 代碼覆蓋率報告- Performance: 性能測試報告安全掃描:- OWASP Dependency Check: 依賴安全檢查- Anchore Container Image Scanner: 容器鏡像安全掃描
7.2 插件安裝和配置
通過Web界面安裝
1. 進入 Manage Jenkins → Manage Plugins
2. 選擇 Available 標簽頁
3. 搜索需要的插件
4. 選擇插件并點擊 "Install without restart"
5. 等待安裝完成
通過命令行安裝
# 使用jenkins-cli安裝插件
java -jar jenkins-cli.jar -s http://localhost:8080/ install-plugin git
java -jar jenkins-cli.jar -s http://localhost:8080/ install-plugin maven-plugin
java -jar jenkins-cli.jar -s http://localhost:8080/ install-plugin docker-plugin# 重啟Jenkins
java -jar jenkins-cli.jar -s http://localhost:8080/ restart
通過插件配置文件批量安裝
# plugins.txt
git:latest
maven-plugin:latest
docker-plugin:latest
email-ext:latest
slack:latest
sonar:latest
junit:latest
workflow-aggregator:latest
blueocean:latest
# 使用Docker安裝插件
FROM jenkins/jenkins:lts
COPY plugins.txt /usr/share/jenkins/ref/plugins.txt
RUN /usr/local/bin/install-plugins.sh < /usr/share/jenkins/ref/plugins.txt
7.3 常用插件配置示例
Blue Ocean配置
// Blue Ocean提供現代化的Pipeline視圖
pipeline {agent anystages {stage('Build') {steps {echo 'Building...'}}stage('Test') {parallel {stage('Unit Tests') {steps {echo 'Running unit tests...'}}stage('Integration Tests') {steps {echo 'Running integration tests...'}}}}stage('Deploy') {steps {echo 'Deploying...'}}}
}
SonarQube集成
pipeline {agent anytools {jdk 'JDK-11'maven 'Maven-3.8'}environment {SONAR_TOKEN = credentials('sonar-token')}stages {stage('Checkout') {steps {git 'https://github.com/company/project.git'}}stage('Build') {steps {sh 'mvn clean compile'}}stage('Test') {steps {sh 'mvn test'}post {always {junit 'target/surefire-reports/*.xml'}}}stage('SonarQube Analysis') {steps {withSonarQubeEnv('SonarQube') {sh """mvn sonar:sonar \-Dsonar.projectKey=my-project \-Dsonar.host.url=${SONAR_HOST_URL} \-Dsonar.login=${SONAR_TOKEN}"""}}}stage('Quality Gate'