土法炼钢 · 系统与基础设施

【Envoy Gateway】EnvoyProxy 与基础设施:谁管数据面生命周期,GatewayNamespaceMode 与 remote infra

文章导航

分类入口
kubernetesnetwork
标签入口
#envoy-gateway#envoyproxy#infra-manager#gateway-namespace-mode#remote-infra#mergebackends#xds#v1.9.0

目录

HTTPRoute Accepted=True 仍可能没有任何监听地址:失败不一定在路由翻译,而在 InfraIR 没有变成可调度的 Envoy 舰队。反过来,舰队已经起来、xDS 却连不上,在 GatewayNamespaceMode 里要先问认证,而不是先改 BackendTrafficPolicy。v1.9.0 又加了一条责任分叉:可以把基础设施管理 完全交给集群外的 gRPC provider

本文只问:数据面 Pod 的生命周期谁管;GatewayNamespaceMode 与 remote infra 改了哪条责任面;mergeBackends 为什么不能写成生产默认。策略如何编译见 第 9 篇;xDS 消费与 warming 见 envoy/11

本文是「Envoy Gateway / Gateway API」系列第 10 篇(共 16 篇)。→ 系列目录

篇目 核心内容
第 9 篇 · Policy attachment 五类策略、mergeType 仅 xRoute
第 10 篇 · EnvoyProxy 与基础设施 舰队所有权、Namespace 模式、remote provider、mergeBackends
第 11 篇 · 可观测 access log / metrics / tracing 默认采样

上一篇Policy attachment · 下一篇可观测

版本锚定:Envoy Gateway v1.9.0(源码 tag v1.9.0,2026-08-14)。机制对齐 v1.9 Concepts 的 EnvoyProxy 行、Customize EnvoyProxy / Deployment Mode / Gateway Namespace Mode / Remote Infrastructure Provider 任务,以及 v1.9.0 Release Notes。契约钉 tag 上的 proto/remoteinfra/service.proto实验台账:未跑。 不把 experimental 写成默认生产,不写未核厂商的 remote provider 教程。


一、EnvoyProxy CR

EnvoyProxy 是 Envoy Gateway API 里表示 托管数据面 的对象:镜像、副本、Service、bootstrap、遥测、过滤器顺序、是否合并 Gateway。它不是 Gateway API 核心资源。Concepts 写明:可被 GatewayClassGateway 引用,Most specific configuration wins

附着方式有两条,官方 Customize EnvoyProxy 任务区分得很硬:

v1.9 API 还允许 EnvoyProxy.spec.mergeType,控制这份对象如何与更不具体的配置合并(EnvoyGateway 默认 < GatewayClass < Gateway)。未设则整份替换。该字段在 EnvoyGateway 默认 EnvoyProxySpec 里无效——不要和 第 9 篇 路由策略的 mergeType 当成同一个开关。

EnvoyProxy 改的是 InfraIR 输入 + 部分 XdsIR 默认(telemetry、filterOrder、backendTLS 默认),不替代 HTTPRoute。舰队没起来时,Gateway Programmed 不会因为路由 Accepted 就变绿。排障时先看谁引用了哪份 EnvoyProxy,再问 Infra Manager 有没有把 InfraIR 调谐成 Deployment/Service。

字段可以按「谁消费」切开,避免把所有旋钮都当成会滚动 Pod:

大致落点 典型字段 谁读
InfraIR 副本、HPA、Service 类型、镜像、资源 request、shutdown drain Infra Manager 或 Remote provider
XdsIR / bootstrap telemetryfilterOrderbackendTLS 默认、bootstrap YAML xDS Translator;bootstrap 进 Pod 配置
翻译策略 routingType(Service ClusterIP vs Endpoint)、preserveRouteOrdermergeGateways / mergeBackends Gateway API Translator 如何长 cluster / listener

bootstrap 官方标了硬边界:与 xDS 服务器通信所必需的字段不可改,改了会让 EnvoyProxy 被拒;跨小版本不保证兼容,建议用 egctl x translate 从默认 bootstrap 出发再改。本篇未跑 egctl,只采用文档语义。自定义 bootstrap 失败时,表象常是代理起不来或连不上 18000,而不是 HTTPRoute 条件变红。


二、Infra Manager

控制面编译管线在 Translator 之后分成两份 IR:XdsIR 交给 xDS Translator 与 go-control-plane;InfraIR 交给 Infra Manager。默认 Kubernetes infrastructure provider 用这份 IR 调谐:

