Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

GKE Gateway APIとService Extensions:複雑なトラフィック課題に挑む新たなツールキット

By Chimbu ChinnaduraiAug 12, 20258 min read

このページはEnglishDeutschEspañolFrançaisItalianoPortuguêsでもご覧いただけます。

Kubernetesはコンテナオーケストレーションを一変させ、Google Kubernetes Engine (GKE)はコンテナアプリのデプロイとスケーリングを支える強力なマネージドプラットフォームを提供しています。GKEはサービスディスカバリやロードバランシングで優れた機能を備える一方、workloadsに到達する前のトラフィックに独自の処理ロジックを適用するには、依然として制約があります。

そこで力を発揮するのが Service Extensions です。GKE Gateway APIと組み合わせてCloud Load Balancingをカスタマイズ・拡張できる、有力な選択肢といえます(注:これはKubernetesの機能であり、Google CloudのAPI Gatewayサービスとは別物です)。

GCPのService Extensionsとは?

Service Extensionsを使うと、データパスに直接カスタムロジックを差し込み、ロードバランサーを通過するトラフィックを高度に加工できます。バックエンドに手を加えることなく、リクエストやレスポンスを操作するコードをパイプラインの各段階に挿入するイメージです。

Service Extensionsには大きく2種類があります。

  • Plugins: ネットワークデータパス内に独自コードをインラインで挿入できます。WebAssembly (Wasm)とProxy-Wasm ABIをベースに構築され、Googleが管理するサンドボックス基盤上でWasmモジュールとして動作します。低レイテンシを前提に設計されており、データプレーンのすぐそばで実行したい軽量ロジックに最適です。

  • Callouts: Cloud Load Balancingから外部サービス(Googleが管理するサービス、ユーザーが管理するサービスのいずれも対象。GKE Pod上で動くものも含みます)へgRPC呼び出しを行えるようにします。Calloutsは既存のソフトウェア資産を再利用でき、ランタイムの制約も少ないため柔軟性が高く、外部データや状態を必要とする複雑なロジックに向いています。

GKEチームは先日、Gateway APIでのService Extensionsプレビューサポートを発表しました。これにより、リクエスト/レスポンスのHTTPヘッダーやペイロードの加工はもちろん、トラフィックルーティングの制御まで、既存のバックエンドサービス選定やセキュリティポリシーに影響を与えずに行えるようになります。

GKE Gateway API Service Extensionsの種類

GKE Gatewayコントローラーは現在、Calloutsタイプとして2種類のService Extensionsをサポートしており、それぞれ用途が分かれています。

  • GCPRoutingExtension:トラフィックルーティングの制御に特化したタイプです。異なるバックエンドサービスへトラフィックを振り分けたり、独自のルーティングロジックを適用したりするケースに最適です。

GCPRoutingExtensionとGatewayの連携イメージ

  • GCPTrafficExtension:リクエストやレスポンスのヘッダー・ペイロードを書き換えるタイプです。バックエンドサービスの選定やセキュリティポリシーには影響を与えないため、データ変換やエンリッチメントの用途にぴったりです。

GCPTrafficExtensionとGatewayの連携イメージ

GKE Gateway APIでService Extensionsを構成する

GKEのService Extensions機能を試すには、バージョン1.33以降のGKEクラスターと、有効化されたGateway APIが必要です。検証に着手する前に、GKEにおけるGateway Service Extensionsの最新の制限事項にも必ず目を通してください。

Gatewayをデプロイする

Service Extensionを構成するには、まずGatewayリソースをデプロイするか、既存のGatewayリソースがサポート対象のGatewayClassを使っていることを確認します。対応するロードバランサーの詳細は、Google Cloud Service ExtensionとGatewayClassesの互換性を参照してください。

  • 以下のマニフェストを適用し、シンプルなリージョナル外部アプリケーションロードバランサーGatewayをデプロイします。
---
kind: Gateway
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
  name: gke-l7-regional-external-managed
spec:
  gatewayClassName: gke-l7-regional-external-managed
  listeners:
  - name: http
    protocol: HTTP
    port: 80

