Kubernetes Gateway API 是 Ingress 的继任者,提供更丰富的路由能力和更清晰的角色分离。本文从核心概念到实际部署,覆盖 GatewayClass、Gateway、HTTPRoute 以及流量分割等高级用法。
为什么需要 Gateway API
Ingress 的局限性:
- 表达能力不足 — 只支持 host + path 路由,header 匹配、流量分割等高级功能只能通过 annotation 实现,且不同 controller 的 annotation 互不兼容
- 角色混淆 — 集群管理员和应用开发者共享同一个 Ingress 资源,职责边界不清
- 功能碎片化 — 每个 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 配置,迁移步骤:
- 安装 Gateway API CRD 和控制器
- 创建 GatewayClass 和 Gateway
- 将 Ingress 规则逐个转换为 HTTPRoute
- 验证流量正常后删除旧 Ingress
大多数 Gateway API 控制器可以与现有 Ingress Controller 并存,支持渐进式迁移。
Gateway API 已经进入 GA(v1.0+),是 Kubernetes 流量管理的未来方向。如果你正在启动新项目或升级现有基础设施,现在是采用 Gateway API 的好时机。