服务器与大带宽专家 · 持牌IDC/CDN/ISP服务商
简米科技官网JIANMI TECH
资讯 2026-08-18 简米科技 3,460 字 8 分钟阅读

用容器做灰度发布先放一小部分流量验证新版本

导读先让新版本接一小部分真实流量,观察没问题再全量放开;出问题就立刻把流量切回旧版本,具体落地方式取决于你的技术栈,Kubernetes环境下最常见的方案是用Ingress流量权重或Service Mesh按比例分流,为什么容器环境做灰度发布比传统虚拟机更顺手传统虚拟机时代做灰度发布,要准备一套完整的新环境,改负载……

先让新版本接一小部分真实流量,观察没问题再全量放开;出问题就立刻把流量切回旧版本,具体落地方式取决于你的技术栈,Kubernetes环境下最常见的方案是用Ingress流量权重或Service Mesh按比例分流。

为什么容器环境做灰度发布比传统虚拟机更顺手

传统虚拟机时代做灰度发布,要准备一套完整的新环境,改负载均衡配置,把少量用户调度过去,整个过程涉及运维、网络、配置管理多个环节,手动操作占据相当比例。

容器环境把这个问题简化了一大截,镜像构建好之后,新版和旧版可以同时跑在同一套基础设施上,通过流量调度层做按比例的分配,内核用namespace做隔离,容器本身启动销毁都在秒级完成,这意味着试错成本被压到极低。

业内专家指出,容器化改造完成后,发布策略的灵活度会获得显著提升,这份红利的核心来源是“环境一致性和编排能力”,镜像把应用代码、依赖库、系统配置全打包在一起,任何一台机器上跑出来的行为都一样,排除了“在我机器上是好的”这类经典甩锅场景。

另一层优势是回滚速度,传统回滚要重新拉代码、重新编译、重新部署,耗时以十分钟甚至小时计,容器回滚就是切换镜像tag重新拉起副本集,通常在几十秒内完成,对在线业务的影响窗口极小。

从零搭建一套容器灰度发布流程

第一件事:把镜像版本管理规范化

灰度发布的前提是能区分新旧版本,建议镜像tag直接关联Git提交号或构建流水线号,形如app-order-api-8f3a2c1,别用latest这种无法区分的tag,否则你根本不知道线上跑的是哪个版本。

一套可复用的发布流水线至少包含以下阶段:

  • 代码合并到主干后自动触发构建
  • 构建产物打上commit短哈希作为镜像tag
  • 推送镜像到私有仓库(Harbor或简米云ACR均可)
  • 更新部署清单中的镜像版本号
  • 触发Kubernetes服务滚动更新或灰度发布流程

第二件事:选择合适的流量分割方案

用容器做灰度发布先放一小部分流量验证新版本

这里需要根据你的集群环境拍板,三个主流选项各有利弊:

方案 原理 适用规模 上手难度
Ingress按权重分流 通过Ingress Controller注解配置新旧版本服务权重 中小规模集群 较低
Kubernetes原生多Service 拆成稳定版和金丝雀版两个Service,再通过外部负载均衡按权重分发 任意规模 中等
Service Mesh按标签分流 通过Istio等网格层配置VirtualService权重 中大规模集群 较高,需要完整部署网格

以应用最广泛的Ingress方案为例,nginx-ingress-controller提供了原生金丝雀发布注解,假设你有一个名为old-app的稳定版Service,再创建一个new-app的Service指向新版本Pod,通过nginx.ingress.kubernetes.io/canary-weight注解把例如5%的请求转发到新版本:

nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "5"

这种配置方式是最贴近“先放一小部分流量验证新版本”这个需求的落地手段,配置完保存后自动生效,无需重启Ingress Controller。

第三件事:按阶段逐步调整权重

灰度发布的状态机并不复杂,关键步骤是设置检查点和内部确认节点:

  1. 初始阶段(5%流量):持续观察错误率、RT(响应时间)、CPU内存使用率,至少持续一个业务高峰期,通常建议4至24小时
  2. 观察正常后的增量阶段(30%流量):此时技术层面已经稳定,重点观察业务指标变化
  3. 确认无异常后的全量阶段(100%流量):如果服务本身有依赖关系,建议在业务低峰期做全量切换

每一个阶段切换流量权重前,检查一遍Kibana或日志系统中的错误日志、Sentinel或Prometheus中的调用链监控,如果发现任何异常指标,执行

