什么需要 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 等)
示例:

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 证书等
由基础设施团队管理
示例:

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 重写和重定向
由应用开发者管理
示例:

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 流量到后端服务,适用于数据库、消息队列等场景。

示例:

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 模式。

示例:

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、游戏服务器等场景。

示例:

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 特有的元数据和方法匹配。

示例:

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 (引用授权)
作用:跨命名空间引用的安全机制,允许一个命名空间的资源引用另一个命名空间的资源。

示例:

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 设计:

用户/开发者 → 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 示例:

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 (可选,用于简化安装)
步骤 1: 部署 metallb
自建集群没有LB所以需要一个负载

下载部署

下载应用包

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

查看运行情况
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 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的资源池

新版本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
执行部署

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
创建测试应用
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 18000/TCP,18001/TCP,18002/TCP,19001/TCP,9443/TCP 30m
cby@DESKTOP-IKRNJQE:~$
测试访问
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
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
应用配置:

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: 部署示例应用
创建两个简单的后端服务用于测试:

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 版本,然后应用:

kubectl apply -f demo-app.yaml
测试查看

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 3000/TCP 21m
kubernetes ClusterIP 10.68.0.1 443/TCP 60d
web-app-v1 ClusterIP 10.68.255.182 80/TCP 27s
web-app-v2 ClusterIP 10.68.113.128 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

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

cby@DESKTOP-IKRNJQE:~$ cby@DESKTOP-IKRNJQE:~$ curl 10.68.113.128

Hello V2

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

cby@DESKTOP-IKRNJQE:~$ 步骤 5: 配置基本 HTTP 路由 首先创建 Gateway:

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:

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
应用配置:

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 并测试:

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

Hello V2

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16

Hello V2

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16

Hello V2

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

cby@DESKTOP-IKRNJQE:~$ 步骤 6: 配置 TLS 终止 6.1 创建自签名证书(测试用) 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
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
应用更新:

kubectl apply -f gateway-with-tls.yaml
测试 HTTPS 访问:

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

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

cby@DESKTOP-IKRNJQE:~$ curl -k -H "Host: app.example.com" https://192.168.1.16

Hello V2

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

cby@DESKTOP-IKRNJQE:~$ curl -k -H "Host: app.example.com" https://192.168.1.16

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

cby@DESKTOP-IKRNJQE:~$ curl -k -H "Host: app.example.com" https://192.168.1.16

Hello V2

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

cby@DESKTOP-IKRNJQE:~$ curl -k -H "Host: app.example.com" https://192.168.1.16

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

cby@DESKTOP-IKRNJQE:~$ 步骤 7: 配置流量分割(金丝雀发布) 创建将 90% 流量发送到 v1,10% 流量发送到 v2 的路由:

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
应用配置:

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:~$
测试流量分割:

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

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

Hello V2

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

Hello V2

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

cby@DESKTOP-IKRNJQE:~$ 步骤 8: 高级路由配置 8.1 基于 Header 的路由 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 测试:

kubectl delete -f httproute-canary.yaml
kubectl apply -f httproute-header.yaml

不带 Header,访问 v1

curl -H “Host: app.example.com” http://192.168.1.16

带 Header,访问 v2

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

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

cby@DESKTOP-IKRNJQE:~$ cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" -H "x-version: v2" http://192.168.1.16

Hello V2

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

cby@DESKTOP-IKRNJQE:~$ 8.2 URL 重写 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 测试使用

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

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

cby@DESKTOP-IKRNJQE:~$ curl -H "Host: app.example.com" http://192.168.1.16/api/v2

Hello V2

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

cby@DESKTOP-IKRNJQE:~$ 8.3 请求/响应头修改 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 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
    <

Hello V1

时间:2026-05-11 星期一

地点:内蒙古自治区 呼和浩特市

* Connection #0 to host 192.168.1.16:80 left intact cby@DESKTOP-IKRNJQE:~$ 最佳实践 1. 安全管理 1.1 使用 RBAC 限制权限 为应用团队创建受限角色,只允许管理 Route 资源:

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 控制跨命名空间访问
    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 重定向
  1. 性能优化
    2.1 合理配置监听器
    限制允许的路由来源,减少配置复杂度:

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: 5% 流量

backendRefs:

  • name: web-app-v1
    weight: 95
  • name: web-app-v2
    weight: 5

阶段 2: 25% 流量

backendRefs:

  • name: web-app-v1
    weight: 75
  • name: web-app-v2
    weight: 25

阶段 3: 100% 流量

backendRefs:

  • name: web-app-v2
    weight: 100
    3.2 蓝绿部署
    通过快速切换权重实现蓝绿部署:

初始状态: 100% 蓝色环境

backendRefs:

  • name: blue-service
    weight: 100
  • name: green-service
    weight: 0

切换时: 快速切换到绿色环境

backendRefs:

  • name: blue-service
    weight: 0
  • name: green-service
    weight: 100
  1. 多租户隔离
    4.1 命名空间隔离策略
    spec:
    listeners:
    • name: http
      port: 80
      protocol: HTTP
      allowedRoutes:
      namespaces:
      from: Selector
      selector:
      matchLabels:
      environment: production
  2. 调试和故障排查
    5.1 常见问题诊断清单
    问题 1: Gateway 状态为 “Not Accepted”

检查步骤:

1. 检查 GatewayClass 是否存在且有效

kubectl get gatewayclass

2. 检查 Controller 是否运行

kubectl get pods -n

3. 查看 Gateway 事件

kubectl describe gateway -n

4. 检查控制器日志

kubectl logs -n -l app=
问题 2: HTTPRoute 未被接受

检查步骤:

1. 验证 parentRefs 是否正确

kubectl get httproute -o yaml

2. 检查 Gateway 是否允许该命名空间的路由

kubectl describe gateway -n

3. 验证后端服务是否存在

kubectl get svc

4. 检查 ReferenceGrant (如果跨命名空间)

kubectl get referencegrant -A
问题 3: 流量未正确路由

检查步骤:

1. 验证路由规则匹配条件

kubectl describe httproute

2. 测试后端服务直接访问

kubectl run test --rm -i --tty --image=curlimages/curl –
curl http://..svc.cluster.local

3. 检查 Gateway 外部 IP

kubectl get gateway -o jsonpath=‘{.status.addresses}’

4. 使用详细输出测试

curl -v -H “Host: ” http://
6. 生产环境建议
6.1 高可用架构
部署多个 Controller 副本实现控制器高可用
使用多个 Gateway 实例分散负载
配置跨区域部署提高灾难恢复能力
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
6.2 备份和恢复
定期备份 Gateway API 资源配置
使用 GitOps 工具(如 ArgoCD、Flux)管理配置
建立配置变更审批流程

备份所有 Gateway API 资源

kubectl get gatewayclass,gateway,httproute,tcproute,referencegrant -A -o yaml > gateway-backup.yaml
6.3 容量规划
关键监控指标:

每秒请求数 (RPS)
平均/ P95/P99 延迟
错误率 (4xx, 5xx)
活跃连接数
带宽使用率
6.4 版本升级策略
先在测试环境验证新版本
阅读发行说明,了解破坏性变更
灰度升级,先升级部分节点
保留回滚方案
7. 常见应用场景
场景 1: 多域名托管
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 网关
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 测试
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 辅助转换:

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:自动化的金丝雀分析
自定义控制器:根据监控指标自动调整权重
总结

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