【Istio 控制面】NACK 与 Warming 归属:CDS→EDS→LDS→RDS 的顺序责任

💡 原文中文,约7400字,阅读约需18分钟。
📝

内容提要

本文分析Istio控制面istiod对Envoy NACK的处理机制:istiod仅记录错误并计数,不重试或回滚;通过PushOrder常量实现CDS→EDS→LDS→RDS的推送顺序,但只保证同批发送顺序;istiod可观测性止步于协议层,warming等Envoy内部状态无法感知,排障需结合控制面与数据面信号。

🔎

延伸解读

NACK 后 istiod 的“不作为”是设计而非缺陷

istiod 对 NACK 的处理仅止于记录日志、增加计数器和更新内存中的 LastError,不触发重试或回滚。这并非疏漏,而是有意避免重试风暴。旧配置继续服务,是因为双方都未主动恢复,而非任何一方保护了配置。理解这一点,有助于排障时避免误判:配置错误不会自动修复,必须等待下一次配置变更触发新的推送。

PushOrder 只保证发送顺序,不保证生效顺序

PushOrder 常量确保同一连接上按 CDS→EDS→LDS→RDS 顺序发送,但这是连续调用,不等待 ACK。因此,它只保证 Envoy 收包顺序,不保证上一类型已处理完毕。对于删除类操作,PushOrder 不提供对称保证,跨批次的资源生命周期一致性仍依赖 istiod 的配置翻译逻辑。理解这一边界,可避免过度依赖 PushOrder 而忽视配置构造的正确性。

控制面可观测性止步于协议层,排障需两端对齐

istiod 只能观测到 ACK/NACK 协议层,对 warming、快照切换、请求绑定等 Envoy 内部状态无原生信号。因此,“istiod 已推送”仅代表协议层接受,不代表配置已生效。排障时需同时查看控制面指标(如 pilot_total_xds_rejects)和数据面状态(如 Envoy admin),两者可能不一致,单看一边易误判。

Q&A

Istio 控制面 istiod 收到 Envoy 的 NACK 后会做什么?

istiod 收到 NACK 后,会记录错误日志、增加 Prometheus 计数器 pilot_total_xds_rejects,并将错误信息存入 WatchedResource.LastError(内存状态),但不会重试或回滚,旧配置继续生效。

istiod 推送 xDS 配置时,CDS、EDS、LDS、RDS 的顺序是如何保证的?

istiod 通过 PushOrder 常量定义推送顺序,依次为 CDS、EDS、LDS、RDS,以及 SDS、Address、Workload 等类型。该顺序仅保证同一条 gRPC 流上发送的先后顺序,不等待 ACK,也不保证对端处理完成。

istiod 能否感知 Envoy 的 warming 状态?

不能。istiod 的可观测性止步于协议层(ACK/NACK),无法感知 Envoy 内部的 warming、快照切换、请求绑定等状态。排障时需要结合控制面信号(如 pilot_total_xds_rejects)和数据面信号(如 Envoy admin 的 config_dump、stats)进行判断。

NACK 后 istiod 不重试,那配置如何恢复?

NACK 后 istiod 不会主动重推,需要等待下一次配置变更触发新的 PushRequest(经过 debounce 合并)才会重新推送。因此,修复配置后需要再次变更配置才能让 Envoy 收到新配置。

istiod 的 PushOrder 能否保证 make-before-break?

PushOrder 只保证同批推送内类型的发送顺序(如先 CDS 后 EDS),但无法保证跨批次的资源生命周期一致性。例如,如果新 Route 引用的 Cluster 在同一批中被删除,仍可能产生时序错位。因此,make-before-break 的最终保障依赖于配置翻译逻辑正确构造资源批次。

排障时如何结合控制面和数据面信号?

控制面信号如 pilot_total_xds_rejects 可以回答配置是否被拒绝,数据面信号如 Envoy admin 的 config_dump、clusters、stats 可以回答配置是否真正生效。两者可能不一致,需要同时查看才能完整定位问题。

🏷️

标签

➡️

继续阅读