Service Extensions を使用して GKE Gateway トラフィックをカスタマイズする


このページでは、Google Kubernetes Engine(GKE)が Service Extensions を使用して Cloud Load Balancing にカスタム ロジックを追加する方法について説明します。

このページは、Service Extension を使用してカスタム トラフィック管理ロジックを構成する必要がある GKE ID とアカウントの管理者とデベロッパーを対象としています。

このページを読む前に、次のことをよく理解しておいてください。

概要

GKE は Service Extensions を使用して、Cloud Load Balancing にカスタム ロジックを追加します。拡張機能は Gateway に接続し、Service または GoogleAPIServiceName を参照します。GoogleAPIServiceNameGCPTrafficExtensions でのみサポートされています。

バックエンド サービスの選択やセキュリティ ポリシーに影響を与えることなく、リクエストとレスポンスの HTTP ヘッダーとペイロードを変更したり、トラフィック ルーティングを制御したりできます。Service Extensions は、高度なトラフィック分割、カスタム認証、リクエスト ロギングなどのタスクに使用できます。

GKE Gateway Controller は、次の Service Extensions をサポートしています。

  • GCPRoutingExtension: この拡張機能は、トラフィック ルーティングを制御するために Cloud Load Balancing にカスタム ロジックを追加します。これは、リージョン外部アプリケーション ロードバランサとリージョン内部アプリケーション ロードバランサでサポートされています。

    GCPRoutingExtension リソースは Gateway に接続され、Service を参照します。拡張機能はトラフィック ルーティングを制御します。
    図: Gateway での「GCPRoutingExtension」の仕組み
  • GCPTrafficExtension: この拡張機能は、Cloud Load Balancing にカスタム ロジックを挿入します。これにより、拡張機能サービスはリクエストとレスポンスを変更できます。GCPTrafficExtension は、バックエンド サービスの選択やバックエンド サービスのセキュリティ ポリシーには影響しません。

    GCPTrafficExtension リソースは Gateway に接続され、Service または GoogleAPIServiceName を参照します。この拡張機能は、リクエストとレスポンスを変更します。
    図: Gateway での「GCPTrafficExtension」の仕組み

Google Cloud GatewayClasses との Service Extensions の互換性

次の表に、サービス拡張機能とさまざまな GatewayClass の互換性を示します。 Google Cloud

GatewayClass GCPRoutingExtension GCPTrafficExtension
gke-l7-rilb サポート対象 サポート対象
gke-l7-regional-external-managed サポート対象 サポート対象
gke-l7-global-external-managed サポート対象外 サポート対象

始める前に

作業を始める前に、次のことを確認してください。

  • Google Kubernetes Engine API を有効にする。
  • Google Kubernetes Engine API の有効化
  • このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、gcloud components update を実行して最新のバージョンを取得する。
  • 必要に応じて、Compute Engine API、Network Services API、Model Armor API を有効にします。

    API へのアクセスを有効にするに移動し、手順に沿って操作します。

  • Google Cloud Service Extensions の料金の詳細については、料金をご覧ください。

  • 必要なロールと権限については、 Service Extensions のアクセス制御をご覧ください。

  • Service Extensions の割り当てで割り当てと上限を確認してください。

  • Common Expression Language(CEL)マッチャーを使用する場合は、CEL マッチャーの言語リファレンスでサポートされている属性と演算子を確認してください。

  • Service Extensions の制限事項を確認します。

GKE Gateway コントローラの要件

  • クラスタは、GKE バージョン 1.28 以降を使用する必要があります。
  • クラスタで Gateway API が有効になっている必要があります。
  • Gateway リソースが構成されている必要があります。
  • HTTPRoute リソースが構成されている必要があります。

制限事項

次の表に、GKE での Gateway Service Extensions の構成に関連する制限を示します。

カテゴリ 制限事項
ロードバランサ GCPRoutingExtension は、リージョン外部アプリケーション ロードバランサとリージョン内部アプリケーション ロードバランサ(gke-l7-regional-external-managedgke-l7-rilb ゲートウェイ クラス)でのみサポートされ、gke-l7-global-external-managed ゲートウェイ クラスではサポートされていません。
拡張機能チェーンと仕様
  • GCPTrafficExtension の場合、各 ExtensionChain に最大 3 つの Extensions を指定できます。
  • GCPRoutingExtension の場合、各 ExtensionChain は 1 つの Extension に制限されます。
  • GCPTrafficExtensionSpecGCPRoutingExtensionSpec にはそれぞれ最大 5 つの ExtensionChains を含めることができます。
