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
ロールモデル ロール分離なし 3ロール(インフラ/クラスタ運用/アプリ開発)
拡張性 アノテーション依存、コントローラ間非互換 ネイティブ拡張、標準CRD
プロトコル対応 主にHTTP/HTTPS HTTP、gRPC、TCP、UDP、TLS
トラフィックルーティング 単層パスマッチ 多層ルーティング(Gateway→Route→Backend)
マルチクラスタ 非対応 ネイティブ対応(MultiClusterService)
ステータス v1安定だが進化停止 GA、継続的イテレーション

Gateway APIコアリソース

Gateway APIは3つのコアロールと対応リソースを定義します:

  • GatewayClass:インフラ管理者がゲートウェイタイプを定義(StorageClass類推)
  • Gateway:クラスタ運用者がゲートウェイインスタンスを定義(PVC類推)
  • HTTPRoute/TCPRoute/GRPCRoute:アプリ開発者がルーティングルールを定義

問題分析

なぜIngressはサービスメッシュシナリオで力不足なのか?

根本原因:Ingressはインフラ設定とアプリルーティングルールを同じリソースに結合しています。サービスメッシュシナリオでは:

  1. 権限競合:運用はTLS証明書を設定、開発はルーティングルールを変更—同じIngressオブジェクトで操作
  2. アノテーション地獄:カナリア、トラフィックミラー、リトライポリシーは全てアノテーション依存、コントローラごとに構文が異なる
  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:ヘッダーベースカナリアルーティング

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証明書のクロスネームスペース参照失敗

現象:GatewayのHTTPSリスナーが他namespaceの証明書を参照。

解決:Gateway APIは証明書とGatewayが同じnamespaceであることを要求。cert-managerで証明書をコピー、またはIstioのistio.io/credential-nameアノテーションを使用。

落とし穴4:カナリアウェイトの合計が100でない

現象:weight 80と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証明書不在またはクロスネームスペース 証明書がGatewayと同じnamespaceにあることを確認
5 port conflict on Gateway listener 同一ポートに複数リスナー ポートごとに1リスナーのみ、プロトコル設定を統合
6 backendRef service not found 対象Serviceが存在しない Service名とnamespaceを確認
7 HTTPRoute condition Accepted=False ルートがGatewayに拒否 allowedRoutesポリシーとhostnameマッチングを確認
8 Istio proxy not ready Sidecar/ztunnel未注入 istio-injection=enabledラベルまたはambientモードを確認
9 MultiClusterService endpoint empty クラスタ間ディスカバリ未動作 東西ゲートウェイ、コントロールプレーン接続性を確認
10 GRPCRoute method match failed gRPCメソッドマッチ形式エラー package.Service/Method形式を使用

高度な最適化

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 VS Gateway API + Istio Gateway API + Envoy GW
設定複雑さ 低(単一リソース) 中(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网关#云原生