3. Jenkins基础架构

Jenkins 作为 CI/CD 流水线的核心编排引擎,其架构设计直接决定了系统的扩展性、可用性与维护成本。本章深入剖析 Jenkins Master/Agent 分布式架构、插件生态体系以及流水线定义语言(Jenkinsfile)的两种范式,为后续模板化开发奠定理论基础。

3.1 Jenkins Master/Agent 分布式架构

Jenkins 采用 Master/Agent 架构实现任务分发与并行构建。Master 节点负责调度、监控与 Web UI 服务,Agent 节点负责执行具体的构建任务。这种分离设计有效避免了单点瓶颈,支持异构环境(Linux、Windows、macOS、容器)下的混合构建。

架构核心原则: Master 不执行构建任务,仅管理 Job 配置、触发流水线、分发任务到 Agent 并收集结果。Agent 可以动态创建(如 Kubernetes Pod)或静态注册(如固定服务器)。
Jenkins Master/Agent 分布式架构 Jenkins Master 调度 · 监控 · Web UI Agent 1 (Linux) 静态节点 Agent 2 (Windows) 静态节点 Agent 3 (K8s Pod) 动态节点 架构优势 水平扩展 · 异构支持 · 故障隔离 · 资源弹性 Master 高可用可通过外部负载均衡 + 共享存储实现

3.2 插件生态体系

Jenkins 拥有超过 1800 个社区插件,覆盖 SCM 集成、构建工具、测试报告、部署、通知、安全等全生命周期。插件是 Jenkins 功能扩展的核心机制,但过度安装会导致性能下降与版本冲突。

插件类别 代表插件 核心能力
SCM 集成 Git Plugin、GitHub Integration 代码拉取、分支扫描、Webhook 触发
流水线 Pipeline、Pipeline: Stage View 声明式/脚本式流水线定义与可视化
构建工具 Maven Integration、Gradle Plugin 编译、测试、打包
容器/K8s Kubernetes Plugin、Docker Pipeline 动态 Agent 创建、容器化构建
通知/报告 Email Extension、Slack Notification 构建结果推送、质量报告
最佳实践: 采用“最小必要插件集”原则,仅安装流水线运行必需的插件。使用 Jenkins Plugin Manager 定期检查插件更新与兼容性,避免版本冲突。

3.3 Jenkinsfile:声明式 vs 脚本式

Jenkinsfile 是定义 CI/CD 流水线的文本文件,存储在 SCM 仓库中,实现“流水线即代码”。Jenkins 支持两种语法范式:声明式(Declarative) 和 脚本式(Scripted)。两者在结构、灵活性和适用场景上存在显著差异。

对比维度 声明式(Declarative) 脚本式(Scripted)
语法风格 结构化、预定义块(pipeline / stages / steps) 自由 Groovy 脚本,node / stage 块
学习曲线 低,适合初学者与标准化场景 高,需要 Groovy 编程基础
灵活性 受限,但覆盖 90% 常见场景 极高,可嵌入复杂逻辑与异常处理
错误处理 内置 post / retry / timeout 块 需手动 try-catch-finally
可视化 原生支持 Stage View 与 Blue Ocean 部分支持,复杂逻辑可能影响展示
推荐场景 标准 CI/CD 流水线、多分支项目 复杂编排、动态并行、自定义扩展

3.4 声明式 Jenkinsfile 示例

pipeline {
    agent any

    stages {
        stage('Checkout') {
            steps {
                git branch: 'main',
                    url: 'https://github.com/example/my-app.git'
            }
        }
        stage('Build') {
            steps {
                sh 'mvn clean compile'
            }
        }
        stage('Test') {
            steps {
                sh 'mvn test'
            }
            post {
                always {
                    junit 'target/surefire-reports/*.xml'
                }
            }
        }
        stage('Deploy') {
            when {
                branch 'main'
            }
            steps {
                sh 'mvn deploy'
            }
        }
    }
    post {
        failure {
            emailext(
                subject: "Pipeline Failed: ${env.JOB_NAME}",
                body: "Build ${env.BUILD_NUMBER} failed.",
                to: 'team@example.com'
            )
        }
    }
}

3.5 脚本式 Jenkinsfile 示例

node('linux-agent') {
    try {
        stage('Checkout') {
            checkout scm
        }
        stage('Build') {
            sh 'mvn clean compile'
        }
        stage('Test') {
            sh 'mvn test'
            junit 'target/surefire-reports/*.xml'
        }
        stage('Deploy') {
            if (env.BRANCH_NAME == 'main') {
                sh 'mvn deploy'
            }
        }
    } catch (Exception e) {
        currentBuild.result = 'FAILURE'
        emailext(
            subject: "Pipeline Failed: ${env.JOB_NAME}",
            body: "Error: ${e.message}",
            to: 'team@example.com'
        )
        throw e
    } finally {
        cleanWs()
    }
}
注意: 脚本式流水线中的 node 块会占用 Agent 执行槽,长时间空闲可能导致资源浪费。建议在声明式流水线中使用 agent 指令配合 when 条件控制资源分配。

3.6 两种范式选择策略

在实际项目中,推荐以 声明式为主、脚本式为辅 的策略:

  • 标准化流水线(构建、测试、部署)使用声明式,保证可读性与可维护性。
  • 复杂业务逻辑(动态并行、条件分支、自定义函数)通过 script 块嵌入 Groovy 代码。
  • 共享库(Shared Library)封装通用逻辑,两种范式均可调用。
Jenkinsfile 范式选择决策流程 流水线需求分析 标准流程 声明式 + 少量 script 块 复杂编排 脚本式 + 共享库 推荐:90% 场景使用声明式,10% 复杂逻辑通过 script 块或共享库实现

3.7 本章小结

  • Master/Agent 架构 是 Jenkins 分布式构建的基础,Master 负责调度,Agent 负责执行,支持静态与动态节点。
  • 插件生态 提供了丰富的扩展能力,但需遵循最小必要原则,避免版本冲突。
  • Jenkinsfile 实现了流水线即代码,声明式适合标准化场景,脚本式适合复杂编排。
  • 实际项目中应优先使用声明式,通过 script 块和共享库弥补灵活性不足。