タイミングと一致
  • 拡張機能内のストリーム上の個々のメッセージのタイムアウトは、10 ~ 1,000 ミリ秒にする必要があります。この 1 秒の制限は、ルート拡張機能とトラフィック拡張機能に適用されます。
  • ExtensionChain 内の各 MatchCondition は、最大 10 個の CELExpressions に制限されます。
  • GCE に送信される結果の MatchCondition 文字列の文字数は 512 文字に制限されています。
  • CELExpression 内の CELMatcher 文字列の最大長は 512 文字で、特定のパターンに従う必要があります。CELExpressionBackendRefs フィールドはサポートされていません。
ヘッダーとメタデータ
  • ExtensionForwardHeaders リストには、最大 50 個の HTTP ヘッダー名を含めることができます。
  • ExtensionMetadata マップには、最大 16 個のプロパティを含めることができます。
  • Metadata マップ内のキーは 1 ~ 63 文字の長さにする必要があります。
  • Metadata マップ内の値は 1 ~ 1,023 文字にする必要があります。
イベント
  • GCPRoutingExtensionrequestBodySendMode が設定されていない場合、supportedEvents リストには RequestHeaders イベントのみを含めることができます。
  • GCPRoutingExtension の場合、requestBodySendModeFullDuplexStreamed に設定されている場合、supportedEvents リストには RequestHeadersRequestBodyRequestTrailers イベントのみを含めることができます。
GCPTrafficExtension
  • responseBodySendMode フィールドは GCPTrafficExtension でのみサポートされています。
  • googleAPIServiceName フィールドは GCPTrafficExtension でのみサポートされています。
googleAPIServiceNamebackendRef 拡張機能で backendRef を使用する Service を参照する場合は、次の条件を満たす必要があります。
  • appProtocol として HTTP2 を使用する必要があります。
  • Extension と、Extension によって参照される Gateway と同じ Namespace に存在する必要があります。
  • IAP を使用できません。
  • Google Cloud Armor セキュリティ ポリシー( GCPBackendPolicyConfigsecurityPolicy フィールド)を使用できません。
  • Cloud CDN を使用できません。
  • Extension には backendRef または googleAPIServiceName のいずれか 1 つを設定する必要があります。
  • backendRef が設定されている場合は、authority を設定する必要があります。
  • googleAPIServiceName が設定されている場合は、authority を設定する必要があります。
  • backendRef のみを使用して、拡張機能の requestBodySendMode を構成します。
  • backendRef のみを使用して、拡張機能の responseBodySendMode を構成します。

GKE Service Extensions を構成する

GKE Service Extensions を構成することで、トラフィック ルーティングをカスタマイズしたり、リクエストまたはレスポンスのペイロードを変更したり、外部サービスと統合したりできます。デフォルトでは、Gateway に Service Extensions はありません。

GKE Service Extensions を構成するには:

  1. Gateway をデプロイする: GKE Service 拡張機能を構成するには、まず Gateway をデプロイして、外部トラフィックをクラスタに転送する必要があります。グローバル外部アプリケーション ロードバランサ、リージョン外部アプリケーション ロードバランサ、リージョン内部アプリケーション ロードバランサ ゲートウェイのいずれかです。

    Gateway のデプロイの詳細については、Gateway のデプロイをご覧ください。

  2. バックエンド コールアウト Service をデプロイする: カスタム ロジック実行のバックエンド サービスを表す Kubernetes Service を作成します。ロードバランサはこのサービスを呼び出します。

  3. Service Extensions を構成する: ロードバランサのタイプと要件に基づいて、適切な Service Extensions を構成します。

    1. リージョン ゲートウェイの GCPRoutingExtension: リージョン外部アプリケーション ロードバランサとリージョン内部アプリケーション ロードバランサでこの拡張機能を使用して、リージョン内にカスタム ルーティング ロジックを実装します。

    2. GCPTrafficExtension(グローバル外部、リージョン外部、内部 Gateway 用): この拡張機能は、グローバル外部アプリケーション ロードバランサ、リージョン外部アプリケーション ロードバランサ、リージョン内部アプリケーション ロードバランサで、さまざまなロードバランサ タイプ間でヘッダーの変更やペイロード検査などのトラフィック操作を行うために使用します。

