半支烟隐 pzishuo2026-08-06 12:02
Kubernetes Gateway API 完全指南
从 Ingress 到 Gateway API:为什么需要一次进化?在 Kubernetes 的世界里,服务暴露和流量管理一直是核心议题。早期,我们使用 Ingress 资源来管理外部流量,但它存在诸多痛点:缺乏跨实现的标准(不同 Ingress Controller 的注解千差万别)、无法表达复杂的流量治理(如金丝雀发布、流量镜像)、以及端口协议支持不完整(对 TCP/UDP 支持薄弱)。Gateway API 应运而生。它是由 Kubernetes SIG-NETWORK 社区主导的下一代流量管理 API,旨在提供更标准、更可移植、更具表达能力 的服务网络模型。它不再是单一资源,而是一组由 GatewayClass、Gateway、HTTPRoute 等资源组成的分层架构 。本文将从零开始,带你逐步掌握 Gateway API 的核心概念、安装配置、以及从基础到高级的实战用法。### 核心概念:三个关键角色Gateway API 的核心思想是解耦基础设施和业务路由 。它由三层资源构成:1. GatewayClass :定义网关的"类型"或"模板",类似于 StorageClass。它指向具体的 Controller(如 NGINX、Istio、Traefik),并定义了该网关的默认行为。2. Gateway :描述一个具体的网关实例,它由 GatewayClass 实例化。Gateway 定义了监听的端口、协议以及绑定的证书等。它通常由集群管理员创建。3. Route (如 HTTPRoute、TCPRoute):描述实际的流量路由规则,比如将请求路径 /foo 路由到后端服务 foo-svc:8080。Route 通常由应用开发者创建。这种分层让基础设施团队和应用团队可以各自管理自己的关注点,实现了真正的职责分离。---### 环境准备:安装 Gateway API CRD在开始之前,我们需要确保集群中安装了 Gateway API 的 CRD(自定义资源定义)。大多数现代集群可以快速安装。bash# 安装 Gateway API 标准 CRD(版本 v1.0.0 或更高)kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml# 验证安装kubectl get crd | grep gateway> 注意 :你还需要一个支持 Gateway API 的 Controller。本教程以 NGINX Gateway Fabric 为例(请根据官方文档安装),但概念是通用的。---### 基础篇:第一个 HTTP 路由让我们从最基础的场景开始:将一个 HTTP 请求路由到后端服务。#### 1. 创建 GatewayClassGatewayClass 是集群级别的资源,通常由管理员定义。它告诉 Kubernetes 使用哪个 Controller 来管理网关实例。yamlapiVersion: gateway.networking.k8s.io/v1kind: GatewayClassmetadata: name: nginx-gateway-classspec: controllerName: gateway.nginx.org/nginx-gateway-controller#### 2. 创建 GatewayGateway 定义了具体的监听端口和协议。这里我们创建一个监听 80 端口的 HTTP 网关。yamlapiVersion: gateway.networking.k8s.io/v1kind: Gatewaymetadata: name: my-gateway namespace: defaultspec: gatewayClassName: nginx-gateway-class listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: Same # 只允许同命名空间的 Route 绑定#### 3. 创建 HTTPRoute 并绑定HTTPRoute 是应用开发者常用的资源。它定义如何将请求匹配并转发到后端 Service。yamlapiVersion: gateway.networking.k8s.io/v1kind: HTTPRoutemetadata: name: example-route namespace: defaultspec: parentRefs: - name: my-gateway # 绑定到上面创建的 Gateway hostnames: - "example.com" rules: - matches: - path: type: PathPrefix value: /api backendRefs: - name: backend-service # 指向一个 Kubernetes Service port: 8080这段代码做了什么? - parentRefs 将路由关联到 my-gateway。- hostnames 限制了只有访问 example.com 的请求才会被匹配。- matches 规则:路径前缀为 /api 的请求将被转发。- backendRefs 指定了目标 Service 和端口。一个可运行的完整示例 (假设你已有名为 backend-service 的 Service):yaml# 1. 部署一个测试后端apiVersion: apps/v1kind: Deploymentmetadata: name: backendspec: replicas: 1 selector: matchLabels: app: backend template: metadata: labels: app: backend spec: containers: - name: app image: hashicorp/http-echo args: - "-text=hello from gateway api" ports: - containerPort: 5678---apiVersion: v1kind: Servicemetadata: name: backend-servicespec: selector: app: backend ports: - port: 8080 targetPort: 5678---### 进阶篇:高级流量管理Gateway API 的强项在于其丰富的流量治理能力。我们来看看如何实现金丝雀发布 和流量镜像 。#### 1. 金丝雀发布(Canary Release)通过 HTTPRoute 中的 backendRefs 权重分配,我们可以逐步将流量从旧版本切换到新版本。yamlapiVersion: gateway.networking.k8s.io/v1kind: HTTPRoutemetadata: name: canary-route namespace: defaultspec: parentRefs: - name: my-gateway rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: backend-v1 # 旧版本服务 port: 8080 weight: 90 # 90% 流量 - name: backend-v2 # 新版本服务 port: 8080 weight: 10 # 10% 流量解释 :weight 字段控制不同后端之间的流量比例。上例中,90% 的流量进入 v1,10% 进入 v2。你可以动态调整权重,实现渐进式发布。#### 2. 基于 Header 的精确路由除了基于路径,我们还可以根据请求头进行路由,这为 A/B 测试提供了极大便利。yamlapiVersion: gateway.networking.k8s.io/v1kind: HTTPRoutemetadata: name: header-route namespace: defaultspec: parentRefs: - name: my-gateway rules: - matches: - headers: - name: "experiment" value: "true" backendRefs: - name: backend-experiment port: 8080 - matches: - path: type: PathPrefix value: / backendRefs: - name: backend-main port: 8080逻辑 :第一个规则匹配时,请求头包含 experiment: true 的请求将被发送到 backend-experiment;其他所有请求走第二条规则,发送到 backend-main。#### 3. 流量镜像(Traffic Mirroring)将生产流量复制一份到测试环境,用于线上验证,而不影响真实用户。yamlapiVersion: gateway.networking.k8s.io/v1kind: HTTPRoutemetadata: name: mirror-route namespace: defaultspec: parentRefs: - name: my-gateway rules: - matches: - path: type: PathPrefix value: /api backendRefs: - name: production-service port: 80 filters: - type: RequestMirror requestMirror: backendRef: name: shadow-service port: 80注意 :镜像流量是"发后即忘"的,响应不会返回给客户端,适合用于性能对比和 Bug 预捕。---### 高级篇:跨命名空间与 TLS 终止#### 1. 跨命名空间路由默认情况下,Route 只能绑定同命名空间的 Gateway。但我们可以通过 allowedRoutes 和 ReferenceGrant 实现跨命名空间访问。首先,在 Gateway 的 listener 中允许所有命名空间:yamlspec: listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All然后,为跨命名空间的 Service 创建一个 ReferenceGrant:yamlapiVersion: gateway.networking.k8s.io/v1kind: ReferenceGrantmetadata: name: allow-cross-namespace namespace: other-namespacespec: from: - group: gateway.networking.k8s.io kind: HTTPRoute namespace: default to: - group: "" kind: Service#### 2. 配置 TLS 终止在 Gateway 资源中,我们可以配置证书和密钥,实现 HTTPS 终止。yamlapiVersion: gateway.networking.k8s.io/v1kind: Gatewaymetadata: name: tls-gateway namespace: defaultspec: gatewayClassName: nginx-gateway-class listeners: - name: https protocol: HTTPS port: 443 tls: certificateRefs: - name: my-tls-secret # 引用 Kubernetes SecretSecret 必须包含 tls.crt 和 tls.key 字段。bashkubectl create secret tls my-tls-secret --cert=server.crt --key=server.key---### 总结Kubernetes Gateway API 代表了服务网络管理的未来方向。它通过 GatewayClass / Gateway / Route 三层模型,完美分离了基础设施与业务逻辑,提供了:- 标准化 :跨厂商一致的行为,不再受制于特定 Ingress Controller 的注解。- 可移植性 :你的路由配置可以在不同实现(NGINX、Envoy、Istio)之间轻松迁移。- 表达能力 :原生支持金丝雀、镜像、Header 路由、跨命名空间等高级场景,无需 Hack 或额外插件。从本文的基础示例开始,你可以逐步将现有的 Ingress 迁移到 Gateway API,并利用其强大的流量治理能力,构建更健壮、更灵活的应用架构。行动建议 :先在测试集群中安装一个 Gateway Controller,然后动手实验上述代码示例。遇到问题时,使用 kubectl describe gateway 和 kubectl describe httproute 检查状态,它们会提供详细的调试信息。随着你对 Gateway API 的深入,你会发现自己正在掌控更强大的流量管理能力。