Helm 安装文档给出控制面与数据面端口分工:xDS 服务器在控制器 0.0.0.0:18000;托管 Envoy 的 admin 在 127.0.0.1:19000,stats 0.0.0.0:19001。控制器 自己 listen 业务端口;业务地址来自 Infra Manager 创建的 Service。

默认部署模型(Controller Namespace):数据面资源落在控制器命名空间(通常 envoy-gateway-system)。动机是 RBAC 最小:控制面与数据面同命名空间。watch 可以收窄到若干业务命名空间,但 控制器自己的命名空间始终被纳入,否则无法调谐自己创建的 Deployment。

v1.9.0 与舰队规模相关的两处默认变化,写在升级前就要看的 Release Notes 里:

v1.9.0 还修了 HPA 场景下控制器用 server-side apply ForceOwnershipspec.replicas、把 HPA 算出的副本数打回去的问题。现在配置了 envoyHpa / rateLimitHpa 时,生成的 Deployment 省略 replicas,下限改用 minReplicas。升级后如果副本数「总是回到 values 里的整数」,先查是否仍把静态 replicas 和 HPA 叠在同一份 InfraIR 上,而不是先怪 Kubernetes scheduler。

Infra Manager 的所有权止于「把 InfraIR 变成 Kubernetes 对象并维持」。对象起来之后,配置是否被 Envoy ACK、是否 warming 完成,是 xDS 轴与数据面轴,见 第 5 篇 与 envoy 系列。控制器指标 resource_apply_total / resource_delete_total第 11 篇)只能证明 apply 循环在动,不能证明 Pod Ready。


三、GatewayNamespaceMode(含 v1.9 xDS 认证修复)

provider.kubernetes.deploy.type: GatewayNamespace 把 Deployment / Service / ServiceAccount 建到 每个 Gateway 所在命名空间,而不是控制器命名空间。多租户隔离从「共享舰队命名空间」变成「数据面落在租户 ns」。代价是控制器需要跨命名空间的基础设施 RBAC;Helm 在该模式下会创建 gateway-helm-cluster-infra-manager ClusterRole(含 tokenreviews)。

与 Merged Gateways 不能同时开。官方 Deployment Mode 对新建集群更推荐 ListenerSet,而不是 mergeGateways

认证模型也换了。默认 Controller Namespace 模式用双向 mTLS。GatewayNamespaceMode 改为 服务端 TLS + JWT

v1.9.0 安全更新明确写:修复了 GatewayNamespaceMode 下的 xDS 服务器认证绕过,补上 Unary interceptor,并校验 SotW 请求。GitHub tag 对应 PR 叙述为 fail-open 认证修复。升级到 v1.9 之前若已使用该模式,应把这次修复当成安全补丁,而不是「行为不变的小版本」。同版本还修了该模式下 xDS 服务器在 cert-manager 轮转后仍提供过期证书的问题(每次 TLS 握手重新读盘)。

另一条所有权修复:GatewayNamespace 模式下,控制器不再接管同名但 未被自己打所有权标签 的已有 ServiceAccount / ConfigMap。撞名时拒绝调谐,避免把租户预先创建的身份对象「收编」成网关基础设施。

watch 与 Namespace 模式正交:显式 namespaces 列表会在每个列出的 ns 建 Role;namespaceSelector 因目标 ns 运行时才确定,改用 ClusterRole。控制器命名空间始终在 watch 集里。v1.9 还修了命名空间 scoped watch 漏掉控制器命名空间、导致自己的基础设施对象读不到的问题——开启 GatewayNamespaceMode 或收窄 watch 之后若舰队突然「没了」,先核 watch 集是否仍包含 envoy-gateway-system(或你的控制器 ns),不要先删 HTTPRoute。

与默认模式对比时,隔离换来的是证书分发面缩小、RBAC 面扩大。TokenReview 权限出现在 ClusterRole 里,是因为 JWT 校验要问 API server「这枚 token 是不是这个 SA」;这不是可选项。把 GatewayNamespaceMode 理解成「只改了 Pod 的 namespace 字段」会漏掉 xDS 信任根与 RBAC 两张表。


四、remote infrastructure provider(v1.9)

v1.9.0 新增 Remote infrastructure provider:控制器仍 watch Gateway API、仍翻译 XdsIR 并跑 xDS server,但 不再 在本集群调谐 Deployment。它把 InfraIR 经 gRPC 发给你自己运的 provider,由对方负责数据面与限流基础设施。

契约在 tag v1.9.0proto/remoteinfra/service.proto

