部署(deploy)和发布(release)是两个独立事件。你可以随时把新版本放到集群里,但只有开始把真实流量路由过去,才叫发布。渐进式交付就是把发布风险摊薄到时间轴上的过程。
核心区分
很多团队把”上线”当作一个瞬间事件:合并代码、构建镜像、替换 Pod。但渐进式交付的前提是承认一个事实——代码在 staging 通过测试,不等于在生产环境对用户安全。真正的风险不在部署瞬间,而在”100% 流量突然切换到未经生产验证的版本”。
渐进式交付的本质是:用负载均衡器的权重和路由规则,把发布变成可观测、可回滚、可逐步放量的连续过程。
三种核心模式
金丝雀发布(Canary)
最常用也最灵活。先把新版本部署到集群,初始权重设为 0;然后缓慢上调(如 1% → 5% → 25% → 50% → 100%),每阶段观察错误率、延迟、业务指标。
关键设计决策:
- 如何选择金丝雀用户?可以按用户 ID 哈希(确保同一用户始终落在同一版本)、按地域(先低风险区域)、按请求特征(内部员工先行)
- 回滚条件是什么?需要预定义 SLO 阈值,如错误率 > 0.1%、P99 延迟 > 200ms、自定义业务指标异常
- 阶段停留多久?取决于观测置信度,通常至少需要几个完整的业务周期
蓝绿部署(Blue-Green)
同时运行两个完整环境(蓝=当前,绿=新版本),通过负载均衡器一次性或渐进式切换流量。与金丝雀的区别在于:蓝绿是环境级切换,金丝雀是流量级渐变。
蓝绿的优势是回滚极快(切回蓝环境即可),劣势是资源翻倍。它更适合:
- 数据库 schema 不兼容的发布(需要双环境并行)
- 需要完整功能验证才能暴露给用户的场景
- 资源成本可接受的关键业务系统
流量镜像(Shadow/Mirroring)
把生产请求复制到影子集群,但不返回响应给用户。新版本在镜像流量上产生日志、指标、甚至副作用(需要确保影子环境不写入共享状态)。
镜像 vs 金丝雀的关键差异:
- 镜像:零用户影响,但只能验证”处理逻辑”,不能验证”用户感知”(如响应时间是否可接受、UI 渲染是否正确)
- 金丝雀:真实用户影响,能验证完整用户体验,但有风险
最佳实践是组合使用:先用镜像做无风险验证,再用金丝雀做真实切流。
负载均衡器作为发布基础设施
渐进式交付的实现依赖负载均衡器的两项能力:
- 动态权重调整:WRR 权重从 0 到 100 的渐进过程
- 基于请求特征的路由:header、cookie、path、用户属性等
在 Traefik 中,这通过 Service 抽象实现:定义多个 backend 版本,用 weighted service 分配流量,用 header-based router 做用户隔离。
在 Envoy 中,通过 RDS(路由发现服务)动态更新路由权重,结合异常检测自动驱逐有问题的实例。
风险与常见陷阱
状态共享问题
如果蓝绿两个环境共享数据库或缓存,新版本的写入可能破坏旧版本的读取假设。解决方案:
- 发布前确保 schema 向前兼容
- 使用独立的数据库副本(成本高)
- 金丝雀阶段限制为有读无写的用户群
观测不足
很多团队的金丝雀发布只靠”服务是否健康”判断,忽略了:
- 长尾延迟变化(P99 可能翻倍而均值不变)
- 业务指标(转化率、订单完成率)
- 下游服务压力(新版本可能更”健谈”,导致依赖服务过载)
过早宣布成功
“5% 流量运行 30 分钟无异常”不等于”100% 流量安全”。统计上不显著的样本无法发现低频错误。金丝雀阶段需要足够的流量和时长,才能获得有意义的置信度。
实践原则
- 发布是负载均衡器的一等职责,不是 CI/CD 流水线的附属功能。你的 ingress/edge proxy 应该支持动态权重调整和请求级路由。
- 镜像和金丝雀不是互斥选项,而是风险梯度上的两个点:镜像 → 内部金丝雀 → 外部金丝雀 → 全量。
- 渐进式交付的终极目标是让发布变得无聊——不是因为没有风险,而是因为风险被系统化地控制在可接受范围内。
来源:advanced-load-balancing-traefik
相关页面:load-balancing-strategies · service-mesh · traefik · envoy