土法炼钢兴趣小组的算法知识备份

Gateway API:Kubernetes 流量管理的未来标准

目录

Ingress 从 Kubernetes 1.1 开始陪伴社区走过了近十年。它用一个极简的资源抽象——hostname + path 到 Service 的映射——解决了 HTTP 反向代理的基本需求。但随着生产环境对流量管理的要求越来越精细(金丝雀、Header 路由、gRPC、跨 namespace 共享网关、角色隔离),Ingress 那张薄薄的 spec 已经无法承载,各厂商不得不把差异化能力塞进 annotation 里,导致”同一份 YAML 换个控制器就不工作”的困境。

Gateway API 正是为了终结这一困境而生。它不是 Ingress v2,而是一套全新的、面向角色的、可扩展的流量管理 API。自 2023 年 v1.0 GA 以来,Istio、Cilium、Contour、Envoy Gateway、NGINX Gateway Fabric 等主流实现相继宣布生产就绪。SIG-Network 已明确:Gateway API 是 Kubernetes 入口流量管理的推荐方案,Ingress 将进入维护模式。

本文将从设计哲学讲到核心资源、从高级流量管理讲到 GAMMA 网格扩展,最后用 Envoy Gateway 完成一次金丝雀发布实验。

本文基于 Gateway API v1.2、Kubernetes 1.31、Envoy Gateway v1.2。 实验环境:kind v0.24、Envoy Gateway v1.2、Ubuntu 22.04。

Gateway API 核心资源关系

一、为什么需要 Gateway API

Ingress 的局限性

Ingress 的问题可归纳为四类:

  1. 表达能力不足:spec 只支持 host + path 路由,Header 匹配、权重分流、请求改写等高级特性只能依赖不可移植的 annotation。
  2. 角色模型缺失:单一层级资源,无法表达”基础设施团队管网关、应用团队管路由”的分层权限。
  3. 协议覆盖不足:仅面向 HTTP/HTTPS,TCP、UDP、gRPC、TLS passthrough 需另起资源或 annotation 变通。
  4. 跨 namespace 能力薄弱:backend 只能引用同 namespace 的 Service,跨 namespace 需 ExternalName 等变通手段。

Gateway API 的设计目标

Gateway API 的 GEP 明确了以下设计目标:


二、设计哲学:角色分离模型

Gateway API 最核心的设计理念是角色分离,把 Ingress 拆成三个层级的资源,每个层级对应一个组织角色。

Gateway API 角色分离模型

Infrastructure Provider(基础设施提供者)

负责部署 Gateway 控制器并创建 GatewayClass。GatewayClass 是集群级别资源,声明集群中可用的网关实现,类比 StorageClass 之于 PVC。

apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: envoy
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller

Cluster Operator(集群运维)

负责创建 Gateway 资源,代表一个实际的数据面实例——监听端口、TLS 证书、Route 绑定策略。

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: main-gateway
  namespace: infra-gw
spec:
  gatewayClassName: envoy
  listeners:
  - name: https
    protocol: HTTPS
    port: 443
    tls:
      mode: Terminate
      certificateRefs:
      - name: wildcard-cert
        namespace: cert-store
    allowedRoutes:
      namespaces:
        from: Selector
        selector:
          matchLabels:
            gateway-access: "true"

allowedRoutes.namespaces 控制哪些 namespace 的 Route 可以绑定——运维决定”谁可以接入”。tls.certificateRefs 可跨 namespace 引用证书(需配合 ReferenceGrant)。

Application Developer(应用开发者)

在自己的 namespace 中创建 Route 资源,通过 parentRefs 绑定到 Gateway:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: shop-route
  namespace: app-team-a
spec:
  parentRefs:
  - name: main-gateway
    namespace: infra-gw
    sectionName: https
  hostnames:
  - "shop.example.com"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /api
    backendRefs:
    - name: shop-api
      port: 8080

开发者无需关心网关实现细节或 TLS 配置。平台团队可通过 RBAC 限制只有运维角色才能创建 Gateway,开发者只能创建 Route。


三、核心资源拆解

Gateway API 由一组 CRD 组成,按层级从上到下:GatewayClass、Gateway、xRoute、ReferenceGrant。

GatewayClass

集群作用域资源,核心字段 controllerName 声明负责管理的控制器。parametersRef 可选,允许引用实现特定配置对象。一个集群中可同时存在多个 GatewayClass。

apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: istio
spec:
  controllerName: istio.io/gateway-controller
  parametersRef:
    group: config.istio.io
    kind: IstioOperator
    name: default

Gateway

Namespace 级别资源,代表实际数据面实例,核心是 listeners 数组。控制器回写 status 报告就绪状态:Programmed: True 表示配置已下发到数据面,Accepted: True 表示配置被接受。

HTTPRoute

最常用的路由资源,支持 Header 匹配、权重路由等在 Ingress 中需要 annotation 的功能。支持的匹配条件:

字段 类型 说明
path Exact / PathPrefix / RegularExpression 路径匹配
headers Exact / RegularExpression Header 匹配
queryParams Exact / RegularExpression 查询参数匹配
method GET / POST / PUT / DELETE … HTTP 方法匹配

示例——Header 匹配 + 权重分流:

rules:
- matches:
  - path:
      type: PathPrefix
      value: /v2
    headers:
    - name: x-canary
      value: "true"
  backendRefs:
  - name: api-v2
    port: 8080
- matches:
  - path:
      type: PathPrefix
      value: /v2
  backendRefs:
  - name: api-v1
    port: 8080
    weight: 90
  - name: api-v2
    port: 8080
    weight: 10

GRPCRoute

为 gRPC 流量提供原生路由支持(v1.2 Standard channel),按 service/method 匹配:

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: grpc-route
  namespace: app
spec:
  parentRefs:
  - name: main-gateway
    namespace: infra-gw
  rules:
  - matches:
    - method:
        service: com.example.UserService
        method: GetUser
    backendRefs:
    - name: user-service
      port: 9090

TLSRoute 与 TCPRoute

TLSRoute 用于 TLS passthrough(基于 SNI 路由),TCPRoute 用于纯四层转发,两者目前在 Experimental channel:

apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
  name: tls-passthrough
spec:
  parentRefs:
  - name: main-gateway
    sectionName: tls-passthrough
  hostnames:
  - "secure.example.com"
  rules:
  - backendRefs:
    - name: secure-backend
      port: 8443
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
  name: mysql-route
spec:
  parentRefs:
  - name: main-gateway
    sectionName: mysql
  rules:
  - backendRefs:
    - name: mysql-primary
      port: 3306

四、ReferenceGrant:跨 Namespace 的安全引用

Gateway API 默认禁止跨 namespace 引用——这是安全性设计。ReferenceGrant 提供显式授权:被引用方 namespace 的管理员声明”允许来自某 namespace 的某类资源引用本 namespace 中的某类资源”。

apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
  name: allow-app-team-a
  namespace: backend-shared
spec:
  from:
  - group: gateway.networking.k8s.io
    kind: HTTPRoute
    namespace: app-team-a
  to:
  - group: ""
    kind: Service

同理可授权 Gateway 跨 namespace 引用 Secret(TLS 证书)。设计要点:授权由被引用方控制;from/to 可精确到 group、kind、namespace;ReferenceGrant 必须部署在被引用资源所在 namespace。


五、与 Ingress 的全面对比

维度 Ingress Gateway API
API 版本 networking.k8s.io/v1(稳定) gateway.networking.k8s.io/v1(稳定)
角色模型 单一层级 三层:GatewayClass / Gateway / Route
HTTP 路由 host + path host + path + header + query + method
权重路由 annotation(不可移植) 原生 backendRefs weight
gRPC 不原生支持 GRPCRoute(Standard)
TCP/UDP 不支持 TCPRoute / UDPRoute(Experimental)
TLS passthrough annotation(不可移植) TLSRoute(Experimental)
跨 namespace 不支持 ReferenceGrant
请求改写 annotation(不可移植) HTTPRoute filter(Standard)
流量镜像 annotation(不可移植) HTTPRoute filter(Experimental)
扩展机制 annotation Policy Attachment / filter / parametersRef
可移植性 低(依赖 annotation) 高(核心 spec 可移植)
状态报告 简单 丰富(per-listener / per-route conditions)

扩展机制对比

Ingress 的扩展完全依赖非类型化的 annotation,没有 schema 校验和版本控制。Gateway API 提供三种标准化扩展机制:

1. Filter:在 HTTPRoute rules 中内联,用于请求/响应改写。

