K8s Gateway API替代Ingress?2026年服務網格流量管理完全遷移指南

DevOps

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將基礎設施配置和應用路由規則耦合在同一個資源中。在服務網格場景下:

  1. 權限衝突:運維要配TLS憑證,開發要改路由規則,都在同一個Ingress物件上操作
  2. 註解地獄:灰度發布、流量鏡像、重試策略全靠註解,不同Ingress控制器註解語法不同
  3. 跨集群盲區:Ingress無法感知其他集群的服務,多集群流量管理需要外部方案
  4. 協議限制: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配置遷移為Gateway API HTTPRoute,原生支援權重灰度:

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將憑證複製到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的跨集群控制面已連通(東西向閘道部署正確),檢查ServiceImportresolution欄位設定為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,實現基於錯誤率的自動流量切換。

4. Gateway API擴展策略

使用policyRef(v1.3+)將重試、超時、斷路器等策略與路由解耦。


對比分析

維度 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可以共存。


線上工具推薦

本站提供瀏覽器本地工具,免註冊即可試用 →

#Kubernetes#Gateway API#服务网格#Istio#Envoy#流量管理#API网关#云原生