🚀 Jenkins 服务器部署与
核心插件安装配置指南

企业级 CI/CD 持续集成平台完整部署方案 —— 从 Docker 容器化部署、Kubernetes 动态 Agent、Git/SonarQube/Harbor 集成到 Pipeline 流水线设计的全流程实操手册

📅 更新日期:2026 年 3 月 12 日 🎯 Jenkins 版本:2.440.x LTS ☸️ Kubernetes Plugin: 4423.vb_59f230b_ce53 ⏱️ 预计耗时:60-90 分钟

1. Jenkins 概述与核心特性

🔄 持续集成

  • 自动化构建与测试
  • 代码质量检查
  • 单元测试覆盖率
  • 集成测试验证
  • 构建产物管理

🚀 持续交付

  • 自动化部署流程
  • 多环境管理(Dev/Test/Prod)
  • 蓝绿部署支持
  • 金丝雀发布
  • 回滚机制

📦 插件生态

  • 1800+ 官方插件
  • Git/SVN 版本控制
  • Docker/K8s 容器化
  • SonarQube 代码质量
  • Harbor 镜像仓库

📊 可视化监控

  • 构建历史与趋势
  • 测试报告展示
  • 代码覆盖率统计
  • 部署状态追踪
  • 告警通知集成

1.1 Jenkins 架构组成

┌─────────────────────────────────────────────────────────────────┐
│                     Jenkins CI/CD Architecture                   │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                  Jenkins Controller                      │   │
│  │  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  │   │
│  │  │   Web UI     │  │  Pipeline    │  │   Plugin     │  │   │
│  │  │  (Dashboard) │  │  Engine      │  │  Manager     │  │   │
│  │  └──────────────┘  └──────────────┘  └──────────────┘  │   │
│  │  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  │   │
│  │  │   Job        │  │  Credentials │  │   Config     │  │   │
│  │  │   Queue      │  │  Store       │  │   Files      │  │   │
│  │  └──────────────┘  └──────────────┘  └──────────────┘  │   │
│  └─────────────────────────────────────────────────────────┘   │
│                           │                                     │
│         ┌─────────────────┼─────────────────┐                  │
│         │                 │                 │                   │
│  ┌──────▼──────┐   ┌──────▼──────┐   ┌──────▼──────┐          │
│  │  Static     │   │  Docker     │   │ Kubernetes  │          │
│  │  Agent      │   │  Agent      │   │   Pod       │          │
│  │  (VM/BM)    │   │  Container  │   │  (Dynamic)  │          │
│  │ ┌─────────┐ │   │ ┌─────────┐ │   │ ┌─────────┐ │          │
│  │ │  Git    │ │   │ │ Docker  │ │   │ │  Helm   │ │          │
│  │ │  Maven  │ │   │ │  Make   │ │   │ │  Kubectl│ │          │
│  │ │  Node   │ │   │ │  Python │ │   │ │  Python │ │          │
│  │ └─────────┘ │   │ └─────────┘ │   │ └─────────┘ │          │
│  └─────────────┘   └─────────────┘   └─────────────┘          │
│                                                                  │
│  External Integrations:                                          │
│  • GitLab/GitHub/Bitbucket (Source Code)                        │
│  • SonarQube (Code Quality)                                     │
│  • Harbor/Nexus/Artifactory (Artifact Repository)               │
│  • Kubernetes/Docker Swarm (Deployment Target)                  │
│  • Slack/Email/DingTalk (Notifications)                         │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
                    

2. 系统要求与环境准备

2.1 硬件配置要求

规模 CPU 内存 磁盘 并发构建数
小型团队 2-4 Core 4-8 GB 50 GB SSD 5-10
中型团队 4-8 Core 8-16 GB 100 GB SSD 10-30
大型企业 8-16 Core 16-32 GB 200GB+ SSD 30-100+

2.2 软件依赖

基础环境

  • JDK 17 或 JDK 21(推荐)
  • Docker 20.10+(容器化部署)
  • Kubernetes 1.20+(K8s 部署)
  • Helm 3.2.0+(Helm 部署)
  • Git 2.30+(版本控制)

构建工具

  • Maven 3.8+(Java 项目)
  • Gradle 8.0+(Java/Kotlin)
  • Node.js 18+(前端项目)
  • Python 3.9+(Python 项目)
  • Go 1.20+(Go 项目)

外部服务

  • GitLab/GitHub(代码仓库)
  • SonarQube(代码质量)
  • Harbor(镜像仓库)
  • Kubernetes(部署目标)
  • SMTP/LDAP(邮件/认证)

2.3 端口要求

端口 协议 用途 可修改
8080 HTTP Jenkins Web 界面
443 HTTPS 加密 Web 访问
50000 TCP JNLP Agent 连接
22 SSH SSH Agent 连接

2.4 环境诊断命令

