2026年K8s Gateway API迁移完全指南:从Ingress到Gateway API

云原生

2026年K8s Gateway API迁移完全指南:从Ingress到Gateway API

如果你在2026年还在用Kubernetes Ingress管理集群流量,你正在错过云原生流量管理的未来。Gateway API在2025年底正式成为Kubernetes GA API,各大厂商(Istio、Contour、Traefik、Kong)已全面支持。Ingress的设计缺陷——单角色、扩展性差、无法表达复杂路由——在微服务规模爆炸的今天已经不可接受了。

Gateway API引入了Gateway、GatewayClass、HTTPRoute等角色分离的API,支持多团队协作、多集群部署、流量拆分和镜像。本文将从架构对比开始,给出完整的迁移步骤,覆盖流量管理、多租户和多集群场景。

为什么Gateway API取代Ingress?

对比维度 Ingress Gateway API
API成熟度 GA(但已停止演进) GA(2025.11)
角色分离 无(全由集群管理员管理) 三角色(基础设施/集群/应用)
路由表达能力 有限(path+host) 强大(header/query/weight/mirror)
多协议支持 仅HTTP/HTTPS HTTP/TLS/TCP/UDP/gRPC
流量拆分 需要annotation hack 原生支持(weight字段)
多租户 不支持 原生支持(Namespace隔离)
扩展性 依赖annotation 原生扩展(PolicyAttachment)
跨集群 不支持 支持Multi-cluster Gateway

核心差异:Ingress把所有配置混在一起,而Gateway API实现了角色分离——基础设施团队管GatewayClass,运维团队管Gateway,开发团队管Route。


一、架构对比