service EnvoyGatewayRemoteInfrastructureProvider {
  rpc CreateOrUpdateProxyInfra(CreateOrUpdateProxyInfraRequest) returns (CreateOrUpdateProxyInfraResponse);
  rpc DeleteProxyInfra(DeleteProxyInfraRequest) returns (DeleteProxyInfraResponse);
  rpc CreateOrUpdateRateLimitInfra(CreateOrUpdateRateLimitInfraRequest) returns (CreateOrUpdateRateLimitInfraResponse);
  rpc DeleteRateLimitInfra(DeleteRateLimitInfraRequest) returns (DeleteRateLimitInfraResponse);
}

CreateOrUpdateProxyInfra 携带结构化 Infra 消息,镜像 internal/ir/infra.go:元数据、名字、命名空间、listener 端口、已解析的 metric sink。config 字段是 JSON 编码的 EnvoyProxy 字节——CRD 太大且独立演化,不放进 protobuf 字段。限流四个 RPC 无参数;限流检查地址仍要在 EnvoyGateway.rateLimit.url 写成带 host:port 的 grpc:// URL,否则回退到 Kubernetes provider 本应创建的 Service 地址。

启用方式是 provider.type: Customcustom.resource 仍为 Kubernetes,custom.infrastructure.type: Remoteservice 用与 ExtensionService 相同的形状:Unix socket、FQDN 或 IP;可配 TLS / mTLS。

官方把该组件标成特权面:它收到每个 Gateway 的完整 InfraIR。被攻破或配错的 provider 可以停建代理、部署攻击者控制的数据面、或把代理暴露到不该到的网络。任务文档要求与 Envoy Gateway 同一节奏审计——bump 控制器可能改变 IR 形状。example(examples/remote-infra)只调谐 Deployment+Service,不是生产级实现。本文不写任何云厂商的「对接教程」——那些材料未在 v1.9 官方契约里核过,不能当 A 级。

生产级 provider 至少还要处理官方任务点到、example 没做的部分:限流基础设施(那四个无参 RPC)、幂等的 server-side apply、以及 rateLimit.url 与实际暴露地址一致。IR 里的 resolved_metric_sinks 已带 endpoint 与上游 TLS,provider 若忽略它们,遥测会在数据面「看起来开了」但出口是错的。

责任面变化可以收成一句话:XdsIR 与 xDS 服务器仍在 Envoy Gateway;InfraIR 的执行权被让出。 Programmed 变绿不再等价于「本集群有一个 Infra Manager 创建的 Pod」。排障必须先问 provider 是否幂等落地了最新 IR。官方要求 provider 对高频 CreateOrUpdate 幂等(churn 时每秒多次),并与 Envoy Gateway 同频率审计——IR 形状会随版本变。控制面日志里看到 gRPC 成功,只证明 IR 送出;Serving 与否是 provider 的 SLO,v1.9 没有把该 SLO 编进 Gateway status 的保证句。


五、mergeBackends experimental

EnvoyProxy.spec.mergeBackends 在 v1.9.0 新增、默认关闭、标 experimental。打开后,引用同一后端的多条路由共享一个 Envoy cluster,而不是每条 route rule 一个 cluster,以减小 xDS、主动健康检查流量和 stats 基数。API 写明:字段一旦出现(即使没有子配置)即启用;与 mergeGateways 互斥

渐进开关是 mergeBackends.selector:只对 Service / ServiceImport / Backend 标签匹配的后端做去重。未设 selector 则对所有否则合格的后端合并;不合格的 backendRef 仍回退到每路由独立 cluster。

v1.9.0 还修过一处:路由 parentRef 省略 sectionName 时,mergeBackends 会错误地共享或拆开 cluster。修复后按路由 实际附着的每个 listener 检查 ClusterSettings 是否可合并,而不是按字面上的 sectionName

不要把「减小 xDS」写成已在生产默认生效的优化。未打开字段就是关。实验结论需要集群数字;本篇 未跑,不写压缩比。

flowchart LR
  subgraph cp["Control plane"]
    watch["K8s Provider watch"]
    trans["Gateway API Translator"]
    xdsir["XdsIR"]
    infroir["InfraIR"]
    xdstr["xDS Translator"]
    xds["xDS gRPC server"]
  end
  subgraph dp["Dataplane ownership"]
    k8s["K8s Infra Manager"]
    remote["Remote provider gRPC"]
    fleet["Envoy fleet"]
  end
  watch --> trans
  trans --> xdsir
  trans --> infroir
  xdsir --> xdstr --> xds --> fleet
  infroir --> k8s
  infroir --> remote
  k8s --> fleet
  remote --> fleet