# ===== 系统检查 ===== # 1. 检查 CPU 和内存 lscpu | grep "CPU(s)" free -h # 2. 检查磁盘空间 df -h / df -h /var/lib/docker # 3. 检查 Java 版本 java -version javac -version # 4. 检查 Docker docker --version docker compose version # 5. 检查 Kubernetes kubectl version --client helm version # 6. 检查网络连接 curl -I https://github.com curl -I https://plugins.jenkins.io curl -I https://repo.maven.apache.org # 7. 检查端口占用 netstat -tlnp | grep -E ':(8080|50000)' ss -tlnp | grep -E ':(8080|50000)'

3. 部署方式选择与对比

部署方式 适用场景 优点 缺点 推荐度
Docker 容器 快速部署/开发测试 简单快速、易于迁移 数据持久化需配置 ⭐⭐⭐⭐⭐
Kubernetes 生产环境/大规模 高可用、易扩展、自愈 复杂度高、需要 K8s ⭐⭐⭐⭐⭐
WAR 包部署 传统 Tomcat 环境 灵活可控、兼容性好 手动配置多、维护复杂 ⭐⭐⭐
原生安装包 专用服务器 性能最优、完全掌控 安装繁琐、升级麻烦 ⭐⭐⭐
💡 推荐方案:
  • 开发测试/中小团队:Docker Compose 部署(简单快速)
  • 生产环境/大规模:Kubernetes Helm 部署(高可用、弹性伸缩)
  • 已有 Tomcat 环境:WAR 包部署(兼容现有架构)

4. Docker 容器化部署

步骤 1:拉取 Jenkins 官方镜像

# 拉取最新 LTS 版本(JDK 21) docker pull jenkins/jenkins:lts-jdk21 # 或者指定具体版本 docker pull jenkins/jenkins:2.440.1-lts-jdk21 # 查看镜像信息 docker images jenkins/jenkins # 国内加速镜像(可选) docker pull registry.cn-hangzhou.aliyuncs.com/jenkinsci/jenkins:lts-jdk21

步骤 2:创建数据持久化目录

# 创建 Jenkins 主目录 mkdir -p /data/jenkins/{home,plugins,workspace,backup} chmod -R 777 /data/jenkins # 创建 Docker Socket 映射(用于 Docker in Docker) ls -la /var/run/docker.sock # 确保当前用户可以访问 docker.sock sudo usermod -aG docker $USER # 创建插件列表文件 cat > /data/jenkins/plugins.txt << 'EOF' jenkins:lts-jdk21 git:latest gitlab:latest github:latest kubernetes:latest kubernetes-cli:latest docker-plugin:latest docker-workflow:latest sonar:latest pipeline:latest pipeline-stage-view:latest workflow-aggregator:latest blueocean:latest configuration-as-code:latest credentials-binding:latest ssh-agent:latest nexus-artifact-uploader:latest harbor:latest EOF

步骤 3:编写 Docker Compose 配置

# docker-compose.yml version: '3.8' services: jenkins: image: jenkins/jenkins:lts-jdk21 container_name: jenkins-master hostname: jenkins-master privileged: true user: root ports: - "8080:8080" - "50000:50000" environment: - JAVA_OPTS=-Duser.timezone=Asia/Shanghai -Xmx2g -Xms1g - JENKINS_OPTS=--prefix=/jenkins - TZ=Asia/Shanghai volumes: - /data/jenkins/home:/var/jenkins_home - /data/jenkins/plugins:/usr/share/jenkins/ref/plugins - /var/run/docker.sock:/var/run/docker.sock - /usr/bin/docker:/usr/bin/docker - /etc/docker:/etc/docker networks: - jenkins-network restart: always healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/login"] interval: 30s timeout: 10s retries: 3 start_period: 60s networks: jenkins-network: driver: bridge ipam: config: - subnet: 172.28.0.0/16

步骤 4:启动 Jenkins 容器

# 启动容器 cd /data/jenkins docker compose up -d # 查看容器状态 docker compose ps # 查看启动日志 docker compose logs -f jenkins # 等待 Jenkins 完全启动(约 1-2 分钟) sleep 60 # 获取初始管理员密码 docker exec jenkins-master cat /var/jenkins_home/secrets/initialAdminPassword # 输出类似:a1b2c3d4e5f6g7h8i9j0 # 访问 Jenkins Web 界面 echo "访问地址:http://localhost:8080/jenkins" echo "初始密码:$(docker exec jenkins-master cat /var/jenkins_home/secrets/initialAdminPassword)"

步骤 5:初始化配置