rules:
- filters:
  - type: RequestHeaderModifier
    requestHeaderModifier:
      add:
      - name: x-request-id
        value: "generated-by-gateway"
  - type: URLRewrite
    urlRewrite:
      path:
        type: ReplacePrefixMatch
        replacePrefixMatch: /v2

2. Policy Attachment:通过 targetRef 将策略附加到 Gateway 或 Route,用于超时、重试、限流等。

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
  name: timeout-policy
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: HTTPRoute
    name: shop-route
  timeout:
    http:
      connectionIdleTimeout: 60s
      requestTimeout: 15s
  retry:
    numRetries: 3
    retryOn:
    - gateway-error
    - connection-failure

3. parametersRef:GatewayClass 和 Gateway 可通过 parametersRef 引用实现特定配置对象。


六、高级流量管理

以下是生产中常见的高级流量管理场景。

金丝雀发布(Canary)

通过 backendRefs 的 weight 字段实现按比例分配,配合 CI/CD 逐步调整即可实现渐进式发布:

rules:
- backendRefs:
  - name: app-stable
    port: 8080
    weight: 95
  - name: app-canary
    port: 8080
    weight: 5

Header-based 路由

将特定 Header 的请求路由到指定后端,常用于内部测试或 A/B 实验:

rules:
- matches:
  - headers:
    - name: x-env
      value: staging
  backendRefs:
  - name: app-staging
    port: 8080
- matches:
  - path:
      type: PathPrefix
      value: /
  backendRefs:
  - name: app-production
    port: 8080

URL Rewrite

rules:
- matches:
  - path:
      type: PathPrefix
      value: /api/v1
  filters:
  - type: URLRewrite
    urlRewrite:
      path:
        type: ReplacePrefixMatch
        replacePrefixMatch: /v1
  backendRefs:
  - name: api-server
    port: 8080

客户端请求 /api/v1/users 会被改写为 /v1/users 后转发到 api-server

Request Mirror

将生产流量副本发送到镜像后端(Experimental channel),响应会被丢弃:

filters:
- type: RequestMirror
  requestMirror:
    backendRef:
      name: app-shadow
      port: 8080

请求/响应 Header 修改

filters:
- type: RequestHeaderModifier
  requestHeaderModifier:
    set:
    - name: x-forwarded-proto
      value: https
    remove:
    - x-internal-token

超时与重试(Policy Attachment)

超时、重试、熔断通过 Policy Attachment 实现。以 Envoy Gateway 为例:

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
  name: resilience
  namespace: app
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: HTTPRoute
    name: shop-route
  timeout:
    http:
      requestTimeout: 10s
  retry:
    numRetries: 3
    perRetry:
      timeout: 3s
    retryOn:
    - "5xx"
    - connect-failure
  circuitBreaker:
    maxConnections: 1024
    maxPendingRequests: 128

各实现有各自的 CRD,但 API 模式趋同。标准化仍在推进中(GEP-1731、GEP-1619)。


七、各实现的成熟度

合规性等级

通道 说明 对应资源
Standard GA 等效,所有实现必须支持 GatewayClass、Gateway、HTTPRoute、GRPCRoute
Experimental 可选,API 可能变更 TLSRoute、TCPRoute、UDPRoute、RequestMirror
Implementation-specific 各实现自行定义 Policy Attachment CRD

主流实现对比

实现 数据面 Standard 合规 亮点 局限
Envoy Gateway Envoy Proxy 完全 原生 Gateway API 设计;丰富 Policy Attachment 较年轻,社区规模相对较小
Istio Envoy Proxy 完全 GAMMA 最成熟;服务网格一体化 部署复杂度较高
Cilium Envoy + eBPF 完全 eBPF 加速;与网络策略集成 部分 Experimental 特性依赖 Envoy 旁路
Contour Envoy Proxy 完全 轻量级;HTTPProxy 可共存 扩展能力不如 Envoy Gateway 和 Istio
NGINX Gateway Fabric NGINX 完全 NGINX 生态;性能成熟 Experimental 特性支持较少

选型建议


八、GAMMA:Gateway API for Mesh Management and Administration

Gateway API 最初面向南北向(ingress)流量。GAMMA 子项目将其资源模型扩展到东西向(service mesh),解决各网格实现各自定义 CRD 缺乏统一标准的问题。

GAMMA 的核心理念

在 GAMMA 模型中,HTTPRoute 的 parentRef 可指向 Service(东西向),描述”如何路由到这个 Service 的流量”:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: reviews-canary
  namespace: bookinfo
