Kubernetes Gateway API 完全指南 目录
简介
基础概念
架构原理
实践指南
最佳实践
常见问题与故障排查
简介 Kubernetes Gateway API 是一个面向服务的、可扩展的 Kubernetes 流量管理标准,由 SIG-NETWORK 社区维护。它是 Ingress API 的演进版本,旨在解决 Ingress 在表达能力、扩展性和标准化方面的局限性。
为什么需要 Gateway API? 传统 Ingress 的局限性:
功能有限 :仅支持 HTTP/HTTPS,缺乏对 TCP、UDP、gRPC 等协议的原生支持
扩展性差 :不同 Ingress Controller 使用不同的注解(annotation),导致配置不兼容
表达能力弱 :难以实现复杂的流量管理场景(如流量分割、镜像、高级路由匹配)
角色分离不清 :基础设施团队和应用团队的职责边界模糊
Gateway API 的优势:
角色导向 :明确区分集群操作员、基础设施提供商和应用开发者的职责
表达式丰富 :支持更复杂的路由规则、流量管理和安全策略
协议无关 :原生支持 HTTP、HTTPS、TCP、UDP、gRPC、TLS 等多种协议
标准化 :通过 CRD(Custom Resource Definition)实现跨厂商的一致性
可扩展 :通过参数化配置支持厂商特定的扩展
基础概念 核心资源对象 Gateway API 定义了一组相互关联的资源对象,每个对象都有明确的职责:
1. GatewayClass (网关类) 作用 :定义网关的实现类型和配置模板,由基础设施提供商创建和管理。
特点 :
集群级别资源(Cluster-scoped)
引用具体的 Gateway Controller 实现
一个集群可以有多个 GatewayClass(如 nginx、envoy、istio 等)
示例 :
1 2 3 4 5 6 apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: nginx-gateway-class spec: controllerName: gateway.networking.k8s.io/nginx-ingress-controller
2. Gateway (网关) 作用 :表示实际的负载均衡器实例,定义监听器(Listeners)和网络端点。
特点 :
命名空间级别资源(Namespace-scoped)
引用 GatewayClass 确定实现方式
配置监听端口、协议、TLS 证书等
由基础设施团队管理
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: production-gateway namespace: web-app spec: gatewayClassName: nginx-gateway-class listeners: - name: http port: 80 protocol: HTTP allowedRoutes: namespaces: from: All - name: https port: 443 protocol: HTTPS tls: mode: Terminate certificateRefs: - name: tls-secret kind: Secret allowedRoutes: namespaces: from: Same
3. HTTPRoute (HTTP 路由) 作用 :定义如何将 HTTP/HTTPS 流量路由到后端服务,是最常用的路由类型。
特点 :
支持基于路径、主机名、Header、Query 参数的路由规则
支持流量权重分配(流量分割)
支持请求/响应头修改
支持 URL 重写和重定向
由应用开发者管理
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: web-app-route namespace: default spec: parentRefs: - name: production-gateway namespace: web-app hostnames: - "app.example.com" rules: - matches: - path: type: PathPrefix value: /api backendRefs: - name: api-service port: 8080 weight: 90 - name: api-service-v2 port: 8080 weight: 10 - matches: - path: type: PathPrefix value: / backendRefs: - name: web-service port: 80
4. TCPRoute (TCP 路由) 作用 :路由 TCP 流量到后端服务,适用于数据库、消息队列等场景。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 apiVersion: gateway.networking.k8s.io/v1alpha2 kind: TCPRoute metadata: name: database-route namespace: default spec: parentRefs: - name: tcp-gateway namespace: default rules: - backendRefs: - name: backend port: 3000
5. TLSRoute (TLS 路由) 作用 :在 TLS 层面路由流量,支持 TLS Passthrough 模式。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 apiVersion: gateway.networking.k8s.io/v1alpha2 kind: TLSRoute metadata: name: tls-passthrough-route namespace: default spec: parentRefs: - name: tls-gateway hostnames: - "secure.example.com" rules: - backendRefs: - name: secure-service port: 443
6. UDPRoute (UDP 路由) 作用 :路由 UDP 流量,适用于 DNS、游戏服务器等场景。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 apiVersion: gateway.networking.k8s.io/v1alpha2 kind: UDPRoute metadata: name: dns-route namespace: default spec: parentRefs: - name: udp-gateway rules: - backendRefs: - name: dns-service port: 53
7. GRPCRoute (gRPC 路由) 作用 :专门用于 gRPC 流量的路由,支持 gRPC 特有的元数据和方法匹配。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 apiVersion: gateway.networking.k8s.io/v1 kind: GRPCRoute metadata: name: grpc-service-route namespace: default spec: parentRefs: - name: production-gateway hostnames: - "grpc.example.com" rules: - matches: - method: service: helloworld.Greeter method: SayHello backendRefs: - name: grpc-service port: 50051
8. ReferenceGrant (引用授权) 作用 :跨命名空间引用的安全机制,允许一个命名空间的资源引用另一个命名空间的资源。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 apiVersion: gateway.networking.k8s.io/v1beta1 kind: ReferenceGrant metadata: name: allow-gateway-ref namespace: web-app spec: from: - group: gateway.networking.k8s.io kind: HTTPRoute namespace: default to: - group: "" kind: Secret name: tls-secret
Gateway API vs Ingress 对比
特性
Ingress
Gateway API
API 成熟度
Stable (v1)
Graduating to Standard (v1)
协议支持
HTTP/HTTPS
HTTP, HTTPS, TCP, UDP, gRPC, TLS
路由能力
基于路径和主机
路径、主机、Header、Query、方法等
流量管理
有限
权重分配、镜像、超时、重试
扩展机制
注解(非标准)
参数化配置 + CRD
角色分离
不明确
清晰的三层模型
跨命名空间
不支持
通过 ReferenceGrant 支持
TLS 配置
简单
灵活(Terminate/Passthrough)
供应商兼容性
差异大
标准化程度高
架构原理 整体架构 Gateway API 遵循 Kubernetes 的标准控制器模式,采用声明式 API 设计:
1 2 3 用户/开发者 → Kubernetes API Server → Gateway Controller → Data Plane ↓ ↓ ↓ ↓ 创建资源 存储CRD资源 监听变化并生成配置 代理处理流量
工作机制详解 1. 资源生命周期 创建阶段 :
用户通过 kubectl apply 创建 Gateway API 资源
API Server 验证资源格式并存储到 etcd
Gateway Controller 通过 Watch 机制检测到新资源
Controller 验证资源的语义正确性
Controller 将配置转换为数据平面的具体配置
Controller 更新资源的 Status 字段,反映配置状态
运行阶段 :
数据平面(如 Envoy)加载最新配置
客户端请求到达负载均衡器
数据平面根据路由规则匹配请求
请求被转发到相应的后端服务
响应返回给客户端
更新阶段 :
用户修改资源配置
Controller 检测到变更
重新计算配置并推送到数据平面
数据平面热重载配置(无中断)
2. 控制平面与数据平面交互 控制平面组件 :
Gateway Controller :核心控制器,负责资源协调
Configuration Generator :将 Gateway API 资源转换为代理特定配置
Status Updater :更新资源状态,提供可观测性
数据平面组件 :
Proxy :实际的流量处理引擎(Envoy/Nginx/HAProxy 等)
Config Listener :监听配置变化并应用
Metrics Exporter :导出监控指标
3. 状态反馈机制 Gateway API 强调可观测性,每个资源都有详细的 Status 字段:
Gateway Status 示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 status: conditions: - type: Accepted status: "True" reason: Accepted message: Gateway successfully accepted - type: Programmed status: "True" reason: Programmed message: Configuration programmed to data plane listeners: - name: http attachedRoutes: 5 conditions: - type: Ready status: "True"
实践指南 环境准备 前置要求 :
Kubernetes 集群 (v1.22+)
kubectl 命令行工具
Helm v3 (可选,用于简化安装)
自建集群没有LB所以需要一个负载
下载部署 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 下载应用包 wget https://raw.githubusercontent.com/metallb/metallb/v0.15.3/config/manifests/metallb-native.yaml # 修改镜像地址 # 自行找代理 sed -i "s#quay.io#quay.chenby.cn#g" metallb-native.yaml cat metallb-native.yaml | grep image image: quay.chenby.cn/metallb/controller:v0.14.5 image: quay.chenby.cn/metallb/speaker:v0.14.5 # 执行部署 kubectl apply -f metallb-native.yaml # 可以连接国际网络 # kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.15.3/config/manifests/metallb-native.yaml
查看运行情况 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 cby@DESKTOP-IKRNJQE:~$ kubectl -n metallb-system get all NAME READY STATUS RESTARTS AGE pod/controller-9c6cff498-h7khm 1/1 Running 0 45m pod/speaker-kp5wl 1/1 Running 0 45m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/metallb-webhook-service ClusterIP 10.68.104.187 <none> 443/TCP 45m NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset.apps/speaker 1 1 1 1 1 kubernetes.io/os=linux 45m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/controller 1/1 1 1 45m NAME DESIRED CURRENT READY AGE replicaset.apps/controller-9c6cff498 1 1 1 45m cby@DESKTOP-IKRNJQE:~$
配置VIP的资源池 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 # 新版本metallb使用了CR(Custom Resources),这里我们通过IPAddressPool的CR,进行地址池的定义。 # 如果实例中不设置IPAddressPool选择器L2Advertisement;那么L2Advertisement默认为该实例所有的IPAddressPool相关联。 cat > metallb-config-ipaddresspool.yaml << EOF apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: first-pool namespace: metallb-system spec: addresses: - 192.168.1.15-192.168.1.19 EOF # 进行L2关联地址池的绑定。 cat > metallb-config-L2Advertisement.yaml << EOF apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: example namespace: metallb-system spec: ipAddressPools: - first-pool EOF # 执行部署 kubectl apply -f metallb-config-ipaddresspool.yaml kubectl apply -f metallb-config-L2Advertisement.yaml
步骤 2: 安装 Envoy Gateway 执行部署 1 2 3 # https://gateway.envoyproxy.io/docs/install/install-helm/ # 安装网关 API CRD 和 Envoy 网关 helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.7.3 -n envoy-gateway-system --create-namespace
创建测试应用 1 2 3 4 5 6 7 8 kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/v1.7.3/quickstart.yaml -n default # 查看访问地址 cby@DESKTOP-IKRNJQE:~$ kubectl get svc -n envoy-gateway-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE envoy-default-eg-e41e7b31 LoadBalancer 10.68.120.80 192.168.1.15 80:32116/TCP 6s envoy-gateway ClusterIP 10.68.64.83 <none> 18000/TCP,18001/TCP,18002/TCP,19001/TCP,9443/TCP 30m cby@DESKTOP-IKRNJQE:~$
测试访问 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 cby@DESKTOP-IKRNJQE:~$ curl --verbose --header "Host: www.example.com" http://192.168.1.15/get * Trying 192.168.1.15:80... * Established connection to 192.168.1.15 (192.168.1.15 port 80) from 172.30.72.41 port 39072 * using HTTP/1.x > GET /get HTTP/1.1 > Host: www.example.com > User-Agent: curl/8.18.0 > Accept: */* > * Request completely sent off < HTTP/1.1 200 OK < content-type: application/json < x-content-type-options: nosniff < date: Mon, 11 May 2026 13:51:37 GMT < content-length: 475 < { "path": "/get", "host": "www.example.com", "method": "GET", "proto": "HTTP/1.1", "headers": { "Accept": [ "*/*" ], "User-Agent": [ "curl/8.18.0" ], "X-Envoy-External-Address": [ "192.168.1.100" ], "X-Forwarded-For": [ "192.168.1.100" ], "X-Forwarded-Proto": [ "http" ], "X-Request-Id": [ "d30d74c9-2c8e-4249-8ca6-ee24156e3317" ] }, "namespace": "default", "ingress": "", "service": "", "pod": "backend-869c8646c5-s4426" * Connection #0 to host 192.168.1.15:80 left intact }cby@DESKTOP-IKRNJQE:~$
其他可选实现:
Envoy Gateway : Envoy 官方实现
Istio : 服务网格方案
Contour : VMware 维护的 Envoy 控制器
Kong : Kong Ingress Controller
步骤 3: 创建 GatewayClass 1 2 3 4 5 6 7 8 cat > gatewayclass.yaml << EOF apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: nginx-gateway-class spec: controllerName: gateway.envoyproxy.io/gatewayclass-controller EOF
应用配置:
1 2 3 4 5 6 7 8 9 kubectl apply -f gatewayclass.yaml kubectl get gatewayclass cby@DESKTOP-IKRNJQE:~$ kubectl get gatewayclass gatewayclass.gateway.networking.k8s.io/nginx-gateway-class created NAME CONTROLLER ACCEPTED AGE eg gateway.envoyproxy.io/gatewayclass-controller True 19m nginx-gateway-class gateway.envoyproxy.io/gatewayclass-controller True 18s cby@DESKTOP-IKRNJQE:~$
步骤 4: 部署示例应用 创建两个简单的后端服务用于测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 cat > demo-app.yaml << EOF apiVersion: apps/v1 kind: Deployment metadata: name: web-app-v1 spec: replicas: 1 selector: matchLabels: app: web-app-v1 template: metadata: labels: app: web-app-v1 spec: containers: - name: web-app-v1 image: registry.cn-hangzhou.aliyuncs.com/chenby/cby:nginx-v1 ports: - containerPort: 80 --- apiVersion: apps/v1 kind: Deployment metadata: name: web-app-v2 spec: replicas: 1 selector: matchLabels: app: web-app-v2 template: metadata: labels: app: web-app-v2 spec: containers: - name: web-app-v2 image: registry.cn-hangzhou.aliyuncs.com/chenby/cby:nginx-v2 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: labels: app: web-app-v2 name: web-app-v2 spec: selector: app: web-app-v2 ports: - port: 80 protocol: TCP targetPort: 80 --- apiVersion: v1 kind: Service metadata: labels: app: web-app-v1 name: web-app-v1 spec: selector: app: web-app-v1 ports: - port: 80 protocol: TCP targetPort: 80 EOF
同样创建 v2 版本,然后应用:
1 kubectl apply -f demo-app.yaml
测试查看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 cby@DESKTOP-IKRNJQE:~$ kubectl get pod NAME READY STATUS RESTARTS AGE backend-869c8646c5-s4426 1/1 Running 0 20m web-app-v1-844db9d88f-tjwzz 1/1 Running 0 22s web-app-v2-dd8d978b8-9stzg 1/1 Running 0 22s cby@DESKTOP-IKRNJQE:~$ cby@DESKTOP-IKRNJQE:~$ cby@DESKTOP-IKRNJQE:~$ cby@DESKTOP-IKRNJQE:~$ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE backend ClusterIP 10.68.86.118 <none> 3000/TCP 21m kubernetes ClusterIP 10.68.0.1 <none> 443/TCP 60d web-app-v1 ClusterIP 10.68.255.182 <none> 80/TCP 27s web-app-v2 ClusterIP 10.68.113.128 <none> 80/TCP 27s cby@DESKTOP-IKRNJQE:~$ cby@DESKTOP-IKRNJQE:~$ curl ^[[200~10.68.255.182~^C cby@DESKTOP-IKRNJQE:~$ cby@DESKTOP-IKRNJQE:~$ cby@DESKTOP-IKRNJQE:~$ curl 10.68.255.182 <h1 style="color: #4CAF50;">Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> cby@DESKTOP-IKRNJQE:~$ cby@DESKTOP-IKRNJQE:~$ curl 10.68.113.128 <h1 style="color: #2196F3;">Hello V2</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> cby@DESKTOP-IKRNJQE:~$
步骤 5: 配置基本 HTTP 路由 首先创建 Gateway:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 cat > gateway.yaml << EOF apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: production-gateway namespace: web-app spec: gatewayClassName: nginx-gateway-class listeners: - name: http port: 80 protocol: HTTP allowedRoutes: namespaces: from: All EOF
创建 HTTPRoute:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 cat > httproute-basic.yaml << EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: web-app-route namespace: default spec: parentRefs: - name: production-gateway namespace: web-app hostnames: - "app.example.com" rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: web-app-v1 port: 80 - name: web-app-v2 port: 80 EOF
应用配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 kubectl create namespace web-app kubectl apply -f gateway.yaml kubectl apply -f httproute-basic.yaml kubectl get gateway -n web-app kubectl get httproute -n default cby@DESKTOP-IKRNJQE:~$ kubectl get gateway -n web-app NAME CLASS ADDRESS PROGRAMMED AGE production-gateway nginx-gateway-class 192.168.1.16 True 13s cby@DESKTOP-IKRNJQE:~$ cby@DESKTOP-IKRNJQE:~$ kubectl get httproute -n default NAME HOSTNAMES AGE backend ["www.example.com" ] 26m web-app-route ["app.example.com" ] 56s cby@DESKTOP-IKRNJQE:~$
获取 LoadBalancer IP 并测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 curl -H "Host: app.example.com" http://192.168.1.16 cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16 <h1 style="color: #2196F3;" >Hello V2</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16 <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16 <h1 style="color: #2196F3;" >Hello V2</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16 <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16 <h1 style="color: #2196F3;" >Hello V2</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16 <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> cby@DESKTOP-IKRNJQE:~$
步骤 6: 配置 TLS 终止 6.1 创建自签名证书(测试用) 1 2 3 4 5 6 7 8 9 10 openssl genrsa -out tls.key 2048 openssl req -new -key tls.key -out tls.csr -subj "/CN=app.example.com" openssl x509 -req -in tls.csr -signkey tls.key -out tls.crt -days 365 kubectl create secret tls app-tls-secret \ --cert=tls.crt \ --key=tls.key \ -n web-app rm tls.key tls.csr tls.crt
6.2 更新 Gateway 配置启用 HTTPS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 cat > gateway-with-tls.yaml << EOF apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: production-gateway namespace: web-app spec: gatewayClassName: nginx-gateway-class listeners: - name: http port: 80 protocol: HTTP allowedRoutes: namespaces: from: All - name: https port: 443 protocol: HTTPS tls: mode: Terminate certificateRefs: - name: app-tls-secret kind: Secret group: "" allowedRoutes: namespaces: from: All EOF
应用更新:
1 kubectl apply -f gateway-with-tls.yaml
测试 HTTPS 访问:
1 2 3 4 5 6 7 8 9 10 11 12 13 curl -k -H "Host: app.example.com" https://192.168.1.16 cby@DESKTOP-IKRNJQE:~$ curl -k -H "Host: app.example.com" https://192.168.1.16 <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> cby@DESKTOP-IKRNJQE:~$ curl -k -H "Host: app.example.com" https://192.168.1.16 <h1 style="color: #2196F3;" >Hello V2</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> cby@DESKTOP-IKRNJQE:~$ curl -k -H "Host: app.example.com" https://192.168.1.16 <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> cby@DESKTOP-IKRNJQE:~$ curl -k -H "Host: app.example.com" https://192.168.1.16 <h1 style="color: #2196F3;" >Hello V2</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> cby@DESKTOP-IKRNJQE:~$ curl -k -H "Host: app.example.com" https://192.168.1.16 <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> cby@DESKTOP-IKRNJQE:~$
步骤 7: 配置流量分割(金丝雀发布) 创建将 90% 流量发送到 v1,10% 流量发送到 v2 的路由:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 cat > httproute-canary.yaml << EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: web-app-canary-route namespace: default spec: parentRefs: - name: production-gateway namespace: web-app hostnames: - "app.example.com" rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: web-app-v1 port: 80 weight: 90 - name: web-app-v2 port: 80 weight: 10 EOF
应用配置:
1 2 3 4 5 6 7 8 kubectl delete -f httproute-basic.yaml kubectl apply -f httproute-canary.yaml cby@DESKTOP-IKRNJQE:~$ kubectl get HTTPRoute NAMESPACE NAME HOSTNAMES AGE default backend ["www.example.com" ] 45m default web-app-canary-route ["app.example.com" ] 104s cby@DESKTOP-IKRNJQE:~$
测试流量分割:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 for i in {1..20}; do curl -s -H "Host: app.example.com" http://192.168.1.16 done cby@DESKTOP-IKRNJQE:~$ for i in {1..20}; do curl -s -H "Host: app.example.com" http://192.168.1.16 done <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> <h1 style="color: #2196F3;" >Hello V2</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> <h1 style="color: #2196F3;" >Hello V2</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> cby@DESKTOP-IKRNJQE:~$
步骤 8: 高级路由配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 cat > httproute-header.yaml << EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: header-based-route namespace: default spec: parentRefs: - name: production-gateway namespace: web-app hostnames: - "app.example.com" rules: - matches: - headers: - name: x-version value: v2 backendRefs: - name: web-app-v2 port: 80 - matches: - path: type: PathPrefix value: / backendRefs: - name: web-app-v1 port: 80 EOF
测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 kubectl delete -f httproute-canary.yaml kubectl apply -f httproute-header.yaml curl -H "Host: app.example.com" http://192.168.1.16 curl -H "Host: app.example.com" -H "x-version: v2" http://192.168.1.16 cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16 <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> cby@DESKTOP-IKRNJQE:~$ cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" -H "x-version: v2" http://192.168.1.16 <h1 style="color: #2196F3;" >Hello V2</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> cby@DESKTOP-IKRNJQE:~$
8.2 URL 重写 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 cat > httproute-rewrite.yaml << EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: rewrite-route namespace: default spec: parentRefs: - name: production-gateway namespace: web-app hostnames: - "app.example.com" rules: - matches: - path: type: PathPrefix value: /api/v1 filters: - type: URLRewrite urlRewrite: path: type: ReplacePrefixMatch replacePrefixMatch: / backendRefs: - name: web-app-v1 port: 80 - matches: - path: type: PathPrefix value: /api/v2 filters: - type: URLRewrite urlRewrite: path: type: ReplacePrefixMatch replacePrefixMatch: / backendRefs: - name: web-app-v2 port: 80 EOF
测试使用
1 2 3 4 5 6 7 8 9 10 11 kubectl delete -f httproute-header.yaml kubectl apply -f httproute-rewrite.yaml curl -H "Host: app.example.com" http://192.168.1.16/api/v1 curl -H "Host: app.example.com" http://192.168.1.16/api/v2 cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16/api/v1 <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16/api/v2 <h1 style="color: #2196F3;" >Hello V2</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> cby@DESKTOP-IKRNJQE:~$
8.3 请求/响应头修改 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 cat > httproute-modify.yaml << EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: header-modify-route namespace: default spec: parentRefs: - name: production-gateway namespace: web-app hostnames: - "app.example.com" rules: - matches: - path: type: PathPrefix value: / filters: - type: RequestHeaderModifier requestHeaderModifier: add: - name: X-Forwarded-Gateway value: "nginx-gateway" set: - name: X-Custom-Header value: "custom-value" - type: ResponseHeaderModifier responseHeaderModifier: add: - name: X-Powered-By value: "Gateway-API" backendRefs: - name: web-app-v1 port: 80 EOF
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 kubectl delete -f httproute-rewrite.yaml kubectl apply -f httproute-modify.yaml curl -v -H "Host: app.example.com" http://192.168.1.16/ cby@DESKTOP-IKRNJQE:~$ curl -v -H "Host: app.example.com" http://192.168.1.16/ * Trying 192.168.1.16:80... * Established connection to 192.168.1.16 (192.168.1.16 port 80) from 172.30.72.41 port 46798 * using HTTP/1.x > GET / HTTP/1.1 > Host: app.example.com > User-Agent: curl/8.18.0 > Accept: */* > * Request completely sent off < HTTP/1.1 200 OK < server: nginx/1.29.8 < date : Mon, 11 May 2026 14:54:24 GMT < content-type: text/html < content-length: 128 < last-modified: Mon, 11 May 2026 14:02:13 GMT < etag: "6a01e165-80" < accept-ranges: bytes < x-powered-by: Gateway-API < <h1 style="color: #4CAF50;" >Hello V1</h1><p>时间:2026-05-11 星期一</p><p>地点:内蒙古自治区 呼和浩特市</p> * Connection cby@DESKTOP-IKRNJQE:~$
最佳实践 1. 安全管理 1.1 使用 RBAC 限制权限 为应用团队创建受限角色,只允许管理 Route 资源:
1 2 3 4 5 6 7 8 9 apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: gateway-route-manager namespace: default rules: - apiGroups: ["gateway.networking.k8s.io" ] resources: ["httproutes" , "grpcroutes" ] verbs: ["get" , "list" , "watch" , "create" , "update" , "patch" ]
1.2 使用 ReferenceGrant 控制跨命名空间访问 1 2 3 4 5 6 7 8 9 10 11 12 13 14 apiVersion: gateway.networking.k8s.io/v1beta1 kind: ReferenceGrant metadata: name: allow-tls-ref namespace: cert-manager spec: from: - group: gateway.networking.k8s.io kind: Gateway namespace: web-app to: - group: "" kind: Secret name: wildcard-tls-cert
1.3 TLS 最佳实践
使用通配符证书减少证书管理复杂度
定期轮换证书,建议使用 cert-manager 自动化
优先使用 TLS Terminate 模式
强制 HTTPS,配置 HTTP 到 HTTPS 重定向
2. 性能优化 2.1 合理配置监听器 限制允许的路由来源,减少配置复杂度:
1 2 3 4 5 6 7 8 9 10 11 spec: listeners: - name: http port: 80 protocol: HTTP allowedRoutes: namespaces: from: Selector selector: matchLabels: allow-gateway-access: "true"
2.2 避免过度复杂的路由规则
合并相似的路由规则,减少配置数量
使用最具体的匹配条件优先,提高匹配效率
避免过多的 Header/Query 匹配,影响性能
3. 可靠性保障 3.1 渐进式发布策略 金丝雀发布流程 :
部署新版本服务(v2)
配置 5% 流量到 v2
监控错误率和延迟
逐步增加流量比例(10% → 25% → 50% → 100%)
确认稳定后,移除旧版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 backendRefs: - name: web-app-v1 weight: 95 - name: web-app-v2 weight: 5 backendRefs: - name: web-app-v1 weight: 75 - name: web-app-v2 weight: 25 backendRefs: - name: web-app-v2 weight: 100
3.2 蓝绿部署 通过快速切换权重实现蓝绿部署:
1 2 3 4 5 6 7 8 9 10 11 12 13 backendRefs: - name: blue-service weight: 100 - name: green-service weight: 0 backendRefs: - name: blue-service weight: 0 - name: green-service weight: 100
4. 多租户隔离 4.1 命名空间隔离策略 1 2 3 4 5 6 7 8 9 10 11 spec: listeners: - name: http port: 80 protocol: HTTP allowedRoutes: namespaces: from: Selector selector: matchLabels: environment: production
5. 调试和故障排查 5.1 常见问题诊断清单 问题 1: Gateway 状态为 “Not Accepted”
检查步骤:
1 2 3 4 5 6 7 8 9 10 11 kubectl get gatewayclass kubectl get pods -n <controller-namespace> kubectl describe gateway <name> -n <namespace> kubectl logs -n <controller-namespace> -l app=<controller-name>
问题 2: HTTPRoute 未被接受
检查步骤:
1 2 3 4 5 6 7 8 9 10 11 kubectl get httproute <name> -o yaml kubectl describe gateway <gateway-name> -n <namespace> kubectl get svc <backend-service-name> kubectl get referencegrant -A
问题 3: 流量未正确路由
检查步骤:
1 2 3 4 5 6 7 8 9 10 11 12 kubectl describe httproute <name> kubectl run test --rm -i --tty --image=curlimages/curl -- \ curl http://<service-name>.<namespace>.svc.cluster.local kubectl get gateway <name> -o jsonpath='{.status.addresses}' curl -v -H "Host: <hostname>" http://<gateway-ip><path>
6. 生产环境建议 6.1 高可用架构
部署多个 Controller 副本实现控制器高可用
使用多个 Gateway 实例分散负载
配置跨区域部署提高灾难恢复能力
1 2 3 4 5 6 7 spec: replicas: 3 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0
6.2 备份和恢复
定期备份 Gateway API 资源配置
使用 GitOps 工具(如 ArgoCD、Flux)管理配置
建立配置变更审批流程
1 2 kubectl get gatewayclass,gateway,httproute,tcproute,referencegrant -A -o yaml > gateway-backup.yaml
6.3 容量规划 关键监控指标:
每秒请求数 (RPS)
平均/ P95/P99 延迟
错误率 (4xx, 5xx)
活跃连接数
带宽使用率
6.4 版本升级策略
先在测试环境验证新版本
阅读发行说明,了解破坏性变更
灰度升级,先升级部分节点
保留回滚方案
7. 常见应用场景 场景 1: 多域名托管 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: multi-domain-route spec: parentRefs: - name: production-gateway hostnames: - "app1.example.com" - "app2.example.com" - "app3.example.com" rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: shared-backend port: 80
场景 2: API 网关 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: api-gateway-route spec: parentRefs: - name: production-gateway hostnames: - "api.example.com" rules: - matches: - path: type: PathPrefix value: /users backendRefs: - name: user-service port: 8080 - matches: - path: type: PathPrefix value: /orders backendRefs: - name: order-service port: 8080 - matches: - path: type: PathPrefix value: /payments backendRefs: - name: payment-service port: 8080
场景 3: A/B 测试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: ab-test-route spec: parentRefs: - name: production-gateway hostnames: - "app.example.com" rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: variant-a port: 80 weight: 50 - name: variant-b port: 80 weight: 50
常见问题与故障排查 FAQ Q1: Gateway API 和 Ingress 可以共存吗?
A: 可以。它们使用不同的资源类型,可以同时在集群中运行。建议逐步迁移,先在新服务中使用 Gateway API。
Q2: 如何选择 Gateway Controller 实现?
A: 考虑因素:
功能需求 :是否需要 gRPC、TCP 等高级功能
性能要求 :吞吐量、延迟指标
生态系统 :与现有工具链的集成
社区活跃度 :维护频率、问题响应速度
企业支持 :是否需要商业支持
推荐选择:
通用场景 : Envoy Gateway、NGINX Gateway Fabric
服务网格 : Istio
高性能 : Envoy Gateway
简单易用 : Contour
Q3: Gateway API 的性能如何?
A: Gateway API 本身是控制平面,性能取决于数据平面实现(Envoy/Nginx 等)、配置复杂度和硬件资源。现代实现(如 Envoy)可以达到数十万 QPS,延迟在毫秒级。
Q4: 如何处理 WebSocket 连接?
A: HTTPRoute 天然支持 WebSocket,无需特殊配置。确保后端服务正确处理 Upgrade 头即可。
Q5: 可以实现速率限制吗?
A: Gateway API v1 标准不直接支持速率限制,但可以通过以下方式实现:
Controller 特定扩展(如 Envoy Gateway 的 RateLimitFilter)
在服务网格层实现(Istio)
使用外部速率限制服务
Q6: 如何迁移现有的 Ingress 配置?
A: 迁移步骤:
分析现有 Ingress 资源
映射 Ingress 规则到 HTTPRoute
创建对应的 Gateway 资源
测试新配置
逐步切换流量
删除旧 Ingress 资源
可以使用官方工具 ingress2gateway 辅助转换:
1 kubectl get ingress -A -o yaml | ingress2gateway -f -
Q7: Gateway API 支持哪些 Kubernetes 版本?
A: Gateway API v1 需要 Kubernetes 1.22+,推荐使用最新的稳定版 Kubernetes 以获得最佳支持。
Q8: 如何实现灰度发布的自动化?
A: 结合以下工具:
Argo Rollouts :渐进式交付
Flagger :自动化的金丝雀分析
自定义控制器 :根据监控指标自动调整权重
总结 Kubernetes Gateway API 代表了 Kubernetes 流量管理的未来方向。通过本教程,您应该已经掌握了:
核心概念 :理解了 GatewayClass、Gateway、HTTPRoute 等资源的作用和关系
架构原理 :了解了控制平面和数据平面的交互机制
实践能力 :能够从零搭建 Gateway API 环境并配置各种路由场景
最佳实践 :学会了安全管理、性能优化、可靠性保障等生产环境技巧
下一步学习建议 :
深入研究特定 Gateway Controller 的文档
探索服务网格与 Gateway API 的集成
学习 GitOps 工作流管理 Gateway 配置
祝您在 Kubernetes Gateway API 的学习之路上取得成功!
关于
https://www.oiox.cn/
https://www.oiox.cn/index.php/start-page.html
CSDN、GitHub、知乎、开源中国、思否、掘金、简书、华为云、阿里云、腾讯云、哔哩哔哩、今日头条、新浪微博、个人博客
全网可搜《小陈运维》
文章主要发布于微信公众号