6.3. 发布与变更:灰度、特性开关与回滚

发布不是「把镜像推上去」,而是一次受控的变更:谁批准、影响哪些用户、失败如何回滚、数据库能否兼容。把发布当成工程问题,而不是勇气问题。

层级:

L4 · 实战

难度:

进阶

预计:

45 分钟

前置:

Deployment、GitOps、可观测性

6.3.1. 发布单元

一次发布至少包含四类变更:

变更

例子

回滚方式

应用

新镜像

切回旧 digest

配置

ConfigMap/Secret/values

回滚 Git commit

数据库

加字段/索引/迁移

兼容性设计 + 反向迁移

基础设施

节点池/网络/CRD

基础设施回滚计划

只回滚应用、不回滚数据库,是最常见的发布事故来源。数据库迁移必须遵循 expand/contract:先加新字段(expand),双写/回填,再切读,最后删旧字段(contract)。

6.3.2. 环境晋级

dev → staging → prod
  • dev:每次合并自动部署,快速反馈。

  • staging:与生产同构,跑 E2E、性能、安全扫描。

  • prod:人工审批或自动策略(SLO 达标 + 变更窗口)。

环境差异用 Helm values/Kustomize overlay 管理,镜像 digest 保持一致。

6.3.3. 渐进式发布

  • 金丝雀:5% → 25% → 50% → 100%,每步看错误率/延迟。

  • 蓝绿:两套环境,切流量;回滚快,但资源翻倍。

  • 特性开关:代码已部署,功能按用户/租户开启;适合长期灰度。

  • 影子流量:复制生产流量到新版本,不影响用户;适合高风险变更。

rollout-canary.yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: demoapp
spec:
  replicas: 10
  strategy:
    canary:
      steps:
        - setWeight: 10
        - pause: {duration: 5m}
        - setWeight: 50
        - pause: {duration: 5m}
        - setWeight: 100

没有指标分析的灰度只是「慢一点的全量发布」。至少接错误率与 P95 延迟两个指标。

6.3.4. 数据库迁移

  1. Expand:加字段/表,旧代码仍可运行。

  2. Dual write:新旧字段同时写,校验一致性。

  3. Backfill:批量回填历史数据。

  4. Switch read:读新字段,观察。

  5. Contract:删除旧字段/代码。

迁移脚本要幂等、可重入;大表加索引用在线 DDL 或分批,避免锁表。回滚不是「执行反向 SQL」这么简单,必须提前演练。

6.3.5. 变更管理

  • 变更单/PR 记录:改什么、为什么、影响面、回滚步骤、验证指标。

  • 冻结窗口:大促、财务结账、重大节假日避免高风险变更。

  • 发布负责人(Release Manager)与值班(On-call)要分离,避免既发布又救火。

  • 发布后 30 分钟是观察期,不要立刻下班。

6.3.6. 实验:一次可回滚的发布

kubectl argo rollouts set image demoapp demoapp=ghcr.io/example/demoapp:v2.0
kubectl argo rollouts get rollout demoapp --watch
# 如果错误率上升
kubectl argo rollouts abort demoapp
kubectl argo rollouts undo demoapp

数据库实验:先加 email_v2 字段,双写并回填,再切读,最后删旧字段。每一步都能独立回滚。

6.3.7. 验证清单

  • 发布有明确的变更说明与回滚步骤。

  • 镜像使用 digest,配置在 Git 中。

  • 灰度有指标分析,失败自动/手动 abort。

  • 数据库迁移遵循 expand/contract,回滚已演练。

  • 发布后观察期与值班安排明确。

  • 变更窗口避开业务高峰。

6.3.8. 排错表

现象

原因

处理

灰度卡住

没有 promote/分析失败

argo rollouts promote 或查 AnalysisRun

回滚后仍报错

数据库 schema 不兼容

用 expand/contract,先回滚应用再处理数据

配置未生效

ConfigMap 未更新/Pod 未重启

rollout restart,检查挂载

只有部分用户异常

灰度规则/缓存/租户

查 header/用户分群与缓存键

发布后延迟升高

新版本资源不足/连接池

看指标,调 resources/HPA

6.3.9. 进阶挑战

  1. 用 Argo Rollouts + Prometheus 做自动金丝雀。

  2. 用特性开关控制一个新功能,按租户灰度。

  3. 设计一次「加字段 + 双写 + 回填 + 切读 + 删字段」的迁移。

  4. 写一份发布检查表,覆盖应用、配置、数据库、基础设施。

6.3.10. 小结

  • 发布是受控变更,不是一次 kubectl apply。

  • 应用、配置、数据库、基础设施要分别设计回滚。

  • 灰度必须绑定指标,否则只是延迟切换。

  • 数据库迁移用 expand/contract,先兼容再清理。

6.3.11. 延伸阅读