spec:
  parentRefs:
  - group: ""
    kind: Service
    name: reviews
  rules:
  - backendRefs:
    - name: reviews-v1
      port: 9080
      weight: 90
    - name: reviews-v2
      port: 9080
      weight: 10

到达 reviews 的流量 90% 转发到 v1、10% 转发到 v2——即网格内金丝雀发布。

GAMMA 与传统网格 API 的对比

场景 传统方式(VirtualService) GAMMA 方式(HTTPRoute)
金丝雀路由 VirtualService + DestinationRule HTTPRoute(parentRef=Service)
Header 路由 VirtualService HTTPRoute matches
超时/重试 VirtualService Policy Attachment
可移植性 Istio 专有 跨网格可移植

Istio 从 1.22 开始将 Gateway API 作为推荐 API,计划逐步弃用 VirtualService/DestinationRule。

GAMMA 当前状态

GAMMA 在 v1.1 中进入 Experimental channel。支持情况:Istio 最完整(Service parentRef、流量分割、Header 路由);Linkerd 支持流量分割;Cilium 部分支持。长期目标是让开发者用同一套 HTTPRoute 定义南北向和东西向路由。


九、从 Ingress 迁移到 Gateway API 的实战路径

评估阶段

迁移前需回答三个问题:

  1. 当前 Ingress 用了哪些 annotation? 检查每个 annotation 在 Gateway API 中是否有原生替代。
kubectl get ingress -A -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}: {.metadata.annotations}{"\n"}{end}'
  1. 是否有跨 namespace 引用需求? 如有,需规划 ReferenceGrant。
  2. 选择哪个 Gateway API 实现? 参考第七节选型建议。

共存阶段

大多数实现可与现有 Ingress 控制器共存。推荐策略:部署 Gateway API 实现并创建 GatewayClass 和 Gateway;选择非关键应用创建 HTTPRoute 替代 Ingress;验证后逐步扩大范围;全部迁移后下线旧控制器。

资源映射

以带 rewrite 的 Ingress 为例:

# Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: simple
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /old-api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
# 等效 HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: simple
spec:
  parentRefs:
  - name: main-gateway
    namespace: infra-gw
  hostnames:
  - "app.example.com"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /old-api
    filters:
    - type: URLRewrite
      urlRewrite:
        path:
          type: ReplacePrefixMatch
          replacePrefixMatch: /
    backendRefs:
    - name: api-service
      port: 80

关键区别:在 Gateway API 中,TLS 终止由 Cluster Operator 在 Gateway 上配置,App Developer 的 HTTPRoute 只关心路由逻辑。

自动化迁移工具

社区提供 ingress2gateway 工具:

go install github.com/kubernetes-sigs/ingress2gateway@latest
ingress2gateway print --all-resources
ingress2gateway print --providers=ingress-nginx

支持 nginx、istio、kong 等主流控制器的 annotation 转换,复杂自定义 annotation 仍需手动处理。


十、实验:用 Envoy Gateway 实现金丝雀发布

环境准备

cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
EOF

kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml

helm install eg oci://docker.io/envoyproxy/gateway-helm \
  --version v1.2.0 -n envoy-gateway-system --create-namespace

kubectl wait --timeout=5m -n envoy-gateway-system \
  deployment/envoy-gateway --for=condition=Available

部署应用

部署 stable(v1)和 canary(v2)两个版本,结构相同仅 version 标签和返回文本不同:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-stable
  namespace: demo
spec:
  replicas: 2
  selector:
    matchLabels: {app: demo, version: stable}
  template:
    metadata:
      labels: {app: demo, version: stable}
    spec:
      containers:
      - name: app
        image: hashicorp/http-echo:0.2.3
        args: ["-text=stable-v1"]
        ports: [{containerPort: 5678}]
---
apiVersion: v1
kind: Service
metadata:
  name: app-stable
  namespace: demo
spec:
  selector: {app: demo, version: stable}
  ports: [{port: 8080, targetPort: 5678}]
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-canary
  namespace: demo
spec:
  replicas: 1
  selector:
    matchLabels: {app: demo, version: canary}
  template:
    metadata:
      labels: {app: demo, version: canary}
    spec:
      containers:
      - name: app
        image: hashicorp/http-echo:0.2.3
        args: ["-text=canary-v2"]
        ports: [{containerPort: 5678}]