バックエンド コールアウト サービスをデプロイする

コールアウト サービスは、GKE の Gateway Service Extensions のカスタム ロジックを実装します。Gateway は、GCPTrafficExtension または GCPRoutingExtension の構成に基づいてこれらのバックエンド アプリケーションを呼び出し、トラフィックを変更またはルーティングします。

コールアウト サービスをデプロイして、Gateway にカスタム ロジックを追加します。この個別のサービスは、ヘッダーの操作、ペイロードの変換、トラフィックのルーティングなどのカスタム処理を処理します。

Gateway のコールアウトとして機能するバックエンド サービスをデプロイする手順は次のとおりです。

  1. (省略可)TLS の Secret を作成する: このコマンドは、TLS 証明書と秘密鍵を含む TLS タイプの Kubernetes Secret を作成します。

    コールアウト サービスの TLS シークレットを作成するには、次の部分を置き換えます。

    • SECRET_NAME: コールアウト サービスのシークレット名
    • path-to-cert: 証明書のファイルパス
    • path-to-key: 鍵のファイルパス
  2. Secret が追加されたことを確認するには、次のコマンドを実行します。

    kubectl get secrets SECRET_NAME
    

    SECRET_NAME は、コールアウト サービスのシークレット名に置き換えます。

    出力例を以下に示します。

    NAME            TYPE                DATA   AGE
    SECRET_NAME     kubernetes.io/tls   2      12s
    
  3. Deployment リソースと Service リソースを定義します。

    次のことを定義する必要があります。

    • Deployment: Service Extensions のカスタム ロジックを含むアプリケーション Pod を管理します。
    • Service: Deployment によって管理されるアプリケーション Pod をネットワーク サービスとして公開します。
    1. Deployment と Service の定義を含むサンプル マニフェスト extension-service-app.yaml を作成します。

      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/path-to-cert"
              - name: TLS_SERVER_PRIVKEY
                value: "/etc/certs/path-to-key"
                resources:
                requests:
                  cpu: 10m
            volumes:
            - name: certs
              secret:
                secretName: SECRET_NAME
                optional: false
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: extension-service
      spec:
        ports:
        - port: 443
          targetPort: 443
          appProtocol: HTTP2
        selector:
          app: store
      
    2. extension-service-app.yaml マニフェストを適用します。

      kubectl apply -f extension-service-app.yaml
      
  4. 構成を確認します

    1. アプリケーションがデプロイされたことを確認します。

      kubectl get pod --selector app=store
      

      アプリケーションの実行が開始すると、出力は次のようになります。

      NAME                                     READY   STATUS    RESTARTS   AGE
      extension-service-app-85f466bc9b-b5mf4   1/1     Running   0          7s
      
    2. Service がデプロイされたことを確認します。

      kubectl get service extension-service
      

      出力は次のようになります。各ストアの Deployment の Service を示しています。

      NAME                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
      extension-service   ClusterIP   34.118.225.9   <none>        443/TCP   2m40s
      

サービス拡張機能を構成する

GCPRoutingExtension または GCPTrafficExtension を構成して、トラフィック フローをカスタマイズできます。

リージョン Gateway の GCPRoutingExtension を構成する