图:XdsIR 始终由本进程的 xDS 服务器消费;InfraIR 在 v1.9 可留在 Kubernetes Infra Manager,或让渡给 Remote provider。节点为英文。

部署模式 数据面对象落点 xDS 认证(官方叙述) 谁调谐 Pod
Controller Namespace(默认) 控制器命名空间 双向 mTLS Kubernetes Infra Manager
GatewayNamespace 每个 Gateway 的命名空间 服务端 TLS + SA JWT Kubernetes Infra Manager(跨 ns RBAC)
Remote infrastructure 由 provider 决定(可跨集群 / 非 K8s) 仍由控制器提供 xDS;传输面是 provider 的事 远程 gRPC 服务

六、谱系、争论与开放问题

控制面 / 数据面分离(网络控制平面经典问题)
  → Envoy 作为可编程数据面 + xDS(Universal Data Plane API)
  → Istio:控制面常通过注入或修订管理 sidecar 生命周期
  → Envoy Gateway:独立南北向舰队,Infra Manager 调谐 Deployment
  → v1.9:InfraIR 可经 gRPC 让渡(Remote provider)

Burns et al.(Borg, Omega, and Kubernetes, ACM Queue 2016)把 Kubernetes 写成持续调谐的控制循环:声明对象,控制器把世界推回声明。Infra Manager 是这条循环在「Envoy Deployment」上的实例。Remote provider 把循环的 执行端 移出进程,但没有取消循环——CreateOrUpdate 仍可能每秒多次,provider 必须幂等。这与「一次 Terraform apply」不是同一运维模型。

Istio 把工作负载身份与 sidecar 生命周期绑在应用 Pod 上;Envoy Gateway 默认把南北向代理做成 独立舰队。GatewayNamespaceMode 是折中:舰队仍独立,但落在租户命名空间,身份改用 SA JWT 而不是把客户端证书发进每个租户 ns。JWT 作为承载令牌(RFC 7519)把「谁可以连 xDS」从证书分发改成 TokenReview;v1.9 的认证绕过修复说明:模式切换不只是 RBAC 表格,而是 xDS 信任根的替换。Unary RPC 与 SotW 流若有一条 fail-open,就会把「能连上 xDS」误读成「已认证」。安全更新必须当补丁吃,不能当成「行为不变的小版本」。

争论:隔离(每 Gateway 一命名空间、每租户一舰队)vs 运维复杂度(跨 ns RBAC、JWT 与证书轮转、不能与 mergeGateways 组合)。另一侧是 Remote provider:最大灵活性,代价是把 CIA 信任边界扩到自研服务。官方原文写「Most users should use the built-in Kubernetes infrastructure provider」。第三条分叉是 mergeBackends:用 cluster 去重换 xDS 体积,但与 mergeGateways 互斥,且仍是 experimental——论文式的「合并一定更优」在这里不成立,因为 listener 级 ClusterSettings 不一致时必须拆开,错误合并会把不该共享健康检查的后端绑在一起。

开放问题:Remote provider 的责任面如何做成可审计 SLO——InfraIR 已发送、provider ACK、数据面实际 serving 是否三阶段可观测?v1.9 的 xdsNACKTotal 只覆盖 xDS 轴(第 11 篇),不覆盖「provider 把 Pod 建成了错误形状」。跨集群数据面与控制面的失败域如何写进与 Cilium 四元组的联合 runbook,留到第 16 篇。GatewayNamespaceMode 与 ListenerSet(官方更推荐的多监听器分组)如何在「不要 mergeGateways」的前提下覆盖原合并舰队的地址共享需求,也仍开放。


七、小结

  1. EnvoyProxy 描述舰队;Infra Manager 把 InfraIR 变成 Pod。路由 Accepted 不蕴含舰队存在。
  2. GatewayNamespaceMode 改变落点与 xDS 认证;v1.9 修复认证绕过(Unary interceptor + SotW 校验)。
  3. Remote provider 让渡 InfraIR 执行权,官方示例不是生产实现。
  4. mergeBackends 默认关、experimental;用 selector 渐进,且与 mergeGateways 互斥。

下一篇问这些层上的信号能证明什么。


八、参考资料

规范 / 官方文档(A)

源码(A)

核心论文

实验 / 工具

站内对照


上一篇:Policy attachment · 系列目录 · 下一篇:可观测

读完这篇,下一步读什么

优先读同系列或同问题的下一篇,把单篇消费变成主题集群。


By .