Kubernetes Gateway API 是社区力推的新一代流量治理标准,用来取代已经显出疲态的 Ingress。它通过 Gateway、GatewayClass、HTTPRoute 等一组角色化资源,把“谁能建网关、怎么路由流量”拆得清清楚楚,原生支持流量分割、基于请求头的路由、跨命名空间引用等 Ingress 难以实现的能力。如果你正在被 Ingress 的 annotations 满天飞、功能受限所困扰,Gateway API 值得立刻评估。
一、为什么需要 Gateway API:Ingress 的三大痛点
经典 Ingress 只有一条规则模型:一个 Ingress 资源描述“域名 + 路径 → 后端 Service”。这带来三个绕不开的问题。
- 表达能力弱:加权负载均衡、基于请求头的路由、请求/响应改写,几乎都要靠各厂商私有的 annotation(如
nginx.ingress.kubernetes.io/前缀),可移植性极差。 - 权限不分租户:任何能创建 Ingress 的人都能指向任意 Service,基础设施团队无法把“建网关”和“配路由”两个权限分离开。
- 扩展靠碎片:想加新功能就得等控制器厂商实现新 annotation,社区无法用一套标准覆盖所有实现。
Gateway API 的核心思路是面向角色(role-oriented):把“基础设施提供方”“网关运维方”“应用开发者”三种角色用不同的 CRD 分开,谁该管什么一目了然。它与我们之前讲过的 Nginx 反向代理 思想一脉相承,只是把配置搬到了声明式 API 上。
二、Gateway API 的核心资源模型
落地前先厘清四个关键资源:
| 资源 | 角色 | 负责方 | 作用 |
|---|---|---|---|
| GatewayClass | 集群级模板 | 基础设施团队 | 定义“网关由哪种控制器实现”(类似 StorageClass) |
| Gateway | 网关实例 | 平台/运维团队 | 声明监听端口、域名与可被谁引用 |
| HTTPRoute | 路由规则 | 应用开发者 | 把请求按路径/头/方法转发到具体 Service |
| ReferenceGrant | 跨命名空间授权 | 运维团队 | 允许某命名空间的 HTTPRoute 引用另一个命名空间的 Service |
这种拆分让“建网关”和“配路由”彻底解耦:平台团队把 Gateway 建好交给开发者,开发者只需关心自己的 HTTPRoute,互不踩脚。
三、环境准备:安装 CRD 与控制器
Gateway API 本身是 CRD,需要先在集群里安装标准资源定义,再选一个支持它的控制器(主流有 Istio、Envoy Gateway、NGINX Gateway Fabric)。下面以 Envoy Gateway 为例。
# 安装 Gateway API 标准 CRD(与具体控制器解耦)
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml
# 用 Helm 安装 Envoy Gateway 控制器
helm repo add envoy-gateway https://helm.envoy.io
helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.2.0 -n envoy-gateway --create-namespace
# 等待控制器就绪
kubectl rollout status deployment -n envoy-gateway envoy-gateway
由于控制器本身以容器方式运行,建议把它和业务的 Docker 镜像统一纳入镜像仓库与版本管理,避免环境漂移。
四、定义 Gateway:把“门”立起来
Gateway 资源声明“监听什么端口、允许哪些命名空间把路由挂上来”。下面这段由平台团队维护:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: public-gateway
namespace: gateway-system
spec:
gatewayClassName: eg # 对应 Envoy Gateway 提供的 GatewayClass
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All # 允许所有命名空间的 HTTPRoute 挂到这个网关
创建后,Envoy Gateway 会自动生成一个 LoadBalancer 类型的 Service,把外部流量接进来。
五、用 HTTPRoute 做路由与流量分割
开发者现在只需写 HTTPRoute,把它 parentRef 指向上面的 Gateway 即可。最基础的“路径路由”:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: store-route
namespace: store
spec:
parentRefs:
- name: public-gateway
namespace: gateway-system
hostnames: ["store.example.com"]
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: store-api
port: 8080
更香的是原生流量分割——再也不用靠 annotation 凑权重。下面把 /api 按 80/20 切到新旧两个版本,做灰度发布:
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: store-api-v1
port: 8080
weight: 80
- name: store-api-v2
port: 8080
weight: 20
六、进阶:基于头的路由、重定向与重写
Gateway API 把很多 Ingress 需要 annotation 才能实现的能力变成了一等公民。例如“带 x-canary: true 头的请求全打到 v2”:
rules:
- matches:
- headers:
- type: Exact
name: x-canary
value: "true"
path:
type: PathPrefix
value: /api
backendRefs:
- name: store-api-v2
port: 8080
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: store-api-v1
port: 8080
请求路径重写也只需在 rule 里加 filters,例如把 /api 转发到后端时剥掉前缀:
rules:
- matches:
- path:
type: PathPrefix
value: /api
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /
backendRefs:
- name: store-api
port: 8080
七、与 Ingress-NGINX 的差异与迁移建议
如果你已经在用经典 Ingress,可以参考下面这张对照表决定迁移节奏:
| 能力 | Ingress (Ingress-NGINX) | Gateway API |
|---|---|---|
| 加权负载均衡 | 靠 annotation,厂商私有 | HTTPRoute backendRefs.weight 原生 |
| 基于头的路由 | 有限、需 annotation | matches.headers 原生 |
| 跨命名空间引用 | 不支持 | ReferenceGrant 原生 |
| 角色/权限分离 | 无 | GatewayClass/Gateway/HTTPRoute 分角色 |
| 可移植性 | 实现相关 | 标准 CRD,多控制器通用 |
迁移不必一步到位:很多控制器(如 NGINX Gateway Fabric、Istio)可同时支持 Ingress 与 Gateway API,建议先在新业务上试点 HTTPRoute,跑稳后再逐步把老 Ingress 搬迁过来。
八、生产排障 Checklist
| 现象 | 优先排查项 |
|---|---|
| HTTPRoute 不生效 | parentRefs 的 name/namespace 是否写对;Gateway 的 allowedRoutes 是否放行该命名空间 |
| 跨命名空间 503 | 是否缺少 ReferenceGrant 授权 Service 所在命名空间 |
| 权重不生效 | 确认控制器版本支持流量分割,且后端 Service 就绪 |
| 外部访问不通 | 检查 Gateway 对应 LoadBalancer Service 是否拿到外部 IP、安全组是否放通 |
排障时可以 kubectl describe gateway/public-gateway 与 kubectl get httproute -A 看控制器写入的状态与条件,比翻 Ingress 日志直观得多。
九、用 GitHub Actions 把网关配置纳入 CI/CD
Gateway/HTTPRoute 都是声明式 YAML,天然适合放进 Git 做版本化与自动化发布。在 GitHub Actions 里加一步即可:
# .github/workflows/deploy-gateway.yml
name: deploy-gateway
on:
push:
paths: ["gateway/**"]
jobs:
apply:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: azure/setup-kubectl@v4
- run: kubectl apply -f gateway/gateway.yaml
- run: kubectl apply -f gateway/store-route.yaml
把网关配置和代码一起走 PR 审核,既能审计变更,也能在回滚时一键 kubectl apply 旧版本,运维体验比手动改 Ingress 清爽太多。
十、超时、重试与熔断:把韧性写进路由
入口网关是整条链路的咽喉,网络抖动和后端偶发慢响应都会在这里被成倍放大。Gateway API 通过 HTTPRoute 的 timeouts 与 retry 字段把韧性策略声明化,不再依赖控制器私有配置,也不需要去改 Ingress 那一长串难以维护的 annotation。
rules:
- matches:
- path:
type: PathPrefix
value: /api
timeouts:
request: "10s" # 单次请求最长 10 秒
backendRequest: "8s"
retry:
attempts: 3
perTryTimeout: "2s"
retryOn: "5xx,reset,connect-failure"
backendRefs:
- name: store-api
port: 8080
这样配置后,即使后端短暂抖动,网关也会在每次尝试 2 秒超时的前提下最多重试 3 次,既保护了用户体验,又避免把瞬时压力无脑转嫁给上游。再配合上游服务自身的熔断(例如 Resilience4j),就能挡住绝大部分级联故障,而这整套配置如今都是可读、可审计的 YAML。
十一、TLS 终止与证书管理
生产环境的入口必须走 HTTPS,否则不仅有安全风险,还会被现代浏览器标记为“不安全”。Gateway 的 listener 可以直接声明 TLS 终止,并引用集群里的 Secret 作为证书;再配合 cert-manager 自动签发与续期,运维心智负担会大幅降低,不必再为证书过期半夜爬起来手动轮换。
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: example-com-tls # 由 cert-manager 维护的 Secret
group: ""
kind: Secret
把证书生命周期整体交给 cert-manager 之后,你只需要在 HTTPRoute 上配好域名,剩下的签发、续期、轮换都由控制器自动完成,再也不用盯着证书过期邮件提心吊胆。这也是 Gateway API 相比传统 Ingress 在“生产就绪”维度上更省心的一点。
十二、小结
Gateway API 不是 Ingress 的修补,而是重新设计:用角色化资源和原生流量治理能力,解决了 Ingress 表达弱、权限混、难扩展的顽疾。它已经是 Kubernetes 流量治理的事实下一代标准,新项目建议直接上手 HTTPRoute,老项目可平滑迁移。把它和 GitOps/CI 结合起来,你的入口网络会更清晰、更可控。