トラフィックを再ルーティングするには、GCPRoutingExtension を使用します。GCPRoutingExtension を構成するには、HTTPRoute を更新して、service-extensions.com ホストのリクエストを指定します。

  1. HTTPRoute を更新します。HTTPRoute を変更して、ルーティング拡張機能をトリガーするホスト名またはパスを追加します。

    1. 次のサンプル マニフェストを store-route.yaml ファイルとして保存します。

      kind: HTTPRoute
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: store
      spec:
        parentRefs:
        - kind: Gateway
          name:GATEWAY_NAME
        hostnames:
        - "store.example.com"
        - "service-extensions.example.com"
        rules:
        - backendRefs:
          - name: store-v1
            port: 8080
        - matches:
          - headers:
            - name: env
              value: canary
          backendRefs:
          - name: store-v2
            port: 8080
        - matches:
          - path:
              value: /de
          backendRefs:
          - name: store-german
            port: 8080
      

      GATEWAY_NAME は、Gateway の名前に置き換えます。

    2. store-route.yaml マニフェストを適用します。

      kubectl apply -f store-route.yaml
      
  2. GCPRoutingExtension を定義します。

    1. GCPRoutingExtension 構成をサンプルの gcp-routing-extension.yaml ファイルに保存します。

      kind: GCPRoutingExtension
      apiVersion: networking.gke.io/v1
      metadata:
        name: my-gateway-extension
        namespace: default
      spec:
        targetRefs:
        - group: "gateway.networking.k8s.io"
          kind: Gateway
          name: GATEWAY_NAME
        extensionChains:
        - name: chain1
          matchCondition:
            celExpressions:
            - celMatcher: request.path.contains("serviceextensions")
          extensions:
          - name: ext1
            authority: "myext.com"
            timeout: 1s
              backendRef:
                group: ""
              kind: Service
              name: extension-service
              port: 443
      

      GATEWAY_NAME は、Gateway の名前に置き換えます。

    2. サンプル マニフェストをクラスタに適用します。

      kubectl apply -f gcp-routing-extension.yaml
      
  3. GCPRoutingExtension の構成と、Gateway へのバインディングを確認します。

    1. GCPRoutingExtension Deployment を確認します。

      kubectl describe gcproutingextension my-gateway-extension
      

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

      Name:         my-gateway-extension
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPRoutingExtension
      Metadata:
        Creation Timestamp:  2025-03-02T17:12:30Z
        Generation:        1
        Resource Version:  31283253
        UID:               ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
      Spec:
        Extension Chains:
          Extensions:
            Authority:    myext.com
            Backend Ref:
              Group:
              Kind: Service
              Name: extension-service
              Port: 443
            Name:       ext1
            Timeout:    1s
          Match Condition:
            Cel Expressions:
              Cel Matcher: request.path.contains("serviceextensions")
          Name:  chain1
        Target Refs:
          Group: gateway.networking.k8s.io
          Kind: Gateway
          Name: GATEWAY_NAME
      Events:  <none>
      

      出力には、デフォルト Namespace 内の GCPRoutingExtensionmy-gateway-extension という名前)の詳細が表示されます。出力には Spec フィールドが表示されます。このフィールドには、拡張機能の動作の定義が含まれています。

    2. Gateway バインディングを確認します。

      1. GCPRoutingExtension が Gateway にバインドされていることを確認します。これには数分かかることがあります。

        kubectl describe gateway GATEWAY_NAME
        

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

        Name:         GATEWAY_NAME
        Namespace:    default
        Labels:       none
        Annotations:  networking.gke.io/addresses: /projects/1234567890/regions/us-central1/addresses/test-hgbk-default-internal-http-5ypwen3x2gcr
                      networking.gke.io/backend-services:
                        /projects/1234567890/regions/us-central1/backendServices/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/re...
                      networking.gke.io/firewalls: /projects/1234567890/global/firewalls/test-hgbk-l7-default-us-central1
                      networking.gke.io/forwarding-rules: /projects/1234567890/regions/us-central1/forwardingRules/test-hgbk-default-internal-http-qn7dk9i9zm73
                      networking.gke.io/health-checks:
                        /projects/1234567890/regions/us-central1/healthChecks/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/regio...
                      networking.gke.io/last-reconcile-time: 2025-03-02T17:15:02Z
                      networking.gke.io/lb-route-extensions:
                        /projects/1234567890/locations/us-central1/lbRouteExtensions/test-hgbk-default-internal-http-lwh0op4qorb0
                      networking.gke.io/lb-traffic-extensions:
                      networking.gke.io/ssl-certificates:
                      networking.gke.io/target-http-proxies:
                        /projects/1234567890/regions/us-central1/targetHttpProxies/test-hgbk-default-internal-http-2jzr7e3xclhj
                      networking.gke.io/target-https-proxies:
                      networking.gke.io/url-maps: /projects/1234567890/regions/us-central1/urlMaps/test-hgbk-default-internal-http-2jzr7e3xclhj
        API Version:  gateway.networking.k8s.io/v1
        Kind:         Gateway
        Metadata:
          Creation Timestamp:  2025-03-02T16:37:50Z
          Finalizers:
          gateway.finalizer.networking.gke.io
          Generation:        1
          Resource Version:  31284863
          UID:               fd512611-bad2-438e-abfd-5619474fbf31
        ...
        

        出力には、GKE が Gateway と基盤となるGoogle Cloud リソース間のリンクの保存に使用するアノテーションが表示されます。networking.gke.io/lb-route-extensions アノテーションは、ゲートウェイが GCPRoutingExtension にバインドされていることを確認します。

      2. GCPRoutingExtension のステータスが Reconciled で、理由が ReconciliationSucceeded であることを確認して、延長ステータスを確認します。このコマンドは数分かかることがあります。

        kubectl describe gcproutingextension my-gateway-extension
        

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

        Name:         my-gateway-extension
        Namespace:    default
        Labels:       <none>
        Annotations:  <none>
        API Version:  networking.gke.io/v1
        Kind:         GCPRoutingExtension
        Metadata:
          Creation Timestamp:  2025-03-02T17:12:30Z
          Generation:          1
          Resource Version:    31284378
          UID:                 ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
        Spec:
          Extension Chains:
            Extensions:
              Authority:  myext.com
              Backend Ref:
                Group:
                Kind:   Service
                Name:   extension-service
                Port:   443
              Name:     ext1
              Timeout:  1s
            Match Condition:
              Cel Expressions:
                Cel Matcher:  request.path.contains("serviceextensions")
            Name:             chain1
          Target Refs:
            Group:  gateway.networking.k8s.io
            Kind:   Gateway
            Name:   GATEWAY_NAME
        Status:
          Ancestors:
            Ancestor Ref:
              Group:      gateway.networking.k8s.io
              Kind:       Gateway
              Name:       GATEWAY_NAME
              Namespace:  default
            Conditions:
              Last Transition Time:  2025-03-02T17:14:15Z
              Message:
              Reason:                Accepted
              Status:                True
              Type:                  Accepted
              Last Transition Time:  2025-03-02T17:14:15Z
              Message:
              Reason:                ReconciliationSucceeded
              Status:                True
              Type:                  Reconciled
            Controller Name:         networking.gke.io/gateway
        Events:
          Type    Reason  Age                From                   Message
          ----    ------  ----               ----                   -------
          Normal  ADD     2m31s              sc-gateway-controller  default/my-gateway-extension
        Normal  SYNC    51s (x2 over 98s)  sc-gateway-controller  Attachment of GCPRoutingExtension "default/my-gateway-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        "GATEWAY_NAME",
        SectionName: nil,
        Port:        nil} was a success
          Normal  SYNC    23s           sc-gateway-controller  Reconciliation of GCPRoutingExtension "default/my-gateway-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        "GATEWAY_NAME",
        SectionName: nil,
        Port:        nil} was a success
        

        Status.Conditions フィールドには、Status: TrueReason: ReconciliationSucceeded を含む Reconciled 条件が表示されます。

        True と Reason: ReconciliationSucceeded。この情報は、拡張機能が正常に適用されたことを確認します。

  4. アプリケーションにトラフィックを送信します。

    クラスタに Gateway、Route、アプリケーションがデプロイされたら、アプリケーションにトラフィックを転送できます。

    1. アプリケーションにアクセスするには、Gateway の IP アドレスを見つける必要があります。

      ターミナルで次のコマンドを使用します。

      kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
      

      GATEWAY_NAME は、Gateway の名前に置き換えます。

      このコマンドは、Gateway の IP アドレスを出力します。後続のコマンドで、GATEWAY_IP_ADDRESS は出力から取得した IP アドレスに置き換えます。

    2. store.example.com/serviceextensions にあるストアサービスの serviceextensions バージョンにアクセスして、パスの更新をテストします。

      curl http://store.example.com/serviceextensions --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
      

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

      {
      "cluster_name": "gke1",
      "host_header": "service-extensions.com",
      "metadata": "store-v1",
      "pod_name": "store-v1-5d9554f847-cvxpd",
      "pod_name_emoji": "💇🏼‍♀️",
      "project_id": "gateway-demo",
      "timestamp": "2025-03-15T12:00:00",
      "zone": "us-central1-c"
      }
      

