服务网格 07:xDS 更新、依赖与拒绝
ACK 到了,为什么这条请求仍走旧路由
第 06 篇区分路由声明、Istiod 处理、代理状态和实际请求。现在要观察代理同控制面协商资源的过程:Envoy 对一次 xDS 响应确认(ACK),究竟确认了什么?路由(RDS)可能引用 cluster(CDS),cluster 可能引用端点集合(EDS);更新不是把一份“最终 YAML”原子广播给所有代理。适合已经认识 listener、route、cluster、endpoint 的读者。
图里的 ACK/NACK 属于特定流和资源类型的控制反馈;图下方的请求沿代理活跃配置执行。两条时间线需要同一代理标识和时间戳连接,不能把 Istiod 画在普通业务请求的中途。
ACK/NACK、资源依赖分别约束什么
控制面可使用聚合发现服务 ADS 在一个 gRPC 流内交换多类发现资源。SotW(state of the world)响应提供相应订阅范围的一组当前资源;Delta xDS 按增量订阅和新增/移除表达变化,两者资源版本的含义和删除方式不能机械套用。具体使用哪种模式须读取实际代理/控制面的协商与日志,不因文档提供两种协议就断言当前集群启用了 Delta。
代理收到响应,要按资源类型校验配置并以与响应关联的标识回传 ACK 或 NACK;NACK 有拒绝原因。它说明这次响应在该协议阶段未被接受,不能推出此前已接受的所有配置都被删除;也不能把“已有监听继续工作”写成“新资源已生效”。资源版本、响应 nonce、关联 proxy ID 和时间顺序应一起保存,单取一行 SYNCED 丢失了依赖和路径信息。
更新可能存在依赖:listener 引用尚未可用的 route,route 选择的 cluster 尚在构造,或 cluster 要等 endpoint/健康状态才能具备预期转发能力。Envoy 有活跃、warming 和排空等状态;即使对某资源发送 ACK,仍须检查本次请求将使用的活跃 listener/route/cluster/endpoint。旧连接可能仍使用旧配置或旧后端,配置推进与业务结果的时序不能跳步。
尤其要防止两种误诊:一是代理 NACK 某条错误 route,却把后端连接失败归咎于“全部端点被清空”;二是 route 已更新且有 ACK,但本次请求的 Host、路径或代理实例根本没命中这条路由。故障归因要跨越确认消息、当前配置、代理请求日志和真实应用结果。
复跑矩阵和证据状态
资源依赖还包括秘密发现服务 SDS:它可以向代理提供 TLS 证书、私钥及证书验证配置,分发凭据与签发凭据是不同职责。依赖远程 SDS 证书的 TLS listener 在首次取得证书前可能尚未激活;因此 RDS/CDS 的 ACK 不能证明握手材料已就绪。核对时记录 secret 名称、公开证书元数据及 listener 状态,不输出私钥。证书签发和轮换衔接第 19 篇;本篇尚无 SDS 运行证据。具体初始化及失败行为见 Envoy v1.37.0 SDS 文档。
在隔离实验集群里沿用相同的 frontend → orders → inventory-v1/v2 与请求 ID,选定兼容的 Istio/Kubernetes 版本及二进制/镜像 digest:
- 正常路径:提交带 v2 匹配条件的资源,保存提交后的 generation、Istiod 处理记录、目标 orders 代理的 ADS 响应/ACK、活跃配置快照和有头/无头请求实际命中的库存版本。以带标识请求而不是随机权重作为首次断言。
- 拒绝边界:只在实验环境提交能触发版本校验拒绝的受控配置,观察具体资源类型的 NACK/原因、此前已接受配置和新请求是否仍可用;不得猜测哪种畸形对象一定能绕过 Kubernetes/Istio 的前置校验。若资源在 API 层即被拒绝,应记录为API 拒绝而非伪造 xDS NACK。
- 依赖/收敛:逐一记录 RDS/CDS/EDS 的引用和活跃/待激活状态,端点变更后用新旧连接分别调用。NACK 断言对“预期拒绝却仍显示接受”返回非零;成功断言必须匹配实际后端请求 ID。
采证前在 examples/service-mesh/ 执行安全只读前置检查:
1 | |
当前检查证据 examples/service-mesh/evidence/02/20261001T130351Z-2539112/ 为退出 127(kubectl 不存在),独立 Envoy 固定版下载亦超时(research/03.md)。没有 xDS 流、资源版本、ACK/NACK、warming 配置或真实请求日志;本篇所有 xDS 运行结论均 NOT_RUN,不能用图、静态 YAML 或进程 HTTP 成功代替。在具备环境之前,只能核对官方协议约束和提出可证伪的采证步骤。
练习与参考解答
- 有 RDS 的 ACK,两个 orders Pod 中只有一个返回 v2。怎样判断是收敛还是请求匹配?参考解答:先按代理 ID 分别检查当前活跃 route、cluster/endpoint 与资源时间线,再发送相同 host/头、不同请求 ID,通过两个代理日志与后端记录分别核对;只从一个 ACK 无法推断另一代理状态,更不能推出两次请求是否使用同一连接。
- 构造“配置被拒却业务暂时仍成功”的反例。参考解答:在实验环境尝试一条会产生确切 xDS NACK 的受控更新,并保留此前工作正常的旧版配置;若 API 层先拒绝,则改记 API 拒绝而不冒充 NACK。若实际观察到 NACK 后旧 route 仍被用于同一请求 ID 的成功返回,说明新响应被拒不等于旧资源立刻消失;必须用时间线验证,不能从规范文字虚构结果。
官方资料与系列导航
- Envoy v1.37.0 xDS 协议:ADS、SotW/Delta、ACK/NACK 与资源依赖;这里按固定候选文档版本阅读。
- Envoy v1.37.0 初始化与 warming:活跃前的配置阶段,具体可观测字段需实测。
- Istio proxy-status:同步诊断工具入口,不代替 proxy 的 config dump 和请求路径。
系列导航:00 基线 → 01 治理 → 02 Service → 03 Envoy → 04 Sidecar → 05 启停 → 06 路由 → 07 xDS 更新、依赖与拒绝(本文)→ 08 服务发现、DNS 与端点更新。
