Kubernetes Gateway API实战

Kubernetes Gateway API 是 Ingress 的继任者,提供更丰富的路由能力和更清晰的角色分离。本文从核心概念到实际部署,覆盖 GatewayClass、Gateway、HTTPRoute 以及流量分割等高级用法。

为什么需要 Gateway API

Ingress 的局限性:

  1. 表达能力不足 — 只支持 host + path 路由,header 匹配、流量分割等高级功能只能通过 annotation 实现,且不同 controller 的 annotation 互不兼容
  2. 角色混淆 — 集群管理员和应用开发者共享同一个 Ingress 资源,职责边界不清
  3. 功能碎片化 — 每个 Ingress Controller(Nginx、Traefik、Envoy)都有自己的 CRD 扩展,无法移植

Gateway API 的设计目标就是解决这些问题:

维度 Ingress Gateway API
路由能力 host + path host + path + header + query + method
流量分割 不支持(需 annotation) 原生支持 weight
角色分离 GatewayClass / Gateway / Route 三层
跨命名空间 有限 ReferenceGrant 机制
协议支持 HTTP/HTTPS HTTP / HTTPS / TCP / UDP / gRPC / TLS
可移植性 annotation 不兼容 标准 API,实现可互换

核心概念

Gateway API 有三层资源,对应三种角色:

GatewayClass  (集群管理员 / 基础设施提供者)
    │
    ▼
Gateway       (平台运维)
    │
    ▼
HTTPRoute     (应用开发者)

GatewayClass

类比 Ingress 的 IngressClass,定义用什么实现来处理流量。通常由集群管理员或云厂商创建:

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

Gateway

定义监听端口和协议,类比传统的负载均衡器:

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

关键点:allowedRoutes 控制哪些命名空间的 Route 可以绑定到这个 Gateway。这是角色分离的核心——运维控制 Gateway,开发者只需要创建 Route。

HTTPRoute

应用开发者定义路由规则:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: app-routes
  namespace: my-app
spec:
  parentRefs:
    - name: prod-gateway
      namespace: gateway-infra
  hostnames:
    - "api.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /v1/users
      backendRefs:
        - name: user-service
          port: 8080
    - matches:
        - path:
            type: PathPrefix
            value: /v1/orders
      backendRefs:
        - name: order-service
          port: 8080

流量分割(Canary / Blue-Green)

Gateway API 原生支持基于权重的流量分割,无需 annotation hack:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: canary-route
spec:
  parentRefs:
    - name: prod-gateway
      namespace: gateway-infra
  hostnames:
    - "app.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: app-v1
          port: 8080
          weight: 90
        - name: app-v2
          port: 8080
          weight: 10

90% 流量到 v1,10% 到 v2。调整 weight 值即可控制灰度比例,完成金丝雀发布。

Header 匹配与请求修改

基于 Header 路由

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

x-canary: true header 的请求走 v2,其余走 v1。适合测试人员精准验证新版本。

请求/响应修改

rules:
  - matches:
      - path:
          type: PathPrefix
          value: /api/legacy
    filters:
      - type: URLRewrite
        urlRewrite:
          path:
            type: ReplacePrefixMatch
            replacePrefixMatch: /api/v2
      - type: RequestHeaderModifier
        requestHeaderModifier:
          add:
            - name: x-forwarded-prefix
              value: /api/legacy
    backendRefs:
      - name: new-api-service
        port: 8080

与 Envoy Gateway 集成

Envoy Gateway 是目前最活跃的 Gateway API 实现之一。部署:

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

# 验证
kubectl get gatewayclass
# NAME            CONTROLLER                                      AGE
# eg              gateway.envoyproxy.io/gatewayclass-controller    30s

Envoy Gateway 会自动为每个 Gateway 资源创建 Envoy Proxy 的 Deployment 和 Service,无需手动管理 Envoy 配置。

查看实际生成的 Envoy 配置

# 查看 Envoy Gateway 为某个 Gateway 生成的 xDS 配置
egctl config envoy-proxy route -n envoy-gateway-system

实际部署示例

一个完整的多服务部署:

# 1. Gateway (运维创建)
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: main-gw
  namespace: infra
spec:
  gatewayClassName: eg
  listeners:
    - name: http
      protocol: HTTP
      port: 80
      allowedRoutes:
        namespaces:
          from: All
---
# 2. API 路由 (后端团队创建)
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: api-routes
  namespace: backend
spec:
  parentRefs:
    - name: main-gw
      namespace: infra
  hostnames:
    - "api.myapp.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /users
          method: GET
      backendRefs:
        - name: user-svc
          port: 8080
    - matches:
        - path:
            type: PathPrefix
            value: /users
          method: POST
      backendRefs:
        - name: user-write-svc
          port: 8080
---
# 3. 前端路由 (前端团队创建)
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: frontend-route
  namespace: frontend
spec:
  parentRefs:
    - name: main-gw
      namespace: infra
  hostnames:
    - "myapp.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: frontend-svc
          port: 3000

不同团队在各自的 namespace 中管理自己的 HTTPRoute,互不干扰,都绑定到同一个 Gateway。这就是 Gateway API 角色分离的实际体现。

从 Ingress 迁移

如果已有 Ingress 配置,迁移步骤:

  1. 安装 Gateway API CRD 和控制器
  2. 创建 GatewayClass 和 Gateway
  3. 将 Ingress 规则逐个转换为 HTTPRoute
  4. 验证流量正常后删除旧 Ingress

大多数 Gateway API 控制器可以与现有 Ingress Controller 并存,支持渐进式迁移。

Gateway API 已经进入 GA(v1.0+),是 Kubernetes 流量管理的未来方向。如果你正在启动新项目或升级现有基础设施,现在是采用 Gateway API 的好时机。