1.1 Ingress架构

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "10"
spec:
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /v1/users(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: user-service
            port:
              number: 8080

问题:所有配置挤在一个Ingress对象里,annotation满天飞,不同厂商的annotation互不兼容。

1.2 Gateway API架构

apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: istio
spec:
  controllerName: istio.io/gateway-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: api-gateway
  namespace: infra
spec:
  gatewayClassName: istio
  listeners:
  - name: http
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: Selector
        selector:
          matchLabels:
            shared-gateway-access: "true"
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: user-route
  namespace: app-team
spec:
  parentRefs:
  - name: api-gateway
    namespace: infra
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /v1/users
    backendRefs:
    - name: user-service
      port: 8080
      weight: 90
    - name: user-service-canary
      port: 8080
      weight: 10

优势:角色清晰——GatewayClass由平台团队定义,Gateway由运维团队配置,HTTPRoute由开发团队管理。


二、逐步迁移指南

2.1 安装Gateway API CRD

kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml

2.2 安装控制器(以Istio为例)

istioctl install --set profile=minimal
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: istio
spec:
  controllerName: istio.io/gateway-controller
EOF

2.3 迁移Ingress到Gateway+HTTPRoute

迁移脚本思路

for ingress in $(kubectl get ingress -A -o name); do
  namespace=$(echo $ingress | cut -d'/' -f1 | cut -d'.' -f1)
  name=$(echo $ingress | cut -d'/' -f2)

  kubectl get $ingress -o yaml | python3 ingress2gateway.py > gateway-route.yaml
  kubectl apply -f gateway-route.yaml

  echo "Migrated $ingress, verify before deleting"
done

2.4 自动化迁移工具

import yaml
import sys

def ingress_to_gateway_route(ingress_data):
    metadata = ingress_data['metadata']
    spec = ingress_data['spec']

    gateway = {
        'apiVersion': 'gateway.networking.k8s.io/v1',
        'kind': 'Gateway',
        'metadata': {
            'name': f"{metadata['name']}-gateway",
            'namespace': metadata.get('namespace', 'default'),
        },
        'spec': {
            'gatewayClassName': 'istio',
            'listeners': [],
        },
    }

    routes = []
    for rule in spec.get('rules', []):
        host = rule.get('host', '*')
        listener_name = f"http-{host.replace('.', '-')}" if host != '*' else 'http'

        gateway['spec']['listeners'].append({
            'name': listener_name,
            'port': 80,
            'protocol': 'HTTP',
            'hostname': host if host != '*' else None,
        })

        for path in rule.get('http', {}).get('paths', []):
            route = {
                'apiVersion': 'gateway.networking.k8s.io/v1',
                'kind': 'HTTPRoute',
                'metadata': {
                    'name': f"{metadata['name']}-route",
                    'namespace': metadata.get('namespace', 'default'),
                },
                'spec': {
                    'parentRefs': [{'name': f"{metadata['name']}-gateway"}],
                    'rules': [{
                        'matches': [{
                            'path': {
                                'type': 'PathPrefix',
                                'value': path.get('path', '/'),
                            }
                        }],
                        'backendRefs': [{
                            'name': path['backend']['service']['name'],
                            'port': path['backend']['service']['port']['number'],
                        }],
                    }],
                },
            }
            routes.append(route)

    return gateway, routes

if __name__ == '__main__':
    ingress = yaml.safe_load(sys.stdin)
    gw, routes = ingress_to_gateway_route(ingress)
    for doc in [gw] + routes:
        print('---')
        print(yaml.dump(doc, default_flow_style=False))

三、流量管理

3.1 流量拆分(金丝雀发布)

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: canary-route
spec:
  parentRefs:
  - name: api-gateway
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /api/v2
    backendRefs:
    - name: api-v2-stable
      port: 8080
      weight: 95
    - name: api-v2-canary
      port: 8080
      weight: 5

3.2 流量镜像

apiVersion: gateway.networking.k8s.io/v1alpha2
kind: HTTPRouteFilter
metadata:
  name: mirror-filter
spec:
  type: RequestMirror
  requestMirror:
    backendRef:
      name: api-mirror
      port: 8080

3.3 基于Header的路由

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: header-route
spec:
  parentRefs:
  - name: api-gateway
  rules:
  - matches:
    - headers:
      - type: Exact
        name: X-Feature-Flag
        value: new-ui
    backendRefs:
    - name: frontend-v2
      port: 80
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: frontend-v1
      port: 80

3.4 gRPC路由

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: grpc-route
spec:
  parentRefs:
  - name: api-gateway
  rules:
  - matches:
    - method:
        service: "com.example.UserService"
        method: "GetUser"
    backendRefs:
    - name: user-grpc-service
      port: 50051

四、多集群与多租户

4.1 多集群Gateway

apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
  name: allow-cross-namespace
  namespace: app-team
spec:
  from:
  - group: gateway.networking.k8s.io
    kind: HTTPRoute
    namespace: infra
  to:
  - group: ""
    kind: Service

4.2 多租户隔离

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: tenant-a-gateway
  namespace: tenant-a
spec:
  gatewayClassName: istio
  listeners:
  - name: http
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: Same

租户隔离策略对比

策略 隔离级别 资源开销 管理复杂度 适用场景
共享Gateway Route级 小规模、信任租户
Namespace隔离 Namespace级 中规模、一般隔离
独立Gateway Gateway级 大规模、强隔离需求

5个常见陷阱

# 陷阱 后果 解决方案
1 直接删除Ingress再创建Gateway 流量中断 先并行运行,验证后再删除
2 HTTPRoute引用其他Namespace的Gateway 权限被拒 创建ReferenceGrant
3 Gateway的allowedRoutes配置过严 Route无法绑定 检查namespace selector
4 忽略GatewayClass的参数 控制器行为不符预期 仔细阅读GatewayClassSpec.parametersRef
5 流量拆分weight总和不为100 行为未定义(实现相关) 确保weight总和为100

10个常见错误排查

# 错误现象 可能原因 排查方法
1 HTTPRoute的Parents条件为Accepted: False Gateway不允许该Namespace 检查Gateway的allowedRoutes
2 流量未到达后端 Route匹配规则错误 kubectl describe httproute检查ResolvedRefs
3 GatewayNotReady 控制器未安装或未运行 检查GatewayClass和控制器Pod
4 TLS证书未生效 证书Secret不存在或格式错误 检查Secret类型为kubernetes.io/tls
5 金丝雀流量比例不对 weight计算错误 确认weight总和为100且比例正确
6 跨Namespace引用被拒 缺少ReferenceGrant 创建ReferenceGrant允许跨Namespace引用
7 GRPCRoute不生效 Gateway listener未配置H2C 添加protocol: HTTP的listener并启用H2C
8 流量镜像不工作 控制器不支持RequestMirror 确认控制器实现支持该扩展
9 Gateway IP未分配 控制器未配置LB 检查控制器的Service和LoadBalancer
10 迁移后性能下降 控制器配置未优化 对比Ingress和Gateway的代理配置

工具推荐

在Gateway API迁移过程中,以下工具可以帮助你处理配置和编码问题:

  • JSON格式化工具 — 格式化Gateway API的Status和条件信息,方便调试路由状态
  • Base64编码工具 — 对TLS证书和密钥进行Base64编码,用于Kubernetes Secret
  • 哈希计算工具 — 为Gateway配置生成版本指纹,用于配置变更检测和回滚判断

总结:Gateway API不是Ingress的"升级版",而是流量管理的"重新设计"。三角色分离让平台、运维、开发各司其职;原生流量拆分让金丝雀发布不再依赖annotation hack;多协议支持让gRPC和TCP服务也能享受统一的流量管理。2026年,Ingress已经进入维护模式,Gateway API是唯一的方向。迁移的核心原则:先并行、再验证、最后切换——不要一步到位,让Ingress和Gateway API共存一段时间,确认流量正常后再移除Ingress。

本站提供浏览器本地工具,免注册即可试用 →

#K8s Gateway API#Ingress迁移#服务网格#流量管理#2026