サンプルのstoreバックエンドアプリケーションをデプロイする

  • 以下のマニフェストを適用して、サンプルバックエンドアプリケーションとHTTPRouteリソースをデプロイします。HTTPRouteは、GatewayリスナーからバックエンドアプリケーションへHTTPリクエストをどうルーティングするかを定義します。
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: store-v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: store
      version: v1
  template:
    metadata:
      labels:
        app: store
        version: v1
    spec:
      containers:
      - name: whereami
        image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1.2.20
        ports:
          - containerPort: 8080
        env:
        - name: METADATA
          value: "store-v1"
---
apiVersion: v1
kind: Service
metadata:
  name: store-v1
spec:
  selector:
    app: store
    version: v1
  ports:
  - port: 8080
    targetPort: 8080
------
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
  name: store
spec:
  parentRefs:
  - kind: Gateway
    name: gke-l7-regional-external-managed
  hostnames:
  - "store.example.com"
  rules:
  - backendRefs:
    - name: store-v1
      port: 8080
  • Gateway APIのIPアドレスにサンプルリクエストを送って、バックエンドのレスポンスを確認します。
curl http://store.example.com --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v

出力は次のようになります。

{
  "cluster_name": "gateway-api-service-extensio-demo",
  "gce_instance_id": "2936941014208025864",
  "gce_service_account": "chimbuc-playground.svc.id.goog",
  "host_header": "store.example.com",
  "metadata": "store-v1",
  "pod_name": "store-v1-796c8ff75-mnssb",
  "pod_name_emoji": "🧑🏿‍⚖",
  "project_id": "chimbuc-playground",
  "timestamp": "2025-07-30T12:21:44",
  "zone": "us-central1-a"
}

バックエンドのcalloutサービスをデプロイする

calloutサービスは、GKEのGateway Service Extensionsにおけるカスタムロジックの実装本体です。ロードバランサーはGCPTrafficExtensionまたはGCPRoutingExtensionの設定にもとづいてバックエンドアプリケーションを呼び出し、トラフィックを書き換えたりルーティングしたりします。

GKEクラスター上にcalloutサービスをデプロイする場合は、制限事項に記載された要件をすべて満たす必要があります。

  • mkcertなどを使って、calloutサービスのバックエンド用に自己署名証明書を発行します。appProtocolとしてHTTP2を使う必要があり、エンドツーエンドのTLSが前提となるため、これは欠かせません。
mkcert internal
  • 自己署名証明書からK8sのSecretを作成します。
kubectl create secret tls extension-service-app-secret \
  --cert=internal.pem \
  --key=internal-key.pem
  • 以下のマニフェストを適用して、サンプルcalloutアプリケーションをデプロイします。さらに多くのコードサンプルは、service-extensionsのGitHubリポジトリを参照してください。
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: extension-service-app
spec:
  selector:
    matchLabels:
      app: store
  replicas: 1
  template:
    metadata:
      labels:
        app: store
    spec:
      containers:
      - name: serviceextensions
        image: us-docker.pkg.dev/service-extensions-samples/callouts/python-example-basic:main
        ports:
        - containerPort: 8080
        - containerPort: 443
        volumeMounts:
        - name: certs
          mountPath: "/etc/certs/"
          readOnly: true
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: TLS_SERVER_CERT
          value: "/etc/certs/tls.crt"
        - name: TLS_SERVER_PRIVKEY
          value: "/etc/certs/tls.key"
        resources:
          requests:
            cpu: 10m
      volumes:
      - name: certs
        secret:
          secretName: "extension-service-app-secret"
          optional: false
---
apiVersion: v1
kind: Service
metadata:
  name: extension-service
spec:
  ports:
  - port: 443
    targetPort: 443
    appProtocol: HTTP2
  selector:
    app: store
  • このサンプルアプリは、リクエストとレスポンスの両方に対して基本的なヘッダー書き換えを行います。詳細はservice_callout_example.pyを参照してください。これをベースに、自社の業務要件に合わせた独自アプリを開発できます。

Service Extensionsを構成する

