声明“给 v2 一部分流量”以后,谁真正执行

前面已建立 frontend → orders → inventory-v1 / inventory-v2 的服务链,并在 第 03 篇拆开独立代理的 route、cluster 与 endpoint。sidecar 模式下,应用继续用原来的上游地址,配置却需要从 Kubernetes 资源变成 orders 旁的 Envoy 可执行的路由。Istiod 负责观察和生成配置,不是业务请求必经的转发节点。读者需要知道 Service 与 Envoy route 的不同,并能用请求 ID 定位实际库存实例。

声明经 Istiod 和 xDS 到代理配置,再由实际后端响应验证

这张图中上方为控制路径,下方为请求路径;两个箭头不能合并。“资源已提交”“代理已确认”“配置已存在”“本次请求匹配”是四种不同命题。

五步收集证据

  1. 声明:VirtualService 表达匹配/路由意图,DestinationRule 可定义 v1/v2 subset;分别核对资源的 generation、host、port、规则所在作用域、子集标签。API 接受对象,只证明资源提交成功。错误 host 或不匹配的请求头即使语法合法,也可能让目标请求始终沿旧路径。
  2. 控制器处理:Istiod 观察配置与服务发现变化,按关联代理的范围构造 xDS 所需资源。哪些 namespace、工作负载和网关能看到规则,须按实际 Istio 版本及安装方式核对;不能从“某一个代理同步了”推广到所有代理。
  3. 下发:对本次 orders Pod 对应的代理看 xDS 资源版本及 ACK/NACK、拒绝原因。ACK 表达对相应响应的确认,不证明依赖资源已完成 warming、所有配置可用或测试请求按预期路由。
  4. 数据面:用代理当前配置快照核对 virtual host、route、cluster、endpoint 是否对应 v2,并检查 v2 后端是否实际存在。即使配置快照正确,仍不能证明流量通过了该代理。
  5. 执行:发同一 SKU、分别带/不带特定请求头的两个请求 ID,联合代理访问日志、v1/v2 应用日志、响应中的 inventory_version 与副作用账本断言实际命中情况。旧连接复用和多个 orders Pod 都会影响观察范围,不能以一条 200 宣告所有实例收敛。

对于错写 subset 标签而导致无 v2 endpoint、或 route 的 host 与实际请求不匹配这两种情况,排查起点不同:先比较请求 Host 与当前 route,再查 cluster/endpoint,而不是直接调权重。下一篇将拆解 xDS 的更新依赖与拒绝,不把 ACK 当作万能“已生效”信号。

把一条路由追到库存响应

累计清单 deploy/kubernetes/inventory-route.yaml 同时定义 DestinationRule 与 VirtualService:inventory 的 v1/v2 subset 按 Pod 的 version 标签选择;VirtualService 第一条精确匹配 x-canary: yes 到 v2,最后一条把其余请求送 v1,目标端口是 8080。应用的 Deployment 名称本身不参与 subset 选择。

从 examples/service-mesh/ 执行,前提是已完成第 04 篇 sidecar 集群:

1
SM_CONTEXT=kind-service-mesh-sidecar bash scripts/cluster-case.sh 06

脚本拒绝替换已有同名规则,提交清单后轮询带头请求直到响应 v2,另用无头请求确认 v1。控制路径为 Kubernetes 对象 → Istiod → orders 代理资源;业务路径为 orders → 本地代理 → inventory-v2。证据目录保存声明 YAML、orders 的 active-routes/active-endpoints,以及 v2 应用中的相同请求 ID。

故障把 DestinationRule 第二个 subset 的标签改成 version=missing。这仍是可提交的标签选择器,但没有匹配 Pod;带头调用应失败。恢复重新 apply 原清单,等待相同带头输入回到 v2。EXIT 钩子删除本次创建的规则,避免影响后面的 Gateway API 实验。提交成功不等于转发成功,清理成功也不等于恢复阶段成功。

evidence/06/<时间>-<PID>/ 中 canary/default、wrong-subset/recovered 各自的命令、原始输出和退出码必须一起检查。当前 Istio 集群实验 NOT_RUN;本章材料不声称观测到某个固定收敛时长。

[PATTERN] 声明式调和把期望状态转为代理资源;它与请求处理分属两个时序,必须分别验收。

原则 具体约束
配置身份独立于进程名称 subset 看标签而非 Deployment 名称
验证整个依赖链 route 有目标还需 endpoint 非空
恢复复用原输入 相同 canary 头恢复到 v2

练习与参考解答

  1. 看到代理同步状态正常,v2 日志却没有目标请求,应怎样定位?参考解答:锁定真实发请求的 orders Pod/代理,查该代理 route、cluster、endpoint 与实际请求 Host/头/端口是否匹配,再关联代理与两个库存后端的请求 ID。同步状态不等于该请求选择了 v2。
  2. 造一个“合法配置但仍落 v1”的反例。参考解答:v2 route 只匹配 x-canary: yes,实际发往 inventory 的请求却没带头;分别发送有头和无头的相同 SKU、不同 ID,并检查 route 快照与后端日志,才能证明是匹配条件而非配置完全没下发。未运行前不预填结果。

官方资料与系列导航

系列导航:00 基线 → 01 治理位置 → 02 Service → 03 Envoy → 04 Sidecar → 05 启停 → 06 路由配置(本文)→ 07 xDS 更新、依赖与拒绝。