8.1. Ingress 之后:Gateway API

Ingress 解决了「域名和路径转发到哪个 Service」,但把 TLS、流量分割、头路由、跨命名空间授权都塞进注解,导致不同控制器的行为互不兼容。Gateway API 用类型化资源把「谁管入口、谁管路由、谁管后端」拆开,是 Ingress 的下一代标准。

层级:

L3 · 平台

难度:

进阶

预计:

50 分钟

前置:

Service、Ingress、TLS 基础

8.1.1. Ingress 的边界

Ingress 的核心字段只有 rules、tls 和 backend。灰度权重、重写、超时、重试、mTLS 等能力通常靠控制器注解实现,例如 ingress-nginx 的 nginx.ingress.kubernetes.io/*。这带来三个问题:

  • 注解不是标准,换控制器就要重写。

  • 权限边界模糊:应用团队改一个 Ingress,可能顺带改掉入口的安全策略。

  • 多团队共享入口时,难以表达「网关管理员」与「路由所有者」的分工。

Gateway API 把这些问题拆成 GatewayClass → Gateway → HTTPRoute 三层。

8.1.2. 资源模型

资源

谁负责

作用

GatewayClass

平台/基础设施团队

声明使用哪个网关实现,如 Envoy Gateway、Traefik

Gateway

平台/网关管理员

定义监听端口、TLS、允许挂载的命名空间

HTTPRoute

应用团队

定义域名、路径、头匹配、后端与权重

架构图

图:GatewayClass 选择实现,Gateway 管监听与 TLS,HTTPRoute 管应用路由。

8.1.3. 安装 Envoy Gateway

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

如果使用 Traefik、Kong 或 HAProxy,安装对应的 Gateway API 实现即可;HTTPRoute 的写法基本一致,差异在 GatewayClass 与部分扩展字段。

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

8.1.4. HTTPRoute:路径、头与权重

httproute-demoapp.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: demoapp
  namespace: default
spec:
  parentRefs:
    - name: prod-gw
  hostnames:
    - demo.example.com
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: demoapp-v1
          port: 80
          weight: 90
        - name: demoapp-v2
          port: 80
          weight: 10

权重是 Gateway API 的原生字段,不需要控制器注解。把 90/10 改成 50/50 再观察错误率,就是最小可用的金丝雀发布。

8.1.4.1. 头匹配与重定向

httproute-header.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: demoapp-canary
  namespace: default
spec:
  parentRefs:
    - name: prod-gw
  hostnames:
    - demo.example.com
  rules:
    - matches:
        - headers:
            - name: x-canary
              value: "true"
      backendRefs:
        - name: demoapp-v2
          port: 80
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: demoapp-v1
          port: 80

带 x-canary: true 的请求进入 v2,其余进入 v1。与 Ingress 注解相比,这种规则是类型化、可校验、可移植的。

8.1.5. 实验:从 Gateway 到两个版本

kubectl create deployment demoapp-v1 --image=ikubernetes/demoapp:v1.0
kubectl create deployment demoapp-v2 --image=ikubernetes/demoapp:v2.0
kubectl expose deployment demoapp-v1 --name=demoapp-v1 --port=80
kubectl expose deployment demoapp-v2 --name=demoapp-v2 --port=80
kubectl apply -f gateway.yaml
kubectl apply -f httproute-demoapp.yaml
kubectl get httproute demoapp -o yaml

用 curl -H 'Host: demo.example.com' http://<gateway-ip>/ 连续请求,观察 v1/v2 比例。Envoy Gateway 的 Gateway 地址可用 kubectl get gateway prod-gw -o jsonpath='{.status.addresses[0].value}' 获取。

8.1.6. 与 Ingress 的迁移策略

  1. 先让新旧入口并行,DNS 或负载均衡按比例切流。

  2. 把 Ingress 注解翻译成 HTTPRoute 的 matches/filters/backendRefs。

  3. 验证 TLS、重写、超时、重试、灰度、访问日志。

  4. 确认回滚路径后,再删除旧 Ingress。

不要一次性重写所有入口;先挑一个无状态、低风险的域名试点。

8.1.7. 验证清单

  • GatewayClass 处于 Accepted,Gateway 有地址且 Programmed。

  • HTTPRoute 的 parentRefs 指向正确的 Gateway。

  • 权重、头匹配、路径匹配都按预期生效。

  • TLS 证书与监听器配置正确,HTTP 能按需重定向到 HTTPS。

  • 跨命名空间路由已通过 allowedRoutes 显式授权。

8.1.8. 排错表

现象

原因

处理

Gateway 一直 Pending

没有可用的 GatewayClass/控制器

kubectl get gatewayclass、查控制器日志

HTTPRoute Accepted=False

parentRefs 名字/命名空间错误

kubectl describe httproute

404

hostname/path 不匹配

检查 Host 头与 matches

权重不生效

后端 Service 没有 Endpoints

kubectl get endpoints

TLS 握手失败

Secret 不在 Gateway 命名空间/格式错

检查 certificateRefs 与证书链

8.1.9. 进阶挑战

  1. 用 HTTPRoute 实现 /api 与 /web 两个后端的路由。

  2. 配置 HTTP → HTTPS 重定向,并验证 HSTS 头。

  3. 用两个 Gateway 实现内外网隔离,allowedRoutes 只允许指定命名空间。

  4. 把现有 ingress-nginx 的一个域名迁移到 Gateway API,写一份回滚步骤。

8.1.10. 小结

  • Gateway API 用 GatewayClass/Gateway/HTTPRoute 拆分角色与职责。

  • 权重、头匹配、重定向是原生字段,不再依赖控制器注解。

  • 迁移要并行运行、逐域名切换,不要一次性替换所有入口。

  • 新项目优先 Gateway API;存量 ingress-nginx 可以按域名逐步迁移。

8.1.11. 延伸阅读