【Envoy Gateway】Provider 与 watch:哪些对象进入翻译输入集
内容提要
Envoy Gateway v1.9.0中Kubernetes provider的资源收集与状态写回机制:一次Reconcile收集整个GatewayClass的输入集,而非单个Route;缺失CRD时跳过watch,跨命名空间引用需ReferenceGrant;Status Manager通过UpdateHandler写回,但cache滞后可能导致状态丢失;静态EnvoyGateway配置仅定义watch范围,不替代动态对象。排障时需检查informer、namespace和CRD是否存在。
延伸解读
输入集与单对象翻译的差异
Envoy Gateway 的 Kubernetes provider 并非在每次 API 事件中单独翻译某个 HTTPRoute,而是通过 informer 监听一组类型,将属于本 controllerName 的 GatewayClass 收集成一份 resource.Resources 快照,再整体交给 Translator。这意味着一次 Reconcile 对应整个 GatewayClass 的输入集,而非单个 Route。理解这一点有助于排查“YAML 在、流量不在”的问题:失败可能发生在翻译之前,例如对
缺失 CRD 与 watch 范围的影响
当集群缺少某些 CRD(如 TCPRoute、UDPRoute)时,provider 会通过 discovery 跳过对应的 watch,导致这些对象根本不会进入 informer,即使 YAML 存在于 etcd 中。此外,watch 范围可通过静态配置收窄到特定 namespace 或使用 NamespaceSelector,若配置不当,被排除的 namespace 中的 Route 不会获得任何 status,且不会收到“我不 watch 你”的提示。排查时应先确认 CRD 是否存在、namespace 是否
Status 写回的潜在丢失风险
Status 写回由 UpdateHandler 在独立 goroutine 中执行,且仅在 leader 副本上运行。v1.9.0 修复了因 informer cache 滞后导致新建对象 status 更新被静默丢弃的问题,但 cache 健康仍可能影响写回。若 Route 长时间无 status,除了怀疑 Translator 未计算,还应检查是否因 cache 滞后或非 leader 副本导致。此外,Gateway 的 Programmed 条件会结合活的基础设施对象(如 Envoy Service 和 D
Q&A
Envoy Gateway 中,一次 Reconcile 是处理单个 HTTPRoute 还是整个 GatewayClass 的输入集?
Envoy Gateway 的 Kubernetes provider 在每次 Reconcile 时收集整个 GatewayClass 的输入集,而不是单独处理某个 HTTPRoute。所有相关资源事件都会 enqueue 同一个 request(gateway controller name),从而合并成一次全量收集,并将整个 resource.Resources 快照交给 Translator。
Envoy Gateway 在集群缺少某些 CRD(如 TCPRoute、UDPRoute)时会如何处理?
Envoy Gateway 在启动时会通过 discovery 检查 CRD 是否存在,如果缺失,则会跳过对该 kind 的 watch,避免控制器启动时 crash-loop。例如,在 GKE 或 OpenShift 托管环境中,缺少 ListenerSet、GRPCRoute、TLSRoute 等 CRD 时,控制器会跳过 watch 并记录日志,但对象不会进入 informer,因此不会出现在输入集中。
Envoy Gateway 中,跨命名空间引用 Secret 或 Service 时,需要什么条件才能进入翻译输入集?
跨命名空间引用 Secret、Service 或 ConfigMap 时,必须存在对应的 ReferenceGrant,且 findReferenceGrant 成功,否则这些对象不会进入 resource.Resources 的相应字段。如果缺少 ReferenceGrant,即使对象存在于 etcd,Translator 也无法看到它们,可能导致 RefNotPermitted 或后端不可见。
Envoy Gateway 的 Status Manager 是如何将状态写回 Kubernetes API 的?
Status Manager 在 Envoy Gateway v1.9.0 中由三部分组成:Translator 计算状态,runner 发布状态到 ProviderResources 的 *Statuses map,然后 Kubernetes provider 的 UpdateHandler 在独立 goroutine 中通过 Status().Update 写回。UpdateHandler 仅在 leader 副本上运行,且写回前会检查 status 是否变化,忽略 LastTransitionTime 以避免抖动。
Envoy Gateway 中,静态配置(EnvoyGateway API)和动态对象(Gateway API 资源)的边界是什么?
静态配置(EnvoyGateway API)在进程启动时生效,决定 provider 类型、watch 范围、controllerName 以及扩展 API 是否启用(如 enableLua、enableBackend)。动态对象(如 Gateway、HTTPRoute、SecurityPolicy)在 reconcile 循环中生效,决定翻译出的 IR。静态配置不替代动态对象,只定义 watch 范围和功能开关。
Envoy Gateway 中,如果 informer cache 滞后于 API Server,可能导致什么问题?
如果 informer cache 滞后于 API Server,UpdateHandler 在写回 status 时可能因 cache 中找不到对象而返回 NotFound,旧逻辑会静默丢弃 status 更新,导致新建对象一直没有 status,直到控制器重启。v1.9.0 已修复此问题,在 cache 返回 NotFound 时会用 uncached apiReader 再次确认对象是否存在。
Envoy Gateway 中,watch 范围可以通过哪些方式收窄?
watch 范围可以通过两种方式收窄:一是通过静态配置 provider.kubernetes.watch 指定 namespace 列表(WatchesNamespaces),此时 cache 只覆盖这些 namespace;二是使用 NamespaceSelector,通过标签选择器过滤 namespace,只有匹配标签的 namespace 中的对象才会被 watch。注意,v1.9.0 要求 namespace-scoped watch 必须包含 controller namespace,否则控制器无法读取自身的基础设施对象。
Envoy Gateway 中,如果 TCPRoute 的 CRD 存在但 API 版本未升级到 v1,会发生什么?
如果 TCPRoute 的 CRD 存在,但 Envoy Gateway v1.9.0 只调和 gateway.networking.k8s.io/v1 版本,而集群中只有 v1alpha2 版本,则 TCPRoute 会被静默跳过,不会进入输入集。这与 watch 层缺失 CRD 不同,属于 API 版本层的静默跳过。排障时需要检查 CRD 的 served version。