灰度发布基础概念

灰度发布基础概念

什么是灰度发布

灰度发布(Gray Release)是一种渐进式的软件发布策略,通过控制新版本的流量占比,将风险降到最低。

为什么需要灰度发布

传统发布的问题

一次性全量发布
     ↓
新版本有 Bug
     ↓
影响所有用户 ❌

灰度发布的优势

渐进式发布
     ↓
新版本有问题,只影响少量用户
     ↓
快速发现 → 快速回滚 ✅

发布策略对比

策略 说明 风险 回滚速度 资源成本
全量发布 一次性更新所有实例
滚动发布 逐个实例更新
金丝雀发布 小流量验证
蓝绿部署 两套环境切换 极快
A/B 测试 按用户分流

金丝雀发布原理

名称由来

金丝雀(Canary)源自矿工用金丝雀检测矿井中的有毒气体:

  • 金丝雀对有毒气体敏感,先倒下
  • 矿工看到金丝雀异常,立即撤离
  • 类比:金丝雀版本先验证,发现问题快速回滚

核心思想

┌─────────────────────────────────┐
│      100% 用户流量              │
└──────────┬──────────────────────┘
           │
           ▼
    ┌──────────────┐
    │   Service    │
    └──────┬───────┘
           │
      ┌────┴────┐
      │         │
   90% │         │ 10%
      ▼         ▼
┌──────────┐ ┌──────────┐
│ 稳定版本  │ │ 金丝雀版本│
│ v1.0     │ │ v2.0     │
│ 9 Pod    │ │ 1 Pod    │
└──────────┘ └──────────┘

关键步骤

  1. 部署少量新版本实例(金丝雀)
  2. 导入少量流量(1-10%)
  3. 观察指标(错误率、延迟、业务指标)
  4. 如果正常 → 逐步扩大流量
  5. 如果异常 → 立即回滚

流量分配方式

1. 基于副本数(最简单)

稳定版本: 9 Pod
金丝雀: 1 Pod
总共: 10 Pod

流量分配: 90% vs 10%

优点

  • 实现简单
  • 基于 Kubernetes Service 负载均衡

缺点

  • 粒度粗(受 Pod 数量限制)
  • 无法精确控制百分比

2. 基于权重(更精确)

使用 Ingress 或服务网格控制流量权重:

稳定版本: weight=90
金丝雀版本: weight=10

优点

  • 精确控制百分比
  • 可以做到 1% 甚至更小

缺点

  • 需要 Ingress Controller 或服务网格支持

3. 基于规则(最灵活)

根据请求特征路由:

条件路由:
- Header "X-Canary: true" → 金丝雀
- Cookie "beta-user=true" → 金丝雀
- IP 地址段 → 金丝雀
- User-Agent → 金丝雀

适用场景

  • 内部员工先体验
  • Beta 用户测试
  • 特定地区灰度

蓝绿部署原理

基本概念

蓝绿部署维护两套完全相同的生产环境:

            Service
               │
          ┌────┴────┐
          │ Selector │
          └────┬─────┘
               │
        ┌──────┴──────┐
        │             │
    version=blue  version=green
        │             │
   ┌────▼────┐   ┌───▼─────┐
   │ Blue    │   │ Green   │
   │ v1.0    │   │ v2.0    │
   │ 运行中  │   │ 准备中  │
   └─────────┘   └─────────┘

切换过程

  1. 蓝色环境:当前生产环境(v1.0)
  2. 绿色环境:部署新版本(v2.0)
  3. 测试绿色环境:独立验证
  4. 切换流量:Service Selector 指向 Green
  5. 观察监控:验证切换成功
  6. 保留蓝色环境:作为回滚备份

优势

切换快速:只需修改 Service Selector,秒级切换
回滚简单:切回蓝色环境即可
完整测试:绿色环境可以充分测试
零停机:用户无感知

劣势

