
企业灰度发布 09:Istio 流量管理机制——从 Gateway 到 stable/canary subset
Istio 能做灰度,不等于配置一个 weight: 10 就结束。一次请求从入口 Gateway 进入,VirtualService 匹配 host、path、header 等条件并选择目标,DestinationRule 再定义 subset、连接池、负载均衡、异常端点驱逐和 TLS。三个对象职责混淆,是生产 404、503 和流量偏差的主要来源。
最简记法是:Gateway 管入口,VirtualService 管“到哪里”,DestinationRule 管“到了以后怎样处理”。
host-level 与 subset-level 两种版本路由
host-level 使用 stable-service 和 canary-service 两个 Kubernetes Service,VirtualService 在两个 host 之间分配权重。发布控制器修改两个 Service selector,使其分别指向 stable 与 canary ReplicaSet。这种模型直观,也便于按 service 指标区分版本。
subset-level 使用一个 Service,在 DestinationRule 中按 label 定义 stable、canary subset,VirtualService 对两个 subset 分流。发布控制器更新 subset label 和 route weight。它避免微服务内部出现两个 DNS 名称,更适合东西向调用,但指标查询要按 workload/version 维度区分。
权重必须合计为 100。它描述代理对新请求的概率选择,不保证短时间样本严格等于比例,也不代表连接数、并发或业务价值等比例。低 QPS 服务的 5% 可能长时间没有统计意义,高价值租户的一个请求又可能远重于普通请求。
Header 与 Cookie 灰度适合确定人群
内部测试、特定租户或 beta 用户不适合随机百分比。VirtualService 可按 header exact、prefix、regex 或 cookie 条件匹配,把请求送到 canary。规则按顺序匹配,因此特定人群规则应位于通用权重规则之前,并设置明确 fallback。
身份 header 不能无条件信任外部客户端。入口 Gateway 应删除用户伪造值,再根据已认证身份写入内部 header;服务间调用要传播但不能任意提升灰度身份。Cookie 需要考虑过期、跨域、缓存键和隐私,且无法覆盖非浏览器调用。
会话黏性也不是默认答案。登录态保存在外部存储时,请求无需固定版本;如果新版本改变会话结构,黏性只能暂时掩盖兼容问题。长连接和 gRPC stream 更应按连接而非单请求理解权重,发布步骤要给旧连接排空时间。
Traffic Mirroring 能验证什么
镜像把主请求复制一份发给新版本,用户只接收主路径响应。它适合观察解析、性能和只读逻辑,不会验证真实 canary 响应能否被客户端接受,也不能安全复制任意写请求。支付、发信、写库等副作用必须在影子环境隔离,或让应用识别镜像上下文并禁用外部动作。
镜像流量还会消耗下游资源。复制 100% 生产请求可能让数据库、缓存和第三方 API 承担双倍负载。应设置采样率、资源隔离、数据脱敏与独立指标,不让影子错误污染正式 SLO。
超时、重试与异常端点驱逐要一起看
VirtualService 可设置 timeout 和 retry,DestinationRule 可配置连接池、负载均衡和 outlier detection。若应用 SDK 已重试,Mesh 再重试会产生乘法放大;发布平台需要展示“有效策略”,而不是只看 Istio YAML。
异常端点驱逐会暂时移除连续失败的实例,但它不是业务回滚。canary 只有一个 Pod 时,被驱逐可能使该 subset 无可用端点;是 fallback stable、直接失败还是让发布控制器 abort,需要明确测试。重试也可能把 canary 首次失败改送 stable,使总体成功率看起来健康,却隐藏新版本错误。分析指标应同时看首次尝试、最终响应和版本维度。
最容易踩中的配置陷阱
端口命名或 appProtocol 会影响协议识别;把 HTTP 当 TCP 后,Header 路由自然不生效。VirtualService 的 host 作用域、namespace 和 exportTo 决定可见范围;短名可能被解析到规则所在 namespace,而不是调用方预期服务。subset label 必须与实际 Pod label 完全一致,发布期间还要防止稳定和灰度 selector 重叠。
多个资源修改同一 host 时可能产生合并和冲突,匹配顺序也会改变行为。任何灰度配置都应先经过静态分析,再在隔离环境生成真实代理 route dump,最后用携带/不携带灰度身份的请求分别验证。
路由变更的安全工作流
| 步骤 | 证据 |
|---|---|
| 生成意图 | release id、stable/canary 版本与目标人群 |
| 静态校验 | host、subset、权重、匹配顺序和协议 |
| 配置下发 | 目标代理全部 ACK,无关键 NACK |
| 合成测试 | stable、canary、fallback 与镜像路径正确 |
| 实际观察 | desired 与 observed 流量、错误和延迟一致 |
| 恢复验证 | 权重归零后 canary 不再收到正式流量 |
Istio 提供的是精确流量执行能力,却不会主动把 5% 变成 20%,也不会判断业务指标是否合格。下一篇把发布状态机放到 Mesh 之上,解释 Progressive Delivery Controller 为什么是独立层。