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 块是顶级块,所有指令必须位于其内部。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 中运行,适合云原生 |
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'
}
}
}
}
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
'''
}
}
}
}
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'
}
}
}
always → changed → failure → success → unstable 的顺序执行。在 Runbook 联动中,建议在 failure 中调用 Webhook 或发送事件到事件总线,实现自动化故障响应。
4.6 声明式 Pipeline 完整结构图
下图展示了声明式 Pipeline 的完整语法结构及各元素之间的层级关系:
4.7 声明式 vs 脚本式 Pipeline 对比
理解声明式与脚本式 Pipeline 的差异,有助于在 Runbook 联动场景中选择合适的语法风格:
| 对比维度 | 声明式 Pipeline | 脚本式 Pipeline |
|---|---|---|
| 语法风格 | 结构化、声明意图 | 自由编程、Groovy 脚本 |
| 学习曲线 | 低,适合运维和测试人员 | 高,需要 Groovy 基础 |
| 可视化支持 | Blue Ocean 原生支持 | 部分支持,复杂逻辑可能不兼容 |
| 错误处理 | 内置 post 条件块 | 需手动 try/catch/finally |
| 代码复用 | 通过 Shared Libraries | 通过函数、类、Shared Libraries |
| 推荐场景 | 标准化 CI/CD、事件触发 Runbook | 复杂逻辑、自定义 DSL |
4.8 声明式 Pipeline 执行流程
下图展示了声明式 Pipeline 从触发到完成的完整执行流程,突出 Agent、Stage、Step、Post 的协作关系: