本节摘要:部署管道(Deployment Pipeline)将 CI 产出的制品依次部署到 dev、test、staging 等环境,每级运行更全面的测试。本节用 Jenkins Declarative Pipeline 的
input审批、GitLabenvironment与 GitHub Environments 实现制品晋级而不 rebuild。
阅读完本节,你应当能够:
pipeline { agent any environment { IMAGE = "registry.corp/pay:${env.GIT_COMMIT}" } stages { stage('CI') { steps { sh 'mvn -B verify && docker build -t $IMAGE .' } } stage('Deploy Dev') { steps { sh 'kubectl -n dev set image deploy/pay pay=$IMAGE' } } stage('Deploy Staging') { steps { sh 'kubectl -n staging set image deploy/pay pay=$IMAGE' } } stage('Deploy Prod') { input { message 'Deploy to production?' ok 'Deploy' } steps { sh 'kubectl -n prod set image deploy/pay pay=$IMAGE' } } } }
同一 $IMAGE digest 从 dev 走到 prod——没有第二次 docker build。

jobs: deploy-staging: runs-on: ubuntu-latest environment: staging steps: - run: helm upgrade myapp ./chart --set image.tag=${{ github.sha }} deploy-prod: needs: deploy-staging runs-on: ubuntu-latest environment: name: production url: https://app.example.com steps: - run: helm upgrade myapp ./chart --set image.tag=${{ github.sha }}
Settings → Environments → production → Required reviewers 两人 approve 才执行 deploy-prod job。
deploy-staging: stage: deploy environment: { name: staging, url: https://stg.example.com } script: [kubectl apply -f k8s/staging/] deploy-prod: stage: deploy environment: { name: production } when: manual script: [kubectl apply -f k8s/prod/] needs: [deploy-staging, e2e-test]
when: manual 在 GitLab UI 显示「Play」按钮——CD 的典型形态。
| 模式 | 做法 | 优点 |
|---|---|---|
| Docker tag promote | docker pull + retag + push prod |
简单 |
| Helm chart version | chart 不变,只改 values.image.tag | K8s 原生 |
| Spinnaker pipeline | 自动 bake manifest | 多云 |
| 策略 | 行为 | 适用 |
|---|---|---|
| fail fast | 首错即停 | 默认 |
| unstable | 警告继续 | 非关键 E2E |
| retry | 网络 flake 重试 2 次 | 外部依赖 |
⚠️ 常见坑:staging 通过但 prod 用了不同镜像 tag——审计时对不上 SHA,事故无法 bisect。
💡 关键直觉:管道是单向阀——制品只能 forward promote,禁止 prod 镜像 tag 回写到 dev 重新部署(除非 hotfix 流程)。
Spinnaker 的 pipeline 阶段:Trigger → Bake → Deploy → Scale → Manual Judgment。Judgment 即 CD 审批 gate,Bake 将 Docker 镜像转为 K8s manifest——适合 AWS+GCP 混合云。
.jenkins/Jenkinsfile、.gitlab-ci.yml、.github/workflows/ 与业务代码同 PR 评审——Ops 改 prod gate 必须过 code review,满足 SOX 合规。
// vars/standardPipeline.groovy def call(Map cfg) { pipeline { agent any stages { stage('Build') { steps { sh cfg.buildCmd } } stage('Test') { steps { sh cfg.testCmd } } stage('Deploy') { when { branch 'main' } steps { sh cfg.deployCmd } } } } }
各 repo Jenkinsfile 仅一行 @Library('corp-lib') _; standardPipeline buildCmd: 'mvn verify'——改 library 即全局更新 pipeline 逻辑。
stage('Test') { parallel { stage('Unit') { steps { sh 'pytest unit' } } stage('Lint') { steps { sh 'ruff check .' } } stage('SAST') { steps { sh 'semgrep --config auto' } } } }
三 job 并行,wall time = max(各 job),非 sum——但占 3 倍 runner 并发配额。
Dev 自动 → Staging 自动 → Prod manual 是金融常见模式。Spinnaker 的 Manual Judgment 支持多人会签;GitHub Environment 支持 required reviewers 列表——审计日志谁点了 approve。
| 分支 | 通知渠道 | 响应 SLA |
|---|---|---|
| main 红 | PagerDuty + Slack | 15 min |
| PR 红 | Slack PR thread | 下一工作日 |
| nightly 红 | 邮件 digest | 24 h |
避免所有失败都 pager——on-call burnout 后大家忽略告警。
when: manual 等价下一节 3.2 在 staging 跑 E2E、性能与安全测试。
部署管道设计时要回答四个问题:制品在哪里保存、环境之间如何传递制品、每个 stage 的验证标准是什么、失败时如何阻断下游。制品传递最常见的是容器镜像仓库(Harbor/ECR)与二进制仓库(Nexus),关键原则是「同一 digest 全链路复用」——staging 验证过的那份制品,必须与 prod 部署的是同一份。为此要在管道中显式记录 image digest 并传参,而不是依赖再次 build。
环境晋级的设计上,dev 环境可以快而糙,staging 必须慢而全。每个 stage 的验证标准要写进管道配置:dev 只跑 smoke,staging 跑完整 E2E 与性能,prod 前跑审批。门禁的严格程度应当与环境风险成正比,同时保证「任何环境失败都能阻断后续环境」——这是 fail fast 的核心,也是审计时能讲清楚的部署决策链。