トラフィックフローのカスタマイズには、GCPRoutingExtensionGCPTrafficExtensionのいずれかを構成します。

  • 以下のマニフェストを適用してGCPRoutingExtensionリソースを作成します。routeextensionパスへのリクエストに対し、ロードバランサーがextension serviceアプリを呼び出したうえで、バックエンドのstoreアプリへ転送します。
---
kind: GCPRoutingExtension
apiVersion: networking.gke.io/v1
metadata:
  name: my-gateway-extension
  namespace: default
spec:
  targetRefs:
  - group: "gateway.networking.k8s.io"
    kind: Gateway
    name: gke-l7-regional-external-managed
  extensionChains:
  - name: chain1
    matchCondition:
      celExpressions:
      - celMatcher: request.path.contains("routeextension")
    extensions:
    - name: routeextension
      authority: "store.example.com"
      timeout: 1s
      backendRef:
        group: ""
        kind: Service
        name: extension-service
        port: 443
  • calloutサービスはstoreアプリへリクエストを転送する前にホストヘッダーを書き換えるため、HTTPRouteリソースにservice-extensions.comホストを追加して更新します。
---
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
  name: store
spec:
  parentRefs:
  - kind: Gateway
    name: gke-l7-regional-external-managed
  hostnames:
  - "store.example.com"
  - "service-extensions.com"
  rules:
  - backendRefs:
    - name: store-v1
      port: 8080
  • Gateway APIコントローラーが変更を反映するまで数分かかる場合があります。kubectl describe gateway GATEWAY_NAMEを実行し、GCPRoutingExtensionがGatewayにバインドされていることを確認してください。
Name:         gke-l7-regional-external-managed
Namespace:    default
Labels:       <none>
Annotations:  networking.gke.io/addresses:
                /projects/269684357132/regions/us-central1/addresses/gkegw1-jorz-default-gke-l7-regional-external-manag-8wyhl317c00c
              networking.gke.io/backend-services:
                /projects/269684357132/regions/us-central1/backendServices/gkegw1-jorz-default-extension-service-443-e1aovl10z449, /projects/269684357132/...
              networking.gke.io/firewalls: /projects/269684357132/global/firewalls/gkegw1-jorz-l7-default-us-central1
              networking.gke.io/forwarding-rules:
                /projects/269684357132/regions/us-central1/forwardingRules/gkegw1-jorz-default-gke-l7-regional-external-manag-5s86aj5tzcoj
              networking.gke.io/health-checks:
                /projects/269684357132/regions/us-central1/healthChecks/gkegw1-jorz-default-extension-service-443-e1aovl10z449, /projects/269684357132/reg...
              networking.gke.io/last-reconcile-time: 2025-07-30T12:46:15Z
              networking.gke.io/lb-route-extensions:
                projects/269684357132/locations/us-central1/lbRouteExtensions/gkegw1-jorz-default-gke-l7-regional-external-manag-xivagz6clt0t
              networking.gke.io/lb-traffic-extensions:
                projects/269684357132/locations/us-central1/lbTrafficExtensions/gkegw1-jorz-default-gke-l7-regional-external-manag-lu8d7n5p4kbs
              networking.gke.io/ssl-certificates:
              networking.gke.io/target-http-proxies:
                /projects/269684357132/regions/us-central1/targetHttpProxies/gkegw1-jorz-default-gke-l7-regional-external-manag-kaecv0bs2nyx
              networking.gke.io/target-https-proxies:
              networking.gke.io/url-maps:
                /projects/269684357132/regions/us-central1/urlMaps/gkegw1-jorz-default-gke-l7-regional-external-manag-kaecv0bs2nyx
API Version:  gateway.networking.k8s.io/v1
Kind:         Gateway
Metadata:
  Creation Timestamp:  2025-07-30T07:45:42Z
  Finalizers:
    gateway.finalizer.networking.gke.io
  Generation:        1
  Resource Version:  1753879575407087021
...
  • 出力されるアノテーションは、GKEがGatewayと裏側のGoogle Cloudリソースとの紐付けを保持するために使われます。networking.gke.io/lb-route-extensionsアノテーションが、GatewayとGCPRoutingExtensionのバインドを示しています。
  • 続いて、GATEWAY_IP_ADDRESSを置き換えてrouteextensionパスへのトラフィックを試します。