GCPTrafficExtension を構成する

GCPTrafficExtension を使用すると、 Google Cloud 環境内で高度なトラフィック管理機能を使用できます。この拡張機能は、グローバル外部アプリケーション ロードバランサ、リージョン外部アプリケーション ロードバランサ、リージョン内部アプリケーション ロードバランサ全体で構成できます。GCPTrafficExtension を使用すると、カスタム リクエストとレスポンスのロジック、高度なルーティング、変換、セキュリティ ポリシーを実装できます。

  1. HTTPRoute を更新します。HTTPRoute を変更して、トラフィック拡張をトリガーするホスト名またはパスを含めます。

    1. 次のサンプル マニフェストを store-route.yaml ファイルとして保存します。

      kind: HTTPRoute
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: store
      spec:
        parentRefs:
        - kind: Gateway
          name: GATEWAY_NAME
        hostnames:
        - "store.example.com"
        - "service-extensions.example.com"
        rules:
        - backendRefs:
          - name: store-v1
            port: 8080
        - matches:
          - headers:
            - name: env
              value: canary
          backendRefs:
          - name: store-v2
            port: 8080
        - matches:
          - path:
              value: /de
          backendRefs:
          - name: store-german
            port: 8080
      

      GATEWAY_NAME は、Gateway の名前(internal-httpexternal-httpglobal-external-http など)に置き換えます。

    2. store-route.yaml マニフェストをクラスタに適用します。

      kubectl apply -f store-route.yaml
      
  2. GCPTrafficExtension を定義します。

    1. GCPTrafficExtension 構成をサンプルの gcp-traffic-extension.yaml ファイルに保存します。

      kind: GCPTrafficExtension
      apiVersion: networking.gke.io/v1
      metadata:
        name: my-traffic-extension
        namespace: default
      spec:
        targetRefs:
        - group: "gateway.networking.k8s.io"
          kind: Gateway
          name: GATEWAY_NAME
        extensionChains:
        - name: chain1
          matchCondition:
            celExpressions:
            - celMatcher: request.path.contains("serviceextensions")
          extensions:
          - name: ext1
            authority: "myext.com"
            timeout: 1s
            backendRef:
              group: ""
              kind: Service
              name: extension-service
              port: 443
      

      GATEWAY_NAME は、Gateway の名前(internal-httpexternal-httpglobal-external-http など)に置き換えます。

    2. サンプル マニフェストをクラスタに適用します。

      kubectl apply -f gcp-traffic-extension.yaml
      
  3. GCPTrafficExtension の構成と、Gateway へのバインディングを確認します。

    1. GCPTrafficExtension Deployment を確認します。

      kubectl describe gcptrafficextension my-traffic-extension
      

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

      Name:         my-traffic-extension
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPTrafficExtension
      Metadata:
        Creation Timestamp:  2025-03-02T17:12:30Z
        Generation:        1
        Resource Version:  31283253
        UID:               ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
      Spec:
        Extension Chains:
          Extensions:
            Authority:    myext.com
            Backend Ref:
              Group:
              Kind: Service
              Name: extension-service
              Port: 443
            Name:       ext1
            Timeout:    1s
          Match Condition:
            Cel Expressions:
              Cel Matcher: request.path.contains("serviceextensions")
          Name:  chain1
        Target Refs:
          Group: gateway.networking.k8s.io
          Kind: Gateway
          Name: GATEWAY_NAME
      Events:  <none>
      

      出力には、デフォルト Namespace 内の my-traffic-extension という名前の GCPTrafficExtension の詳細が表示されます。Spec フィールドが表示されます。このフィールドには、拡張機能の動作の定義が含まれています。

    2. Gateway バインディングを確認します。

      GCPTrafficExtension が Gateway にバインドされていることを確認します。このコマンドが完了するまでに数分かかることがあります。

      kubectl describe gateway GATEWAY_NAME
      

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

      Name:         GATEWAY_NAME
      Namespace:    default
      Labels:       <none>
      Annotations:  networking.gke.io/addresses: /projects/1234567890/regions/us-central1/addresses/test-hgbk-default-internal-http-5ypwen3x2gcr
                    networking.gke.io/backend-services:
                      /projects/1234567890/regions/us-central1/backendServices/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/re...
                    networking.gke.io/firewalls: /projects/1234567890/global/firewalls/test-hgbk-l7-default-us-central1
                    networking.gke.io/forwarding-rules: /projects/1234567890/regions/us-central1/forwardingRules/test-hgbk-default-internal-http-qn7dk9i9zm73
                    networking.gke.io/health-checks:
                      /projects/1234567890/regions/us-central1/healthChecks/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/regio...
                    networking.gke.io/last-reconcile-time: 2025-03-02T17:15:02Z
                    networking.gke.io/lb-traffic-extensions:
                      /projects/1234567890/locations/us-central1/lbTrafficExtensions/test-hgbk-default-internal-http-lwh0op4qorb0
                    networking.gke.io/ssl-certificates:
                    networking.gke.io/target-http-proxies:
                      /projects/1234567890/regions/us-central1/targetHttpProxies/test-hgbk-default-internal-http-2jzr7e3xclhj
                    networking.gke.io/target-https-proxies:
                    networking.gke.io/url-maps: /projects/1234567890/regions/us-central1/urlMaps/test-hgbk-default-internal-http-2jzr7e3xclhj
      API Version:  gateway.networking.k8s.io/v1
      Kind:         Gateway
      Metadata:
        Creation Timestamp:  2025-03-02T16:37:50Z
        Finalizers:
          gateway.finalizer.networking.gke.io
        Generation:        1
        Resource Version:  31284863
        UID:               fd512611-bad2-438e-abfd-5619474fbf31
      ...
      

      出力には、GKE が Gateway と基盤となる Google Cloud リソース間のリンクの保存に使用するアノテーションが表示されます。networking.gke.io/lb-traffic-extensions アノテーションはバインディングを確認します。

    3. 拡張機能のステータスを確認します。

      GCPTrafficExtension のステータスが Reconciled で、理由が ReconciliationSucceeded であることを確認します。このコマンドが完了するまで数分かかる場合があります。

      kubectl describe gcptrafficextension my-traffic-extension
      

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

      Name:         my-traffic-extension
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPTrafficExtension
      Metadata:
        Creation Timestamp:  2025-03-02T17:12:30Z
        Generation:          1
        Resource Version:    31284378
        UID:                 ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
      Spec:
        Extension Chains:
          Extensions:
            Authority:  myext.com
            Backend Ref:
              Group:
              Kind:   Service
              Name:   extension-service
              Port:   443
            Name:     ext1
            Timeout:  1s
          Match Condition:
            Cel Expressions:
              Cel Matcher:  request.path.contains("serviceextensions")
          Name:             chain1
        Target Refs:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   GATEWAY_NAME
      Status:
        Ancestors:
          Ancestor Ref:
            Group:      gateway.networking.k8s.io
            Kind:       Gateway
            Name:       GATEWAY_NAME
            Namespace:  default
          Conditions:
            Last Transition Time:  2025-03-02T17:14:15Z
            Message:
            Reason:                Accepted
            Status:                True
            Type:                  Accepted
            Last Transition Time:  2025-03-02T17:14:15Z
            Message:
            Reason:                ReconciliationSucceeded
            Status:                True
            Type:                  Reconciled
          Controller Name:         networking.gke.io/gateway
      Events:
        Type    Reason  Age                From                   Message
        ----    ------  ----               ----                   -------
        Normal  ADD     2m31s              sc-gateway-controller  default/my-traffic-extension
        Normal  SYNC    51s (x2 over 98s)  sc-gateway-controller  Attachment of GCPTrafficExtension "default/my-gateway-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        "GATEWAY_NAME",
        SectionName: nil,
        Port:        nil} was a success
        Normal  SYNC    23s           sc-gateway-controller  Reconciliation of GCPTrafficExtension "default/my-traffic-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        "GATEWAY_NAME",
        SectionName: nil,
        Port:        nil} was a success
      

      Status.Conditions フィールドには、Status: TrueReason: ReconciliationSucceeded を含む Reconciled 条件が表示されます。この情報は、拡張機能が正常に適用されたことを示します。

  4. アプリケーションにトラフィックを送信します。

    クラスタに Gateway、Route、アプリケーションがデプロイされたら、アプリケーションにトラフィックを転送できます。

    1. アプリケーションにアクセスするには、Gateway の IP アドレスを見つける必要があります。

      ターミナルで次のコマンドを使用します。

      kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
      

      GATEWAY_NAME は、Gateway の名前に置き換えます。

      このコマンドは、Gateway の IP アドレスを出力します。後続のコマンドで、GATEWAY_IP_ADDRESS は出力から取得した IP アドレスに置き換えます。

    2. store.example.com/serviceextensions にあるストアサービスの serviceextensions バージョンにアクセスして、パスの更新をテストします。

      curl http://store.example.com/serviceextensions --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
      

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

      {
      *   Request completely sent off
      < HTTP/1.1 200 OK
      < server: Werkzeug/2.3.7 Python/3.11.3
      < date: Sun, 02 Mar 2025 16:58:10 GMT
      < content-type: application/json
      < access-control-allow-origin: *
      < hello: service-extensions
      < via: 1.1 google
      < transfer-encoding: chunked
      }
      

