第60章|跨平台对照 2:同一个 CD 问题在不同平台怎么做(环境/审批/回滚)

发布治理就像交通灯:环境是道路分区,审批是通行许可,回滚是安全刹车。 不同平台的写法不同:GitHub 用 Environments + 审批;GitLab 用 manual jobs; Jenkins 用 input;GitOps 则把审批与回滚嵌入同步策略。 但核心模型只有一个:用证据决定推进,用可解释的路径处理失败。

Environments

dev → stage → prod

  • scoped targets
  • secrets & config
  • sync windows
Approvals

gates with evidence

  • required reviewers
  • time limits
  • audit trail
Rollback

undo with confidence

  • revert / previous revision
  • traffic back
  • post-rollback verify

1. 治理共性模型:推进需要证据,失败需要可解释路径

跨平台对照的关键不是“哪个工具更花哨”,而是抽象出三个共性对象: 环境(Environment):你把发布放到哪里;审批(Approval/Gate):你凭什么允许放行; 回滚(Rollback):如果失败了,你如何回到已知安全状态。 最好把它们写成同一张图,在任何平台里都能“找到对应元素”。

Governance lane map: environment → approval gate → rollback lane dev fast deploy low blast radius evidence: tests stage require gates Approval Gate required reviewers + time limit prod controlled promotion Rollback Lane revert / previous revision / traffic back Audit evidence is a first-class artifact who approved, what revision, when it happened
图 1:无论工具是什么,治理都能落到同一条“环境→审批→回滚”链路。

2. 环境(Environment)怎么跨平台表达?

环境不是“一个字符串”。在工程里它通常绑定: 部署目标(k8s namespace / cluster / VM group)、 凭据与密钥(secrets、config 注入)、 策略与窗口(sync windows、资源配额、审批要求)。 因此跨平台迁移时,先确定你的环境边界长什么样,再去看工具如何映射。

Platform Environment concept Typical binding
GitHub Actions environments URL, secrets, required reviewers
GitLab CI environments: in job name + URL, start/stop actions
Jenkins Stages + credentials clusters, namespaces, locked credentials
GitOps (Argo/Flux) app/projects or overlay targets destination cluster/ns, sync policies

2.1 GitHub Actions:用 Environments 把目标绑定起来

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment:
      name: production
      url: https://prod.example.com
    steps:
      - uses: actions/checkout@v4
      - run: echo "Deploy to production"

2.2 GitLab CI:用 environments 把部署名与 URL 固化

deploy_prod:
  stage: deploy
  environment:
    name: production
    url: https://prod.example.com
  script:
    - echo "Deploy to production"

2.3 Jenkins:环境用 stage + 凭据组表达

pipeline {
  agent any
  stages {
    stage('Deploy to Prod') {
      steps {
        withCredentials([string(credentialsId: 'kubeconfig-prod', variable: 'KUBECONFIG')]) {
          sh 'echo "Deploy to prod"'
        }
      }
    }
  }
}
底线:环境绑定要让“凭据与目标”不可混用。否则审批再强也会在 deploy step 里被意外绕开。

3. 审批(Approvals/Gates):如何跨平台做“证据驱动的放行”

审批的正确姿势不是“等人点按钮”,而是把它设计成一个 可验证的决策点: 触发条件(例如测试通过、SLO 达标)、审批对象(谁可审批)、时间限制(避免长时间悬挂)、以及审批理由/证据(audit)。 不同平台实现略有差异,但都能抽象成 gate:input → decision → record

Approval Gate: evidence in, decision out, immutable record Evidence Input tests passed SLO / metrics OK diff reviewed input snapshot Decision approve / deny / timeout Gate rules who + what + when Record who approved revision pinned reason & timestamp audit artifact
图 2:审批要变成“可追溯的决策”,否则只是等待。

3.1 GitHub Actions:Required reviewers(通过 Environments 配置)

# This is configuration in GitHub UI for the environment's required reviewers.
# The workflow references it via environment.name.
environment:
  name: production

3.2 GitLab CI:用 manual job 做 gate

deploy_prod:
  stage: deploy
  when: manual
  allow_failure: false
  script:
    - echo "Deploy to prod after manual gate"

3.3 Jenkins:用 input step + timeout

stage('Promote to Prod') {
  steps {
    timeout(time: 30, unit: 'MINUTES') {
      input message: 'Approve production deployment?', ok: 'Deploy'
    }
    sh 'echo "Deploy to prod"'
  }
}

3.4 GitOps:用 sync policy / manual sync 实现 gate

# Example: Argo CD Application with automated disabled (manual sync gate)
spec:
  syncPolicy:
    automated: null
    syncOptions:
      - CreateNamespace=true
底线:所有 gate 都要“绑定一个具体 revision”。否则你审批的是旧版本还是新版本会变得不可解释。

4. 回滚(Rollback):跨平台统一成“回到已知安全状态”

回滚必须解决两个问题:回到什么(上一版 revision / 上一个镜像 tag / traffic 权重拉回)、以及回滚是否安全(依赖兼容:DB 迁移是否可逆、配置是否同步、以及回滚后是否复核)。 最好的工程做法是把回滚也当成 stage:回滚后再跑一次最小验证(smoke checks 或指标门禁)。

Rollback options unified: revert revision or shift traffic back Git revert revert commit / tag restores manifest truth Traffic back setWeight down canary PD-style rollback metrics re-checked Previous revision rollback to app history sync to known good Rollback must be followed by verify smoke checks / metrics gates
图 3:回滚方式多,但回到“已知安全状态”与复核是共同底线。

4.1 GitHub/GitLab/Jenkins:re-deploy previous artifact

# Principle: pin artifact version (image tag / build id) then redeploy.
export IMAGE_TAG="v1.2.2"
kubectl set image deployment/payments payments=${IMAGE_TAG}

4.2 GitOps:回滚就是把 Application 指向历史 revision

# Example (Argo CD CLI illustrative)
argocd app history payments-api
argocd app rollback payments-api <revision-id>
底线:回滚要考虑不可逆副作用(DB migrations、一次性消息)。把迁移策略与回滚策略在治理层一起设计。

5. 落地建议:把治理变成“可审计的流水线证据”

为了让跨平台经验真正迁移,建议你在治理层定义统一的证据字段: environment targetapproved byrevision pinnedgate reasonrollback methodverify outcome。 不管你用的是 Jenkins 的输入、GitLab 的 manual job、还是 Argo CD 的 sync history,这些字段都应该能在日志/事件里找到。

6. 本章清单

  1. 能抽象出 CD 治理的共性模型:environment / approval gate / rollback lane。
  2. 能在 GitHub Actions、GitLab CI、Jenkins、GitOps 中分别找到“环境绑定”的对应物。
  3. 能用 gate 设计 evidence-driven approval,并确保 gate 绑定到具体 revision。
  4. 能用统一思路描述回滚:revert / previous revision / traffic back,并强调 post-rollback verify。
  5. 能制定不可逆副作用的回滚边界(尤其 DB migrations)并在 runbook 里写清。
  6. 预告下一章:把这些治理与可观测性/错误预算联动,让自动化止损更可信。
← 上一章:跨平台对照 1 下一章:可观测性 1 →