---
apiVersion: v1
kind: Service
metadata:
  name: app-canary
  namespace: demo
spec:
  selector: {app: demo, version: canary}
  ports: [{port: 8080, targetPort: 5678}]
kubectl create namespace demo && kubectl apply -f app.yaml

创建 Gateway

Envoy Gateway 安装后会自动创建 GatewayClass,只需创建 Gateway:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: demo-gateway
  namespace: demo
spec:
  gatewayClassName: eg
  listeners:
  - name: http
    protocol: HTTP
    port: 80
    allowedRoutes:
      namespaces:
        from: Same
kubectl apply -f gateway.yaml

金丝雀发布:权重路由 + Header 路由

配置 10% 金丝雀流量,同时支持通过 Header 精准控制:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: demo-route
  namespace: demo
spec:
  parentRefs:
  - name: demo-gateway
  hostnames:
  - "demo.example.com"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
      headers:
      - name: x-canary
        value: "true"
    backendRefs:
    - name: app-canary
      port: 8080
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: app-stable
      port: 8080
      weight: 90
    - name: app-canary
      port: 8080
      weight: 10
kubectl apply -f route-canary.yaml

GW_IP=$(kubectl get gateway -n demo demo-gateway \
  -o jsonpath='{.status.addresses[0].value}')

# 普通请求:按 90/10 权重路由
for i in $(seq 1 100); do
  curl -s -H "Host: demo.example.com" http://${GW_IP}/
done | sort | uniq -c | sort -rn

# 带 canary header:100% 走 canary
curl -s -H "Host: demo.example.com" -H "x-canary: true" http://${GW_IP}/

全量切换与清理

确认 canary 稳定后,将 backendRefs 改为仅指向 app-canary 即完成全量切换。通过 kubectl get httproute -n demo demo-route -o yaml 检查 status:Accepted: True 表示 Gateway 接受路由,ResolvedRefs: True 表示 backendRef 解析成功。

kubectl delete namespace demo
kind delete cluster

十一、总结

Gateway API 解决了 Ingress 在角色模型、表达能力、可移植性上的根本缺陷,是一次彻底的重新设计。

核心要点:

  1. 角色分离:GatewayClass / Gateway / xRoute 三层资源对应三种组织角色,通过 RBAC 实现职责隔离。
  2. 核心资源:涵盖 HTTPRoute、GRPCRoute、TLSRoute、TCPRoute,以及跨 namespace 安全引用的 ReferenceGrant。
  3. 高级流量管理:金丝雀、Header 路由、URL 改写、流量镜像等能力是原生 spec,不依赖 annotation。
  4. GAMMA:将 Gateway API 从南北向扩展到东西向,为服务网格提供统一路由 API。
  5. 迁移路径:评估 annotation 依赖、选择实现、共存过渡、逐步切换。

对于新项目建议直接采用 Gateway API;存量项目制定迁移计划逐步推进。Ingress 不会立即消失,但进入维护模式已成定局。


附录 A:Gateway API 资源速查

资源 作用域 API Group 通道 管理者
GatewayClass Cluster gateway.networking.k8s.io Standard Infra Provider
Gateway Namespace gateway.networking.k8s.io Standard Cluster Operator
HTTPRoute Namespace gateway.networking.k8s.io Standard App Developer
GRPCRoute Namespace gateway.networking.k8s.io Standard App Developer
TLSRoute Namespace gateway.networking.k8s.io Experimental App Developer
TCPRoute Namespace gateway.networking.k8s.io Experimental App Developer
UDPRoute Namespace gateway.networking.k8s.io Experimental App Developer
ReferenceGrant Namespace gateway.networking.k8s.io Standard Namespace Admin

附录 B:版本演进

版本 日期 关键变更
v0.1.0 2020-06 初始发布,基本资源模型
v0.5.0 2022-07 HTTPRoute Beta,ReferenceGrant 引入
v1.0.0 2023-10 HTTPRoute、Gateway、GatewayClass GA
v1.1.0 2024-05 GRPCRoute Standard;GAMMA Experimental
v1.2.0 2024-10 GRPCRoute Standard 完善;BackendLBPolicy 引入

附录 C:推荐阅读


系列导航 - 上一篇:Ingress 控制器 - 下一篇:Network Policy - 相关:Service 进阶 | Cilium


By .