Gateway でのトラフィック拡張機能のトラブルシューティング

このセクションでは、Gateway でトラフィック拡張機能を構成する際のトラブルシューティングのヒントを紹介します。

ゲートウェイが見つかりませんでした

次のエラーは、GCPTrafficExtension リソースまたは GCPRoutingExtension リソースの targetRefs フィールドで指定された Gateway リソースが存在しないことを示します。

error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.gatewayRef: gateway "my-gateway" not found in namespace "default"

この問題を解決するには、GCPTrafficExtension リソースまたは GCPRoutingExtension リソースの targetRefs フィールドで指定された Gateway リソースが、指定された Namespace に存在することを確認します。

サービスまたはサービスポートが見つかりません

次のエラーは、GCPTrafficExtension リソースまたは GCPRoutingExtension リソースの backendRef フィールドで指定された Service または Service ポートが存在しないことを示します。

error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.service: service "callout-service" not found in namespace "default"

この問題を解決するには、GCPTrafficExtension リソースまたは GCPRoutingExtension リソースの backendRef フィールドで指定された Service と Service ポートが、指定された Namespace に存在することを確認します。

NEG にネットワーク エンドポイントがない

次のエラーは、GCPTrafficExtension リソースまたは GCPRoutingExtension リソースの backendRef フィールドで指定された Service に NEG 内のネットワーク エンドポイントが関連付けられていないことを示しています。