🔧 首次登录后的配置步骤:
  1. 输入初始管理员密码登录
  2. 选择「安装推荐的插件」或「自定义插件」
  3. 创建第一个管理员账户
  4. 配置 Jenkins URL(如:http://jenkins.yourcompany.com)
  5. 点击「保存并完成」
  6. 进入「系统管理」→「全局工具配置」配置 JDK/Maven/Git 等

4.2 预装插件脚本

#!/bin/bash # install-jenkins-plugins.sh - 批量安装 Jenkins 插件 JENKINS_URL="http://localhost:8080/jenkins" ADMIN_USER="admin" ADMIN_PASSWORD="your_password" # 核心插件列表 PLUGINS=( "git" "gitlab" "github" "kubernetes" "kubernetes-cli" "docker-plugin" "docker-workflow" "sonar" "pipeline" "pipeline-stage-view" "workflow-aggregator" "blueocean" "configuration-as-code" "credentials-binding" "ssh-agent" "nexus-artifact-uploader" "harbor" "email-ext" "slack" "build-timeout" ) # 使用 Jenkins CLI 安装插件 for plugin in "${PLUGINS[@]}"; do echo "Installing plugin: $plugin" java -jar jenkins-cli.jar -s $JENKINS_URL -auth $ADMIN_USER:$ADMIN_PASSWORD \ install-plugin $plugin -deploy done echo "✅ 所有插件安装完成!" echo "请重启 Jenkins 使插件生效:docker restart jenkins-master"

5. Kubernetes Helm 部署

5.1 添加 Helm Chart 仓库

# 添加 Jenkins Helm Chart 仓库 helm repo add jenkins https://charts.jenkins.io helm repo update # 搜索可用的 Chart 版本 helm search repo jenkins --versions # 下载 Chart 到本地 helm pull jenkins/jenkins --version 5.8.139 --untar cd jenkins

5.2 配置 values.yaml

# values.yaml 关键配置项 jenkins: enabled: true controller: replicaCount: 1 imagePullPolicy: Always image: registry: docker.io repository: jenkins/jenkins tag: lts-jdk21 resources: requests: cpu: 500m memory: 1Gi limits: cpu: 2000m memory: 4Gi serviceType: NodePort servicePort: 8080 nodePort: 30080 agentListenerPort: 50000 ingress: enabled: true hostName: jenkins.yourcompany.com annotations: nginx.ingress.kubernetes.io/proxy-body-size: "0" nginx.ingress.kubernetes.io/ssl-redirect: "true" tls: - secretName: jenkins-tls hosts: - jenkins.yourcompany.com persistence: enabled: true storageClass: nfs-client size: 50Gi accessMode: ReadWriteOnce javaOpts: >- -Duser.timezone=Asia/Shanghai -Xmx2g -Xms1g -XX:+UseG1GC installPlugins: - kubernetes:4423.vb_59f230b_ce53 - workflow-aggregator:600.vb_57cdd26fdd7 - git:5.2.1 - gitlab:1.9.6 - github:1.38.0 - docker-plugin:1.5.0 - docker-workflow:580.vc0c340686b_54 - sonar:2.17.3 - pipeline:2.8.0 - blueocean:1.27.9 - configuration-as-code:1810.v9b_c30a_249a_4c - credentials-binding:657.v2b_19db_7d6e6d - ssh-agent:346.vda_a_c4f2c8e50 - email-ext:1806.v856a_01a_fa_39a_ - slack:734.v7f9ec8b_66975 agent: enabled: true defaultsProviderTemplate: jnlp namespace: jenkins-agents privileged: true runAsUser: 1000 runAsGroup: 1000 fsGroup: 1000 volumes: - type: PersistentVolumeClaim claimName: jenkins-agent-pvc mountPath: /home/jenkins/agent envVars: - name: DOCKER_HOST value: tcp://localhost:2375 sideContainers: - name: dind image: docker:24-dind imagePullPolicy: Always securityContext: privileged: true resources: requests: cpu: 500m memory: 512Mi limits: cpu: 1000m memory: 1Gi rbac: create: true readSecrets: true serviceAccount: create: true name: jenkins annotations: {}

5.3 创建 RBAC 权限

# 创建命名空间 kubectl create namespace jenkins kubectl create namespace jenkins-agents # 创建 ServiceAccount 和 RBAC cat > jenkins-rbac.yaml << EOF apiVersion: v1 kind: ServiceAccount metadata: name: jenkins namespace: jenkins --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: jenkins-cluster-role rules: - apiGroups: [""] resources: ["pods", "pods/exec", "pods/log", "persistentvolumeclaims", "events"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - apiGroups: [""] resources: ["secrets", "configmaps", "services", "endpoints"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - apiGroups: ["apps"] resources: ["deployments", "statefulsets", "daemonsets", "replicasets"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - apiGroups: ["batch"] resources: ["jobs", "cronjobs"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - apiGroups: ["extensions", "networking.k8s.io"] resources: ["ingresses"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: jenkins-cluster-role-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: jenkins-cluster-role subjects: - kind: ServiceAccount name: jenkins namespace: jenkins EOF kubectl apply -f jenkins-rbac.yaml

5.4 安装 Jenkins

# 使用 Helm 安装 helm install jenkins jenkins/jenkins \ --namespace jenkins \ --values values.yaml \ --version 5.8.139 # 查看安装状态 helm status jenkins -n jenkins helm list -n jenkins # 等待所有 Pod 就绪 kubectl get pods -n jenkins -w # 查看 Service kubectl get svc -n jenkins # 获取初始管理员密码 kubectl get secret jenkins -n jenkins -o jsonpath="{.data.jenkins-admin-password}" | base64 --decode # 访问 Jenkins(通过 Ingress 或 NodePort) echo "访问地址:http://jenkins.yourcompany.com" echo "或:http://:30080"

5.5 升级与卸载

# 升级 Jenkins helm upgrade jenkins jenkins/jenkins \ --namespace jenkins \ --values values.yaml \ --version 5.8.140 # 回滚到上一个版本 helm rollback jenkins -n jenkins # 查看发布历史 helm history jenkins -n jenkins # 卸载 Jenkins helm uninstall jenkins -n jenkins # 清理 PVC(谨慎操作,会删除数据) kubectl delete pvc -n jenkins -l app.kubernetes.io/name=jenkins

6. 核心插件安装配置

6.1 必备核心插件清单

📦 版本控制

Git Plugin GitLab Plugin GitHub Plugin Bitbucket Plugin

支持主流 Git 代码仓库,实现代码拉取、Webhook 触发、分支构建等功能。

🐳 容器化

Kubernetes Plugin Docker Plugin Docker Pipeline

动态 provision Jenkins Agent,实现弹性构建资源调度。

📊 代码质量

SonarQube Scanner Checkstyle FindBugs JaCoCo

集成 SonarQube 进行代码质量扫描、技术债务分析、漏洞检测。

🔄 流水线

Pipeline Pipeline Stage View Blue Ocean

支持 Pipeline as Code,可视化编排 CI/CD 流程。

🔐 凭证管理

Credentials Binding SSH Agent HashiCorp Vault

安全存储和管理敏感凭证,支持密钥、用户名密码、Token 等类型。

📢 通知告警

Email Extension Slack Notification DingTalk WeCom

构建结果通知,支持邮件、Slack、钉钉、企业微信等渠道。

6.2 插件管理最佳实践

💡 插件管理建议:
  • 最小化原则:只安装必需的插件,减少安全风险和维护成本
  • 定期更新:每月检查并更新插件,修复安全漏洞
  • 版本锁定:生产环境锁定插件版本,避免自动升级导致的不兼容
  • 备份配置:使用 Configuration as Code 插件备份 Jenkins 配置
  • 测试环境先行:新插件先在测试环境验证,再部署到生产

7. Git 与代码仓库集成

7.1 GitLab 集成配置

# ===== Jenkins 系统配置 ===== 路径:系统管理 → 系统配置 → GitLab # 1. 添加 GitLab 服务器 Name: gitlab-prod Server URL: https://gitlab.yourcompany.com Credentials: 添加 GitLab API Token Connection Timeout: 10 Read Timeout: 10 # 2. 生成 GitLab API Token GitLab → Settings → Access Tokens Name: jenkins-integration Scopes: api, read_user, read_repository, write_repository Expires at: 2027-12-31 # 3. 在 Jenkins 中添加凭证 路径:凭证 → 系统 → 全局凭证 → 添加凭证 Kind: Secret text Secret: glpat-xxxxxxxxxxxxxxxxxxxx ID: gitlab-api-token Description: GitLab API Token for Jenkins

7.2 GitHub 集成配置

# ===== GitHub App 认证(推荐)===== 1. 创建 GitHub App GitHub → Settings → Developer settings → GitHub Apps → New GitHub App App name: jenkins-ci Homepage URL: http://jenkins.yourcompany.com Webhook URL: http://jenkins.yourcompany.com/github-webhook/ Permissions: - Contents: Read & Write - Pull requests: Read & Write - Issues: Read & Write - Commit statuses: Read & Write - Repository hooks: Read & Write 2. 在 Jenkins 中配置 路径:凭证 → 添加凭证 → GitHub App App ID: 123456 Owner: your-organization Private Key: 上传下载的私钥文件 ID: github-app-credentials 3. 配置 Webhook GitHub 仓库 → Settings → Webhooks → Add webhook Payload URL: http://jenkins.yourcompany.com/github-webhook/ Content type: application/json Secret: your-webhook-secret Events: Push, Pull Request

7.3 多分支流水线配置

# Jenkinsfile 示例(声明式 Pipeline) pipeline { agent any triggers { pollSCM('*/5 * * * *') // 每 5 分钟检查代码变更 } options { buildDiscarder(logRotator(numToKeepStr: '10')) timeout(time: 1, unit: 'HOURS') disableConcurrentBuilds() } environment { GIT_CREDENTIALS = credentials('gitlab-api-token') SONAR_TOKEN = credentials('sonarqube-token') } stages { stage('Checkout') { steps { checkout scm script { env.GIT_COMMIT_SHORT = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim() env.GIT_BRANCH_NAME = env.BRANCH_NAME.replace('/', '-') } } } stage('Install Dependencies') { steps { sh 'npm ci || mvn dependency:resolve || pip install -r requirements.txt' } } stage('Code Quality') { steps { script { if (fileExists('pom.xml')) { sh 'mvn sonar:sonar -Dsonar.projectKey=${JOB_NAME} -Dsonar.host.url=${SONAR_HOST_URL}' } else if (fileExists('package.json')) { sh 'npx eslint . || true' } } } } stage('Build') { steps { sh 'npm run build || mvn clean package -DskipTests || python setup.py build' } } stage('Test') { steps { sh 'npm test || mvn test || pytest tests/' } post { always { junit allowEmptyResults: true, testResults: '**/target/surefire-reports/*.xml,**/test-results/**/*.xml' } } } } post { success { echo '✅ Build succeeded!' } failure { echo '❌ Build failed!' mail to: 'team@yourcompany.com', subject: "Build Failed: ${env.JOB_NAME} [${env.BUILD_NUMBER}]", body: "Please check: ${env.BUILD_URL}" } } }

8. Docker 与 Harbor 集成

8.1 Docker 插件配置

# ===== 系统管理 → 系统配置 → Docker Builder ===== # 1. 配置 Docker Host Docker Host URI: unix:///var/run/docker.sock Docker API version: 1.41 # 2. 测试连接 点击「Test Connection」应显示成功 # 3. 添加 Docker Registry 凭证 路径:凭证 → 添加凭证 → Username with password Username: admin Password: Harbor12345 ID: harbor-credentials Description: Harbor Registry Credentials

8.2 Harbor 集成配置

# ===== 系统管理 → 系统配置 → Harbor ===== # 1. 添加 Harbor 服务器 Name: harbor-prod Server URL: https://harbor.yourcompany.com Credentials: harbor-credentials Skip TLS Verification: false # 生产环境不要跳过证书验证 # 2. 测试连接 点击「Test Connection」应显示成功 # 3. 在 Pipeline 中使用 Harbor

8.3 Docker 构建与推送 Pipeline

pipeline { agent { kubernetes { yaml ''' apiVersion: v1 kind: Pod spec: containers: - name: docker image: docker:24-dind securityContext: privileged: true volumeMounts: - name: docker-sock mountPath: /var/run volumes: - name: docker-sock emptyDir: {} ''' } } environment { DOCKER_REGISTRY = 'harbor.yourcompany.com' PROJECT_NAME = 'my-project' IMAGE_NAME = 'backend-service' HARBOR_CREDENTIALS_ID = 'harbor-credentials' } stages { stage('Checkout') { steps { checkout scm } } stage('Build Docker Image') { steps { script { def imageTag = "${DOCKER_REGISTRY}/${PROJECT_NAME}/${IMAGE_NAME}:${env.BUILD_NUMBER}-${GIT_COMMIT_SHORT}" def latestTag = "${DOCKER_REGISTRY}/${PROJECT_NAME}/${IMAGE_NAME}:latest" sh """ docker build -t ${imageTag} . docker tag ${imageTag} ${latestTag} """ env.DOCKER_IMAGE_TAG = imageTag env.DOCKER_LATEST_TAG = latestTag } } } stage('Push to Harbor') { steps { withCredentials([usernamePassword(credentialsId: HARBOR_CREDENTIALS_ID, usernameVariable: 'HARBOR_USER', passwordVariable: 'HARBOR_PASS')]) { sh """ echo \${HARBOR_PASS} | docker login ${DOCKER_REGISTRY} -u \${HARBOR_USER} --password-stdin docker push ${DOCKER_IMAGE_TAG} docker push ${DOCKER_LATEST_TAG} """ } } } stage('Vulnerability Scan') { steps { script { sh """ curl -k -X POST \\ -u admin:Harbor12345 \\ "${DOCKER_REGISTRY}/api/v2.0/projects/${PROJECT_NAME}/repositories/${IMAGE_NAME}/artifacts/latest/scan" """ } } } } post { success { echo "✅ Docker image pushed: ${DOCKER_IMAGE_TAG}" } cleanup { sh """ docker logout ${DOCKER_REGISTRY} docker rmi ${DOCKER_IMAGE_TAG} ${DOCKER_LATEST_TAG} || true """ } } }

9. Kubernetes 云配置

9.1 添加 Kubernetes 云

# ===== 系统管理 → Manage Nodes and Clouds → Configure Clouds ===== # 1. 添加新的云 → Kubernetes Name: kubernetes-prod Kubernetes URL: https://kubernetes.default.svc.cluster.local Kubernetes Namespace: jenkins-agents # 2. 配置认证 Credentials: Kubernetes service account credentials # 选择之前创建的 jenkins ServiceAccount # 3. 测试连接 点击「Test Connection」应显示成功 # 4. 配置 Pod 模板 Name: default Namespace: jenkins-agents Label: jenkins-agent Usage: Use this node for jobs which specify the label

9.2 Pod 模板配置

# Pod Template YAML 配置 apiVersion: v1 kind: Pod metadata: labels: app: jenkins-agent spec: serviceAccountName: jenkins containers: - name: jnlp image: jenkins/inbound-agent:jdk21 args: - '${computer.jnlpmac}' - '${computer.name}' resources: requests: cpu: 500m memory: 1Gi limits: cpu: 2000m memory: 4Gi volumeMounts: - name: workspace-volume mountPath: /home/jenkins/agent - name: docker-sock mountPath: /var/run/docker.sock - name: docker image: docker:24-dind securityContext: privileged: true resources: requests: cpu: 500m memory: 512Mi limits: cpu: 1000m memory: 1Gi - name: maven image: maven:3.9.9-eclipse-temurin-21 command: - cat tty: true - name: nodejs image: node:20-alpine command: - cat tty: true volumes: - name: workspace-volume emptyDir: {} - name: docker-sock emptyDir: {}

9.3 动态 Agent 示例

pipeline { agent { kubernetes { label 'jenkins-agent' defaultContainer 'maven' yaml ''' apiVersion: v1 kind: Pod spec: containers: - name: maven image: maven:3.9.9-eclipse-temurin-21 command: - cat tty: true - name: nodejs image: node:20-alpine command: - cat tty: true - name: docker image: docker:24-dind securityContext: privileged: true ''' } } stages { stage('Maven Build') { steps { container('maven') { sh 'mvn -version' sh 'mvn clean package -DskipTests' } } } stage('Node.js Build') { steps { container('nodejs') { sh 'node --version' sh 'npm --version' sh 'npm ci && npm run build' } } } stage('Docker Build') { steps { container('docker') { sh 'docker --version' sh 'docker build -t myapp:latest .' } } } } }

10. SonarQube 代码质量集成

10.1 SonarQube 服务器配置

# ===== 系统管理 → 系统配置 → SonarQube servers ===== # 1. 添加 SonarQube 服务器 Name: sonarqube-prod Server URL: http://sonarqube.yourcompany.com:9000 Server authentication token: 添加 Token 凭证 # 2. 生成 SonarQube Token SonarQube → My Account → Security → Generate Tokens Type: User Token Name: jenkins-integration Expires in: 30 days # 3. 在 Jenkins 中添加凭证 Kind: Secret text Secret: sqp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ID: sonarqube-token Description: SonarQube Authentication Token

10.2 Java 项目 Sonar 扫描

pipeline { agent any environment { SONAR_HOST_URL = 'http://sonarqube.yourcompany.com:9000' SONAR_TOKEN = credentials('sonarqube-token') } stages { stage('Checkout') { steps { checkout scm } } stage('Compile') { steps { sh 'mvn clean compile' } } stage('SonarQube Analysis') { steps { withSonarQubeEnv('sonarqube-prod') { sh ''' mvn sonar:sonar \\ -Dsonar.projectKey=${JOB_NAME} \\ -Dsonar.projectName=${JOB_NAME} \\ -Dsonar.sources=src/main/java \\ -Dsonar.tests=src/test/java \\ -Dsonar.java.binaries=target/classes \\ -Dsonar.junit.reportsPath=target/surefire-reports \\ -Dsonar.jacoco.reportPath=target/jacoco.exec \\ -Dsonar.sourceEncoding=UTF-8 ''' } } } stage('Quality Gate') { steps { timeout(time: 1, unit: 'HOURS') { waitForQualityGate abortPipeline: true } } } } }

10.3 前端项目 Sonar 扫描

pipeline { agent any tools { nodejs 'Node.js 20' } environment { SONAR_HOST_URL = 'http://sonarqube.yourcompany.com:9000' SONAR_TOKEN = credentials('sonarqube-token') } stages { stage('Install Dependencies') { steps { sh 'npm ci' } } stage('Lint & Test') { steps { sh 'npm run lint' sh 'npm test -- --coverage' } } stage('SonarQube Analysis') { steps { withSonarQubeEnv('sonarqube-prod') { sh ''' npx sonar-scanner \\ -Dsonar.projectKey=${JOB_NAME} \\ -Dsonar.projectName=${JOB_NAME} \\ -Dsonar.sources=src \\ -Dsonar.tests=tests \\ -Dsonar.javascript.lcov.reportPaths=coverage/lcov.info \\ -Dsonar.sourceEncoding=UTF-8 ''' } } } stage('Quality Gate') { steps { timeout(time: 1, unit: 'HOURS') { waitForQualityGate abortPipeline: true } } } } }

11. Pipeline 流水线设计

11.1 完整 CI/CD Pipeline 示例

pipeline { agent { kubernetes { label 'jenkins-agent' defaultContainer 'maven' yaml ''' apiVersion: v1 kind: Pod spec: serviceAccountName: jenkins containers: - name: maven image: maven:3.9.9-eclipse-temurin-21 command: ["cat"] tty: true resources: requests: cpu: 500m memory: 1Gi limits: cpu: 2000m memory: 4Gi - name: docker image: docker:24-dind securityContext: privileged: true resources: requests: cpu: 500m memory: 512Mi volumes: - name: docker-sock emptyDir: {} ''' } } parameters { string(name: 'DEPLOY_ENV', defaultValue: 'dev', description: '部署环境:dev/test/prod') booleanParam(name: 'SKIP_TESTS', defaultValue: false, description: '是否跳过测试') } options { buildDiscarder(logRotator(numToKeepStr: '20', artifactNumToKeepStr: '10')) timeout(time: 2, unit: 'HOURS') disableConcurrentBuilds() timestamps() } environment { DOCKER_REGISTRY = 'harbor.yourcompany.com' PROJECT_NAME = 'backend-service' IMAGE_NAME = 'app' SONAR_HOST_URL = 'http://sonarqube.yourcompany.com:9000' KUBECONFIG_CREDENTIALS_ID = 'kubeconfig-prod' } triggers { pollSCM('H/5 * * * *') cron('H 2 * * 1-5') // 工作日凌晨 2 点执行定时构建 } stages { stage('Checkout') { steps { checkout scm script { env.GIT_COMMIT_SHORT = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim() env.BUILD_VERSION = "${env.BUILD_NUMBER}-${GIT_COMMIT_SHORT}" } } } stage('Install Dependencies') { steps { container('maven') { sh 'mvn dependency:resolve' } } } stage('Code Quality') { when { expression { return !params.SKIP_TESTS } } steps { container('maven') { withSonarQubeEnv('sonarqube-prod') { sh """ mvn sonar:sonar \\ -Dsonar.projectKey=${PROJECT_NAME} \\ -Dsonar.sources=src/main/java \\ -Dsonar.tests=src/test/java \\ -Dsonar.java.binaries=target/classes """ } } } } stage('Unit Test') { when { expression { return !params.SKIP_TESTS } } steps { container('maven') { sh 'mvn test' } } post { always { junit allowEmptyResults: true, testResults: 'target/surefire-reports/*.xml' jacoco execPattern: 'target/jacoco.exec' } } } stage('Build Package') { steps { container('maven') { sh 'mvn clean package -DskipTests' } } post { success { archiveArtifacts artifacts: 'target/*.jar', fingerprint: true } } } stage('Build Docker Image') { steps { container('docker') { script { env.DOCKER_IMAGE = "${DOCKER_REGISTRY}/${PROJECT_NAME}/${IMAGE_NAME}:${BUILD_VERSION}" env.DOCKER_LATEST = "${DOCKER_REGISTRY}/${PROJECT_NAME}/${IMAGE_NAME}:latest" } sh """ docker build -t ${DOCKER_IMAGE} -t ${DOCKER_LATEST} . """ } } } stage('Push to Harbor') { steps { container('docker') { withCredentials([usernamePassword(credentialsId: 'harbor-credentials', usernameVariable: 'HARBOR_USER', passwordVariable: 'HARBOR_PASS')]) { sh """ echo \${HARBOR_PASS} | docker login ${DOCKER_REGISTRY} -u \${HARBOR_USER} --password-stdin docker push ${DOCKER_IMAGE} docker push ${DOCKER_LATEST} """ } } } } stage('Deploy to Kubernetes') { when { expression { return params.DEPLOY_ENV != 'none' } } steps { container('maven') { withKubeConfig([credentialsId: KUBECONFIG_CREDENTIALS_ID]) { sh """ kubectl set image deployment/${PROJECT_NAME} \\ ${PROJECT_NAME}=${DOCKER_IMAGE} \\ -n ${DEPLOY_ENV} kubectl rollout status deployment/${PROJECT_NAME} -n ${DEPLOY_ENV} --timeout=300s kubectl get pods -l app=${PROJECT_NAME} -n ${DEPLOY_ENV} """ } } } } stage('Smoke Test') { when { expression { return params.DEPLOY_ENV == 'prod' } } steps { sh """ curl -f http://${PROJECT_NAME}.${DEPLOY_ENV}.yourcompany.com/health || exit 1 """ } } } post { always { cleanWs() container('docker') { sh """ docker logout ${DOCKER_REGISTRY} || true docker rmi ${DOCKER_IMAGE} ${DOCKER_LATEST} || true """ } } success { echo "✅ Build #${BUILD_NUMBER} succeeded!" slackSend(color: 'good', message: "Build #${BUILD_NUMBER} succeeded: ${BUILD_URL}") } failure { echo "❌ Build #${BUILD_NUMBER} failed!" slackSend(color: 'danger', message: "Build #${BUILD_NUMBER} failed: ${BUILD_URL}") emailext( to: 'team@yourcompany.com', subject: "Build Failed: ${JOB_NAME} [${BUILD_NUMBER}]", body: "Please check: ${BUILD_URL}\n\nCommit: ${GIT_COMMIT_SHORT}\nAuthor: ${GIT_AUTHOR_NAME}" ) } unstable { echo "⚠️ Build #${BUILD_NUMBER} is unstable!" } } }

12. 安全加固与运维管理

12.1 安全加固措施

🔐 访问控制

  • 启用矩阵授权策略
  • 配置 LDAP/AD 集成
  • 强制 HTTPS 访问
  • 启用 CSRF 保护
  • 配置会话超时

🛡️ 凭证安全

  • 使用 HashiCorp Vault
  • 启用凭证加密存储
  • 定期轮换密钥
  • 限制凭证访问范围
  • 审计凭证使用记录

🔒 网络安全

  • 配置防火墙规则
  • 限制 Agent 连接 IP
  • 启用 Script Security
  • 禁用 Groovy 沙箱逃逸
  • 配置 CSP 策略

📝 审计日志

  • 启用审计跟踪插件
  • 记录所有配置变更
  • 监控异常登录行为
  • 定期审查操作日志
  • 配置日志归档策略

12.2 备份与恢复

#!/bin/bash # backup-jenkins.sh - Jenkins 备份脚本 JENKINS_HOME="/data/jenkins/home" BACKUP_DIR="/backup/jenkins" DATE=$(date +%Y%m%d_%H%M%S) RETENTION_DAYS=30 # 创建备份目录 mkdir -p ${BACKUP_DIR}/{config,plugins,jobs} # 1. 停止 Jenkins(可选,确保数据一致性) curl -X POST http://admin:token@localhost:8080/jenkins/exit sleep 10 # 2. 备份 JENKINS_HOME tar -czf ${BACKUP_DIR}/jenkins_home_${DATE}.tar.gz \\ --exclude='*.log' \\ --exclude='logs/*' \\ --exclude='war/*' \\ ${JENKINS_HOME} # 3. 导出配置(使用 Configuration as Code) curl -u admin:token \\ http://localhost:8080/jenkins/configuration-as-code/export \\ > ${BACKUP_DIR}/config/jenkins-casc-${DATE}.yaml # 4. 备份 Job 配置 find ${JENKINS_HOME}/jobs -name config.xml \\ -exec cp --parents {} ${BACKUP_DIR}/jobs/ \\; # 5. 启动 Jenkins docker start jenkins-master sleep 30 # 6. 删除旧备份 find ${BACKUP_DIR} -name "*.tar.gz" -mtime +${RETENTION_DAYS} -delete echo "✅ Backup completed: ${DATE}" echo "Backup file: ${BACKUP_DIR}/jenkins_home_${DATE}.tar.gz"

12.3 监控与告警

# Prometheus 监控指标端点 curl http://admin:token@localhost:8080/jenkins/prometheus # 主要监控指标: • default_jvm_threads_current: JVM 当前线程数 • default_jvm_memory_used_bytes: JVM 内存使用量 • jenkins_queue_size_value: 构建队列长度 • jenkins_runs_success_total: 成功构建总数 • jenkins_runs_failure_total: 失败构建总数 • jenkins_builds_duration_milliseconds_summary: 构建耗时 # Grafana 告警规则示例 groups: - name: jenkins-alerts rules: - alert: JenkinsDown expr: up{job="jenkins"} == 0 for: 1m labels: severity: critical annotations: summary: "Jenkins 实例宕机" - alert: JenkinsQueueTooLong expr: jenkins_queue_size_value > 50 for: 5m labels: severity: warning annotations: summary: "Jenkins 构建队列过长" - alert: JenkinsHighFailureRate expr: rate(jenkins_runs_failure_total[1h]) / rate(jenkins_runs_success_total[1h]) > 0.3 for: 15m labels: severity: warning annotations: summary: "Jenkins 构建失败率过高"

12.4 性能优化建议

⚡ 性能优化技巧:
  • JVM 调优:根据负载调整-Xmx/-Xms 参数,使用 G1 GC
  • 并行构建:增加 Executor 数量,使用分布式 Agent
  • 缓存优化:配置 Maven/NPM 本地仓库缓存,使用 S3 存储构建产物
  • 数据库优化:对于大型实例,考虑将构建历史迁移到外部数据库
  • 插件精简:禁用不使用的插件,减少内存占用
  • 日志轮转:配置日志大小限制和保留策略,避免磁盘爆满