curl -v http://store.example.com/routeextension --resolve store.example.com:GATEWAY_IP_ADDRESS
  • 出力は次のようになり、レスポンス内のhost_headerが書き換わっていることが確認できます。
{
  "cluster_name": "gateway-api-service-extensio-demo",
  "gce_instance_id": "2936941014208025864",
  "gce_service_account": "chimbuc-playground.svc.id.goog",
  "host_header": "service-extensions.com",
  "metadata": "store-v1",
  "pod_name": "store-v1-796c8ff75-mnssb",
  "pod_name_emoji": "🧑🏿‍⚖",
  "project_id": "chimbuc-playground",
  "timestamp": "2025-07-30T12:51:06",
  "zone": "us-central1-a"
}

GCPTrafficExtensionを使えば、リクエスト/レスポンスのカスタムロジック、高度なルーティング、データ変換、セキュリティポリシーなどを実装できます。

  • 以下のマニフェストを適用してGCPTrafficExtensionリソースを作成します。trafficetensionパスへのリクエストに対し、ロードバランサーがextension serviceアプリを呼び出します。supportedEventsを変更すれば、ロードバランサーからcalloutアプリケーションへの呼び出しを細かく制御できます。
---
kind: GCPTrafficExtension
apiVersion: networking.gke.io/v1
metadata:
  name: my-traffic-extension
  namespace: default
spec:
  targetRefs:
  - group: "gateway.networking.k8s.io"
    kind: Gateway
    name: gke-l7-regional-external-managed
  extensionChains:
  - name: chain1
    matchCondition:
      celExpressions:
      - celMatcher: request.path.contains("trafficeextension")
    extensions:
    - name: trafficeextension
      authority: "store.example.com"
      timeout: 1s
      supportedEvents: ["RequestHeaders", "RequestBody", "ResponseHeaders", "ResponseBody", "RequestTrailers", "ResponseTrailers"]
      backendRef:
        group: ""
        kind: Service
        name: extension-service
        port: 443
  • 続いて、GATEWAT_IP_ADDRESSを置き換えてtrafficextensionパスへのトラフィックを試します。
curl -v http://store.example.com/trafficeextension --resolve store.example.com:GATEWAY_IP_ADDRESS
  • 出力は次のようになります。helloというカスタムレスポンスヘッダーが追加され、レスポンスボディが取り除かれていることが確認できます。
* Request completely sent off
< HTTP/1.1 200 OK
< server: Werkzeug/2.3.7 Python/3.11.3
< date: Wed, 30 Jul 2025 12:58:00 GMT
< content-type: application/json
< access-control-allow-origin: *
< hello: service-extensions
< via: 1.1 google
< transfer-encoding: chunked
<

Podログのサンプル:

GKE Gateway API向けのGCP Service Extensionsは、プラットフォームチームがイングレス層でトラフィックを管理・整形・保護する手段を大きく前進させます。カスタム認証の適用、ヘッダーの加工、トラフィックシェーピング、外部システムとの連携など、どのユースケースでも、宣言的かつスケーラブルに実現する手段としてService Extensionsが活躍します。

まだプレビュー段階ではありますが、いまこそService Extensionsを試し、非本番環境で検証しながら、自社プラットフォームに合わせた再利用可能な拡張サービスを開発する好機です。

PoCをお考えなら、ぜひDoiTにお任せください。ビジネス成果を起点とした評価・計画・移行までを一貫してご支援します。カスタムクラウドソリューションの設計を専門とするシニアクラウドエキスパートを100名以上擁するチームが、プロセスをスムーズに進めるとともに、コンプライアンスを担保しつつ、将来の需要にも効率よく応えられるインフラへと最適化します。

戦略的なアドバイスから技術的な深い知見まで、当社の専門家があらゆるフェーズでお客様に伴走します。このポリシー適用フェーズで御社にとって最適な打ち手は何か、ぜひ一度ご相談ください。堅牢でコンプライアンスに準拠し、成果につながるクラウドインフラの実現をお手伝いします。今すぐお問い合わせください。