error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.service: no network endpoints found for service "callout-service"

この問題を解決するには、GCPTrafficExtension リソースまたは GCPRoutingExtension リソースの backendRef フィールドで指定された Service にネットワーク エンドポイントがあることを確認します。

リクエストの送信時に返信がない、またはエラーが返信される

リクエストを送信しても返信が届かない、またはエラーを含む返信が届く場合は、コールアウト サービスが正しく機能していない可能性があります。

この問題を解決するには、コールアウト サービスのログでエラーがないか確認します。

JSON ペイロードのエラーコード 404

次のエラーは、コールアウト サービスが見つからないか、リクエストに応答していないことを示します。

{
  "error": {
    "code": 404,
    "message": "Requested entity was not found.",
    "status": "NOT_FOUND"
  }
}

この問題を解決するには、コールアウト サービスが実行されており、正しいポートでリッスンしていること、およびサービスが GCPTrafficExtension リソースまたは GCPRoutingExtension リソースで正しく構成されていることを確認します。

JSON ペイロードのエラーコード 500

次のエラーは、コールアウト サービスで内部サーバーエラーが発生していることを示します。

{
  "error": {
    "code": 500,
    "message": "Internal server error.",
    "status": "INTERNAL"
  }
}

この問題を解決するには、コールアウト サービスのログを確認して、内部サーバー エラーの原因を特定します。

次のステップ