4. Jenkins Pipeline 基础:声明式 Pipeline 语法、Agent、Stage、Step、Post

Jenkins Pipeline 是实现持续交付流水线的核心能力。声明式 Pipeline(Declarative Pipeline)是 Jenkins 2.x 引入的一种结构化、更易读的 DSL(领域特定语言),它将流水线定义为一个代码块,通过预定义的语法结构(Agent、Stage、Step、Post)来描述整个构建、测试、部署流程。与脚本式 Pipeline 相比,声明式语法更强调“声明意图”,而非“编写逻辑”,非常适合团队标准化和可视化运维场景。

4.1 声明式 Pipeline 核心结构

一个完整的声明式 Pipeline 由 pipeline 块包裹,内部包含四个核心元素:Agent(指定执行环境)、Stage(定义阶段)、Step(执行具体操作)、Post(阶段后处理)。其基本骨架如下:

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                echo 'Building...'
            }
        }
        stage('Test') {
            steps {
                echo 'Testing...'
            }
        }
        stage('Deploy') {
            steps {
                echo 'Deploying...'
            }
        }
    }
    post {
        always {
            echo 'Pipeline finished.'
        }
    }
}
提示:声明式 Pipeline 的 pipeline 块是顶级块,所有指令必须位于其内部。Jenkins 在解析时会先校验语法结构,再按顺序执行 stages。

4.2 Agent:指定执行环境

agent 指令用于告诉 Jenkins 在哪个节点或容器中执行 Pipeline。它是流水线的“运行底座”,直接影响资源隔离和并发能力。常见的 agent 类型如下:

Agent 类型 语法示例 适用场景
any agent any 任意可用节点,适合简单任务
none agent none 全局不分配,需在每个 stage 单独指定
label agent { label 'linux' } 匹配特定标签的节点,如构建机、测试机
docker agent { docker 'maven:3.8' } 在指定 Docker 容器内运行,环境隔离
kubernetes agent { kubernetes { ... } } 动态在 K8s Pod 中运行,适合云原生
最佳实践:在事件触发 Runbook 联动场景中,建议使用 agent { label 'runner' } 或 agent { docker { image 'alpine:latest' } },确保每次触发都在干净环境中执行,避免依赖污染。

4.3 Stage:定义流水线阶段

stage 是 Pipeline 的逻辑分段单元,每个 stage 代表一个独立的任务阶段(如编译、测试、部署)。stages 块内可以包含多个 stage,它们按顺序执行。stage 支持嵌套,用于实现更细粒度的任务分组。

pipeline {
    agent any
    stages {
        stage('Prepare') {
            steps {
                echo 'Checkout code & install dependencies'
            }
        }
        stage('Quality Gate') {
            stages {
                stage('Unit Test') {
                    steps { echo 'Run unit tests' }
                }
                stage('Lint') {
                    steps { echo 'Run lint check' }
                }
            }
        }
        stage('Deploy to Staging') {
            steps {
                echo 'Deploy to staging environment'
            }
        }
    }
}
注意:嵌套 stage 时,父 stage 不能包含 steps,只能包含 stages 子块。这种结构常用于“阶段分组”,便于在 Blue Ocean 界面中折叠查看。

4.4 Step:执行具体操作

step 是 Pipeline 中最小的执行单元,每个 step 对应一个 Jenkins 插件提供的操作或一个 Shell 命令。在声明式 Pipeline 中,steps 块内可以包含多个 step,它们按顺序执行。常见的 step 包括:

  • sh:执行 Shell 命令,如 sh 'make build'
  • echo:打印日志信息
  • checkout:从 SCM 拉取代码
  • withCredentials:安全使用凭据
  • timeout:设置步骤超时时间
  • retry:失败时自动重试
stage('Build') {
    steps {
        timeout(time: 10, unit: 'MINUTES') {
            retry(3) {
                sh '''
                    npm install
                    npm run build
                '''
            }
        }
    }
}
提示:step 可以组合使用,如 timeout 包裹 retry,再包裹 sh,形成健壮的执行逻辑。这在 Runbook 联动中非常实用,避免因网络抖动导致流水线失败。

4.5 Post:阶段后处理

post 指令用于定义 Pipeline 或某个 stage 执行完成后的条件化操作。它支持多种条件块,用于处理成功、失败、不稳定等状态。post 可以定义在 pipeline 顶层(全局后处理)或 stage 内部(阶段后处理)。

条件块 触发时机 典型用途
always 无论结果如何都执行 清理临时文件、发送通知
success 仅当 Pipeline/stage 成功 触发后续部署、更新状态
failure 仅当 Pipeline/stage 失败 发送告警、回滚操作
unstable 测试结果不稳定(如单元测试失败) 标记构建为黄色、人工介入
changed 当前结果与上一次不同 状态变更通知
pipeline {
    agent any
    stages {
        stage('Deploy') {
            steps {
                sh 'deploy.sh'
            }
            post {
                success {
                    echo 'Deploy succeeded, send success notification'
                }
                failure {
                    echo 'Deploy failed, trigger rollback'
                    sh 'rollback.sh'
                }
                always {
                    cleanWs()  // 清理工作空间
                }
            }
        }
    }
    post {
        always {
            echo 'Pipeline completed'
        }
    }
}
关键点:post 块中的条件块按 always → changed → failure → success → unstable 的顺序执行。在 Runbook 联动中,建议在 failure 中调用 Webhook 或发送事件到事件总线,实现自动化故障响应。

4.6 声明式 Pipeline 完整结构图

下图展示了声明式 Pipeline 的完整语法结构及各元素之间的层级关系:

声明式 Pipeline 语法结构图 声明式 Pipeline 语法结构 pipeline {} agent { label } stages {} post {} stage('Build') stage('Test') steps { sh } always {} success {} failure {} 核心执行顺序 agent → stages (stage → steps) → post (always → changed → failure → success → unstable)

4.7 声明式 vs 脚本式 Pipeline 对比

理解声明式与脚本式 Pipeline 的差异,有助于在 Runbook 联动场景中选择合适的语法风格:

对比维度 声明式 Pipeline 脚本式 Pipeline
语法风格 结构化、声明意图 自由编程、Groovy 脚本
学习曲线 低,适合运维和测试人员 高,需要 Groovy 基础
可视化支持 Blue Ocean 原生支持 部分支持,复杂逻辑可能不兼容
错误处理 内置 post 条件块 需手动 try/catch/finally
代码复用 通过 Shared Libraries 通过函数、类、Shared Libraries
推荐场景 标准化 CI/CD、事件触发 Runbook 复杂逻辑、自定义 DSL
实战建议:在《事件触发Runbook联动Jenkins管道工程案例》中,推荐使用声明式 Pipeline 作为主语法。它结构清晰、易于审计,且 post 块能天然对接事件通知(如失败时触发 Webhook),减少自定义脚本的维护成本。

4.8 声明式 Pipeline 执行流程

下图展示了声明式 Pipeline 从触发到完成的完整执行流程,突出 Agent、Stage、Step、Post 的协作关系:

声明式 Pipeline 执行流程图 声明式 Pipeline 执行流程 Pipeline 触发 Agent 分配执行环境 Stage 顺序执行 Stage 1 Stage 2 Stage 3 Post 条件处理 Pipeline 完成
流程说明:Pipeline 触发后,Jenkins 首先根据 agent 指令分配执行环境(节点或容器),然后按 stages 块中定义的 stage 顺序依次执行,每个 stage 内部执行 steps 中的具体操作。所有 stage 执行完毕后,进入 post 块,根据最终状态(success/failure/unstable)执行对应的后处理逻辑,最后 Pipeline 完成。