【Istio 控制面】VirtualService / mesh HTTPRoute → RDS:两条编译路径,一份路由表
内容提要
本文探讨Istio中VirtualService与Gateway API HTTPRoute两条配置路径如何汇合至同一RDS生成器。两者均编译为内部VirtualService对象,但合并规则不同:VirtualService跨资源顺序未定义,HTTPRoute有确定性优先级算法。双写同一host是生产风险,Istio计划以Gateway API为默认。
延伸解读
RDS 全量推送的代价
RDS 生成器只支持全量推送,任何路由表变化都会触发所有相关代理的完整重推,这与 EDS 的部分推送形成鲜明对比。这意味着频繁修改路由规则可能带来较大的控制面开销,尤其在规模较大的集群中。运维时需权衡路由更新的频率与推送成本,或考虑将不常变动的路由与频繁变动的端点分离管理。
VirtualService 合并顺序的隐患
多个 VirtualService 挂在同一 ingress gateway 时,跨资源的匹配顺序未定义,可能导致具体路径被泛匹配规则抢先处理,造成流量误路由。这种不确定性依赖资源创建顺序,难以预测和调试。生产环境应尽量避免对同一 host 使用多个 VirtualService,或改用 Gateway API 的 HTTPRoute 以获得确定性优先级。
双写同一 host 的冲突风险
由于 VirtualService 和 HTTPRoute 最终都编译为内部 VirtualService 并存入同一配置存储,若同时用两种方式定义同一 host,可能触发冲突(如 IST0109),但现有工具无法识别冲突来源。迁移期间尤其容易因忘记删除旧资源而导致问题。建议迁移时先清理旧配置,并利用 istioctl analyze 检查潜在冲突。
Q&A
Istio中VirtualService和HTTPRoute在RDS生成时是如何汇合的?
VirtualService和HTTPRoute(包括GAMMA mesh模式)最终都会被编译成同一种内部VirtualService表示,存入同一个配置存储,然后由同一个RdsGenerator的BuildHTTPRoutes处理。HTTPRoute不是绕开VirtualService的独立通道,而是通过Gateway API控制器转换后,以VirtualService的GVK存入配置存储。
VirtualService和HTTPRoute在跨资源合并顺序上有什么不同?
VirtualService跨资源合并顺序未定义,尤其在mesh网关下同host直接冲突报错(IST0109);而HTTPRoute有规范强制的确定性优先级算法,按Exact路径、最长Prefix、Method、header数量、query参数数量、创建时间、namespace/name字典序依次比较。
为什么说双写同一host是生产风险?
因为VirtualService和HTTPRoute两条路径写入的是同一个kind(VirtualService)和同一个配置存储,但现有分析工具(如istioctl analyze)不区分内部VirtualService的原始作者,导致冲突检测可能遗漏,排障时难以定位源头。
RDS生成器支持部分推送吗?
不支持。RDS只支持全量推送,rdsNeedsPush源码注释明确写着“RDS only handles full push”,如果req.Full为假则直接跳过。这与EDS支持部分推送形成对比。
哪些配置变更不会触发RDS重算?
根据skippedRdsConfigs列表,WorkloadEntry、WorkloadGroup、AuthorizationPolicy、RequestAuthentication、PeerAuthentication、Secret、WasmPlugin、Telemetry、ProxyConfig这些Kind的变更不会触发RDS重算。
GAMMA模式下HTTPRoute如何编译成内部VirtualService?
在GAMMA模式下,HTTPRoute的parentRef指向Service,conversion.go中的computeRoute会对mesh分支单独求值,编译出的内部VirtualService等价于原生VirtualService省略gateways字段(默认绑定mesh),只影响sidecar,不挂到ingress gateway。
Istio官方对Gateway API的立场是什么?
Istio官方文档明确表示支持Kubernetes Gateway API,并计划使其成为未来流量管理的默认API。