用容器做灰度发布先放一小部分流量验证新版本

kubectl rollout undo一键回滚到旧版本。

K8s灰度发布工具链的实操对比

人工改Ingress注解在小规模场景能支撑,但团队大了、发布频繁了之后,自动化工具更稳妥,近年来社区常用的几类工具可分为三大方向。

Argo Rollouts是Argo家族面向Kubernetes发布场景的专门工具,支持渐进式交付、自动流量分析、多策略回滚,适合对发布流程有严格管控需求的中大型团队,它在Deployment基础上增加了Rollout资源类型,配合Ingress或Service Mesh实现自动化灰度策略,官方文档中明确支持nginx、traefik、istio等多种流量管理后端。

Flagger是Weaveworks开源的项目,理念更激进,主打“自动化金丝雀发布”,可以根据Prometheus监控指标自动判断是否继续扩大流量比例还是回滚,无需人工介入。

还有一批国内的云厂商在提供托管式的灰度发布能力,比如简米云容器服务ACK的发布应用功能,酷番云TKE的灰度发布与滚动发布控制台,百度智能云CCE的应用管理与发布编排,这套托管方案对不想折腾纯粹的开源工具链的团队更友好,控制台里点点按钮就能完成权重调整和策略配置。

做技术选型时,建议先想清楚一个问题:你的团队是希望全流程自动化,还是保留人工决策环节?前者适合具备完善的监控指标体系的团队,后者适合发布频率相对较低、更看重可控性的团队。

三个高频踩坑场景及其应对

会话保持导致灰度流量不准确

很多业务依赖Session粘滞,用户在灰度阶段被分配到新版本Pod,后续请求因为会话保持仍然路由到新版本,但监控面板只看到5%的流量权重,实际新版本承载的并发可能远超预期,应对方式是提前评估接口是否需要会话保持,如果必须保持,初始权重调低至1%至2%并缩短观察周期。

新旧版本数据库不兼容

新版本代码写了新字段,灰度流量一进来就往数据库表里写新格式的数据,旧版本代码读到这些数据直接报错,引发更大范围的故障,行业共识认为数据库变更需要与代码发布严格解耦,优先采用兼容性扩展策略,新版本的写入必须在旧版本可容忍的范围内,或者做双写迁移。

用容器做灰度发布先放一小部分流量验证新版本

只看了成功率没看延迟

新版本接口错误率没见增长,但P99延迟从50毫秒抬升到800毫秒,用户体感明显变卡,单看错误监控无法识别这类性能劣化问题,灰度发布监控面板至少包含错误率、P50/P99延迟、CPU使用率、GC耗时这四项指标。

Q&A:容器灰度发布常见疑问

容器灰度发布和滚动发布的区别是什么?

滚动发布是用新版本Pod逐步替换旧版本Pod,整个过程没有精确的流量比例控制;灰度发布基于权重将固定比例的流量调度到新版本,控制粒度更细,两者在Kubernetes中的实现机制不同,滚动发布靠Deployment的maxSurge和maxUnavailable参数驱动,灰度发布则依赖Ingress或Service Mesh的流量路由能力。

没有Istio能不能做灰度发布?

能,通过nginx-ingress的canary注解即可实现,配置方法参考上文示例,Kubernetes原生的Service本身不具备流量权重分发能力,但配合Ingress Controller的扩展注解完全可以实现按百分比切流,如果你的集群规模在几十个服务以内,不引入Service Mesh反而降低了运维复杂度。

小团队没有专门的SRE人员,适合引入Argo Rollouts吗?

Argo Rollouts的学习门槛并不低,需要理解Rollout资源定义、AnalysisTemplate的指标查询配置以及和Ingress Controller的联动机制,如果团队没有专门负责基础设施的人,建议先从最朴素的Ingress注解方案开始,用文档把流程固化下来,观察一段时间后再考虑工具化。

容器让灰度发布的门槛降低了一大截,但真正决定成败的还是流程设计:镜像版本管理是否规范、监控指标是否覆盖到位、回滚预案是否经过演练、团队内部是否有人对全链路负责,先把基础的三件事做好规范镜像tag、配好5%权重验证、盯紧监控面板,再谈更复杂的自动化策略,这套循环跑顺了,发布事故的数量会肉眼可见下降。

分享本文
本文为 简米科技官网 原创,已由运维技术专家审核。转载请注明来源:原文链接
售前咨询 服务热线 售后 邮箱