K8s Gateway API替代Ingress?2026年服务网格流量管理完全迁移指南
K8s Gateway API替代Ingress?2026年服务网格流量管理完全迁移指南
你还在用Ingress写一堆注解来实现流量管理吗?每次配灰度发布都要翻文档查nginx.ingress.kubernetes.io/canary的语法?多集群场景下Ingress的跨集群路由让你抓狂?2026年了,Kubernetes Gateway API已经GA稳定,是时候告别Ingress的混乱时代了。
背景知识
Ingress的局限性
Ingress自Kubernetes 1.1引入以来,一直是集群入口流量管理的标准方式。但其设计存在根本性缺陷:
| 维度 | Ingress | Gateway API |
|---|---|---|
| 角色模型 | 无角色分离 | 三角色(基础设施/集群运维/应用开发) |
| 扩展性 | 依赖注解,各控制器不兼容 | 原生扩展,标准CRD |
| 协议支持 | 主要HTTP/HTTPS | HTTP、gRPC、TCP、UDP、TLS |
| 流量路由 | 单层路径匹配 | 多层路由(Gateway→Route→Backend) |
| 多集群 | 不支持 | 原生支持(MultiClusterService) |
| 状态 | v1稳定但不再演进 | GA,持续迭代 |
Gateway API核心资源
Gateway API定义了三种核心角色和对应的资源:
- GatewayClass:基础设施管理员定义网关类型(类比StorageClass)
- Gateway:集群运维定义网关实例(类比PVC)
- HTTPRoute/TCPRoute/GRPCRoute:应用开发定义路由规则(类比应用部署)
问题分析
为什么Ingress在服务网格场景下力不从心?
根本原因:Ingress将基础设施配置和应用路由规则耦合在同一个资源中。在服务网格场景下:
- 权限冲突:运维要配TLS证书,开发要改路由规则,都在同一个Ingress对象上操作
- 注解地狱:灰度发布、流量镜像、重试策略全靠注解,不同Ingress控制器注解语法不同
- 跨集群盲区:Ingress无法感知其他集群的服务,多集群流量管理需要外部方案
- 协议限制:gRPC、TCP长连接等非HTTP协议支持不完整
分步实操:从Ingress迁移到Gateway API
步骤1:安装Gateway API CRD和Istio
# 安装Gateway API标准CRD(v1.2.0+)
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.1/standard-install.yaml
# 安装Istio 1.24+(内置Gateway API支持)
istioctl install --set profile=ambient --set values.pilot.env.ENABLE_GATEWAY_API=true
# 验证GatewayClass已注册
kubectl get gatewayclass
# NAME CONTROLLER ACCEPTED AGE
# istio istio.io/gateway-controller True 1m
步骤2:定义Gateway实例
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: main-gateway
namespace: infra
annotations:
istio.io/traffic-policy: |
connectionPool:
http:
h2UpgradePolicy: UPGRADE
spec:
gatewayClassName: istio
listeners:
- name: http
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: Selector
selectorLabels:
gateway-access: "true"
- name: https
port: 443
protocol: HTTPS
tls:
mode: Terminate
certificateRefs:
- name: wildcard-cert
namespace: cert-manager
allowedRoutes:
namespaces:
from: All
- name: grpc
port: 15443
protocol: HTTPS
tls:
mode: Terminate
certificateRefs:
- name: grpc-cert
步骤3:迁移路由规则
原始Ingress配置:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "20"
spec:
rules:
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-v1
port:
number: 8080
迁移后的Gateway API配置:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-route
namespace: app
spec:
parentRefs:
- name: main-gateway
namespace: infra
sectionName: https
hostnames:
- "app.example.com"
rules:
- backendRefs:
- name: api-v1
port: 8080
weight: 80
- name: api-v2
port: 8080
weight: 20
matches:
- path:
type: PathPrefix
value: /api
步骤4:配置灰度发布(基于Header路由)
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-canary-header
namespace: app
spec:
parentRefs:
- name: main-gateway
namespace: infra
hostnames:
- "app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api
headers:
- type: Exact
name: X-Canary
value: "true"
backendRefs:
- name: api-v2
port: 8080
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-v1
port: 8080
步骤5:多集群网关配置
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ServiceImport
metadata:
name: api-v1-multi
namespace: app
spec:
type: ClusterSetIP
ports:
- port: 8080
resolution: DNS
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: MultiClusterService
metadata:
name: api-v1-global
namespace: app
spec:
serviceImport:
name: api-v1-multi
namespace: app
clusterBackends:
- cluster: us-west-1
weight: 60
- cluster: us-east-1
weight: 40
完整代码:Istio + Gateway API生产级配置
# gateway-class.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: istio-production
spec:
controllerName: istio.io/gateway-controller
parametersRef:
group: ""
kind: ConfigMap
name: istio-gw-params
namespace: infra
---
# gateway-params.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: istio-gw-params
namespace: infra
data:
concurrency: "4"
proxy-config: |
connectionPool:
http:
maxRequestsPerConnection: 1000
h2UpgradePolicy: DEFAULT
tcp:
maxConnections: 10000
outlierDetection:
consecutive5xxErrors: 5
interval: 30s
baseEjectionTime: 30s
---
# gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: prod-gateway
namespace: infra
spec:
gatewayClassName: istio-production
listeners:
- name: http-public
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
- name: https-public
port: 443
protocol: HTTPS
tls:
mode: Terminate
certificateRefs:
- name: prod-wildcard-cert
allowedRoutes:
namespaces:
from: All
addresses:
- type: IPAddress
value: "10.0.1.100"
---
# http-route.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app-route
namespace: app
spec:
parentRefs:
- name: prod-gateway
namespace: infra
sectionName: https-public
hostnames:
- "app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api/v2
headers:
- type: Exact
name: X-Canary
value: "true"
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-Route-Tag
value: canary-v2
backendRefs:
- name: api-v2
port: 8080
weight: 100
- matches:
- path:
type: PathPrefix
value: /api/v2
backendRefs:
- name: api-v2
port: 8080
weight: 20
- name: api-v1
port: 8080
weight: 80
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-v1
port: 8080
- matches:
- path:
type: PathPrefix
value: /health
backendRefs:
- name: api-v1
port: 8080
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
set:
- name: X-Health-Check
value: "true"
---
# grpc-route.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: grpc-route
namespace: app
spec:
parentRefs:
- name: prod-gateway
namespace: infra
hostnames:
- "grpc.example.com"
rules:
- matches:
- method:
service: "com.example.api.UserService"
method: "GetUser"
backendRefs:
- name: user-service
port: 9090
- matches:
- method:
service: "com.example.api.OrderService"
backendRefs:
- name: order-service
port: 9090
避坑指南
坑1:GatewayClass未注册导致Gateway无法绑定
现象:Gateway状态显示Accepted: False,路由规则不生效。
解决:确认Istio控制器已启用Gateway API支持,检查ENABLE_GATEWAY_API=true环境变量,确保GatewayClass的controllerName与Istio注册的一致。
坑2:跨命名空间路由被拒绝
现象:HTTPRoute的parentRefs引用了其他namespace的Gateway,但路由不生效。
解决:Gateway的allowedRoutes必须显式允许跨命名空间路由。设置为from: All或使用Selector匹配目标namespace的标签。
坑3:TLS证书引用跨namespace失败
现象:Gateway的HTTPS listener配置了证书引用,但证书在其他namespace。
解决:Gateway API要求证书和Gateway在同一namespace。使用cert-manager的CertificatePolicy将证书复制到Gateway所在namespace,或使用Istio的istio.io/credential-name注解。
坑4:灰度权重总和不为100导致流量异常
现象:配置weight 80和weight 30,总权重110,流量分配不符合预期。
解决:Gateway API的weight是相对值,总和不需要为100。但建议保持总和为100以便于理解和监控。Istio会自动按比例归一化。
坑5:多集群ServiceImport DNS解析失败
现象:MultiClusterService创建成功,但跨集群流量无法路由。
解决:确保Istio的跨集群控制面已连通(东西向网关部署正确),检查ServiceImport的resolution字段设置为DNS,且集群间网络可达。
报错排查
| 序号 | 报错信息 | 原因 | 解决方法 |
|---|---|---|---|
| 1 | GatewayClass not found |
CRD未安装或控制器未注册 | 安装Gateway API CRD,确认Istio启用Gateway API |
| 2 | no GatewayClass controller matching |
controllerName不匹配 | 检查GatewayClass.spec.controllerName与Istio注册值一致 |
| 3 | route is not accepted by any Gateway |
parentRefs引用错误 | 检查Gateway名称、namespace、sectionName |
| 4 | certificate not found |
TLS证书不存在或跨namespace | 确保证书在Gateway同namespace,或使用Istio注解 |
| 5 | port conflict on Gateway listener |
同一端口定义了多个listener | 每个端口只能有一个listener,合并协议配置 |
| 6 | backendRef service not found |
目标Service不存在 | 检查Service名称和namespace是否正确 |
| 7 | HTTPRoute condition Accepted=False |
路由被Gateway拒绝 | 检查allowedRoutes策略和hostname匹配 |
| 8 | Istio proxy not ready |
Sidecar/ztunnel未注入 | 确认namespace有istio-injection=enabled标签或使用ambient模式 |
| 9 | MultiClusterService endpoint empty |
跨集群发现未工作 | 检查东西向网关、跨集群控制面连通性 |
| 10 | GRPCRoute method match failed |
gRPC方法匹配格式错误 | 使用package.Service/Method格式,检查proto定义 |
进阶优化
1. 流量镜像(Shadow Traffic)
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: mirror-route
namespace: app
annotations:
istio.io/traffic-mirror: |
mirror:
hostname: mirror-service
port: 8080
mirrorPercentage:
value: 10
spec:
parentRefs:
- name: prod-gateway
namespace: infra
rules:
- backendRefs:
- name: api-v1
port: 8080
2. 连接池与断路器
通过GatewayClass的parametersRef ConfigMap配置全局连接池策略,避免单个后端过载拖垮整个网关。
3. 基于速率的流量切换
结合Prometheus指标和Argo Rollouts,实现基于错误率的自动流量切换:
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: api-rollout
spec:
strategy:
canary:
canaryService: api-v2
stableService: api-v1
trafficRouting:
istio:
virtualServices:
- name: api-route
4. Gateway API扩展策略
使用policyRef(v1.3+)将重试、超时、断路器等策略与路由解耦:
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTrafficPolicy
metadata:
name: api-retry-policy
spec:
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
name: api-route
retry:
retryOn:
- 5xx
- connect-failure
attempts: 3
backoff:
defaultDuration: 100ms
maxDuration: 10s
对比分析
| 维度 | Ingress + nginx-ingress | Ingress + Istio VirtualService | Gateway API + Istio | Gateway API + Envoy Gateway |
|---|---|---|---|---|
| 配置复杂度 | 低(单资源) | 中(Ingress+VS) | 中(Gateway+Route) | 中(Gateway+Route) |
| 角色分离 | 无 | 部分 | 完整 | 完整 |
| 灰度发布 | 注解实现 | VirtualService | 原生weight | 原生weight |
| gRPC支持 | 有限注解 | 原生 | 原生GRPCRoute | 原生GRPCRoute |
| 多集群 | 不支持 | 支持(需配置) | 原生支持 | 需扩展 |
| 流量镜像 | 不支持 | 支持 | 注解扩展 | 扩展策略 |
| 社区活跃度 | 维护模式 | 活跃 | 非常活跃 | 活跃 |
| 学习曲线 | 低 | 高 | 中 | 中 |
| 生产就绪度 | 成熟 | 成熟 | 2026 GA成熟 | 快速成熟中 |
总结展望
总结:Gateway API在2026年已成为Kubernetes流量管理的事实标准。相比Ingress,它提供了角色分离、协议扩展、多集群支持等核心优势。迁移路径清晰:先安装CRD,再创建Gateway,最后逐步迁移Route。Istio作为最成熟的服务网格实现,对Gateway API的支持最为完善。建议新项目直接使用Gateway API,存量项目可按服务逐步迁移,Ingress和Gateway API可以共存。
在线工具推荐
- YAML/JSON格式化:/zh-CN/json/format
- Base64编解码(证书处理):/zh-CN/encode/base64
- curl转代码(API测试):/zh-CN/dev/curl-to-code
本站提供浏览器本地工具,免注册即可试用 →