资源消耗大:需要双倍资源
数据库问题:共享数据库可能有版本兼容问题
成本高:适合重要系统

A/B 测试

概念

A/B 测试根据用户特征将流量分配到不同版本,用于功能验证和对比分析。

用户流量
   │
   ├─ 用户 ID % 2 == 0 → 版本 A
   └─ 用户 ID % 2 == 1 → 版本 B

与金丝雀的区别

维度 金丝雀发布 A/B 测试
目标 验证新版本稳定性 对比两个版本效果
持续时间 短期(小时-天) 长期(周-月)
流量分配 随机 按特征分组
评估指标 技术指标(错误率) 业务指标(转化率)
结果 选择稳定版本 选择效果更好的版本

适用场景

金丝雀发布

  • ✅ 验证新版本是否有 Bug
  • ✅ 减少发布风险
  • ✅ 快速回滚

A/B 测试

  • ✅ 对比不同 UI 设计
  • ✅ 测试新功能用户接受度
  • ✅ 优化转化率

滚动更新

Kubernetes 默认的更新策略:

┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐
│ v1  │ │ v1  │ │ v1  │ │ v1  │
└─────┘ └─────┘ └─────┘ └─────┘
   ↓
┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐
│ v2  │ │ v1  │ │ v1  │ │ v1  │
└─────┘ └─────┘ └─────┘ └─────┘
   ↓
┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐
│ v2  │ │ v2  │ │ v1  │ │ v1  │
└─────┘ └─────┘ └─────┘ └─────┘
   ↓
┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐
│ v2  │ │ v2  │ │ v2  │ │ v2  │
└─────┘ └─────┘ └─────┘ └─────┘

配置

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1   # 最多 1 个 Pod 不可用
      maxSurge: 1         # 最多多出 1 个 Pod

特点

  • ✅ 资源利用率高
  • ✅ 实现简单
  • ❌ 回滚慢(需要反向滚动)
  • ❌ 新旧版本会同时存在

发布策略选择指南

按应用规模

小型应用(< 10 Pod):

  • 推荐:Deployment 滚动更新
  • 原因:简单、资源效率高
  • 注意:做好健康检查

中型应用(10-100 Pod):

  • 推荐:基于 Deployment 的金丝雀
  • 原因:风险可控、实现不复杂
  • 工具:手动或简单脚本

大型应用(> 100 Pod):

  • 推荐:Flagger 或 Istio 自动化金丝雀
  • 原因:自动化、可观测性强
  • 工具:Flagger + Prometheus

按业务特点

核心业务系统

  • 推荐:蓝绿部署
  • 原因:回滚最快、影响最小
  • 成本:资源翻倍可接受

互联网应用

  • 推荐:金丝雀 + A/B 测试
  • 原因:灵活控制、数据驱动
  • 工具:Istio / Linkerd

批处理任务

  • 推荐:直接全量更新
  • 原因:非实时、容错性强

按团队成熟度

初级团队

  • Kubernetes Deployment 滚动更新
  • 手动金丝雀(调整副本数)

中级团队

  • Ingress 流量控制
  • 自动化监控告警

高级团队

  • Flagger / Argo Rollouts
  • 完整的可观测性平台
  • GitOps 流程

总结

核心要点

  1. 渐进式发布是降低风险的关键
  2. 监控指标决定是否继续发布
  3. 快速回滚是最后的保险
  4. 自动化减少人为错误

实施建议

第一阶段

  • 使用 Deployment 滚动更新
  • 完善健康检查
  • 建立监控告警

第二阶段

  • 实现简单金丝雀(手动调整副本)
  • 使用 Ingress 流量控制
  • 记录发布流程

第三阶段

  • 引入 Flagger 自动化
  • 集成 Prometheus 监控
  • 实现自动回滚

第四阶段

  • 服务网格(Istio)
  • 完整的 GitOps
  • A/B 测试能力

下一节将详细讲解基于 Deployment 的金丝雀发布实现。