ポリシーを使用して Gateway リソースを構成する

このページでは、GKE クラスタに Gateway をデプロイするときに Google Kubernetes Engine(GKE)が作成するロードバランサの構成方法について説明します。

Gateway をデプロイすると、GatewayClass の構成により、GKE が作成するロードバランサが決まります。このマネージド ロードバランサには、ポリシーで変更可能なデフォルトの設定があらかじめ構成されています。

Gateway、Service、ServiceImport にポリシーを接続して、インフラストラクチャやアプリケーションの要件に合わせて Gateway リソースをカスタマイズできます。ポリシーを適用または変更すると、Gateway コントローラがポリシーを処理し、基盤となるロードバランサ リソースを自動的に再構成します。これにより、Gateway リソース、Route リソース、Service リソースを削除または再作成する必要がなくなります。

BackendTLSPolicy を使用して、Gateway が接続するバックエンドの ID を検証するバックエンド認証済み TLS 設定を構成することもできます。詳細については、バックエンド TLS を構成するをご覧ください。

始める前に

作業を始める前に、次のタスクが完了していることを確認してください。

  • Google Kubernetes Engine API を有効にする。
  • Google Kubernetes Engine API を有効化
  • このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。gcloud CLI をインストール済みの場合は、gcloud components update コマンドを実行して最新のバージョンを取得します。以前のバージョンの gcloud CLI では、このドキュメントのコマンドを実行できない場合があります。
  • すでに Autopilot クラスタまたは Standard クラスタが存在していることを確認する。新しいクラスタを作成するには、Autopilot クラスタの作成をご覧ください。

GKE Gateway コントローラの要件

  • Gateway API は、VPC ネイティブ クラスタでのみサポートされます。
  • リージョンまたはクロスリージョンの GatewayClass を使用している場合は、プロキシ専用サブネットを有効にする必要があります。
  • クラスタで HttpLoadBalancing アドオンが有効になっている必要があります。
  • Istio を使用している場合は、Istio を次のいずれかのバージョンにアップグレードする必要があります。
    • 1.15.2 以降
    • 1.14.5 以降
    • 1.13.9 以降
  • 共有 VPC を使用している場合は、ホスト プロジェクトで、サービス プロジェクトの GKE サービス アカウントに Compute Network User ロールを割り当てる必要があります。

制限事項

GKE Gateway Controller の制限事項に加えて、Gateway リソースに適用されるポリシーには、次の制限事項が適用されます。

  • GCPGatewayPolicy リソースは、gateway.networking.k8s.io Gateway にのみ接続できます。

  • GCPGatewayPolicy リソースは、ターゲットの Gateway と同じ Namespace に存在している必要があります。

  • 単一クラスタ Gateway を使用する場合、GCPBackendPolicyHealthCheckPolicy リソースは Service リソースを参照する必要があります。

  • マルチクラスタ Gateway を使用する場合、GCPBackendPolicyHealthCheckPolicy リソースは ServiceImport リソースを参照する必要があります。

  • 1 つの Service に接続できる GCPBackendPolicy は常に 1 つのみです。2 つの GCPBackendPolicy ポリシーが作成され、同じ Service または ServiceImport をターゲットにしている場合、最も古いポリシーが優先され、2 番目のポリシーは接続できません。

  • GKE Gateway では、階層型ポリシーはサポートされていません。

  • HealthCheckPolicy リソースと GCPBackendPolicy リソースは、ターゲットの Service リソースまたは ServiceImport リソースと同じ Namespace に存在する必要があります。

  • GCPBackendPolicy リソースと HealthCheckPolicy リソースは、1 つのバックエンド サービスのみを参照できる構造になっています。

  • GCPBackendPolicy は、セッション アフィニティの HEADER_FIELD オプションも HTTP_COOKIE オプションもサポートしていません。HEADER_FIELD または HTTP_COOKIE セッション アフィニティの場合は、GCPTrafficDistributionPolicy リソースを使用します。

  • スコープが異なる(グローバル外部やリージョン内部など)Gateway を使用する場合、異なる GCPBackendPolicy 構成が必要な場合は、同じバックエンド Service を使用できません。たとえば、グローバル GCPBackendPolicy はリージョン スコープの Gateway に適用できません。スコープ固有のポリシーを正しく適用するには、Gateway スコープごとに個別の Service を作成します。

  • GCPTrafficDistributionPolicy を使用して構成されたセッション アフィニティは、単一クラスタ Gateway でのみサポートされます。

  • GCPTrafficDistributionPolicy セッション アフィニティは、専用のローカリティ ロード バランシング アルゴリズムを使用するため、InferencePool リソースと互換性がありません。

  • GCPTrafficDistributionPolicy は、従来のアプリケーション ロードバランサのセッション アフィニティまたは地域による負荷分散ポリシーの構成をサポートしていません。

リージョン内部 Gateway のグローバル アクセスを構成する

このセクションでは、バージョン 1.24 以降を実行している GKE クラスタで使用可能な機能について説明します。

内部 Gateway でグローバル アクセスを有効にするには、Gateway リソースにポリシーを接続します。

次の GCPGatewayPolicy マニフェストは、グローバル アクセス用にリージョン内部 Gateway を有効にします。

apiVersion: networking.gke.io/v1
kind: GCPGatewayPolicy
metadata:
  name: my-gateway-policy
  namespace: default
spec:
  default:
    # Enable global access for the regional internal Application Load Balancer.
    allowGlobalAccess: true
  targetRef:
    group: gateway.networking.k8s.io
    kind: Gateway
    name: my-gateway

マルチクラスタ Gateway のリージョンを構成する

このセクションでは、バージョン 1.30.3-gke.1225000 以降を実行している GKE クラスタで使用可能な機能について説明します。

フリートのクラスタが複数のリージョンにまたがっている場合は、クロスリージョン冗長性、低レイテンシ、データ主権などのさまざまなユースケースに合わせて、さまざまなリージョンにリージョン Gateway をデプロイする必要があります。マルチクラスタ Gateway 構成クラスタでは、リージョン Gateway をデプロイするリージョンを指定できます。リージョンを指定しない場合は、構成クラスタのリージョンがデフォルト リージョンになります。

マルチクラスタ Gateway のリージョンを構成するには、GCPGatewayPolicyregion フィールドを使用します。次の例では、Gateway が us-central1 リージョンに構成されています。

apiVersion: networking.gke.io/v1
kind: GCPGatewayPolicy
metadata:
  name: my-gateway-policy
  namespace: default
spec:
  default:
    region: us-central1
  targetRef:
    group: gateway.networking.k8s.io
    kind: Gateway
    name: my-regional-gateway

SSL ポリシーを構成してクライアントとロードバランサ間のトラフィックを保護する

このセクションでは、バージョン 1.24 以降を実行している GKE クラスタで使用可能な機能について説明します。

クライアントからロードバランサへのトラフィックを保護するには、ポリシーの名前を GCPGatewayPolicy に追加して SSL ポリシーを構成します。デフォルトでは、Gateway には SSL ポリシーは定義されておらず、接続もされていません。

GCPGatewayPolicy でポリシーを参照する前に、SSL ポリシーを作成してください。

次の GCPGatewayPolicy マニフェストでは、gke-gateway-ssl-policy という名前のセキュリティ ポリシーを指定しています。

apiVersion: networking.gke.io/v1
kind: GCPGatewayPolicy
metadata:
  name: my-gateway-policy
  namespace: team1
spec:
  default:
    sslPolicy: gke-gateway-ssl-policy
  targetRef:
    group: gateway.networking.k8s.io
    kind: Gateway
    name: my-gateway

ヘルスチェックを構成する

このセクションでは、バージョン 1.24 以降を実行している GKE クラスタで使用可能な機能について説明します。

デフォルトでは、HTTP または kubernetes.io/h2c のアプリケーション プロトコルを使用するバックエンド サービスの場合、HealthCheck は HTTP タイプです。HTTPS プロトコルの場合、デフォルトの HealthCheck は HTTPS タイプです。HTTP2 プロトコルの場合、デフォルトの HealthCheck は HTTP2 タイプです。

HealthCheckPolicy を使用して、ロードバランサのヘルスチェック設定を制御できます。ヘルスチェックの各タイプ(httphttpsgrpchttp2tcp)には、定義可能なパラメータがあります。 Google Cloudは、各 GKE Service のバックエンド サービスごとに固有のヘルスチェックを作成します。

ロードバランサが正常に機能するには、ヘルスチェック パスが標準の「/」でない場合、ロードバランサにカスタム HealthCheckPolicy を構成する必要があります。パスに特別なヘッダーが必要な場合や、ヘルスチェック パラメータを調整する必要がある場合も、この構成が必要です。たとえば、デフォルトのリクエストパス「/」でサービスにアクセスできず、代わりに「/health」を使用して健全性を報告する場合は、それに応じて HealthCheckPolicyrequestPath を構成する必要があります。

次の HealthCheckPolicy マニフェストは、ヘルスチェック ポリシーの構成時に使用可能なすべてのフィールドを示します。

サービス

# Health check configuration for the load balancer. For more information
# about these fields, see https://cloud.google.com/compute/docs/reference/rest/v1/healthChecks.
apiVersion: networking.gke.io/v1
kind: HealthCheckPolicy
metadata:
  name: lb-healthcheck
  namespace: lb-service-namespace
spec:
  default:
    checkIntervalSec: INTERVAL  # The default value is 15 seconds.
    timeoutSec: TIMEOUT
    healthyThreshold: HEALTHY_THRESHOLD
    unhealthyThreshold: UNHEALTHY_THRESHOLD
    logConfig:
      enabled: true
    config:
      type: PROTOCOL
      httpHealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        host: HOST
        requestPath: REQUEST_PATH
        response: RESPONSE
        proxyHeader: PROXY_HEADER
      httpsHealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        host: HOST
        requestPath: REQUEST_PATH
        response: RESPONSE
        proxyHeader: PROXY_HEADER
      grpcHealthCheck:
        grpcServiceName: GRPC_SERVICE_NAME
        portSpecification: PORT_SPECIFICATION
        port: PORT
      http2HealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        host: HOST
        requestPath: REQUEST_PATH
        response: RESPONSE
        proxyHeader: PROXY_HEADER
      tcpHealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        portName: PORT_NAME
        request: REQUEST
        response: RESPONSE
        proxyHeader: PROXY_HEADER
  # Attach to a Service in the cluster.
  targetRef:
    group: ""
    kind: Service
    name: lb-service

マルチクラスタ サービス

apiVersion: networking.gke.io/v1
kind: HealthCheckPolicy
metadata:
  name: lb-healthcheck
  namespace: lb-service-namespace
spec:
  # The default and config fields control the health check configuration for the
  # load balancer. For more information about these fields, see
  # https://cloud.google.com/compute/docs/reference/rest/v1/healthChecks.
  default:
    checkIntervalSec: INTERVAL
    timeoutSec: TIMEOUT
    healthyThreshold: HEALTHY_THRESHOLD
    unhealthyThreshold: UNHEALTHY_THRESHOLD
    logConfig:
      enabled: ENABLED
    config:
      type: PROTOCOL
      httpHealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        host: HOST
        requestPath: REQUEST_PATH
        response: RESPONSE
        proxyHeader: PROXY_HEADER
      httpsHealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        host: HOST
        requestPath: REQUEST_PATH
        response: RESPONSE
        proxyHeader: PROXY_HEADER
      grpcHealthCheck:
        grpcServiceName: GRPC_SERVICE_NAME
        portSpecification: PORT_SPECIFICATION
        port: PORT
      http2HealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        host: HOST
        requestPath: REQUEST_PATH
        response: RESPONSE
        proxyHeader: PROXY_HEADER
      tcpHealthCheck:
        portSpecification: PORT_SPECIFICATION
        port: PORT
        portName: PORT_NAME
        request: REQUEST
        response: RESPONSE
        proxyHeader: PROXY_HEADER
  # Attach to a multi-cluster Service by referencing the ServiceImport.
  targetRef:
    group: net.gke.io
    kind: ServiceImport
    name: lb-service

次のように置き換えます。

  • INTERVAL: 各ヘルスチェック プローバーのチェック間隔を秒単位で指定します。これは、プローバーのチェックを開始してから次のチェックを開始するまでの時間です。このパラメータを省略すると、 Google Cloud のデフォルトは、HealthCheckPolicy が指定されていない場合は 15 秒、checkIntervalSec 値なしで HealthCheckPolicy が指定されている場合は 5 秒になります。詳細については、複数のプローブと頻度をご覧ください。
  • TIMEOUT:Google Cloud でプローブに対するレスポンスを待ち受ける時間を指定します。TIMEOUT の値は INTERVAL 以下にする必要があります。単位は秒です。各プローブでは、プローブ タイムアウトの前に HTTP 200(OK)レスポンス コードを配信する必要があります。
  • HEALTHY_THRESHOLDUNHEALTHY_THRESHOLD: 正常から異常、または異常から正常に健全性を変更するために、少なくとも 1 つのプローバーについて、プローブの成功または失敗の連続回数を示します。これらのパラメータのいずれかを省略した場合、 Google Cloud のデフォルトの 2 が使用されます。
  • PROTOCOL: ヘルスチェックの Probe システムで使用されるプロトコルを指定します。詳細については、HTTP、HTTPS、HTTP/2 での成功基準gRPC での成功基準TCP での成功基準をご覧ください。このパラメータは必須です。
  • ENABLED: ロギングを有効にするかどうかを指定します。
  • PORT_SPECIFICATION: ヘルスチェックで固定ポート(USE_FIXED_PORT)、名前付きポート(USE_NAMED_PORT)、サービスポート(USE_SERVING_PORT)のいずれを使用するかを指定します。指定しない場合、ヘルスチェックは port フィールドで指定された動作に従います。port が指定されていない場合、このフィールドはデフォルトの USE_SERVING_PORT になります。
  • PORT: HealthCheckPolicy では、ポート番号を使用したロードバランサのヘルスチェック ポートの指定のみがサポートされています。このパラメータを省略した場合、 Google Cloud のデフォルトの 80 が使用されます。ロードバランサは、Pod の IP アドレスにプローブを直接送信するため、containerPort が Service の targetPort で参照される場合でも、サービスを提供する Pod の containerPort と一致するポートを選択する必要があります。Service の targetPort で参照される containerPorts に限定されません。
  • HOST: ヘルスチェック リクエストのホストヘッダーの値。この値はホスト名の RFC 1123 定義を使用します。ただし、数値の IP アドレスは使用できません。指定しないか空のままにした場合、この値はデフォルトでヘルスチェックの IP アドレスになります。
  • REQUEST: TCP 接続が確立された後に送信するアプリケーション データを指定します。指定しない場合、値はデフォルトで空になります。リクエストとレスポンスの両方が空の場合、確立された接続はそれ自体で正常であることを示します。リクエスト データは ASCII 形式でのみ指定できます。
  • REQUEST_PATH: ヘルスチェック リクエストのリクエストパスを指定します。指定しないか空のままにした場合、/ がデフォルトになります。
  • RESPONSE: レスポンス データの先頭と照合するバイトを指定します。指定しないか空のままにした場合、GKE はすべてのレスポンスを正常と解釈します。レスポンス データには ASCII のみを使用できます。
  • PROXY_HEADER: プロキシ ヘッダーのタイプを指定します。NONE または PROXY_V1 を使用できます。デフォルトは NONE です。
  • GRPC_SERVICE_NAME: gRPC サービスの名前(省略可)。すべてのサービスを指定する場合は、このフィールドを省略します。

HealthCheckPolicy フィールドの詳細については、healthChecks リファレンスをご覧ください。

Cloud Armor バックエンド セキュリティ ポリシーを構成してバックエンド サービスを保護する

このセクションでは、バージョン 1.24 以降を実行している GKE クラスタで使用可能な機能について説明します。

バックエンド サービスを保護するため、セキュリティ ポリシーの名前を GCPBackendPolicy に追加し、Cloud Armor バックエンド セキュリティ ポリシーを構成します。デフォルトでは、Gateway に Cloud Armor バックエンド セキュリティ ポリシーは定義されません。また接続もされません。

GCPBackendPolicy でポリシーを参照する前に、Cloud Armor バックエンド セキュリティ ポリシーを作成してください。リージョン Gateway を有効にする場合は、リージョン Cloud Armor バックエンド セキュリティ ポリシーを作成する必要があります。

次の GCPBackendPolicy マニフェストでは、example-security-policy という名前のバックエンド セキュリティ ポリシーを指定しています。

サービス

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    # Apply a Cloud Armor security policy.
    securityPolicy: example-security-policy
  # Attach to a Service in the cluster.
  targetRef:
    group: ""
    kind: Service
    name: lb-service

マルチクラスタ サービス

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    # Apply a Cloud Armor security policy.
    securityPolicy: example-security-policy
  # Attach to a multi-cluster Service by referencing the ServiceImport.
  targetRef:
    group: net.gke.io
    kind: ServiceImport
    name: lb-service

IAP を構成する

Identity-Aware Proxy(IAP)は、HTTPRoute に関連付けられたバックエンド サービスにアクセス制御ポリシーを適用します。この適用により、適切な Identity and Access Management(IAM)ロールが割り当てられた認証済みユーザーまたはアプリケーションのみが、これらのバックエンド サービスにアクセスできます。

デフォルトでは、バックエンド サービスに適用される IAP がないため、GCPBackendPolicy で明示的に IAP を構成する必要があります。

Gateway で IAP を構成するには、次の操作を行います。

  1. OAuth クライアントのクライアント ID とクライアント シークレットを取得します。クライアント シークレットは、OAuth クライアントの作成時にのみ使用できます。詳細については、OAuth クライアントを管理するをご覧ください。
  2. GKE の IAP を有効にします。

    BackendConfig は Ingress 構成リソースであるため、BackendConfig を作成する必要はありません。

  3. シークレットを参照する IAP ポリシーを指定するには:

    1. 次の GCPBackendPolicy マニフェストを backend-policy.yaml として保存します。

      サービス

      apiVersion: networking.gke.io/v1
      kind: GCPBackendPolicy
      metadata:
        name: backend-policy
      spec:
        default:
          # IAP OAuth2 settings. For more information about these fields,
          # see https://cloud.google.com/iap/docs/reference/rest/v1/IapSettings#oauth2.
          iap:
            enabled: true
            oauth2ClientSecret:
              name: CLIENT_SECRET
            clientID: CLIENT_ID
        # Attach to a Service in the cluster.
        targetRef:
          group: ""
          kind: Service
          name: SERVICE_NAME
      

      次のように置き換えます。

      • CLIENT_SECRET: OAuth クライアント シークレット。
      • CLIENT_ID: OAuth クライアント ID。
      • SERVICE_NAME: GCPBackendPolicy でターゲットにする Service の名前。

      マルチクラスタ サービス

      apiVersion: networking.gke.io/v1
      kind: GCPBackendPolicy
      metadata:
        name: backend-policy
      spec:
        default:
          # IAP OAuth2 settings. For more information about these fields,
          # see https://cloud.google.com/iap/docs/reference/rest/v1/IapSettings#oauth2.
          iap:
            enabled: true
            oauth2ClientSecret:
              name: CLIENT_SECRET
            clientID: CLIENT_ID
        # Attach to a multi-cluster Service by referencing the ServiceImport.
        targetRef:
          group: net.gke.io
          kind: ServiceImport
          name: SERVICEIMPORT_NAME
      

      次のように置き換えます。

      • CLIENT_SECRET: OAuth クライアント シークレット。
      • CLIENT_ID: OAuth クライアント ID。
      • SERVICEIMPORT_NAME: GCPBackendPolicy でターゲットにする ServiceImport の名前。
    2. backend-policy.yaml マニフェストを適用します。

      kubectl apply -f backend-policy.yaml
      
  4. 構成を確認します

    1. IAP で GCPBackendPolicy を作成したら、ポリシーが適用されたことを確認します。

      kubectl get gcpbackendpolicy
      

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

      NAME             AGE
      backend-policy   45m
      
    2. 詳細を確認するには、describe コマンドを使用します。

      kubectl describe gcpbackendpolicy
      

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

      Name:         backend-policy
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPBackendPolicy
      Metadata:
        Creation Timestamp:  2023-05-27T06:45:32Z
        Generation:          2
        Resource Version:    19780077
        UID:                 f4f60a3b-4bb2-4e12-8748-d3b310d9c8e5
      Spec:
        Default:
          Iap:
            Client ID:  441323991697-luotsrnpboij65ebfr13hlcpm5a4heke.apps.googleusercontent.com
            Enabled:    true
            oauth2ClientSecret:
              Name:  my-iap-secret
        Target Ref:
          Group:
          Kind:   Service
          Name:   lb-service
      Status:
        Conditions:
          Last Transition Time:  2023-05-27T06:48:25Z
          Message:
          Reason:                Attached
          Status:                True
          Type:                  Attached
      Events:
        Type     Reason  Age                 From                   Message
        ----     ------  ----                ----                   -------
        Normal   ADD     46m                 sc-gateway-controller  default/backend-policy
        Normal   SYNC    44s (x15 over 43m)  sc-gateway-controller  Application of GCPBackendPolicy "default/backend-policy" was a success
      

バックエンド サービスのタイムアウトを構成する

このセクションでは、バージョン 1.24 以降を実行している GKE クラスタで使用可能な機能について説明します。

次の GCPBackendPolicy マニフェストでは、バックエンド サービスのタイムアウト期間を 40 秒に設定しています。デフォルトの timeoutSec フィールドは 30 秒です。

サービス

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    # Backend service timeout, in seconds, for the load balancer. The default
    # value is 30.
    timeoutSec: 40
  # Attach to a Service in the cluster.
  targetRef:
    group: ""
    kind: Service
    name: lb-service

マルチクラスタ サービス

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    timeoutSec: 40
  # Attach to a multi-cluster Service by referencing the ServiceImport.
  targetRef:
    group: net.gke.io
    kind: ServiceImport
    name: lb-service

GCPBackendPolicy を使用してバックエンドの選択を構成する

GCPBackendPolicy 内の CUSTOM_METRICS バランシング モードを使用すると、ロードバランサのバックエンド サービスがトラフィックを分散する方法に影響する特定のカスタム指標を構成できます。このバランシング モードでは、定義したカスタム指標に基づいてロード バランシングを行うことができます。この指標は、アプリケーション バックエンドによって報告されます。

詳細については、カスタム指標ベースのロード バランシングによるトラフィック管理をご覧ください。

backends[] フィールドの customMetrics[] 配列には、次のフィールドが含まれます。

  • name: カスタム指標のユーザー定義名を指定します。
  • maxUtilization: この指標の目標使用率または最大使用率を設定します。有効な範囲は [0, 100] です。
  • dryRun: ブール値フィールドです。true の場合、指標データは Cloud Monitoring に報告されますが、ロード バランシングの決定には影響しません。

次の例は、バックエンドの選択とエンドポイント レベルのルーティング用にカスタム指標を構成する GCPBackendPolicy マニフェストを示しています。

  1. 次のマニフェストを my-backend-policy.yaml として保存します。

    kind: GCPBackendPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: my-backend-policy
      namespace: team-awesome
    spec:
      # Attach to the super-service Service.
      targetRef:
        kind: Service
        name: super-service
      default:
        backends:
        # Configuration for all locations.
        - location: "*"
          # Use the rate balancing mode for the load balancer.
          balancingMode: RATE
          # Maximum number of requests per second for each endpoint.
          maxRatePerEndpoint: 9000
        # Configuration for us-central1-a
        - location: us-central1-a
          # maxRatePerEndpoint: 9000 inherited from the * configuration.
          # Use the custom metrics balancing mode for the load balancer.
          balancingMode: CUSTOM_METRICS
          # Configure the custom metrics for the load balancer to use.
          customMetrics:
          - name: gpu-load
            maxUtilizationPercent: 100 # value ranges from 0 to 100 and maps to the floating point range [0.0, 1.0]
            dryRun: false
    
  2. マニフェストをクラスタに適用します。

    kubectl apply -f my-backend-policy.yaml
    

ロードバランサは、RATE バランシング モードとカスタム gpu-load 指標に基づいてトラフィックを分散します。

GCPTrafficDistributionPolicy を使用してエンドポイント レベルのルーティングを構成する

Google Kubernetes Engine(GKE)Gateway の GCPTrafficDistributionPolicy API は、トラフィックをアプリケーション Pod に分散する方法を正確に制御できる高度なトラフィック管理機能を提供します。この統合された GKE ネイティブ リソースにより、ロード バランシング アルゴリズムとセッション アフィニティの設定の管理が簡素化されます。

GCPTrafficDistributionPolicy を使用すると、次の構成を行えます。

  • ロード バランシング アルゴリズム: バックエンド内のエンドポイント間でトラフィックを分散する方法を指定します。

    • WEIGHTED_ROUND_ROBIN: このアルゴリズムを選択すると、ロードバランサはカスタム指標を使用して重みを計算し、報告された指標に基づいてトラフィックを分散します。GCPTrafficDistributionPolicy 構成内の customMetrics[] 配列には、次のフィールドが含まれます。

      • name: カスタム指標のユーザー定義名を指定します。
      • dryRun: true の場合、指標データは Cloud Monitoring に報告されますが、ロード バランシングには影響しません。
  • RING_HASH: このアルゴリズムは、キャッシュ パフォーマンスに敏感なサービスに有効です。コンシステント ハッシュ法を使用して、バックエンド Pod の追加または削除時のリクエストの再マッピングを最小限に抑え、スケーリング イベント中の安定性を確保します。minimumHashRingSize を構成すると、よりきめ細かい負荷分散が可能になります。

  • セッション アフィニティ: 同じクライアントからのリクエストが常に同じバックエンド Pod にルーティングされるようにします。これは、e コマースのショッピング カートやゲーム セッションなどのステートフル ワークロードにとって重要です。GKE Gateway は、HEADER_FIELDHTTP_COOKIE など、Google Cloud アプリケーション ロードバランサ インスタンスで使用可能なすべてのセッション アフィニティ タイプをサポートしています。

詳細については、カスタム指標ベースのロード バランシングによるトラフィック管理をご覧ください。

次の例は、WEIGHTED_ROUND_ROBIN ロード バランシング アルゴリズムとカスタム指標の両方を使用してエンドポイント レベルのルーティングを構成する GCPTrafficDistributionPolicy マニフェストを示しています。

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

    apiVersion: networking.gke.io/v1
    kind: GCPTrafficDistributionPolicy
    metadata:
      name: echoserver-v2
      namespace: team1
    spec:
      targetRefs:
      # Attach to the echoserver-v2 Service in the cluster.
      - kind: Service
        group: ""
        name: echoserver-v2
      default:
        # Use custom metrics to distribute traffic across endpoints.
        localityLbAlgorithm: WEIGHTED_ROUND_ROBIN
        # Configure metrics from an ORCA load report to use for traffic
        # distribution.
        customMetrics:
        - name: orca.named_metrics.bescm11
          dryRun: false
        - name: orca.named_metrics.bescm12
          dryRun: true
    
  2. マニフェストをクラスタに適用します。

    kubectl apply -f GCPTrafficDistributionPolicy.yaml
    

ロードバランサは、WEIGHTED_ROUND_ROBIN アルゴリズムと指定されたカスタム指標に基づいて、エンドポイントにトラフィックを分散します。

ハッシュリングのサイズを構成する

キャッシュミスを最小限に抑えることが重要なサービスには、RING_HASH アルゴリズムを使用します。minimumHashRingSize を調整すると、バックエンド間でよりきめ細かい負荷分散が可能になります。ロードバランサはリングサイズを自動的に管理しますが、最小値を大きくすると、大規模なバックエンド セットに対するリクエストの分散をより均等にすることができます。

apiVersion: networking.gke.io/v1
kind: GCPTrafficDistributionPolicy
metadata:
  name: ring-hash-policy
  namespace: default
spec:
  default:
    localityLbAlgorithm: RING_HASH
    # Defaults to 1024. Larger ring sizes result in more granular
    # load distributions. Supported range is 1 to 2048.
    minimumHashRingSize: 1024
  targetRefs:
  -   group: ""
    kind: Service
    name: my-cache-heavy-service

セッション アフィニティを構成する

このセクションでは、バージョン 1.24 以降を実行している GKE クラスタで使用可能な機能について説明します。

セッション アフィニティは、次の基準に基づいて構成できます。

  • クライアント IP アドレス
  • 生成した Cookie

Service にセッション アフィニティを構成すると、Gateway の localityLbPolicy 設定が MAGLEV に設定されます。

GCPBackendPolicy からセッション アフィニティの構成を削除すると、Gateway は localityLbPolicy の設定をデフォルト値の ROUND_ROBIN に戻します。

次の GCPBackendPolicy マニフェストでは、クライアント IP アドレスに基づいてセッション アフィニティを指定しています。

サービス

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    # On a best-effort basis, send requests from a specific client IP address
    # to the same backend. This field also sets the load balancer locality
    # policy to MAGLEV. For more information, see
    # https://cloud.google.com/load-balancing/docs/backend-service#lb-locality-policy
    sessionAffinity:
      type: CLIENT_IP
  targetRef:
    group: ""
    kind: Service
    name: lb-service

マルチクラスタ サービス

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    # On a best-effort basis, send requests from a specific client IP address
    # to the same backend. This field also sets the load balancer locality
    # policy to MAGLEV. For more information, see
    # https://cloud.google.com/load-balancing/docs/backend-service#lb-locality-policy
    sessionAffinity:
      type: CLIENT_IP
  targetRef:
    group: net.gke.io
    kind: ServiceImport
    name: lb-service

次の GCPBackendPolicy マニフェストは、生成された Cookie に基づいてセッション アフィニティを指定し、Cookie の TTL を 50 秒に構成しています。

サービス

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    # Include an HTTP cookie in the Set-Cookie header of the response.
    # This field also sets the load balancer locality policy to MAGLEV. For more
    # information, see
    # https://cloud.google.com/load-balancing/docs/l7-internal#generated_cookie_affinity.
    sessionAffinity:
      type: GENERATED_COOKIE
      cookieTtlSec: 50  # The cookie expires in 50 seconds.
  targetRef:
    group: ""
    kind: Service
    name: lb-service

マルチクラスタ サービス

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    # Include an HTTP cookie in the Set-Cookie header of the response.
    # This field also sets the load balancer locality policy to MAGLEV. For more
    # information, see
    # https://cloud.google.com/load-balancing/docs/l7-internal#generated_cookie_affinity.
    sessionAffinity:
      type: GENERATED_COOKIE
      cookieTtlSec: 50  # The cookie expires in 50 seconds.
  targetRef:
    group: net.gke.io
    kind: ServiceImport
    name: lb-service

sessionAffinity.type フィールドには、次の値を使用できます。

  • CLIENT_IP
  • GENERATED_COOKIE
  • NONE

GCPTrafficDistributionPolicy を使用した拡張セッション アフィニティ

このセクションでは、バージョン 1.35.2-gke.1269001 以降を実行している GKE クラスタで使用可能な機能について説明します。

GKE Gateway は、GCPTrafficDistributionPolicy リソースを使用して拡張されたセッション アフィニティ タイプをサポートしています。これにより、ロードバランサによって生成されたカスタム HTTP ヘッダーまたは Cookie に基づくルーティングなど、より詳細な制御が可能になります。

注: 高度なセッション アフィニティには GCPTrafficDistributionPolicy を使用します。GCPBackendPolicy は特定のタイプのセッション アフィニティもサポートしていますが、この構成ではレガシー オプションと見なされます。両方のポリシーが同じ Service をターゲットにしている場合、GCPTrafficDistributionPolicy 構成が優先されます。

次の表に、GCPTrafficDistributionPolicy の使用時にサポートされるアフィニティ タイプを示します。

アフィニティ タイプ 説明
HEADER_FIELD 特定の HTTP ヘッダーに基づくアフィニティ。localityLbAlgorithmMAGLEV または RING_HASH に設定する必要があります。
HTTP_COOKIE HTTP Cookie に基づくアフィニティ。最初のリクエストに応答するとき、ロードバランサは Cookie を生成し、Set-Cookie レスポンス ヘッダーで提供します。後続のリクエストでは、クライアントはロードバランサから提供された Cookie を返し、ロードバランサはそれを使用してリクエストを同じ Pod に一貫して転送します。cookie.name を構成する必要があります。必要に応じて、cookie.pathcookie.ttl を構成できます。localityLbAlgorithmMAGLEV または RING_HASH に設定する必要があります。
GENERATED_COOKIE ロードバランサは、セッションを追跡するための Cookie を生成します。グローバル外部アプリケーション ロードバランサの場合、Cookie の名前は GCLB、リージョン内部アプリケーション ロードバランサとリージョン外部アプリケーション ロードバランサの場合、Cookie の名前は GCILB、Cookie のパスは / です。必要に応じて、cookie.ttl を最大 2 週間構成できます。このタイプでは cookie.namecookie.path は構成できません。localityLbAlgorithmMAGLEV または RING_HASH に設定する必要があります。
CLIENT_IP クライアントの IP アドレスに基づくアフィニティ。localityLbAlgorithmMAGLEV または RING_HASH に設定する必要があります。

セッション アフィニティの例(拡張版)

GCPTrafficDistributionPolicy は、それぞれ独自の構成要件を持つ複数のセッション アフィニティ タイプをサポートしています。

ショッピング カートやゲームサーバーなどのステートフル アプリケーションの場合は、ユーザーのセッション データを保持する特定の Pod にリクエストを転送します。この構成では HTTP_COOKIE アフィニティを使用します。これは、ロードバランサによって生成され、Set-Cookie ヘッダーでクライアントに返される特定の Cookie にセッション アフィニティを基づかせます。

  1. 次のマニフェストを policy.yaml として保存します。

    apiVersion: networking.gke.io/v1
    kind: GCPTrafficDistributionPolicy
    metadata:
      name: http-cookie-affinity-policy
      namespace: default
    spec:
      default:
        sessionAffinity:
          type: HTTP_COOKIE
          cookie:
            name: "my-app-session-id"
            ttl: "1h"
            path: "/"
        # HTTP_COOKIE affinity requires localityLbAlgorithm to be MAGLEV or RING_HASH.
        localityLbAlgorithm: MAGLEV
      targetRefs:
      -   group: ""
        kind: Service
        name: my-stateful-service
    
  2. ポリシーをクラスタに適用します。

    kubectl apply -f policy.yaml
    

Cookie ベースのセッション アフィニティの TTL がゼロの場合の動作:

GENERATED_COOKIE アフィニティや HTTP_COOKIE アフィニティなど、すべての Cookie ベースのセッション アフィニティには ttl 属性があります。

TTL が 0 秒の場合、ロードバランサは Cookie に Expires 属性を割り当てません。この場合、クライアントは Cookie をセッション Cookie として扱います。セッションの定義は、クライアントによって異なります。

  • ウェブブラウザなどの一部のクライアントは、ブラウジング セッション全体で Cookie を保持します。つまり、Cookie はアプリケーションが閉じられるまで複数のリクエストにわたって保持されます。
  • 他のクライアントは、セッションを単一の HTTP リクエストとして扱い、直後に Cookie を破棄します。
ヘッダーベースのセッション アフィニティを構成する

A/B テストや、Cookie が適していない特殊なクライアント ルーティングなどのシナリオで、特定の HTTP ヘッダーに基づいてトラフィックをルーティングします。NONE 以外のセッション アフィニティ タイプを使用するには、localityLbAlgorithmMAGLEV または RING_HASH に設定する必要があります。デフォルトの ROUND_ROBIN とは異なり、これらのアルゴリズムは HTTP ヘッダーなどのカスタム フィールドに基づく一貫性のあるハッシュをサポートします。

  1. 次のマニフェストを policy.yaml として保存します。

    apiVersion: networking.gke.io/v1
    kind: GCPTrafficDistributionPolicy
    metadata:
      name: header-affinity-policy
      namespace: default
    spec:
      default:
        sessionAffinity:
          type: HEADER_FIELD
          httpHeaderName: "X-User-Group-ID"
        localityLbAlgorithm: MAGLEV
      targetRefs:
      -   group: ""
        kind: Service
        name: SERVICE_NAME
    
  2. ポリシーをクラスタに適用します。

    kubectl apply -f policy.yaml
    
ポリシーを確認する

GCPTrafficDistributionPolicy が正しく構成され、有効になっていることを確認するには、適用後にステータスを確認します。

  1. ポリシーのステータスを確認するには、ポリシーの説明を取得します。

    kubectl describe gcptrafficdistributionpolicy POLICY_NAME
    

    POLICY_NAME は、ポリシーの名前に置き換えます。

  2. 出力で、Conditions セクションを探します。ステータスが True で、理由が Attached の場合は、構成が有効で適用されていることを示します。

コネクション ドレインのタイムアウトを構成する

このセクションでは、バージョン 1.24 以降を実行している GKE クラスタで使用可能な機能について説明します。

コネクション ドレインのタイムアウトは、GCPBackendPolicy を使用して構成できます。コネクション ドレインのタイムアウトは、接続がドレインするまで待機する時間(秒)です。タイムアウト時間は 0~3,600 秒に設定できます。デフォルト値は 0 で、この場合、コネクション ドレインも無効になります。

次の GCPBackendPolicy マニフェストは、コネクション ドレインのタイムアウトを 60 秒に指定します。

サービス

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    connectionDraining:
      drainingTimeoutSec: 60
  targetRef:
    group: ""
    kind: Service
    name: lb-service

マルチクラスタ サービス

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    connectionDraining:
      drainingTimeoutSec: 60
  targetRef:
    group: net.gke.io
    kind: ServiceImport
    name: lb-service

指定されたタイムアウト期間の間、GKE は削除されたバックエンドに対する既存のリクエストが完了するまで待機します。ロードバランサは、削除されたバックエンドに新しいリクエストを送信しません。タイムアウト時間に達すると、GKE はバックエンドへの残りの接続をすべて閉じます。

HTTP アクセス ロギング

このセクションでは、バージョン 1.24 以降を実行している GKE クラスタで使用可能な機能について説明します。

デフォルトでの設定:

  • Gateway コントローラは、クライアントからのすべての HTTP リクエストを Cloud Logging に記録します。
  • サンプリング レートは 1,000,000 であるため、すべてのリクエストがログに記録されます。
  • オプション フィールドはログに記録されません。

GCPBackendPolicy を使用して Gateway のアクセス ロギングを無効にするには、次の 3 つの方法があります。

  • GCPBackendPolicylogging セクションを追加しないでおく
  • logging.enabledfalse に設定する
  • logging.enabledtrue に、logging.sampleRate0 に設定する

アクセス ロギングのサンプルレートとオプション フィールドのリスト(tls.cipher や orca_load_report など)を構成することもできます。

オプション フィールドのロギングを有効にするには:

  • logging.OptionalModeCUSTOM に設定します。
  • logging.optionalFields に、ログに記録するオプション フィールドのリストを指定します。サポートされているフィールドの一覧については、ロギングとモニタリングをご覧ください。

オプション フィールドのロギングを無効にするには、次の 2 つの方法があります。

  • logging.optionalFields からすべてのエントリを削除する。
  • logging.OptionalModeEXCLUDE_ALL_OPTIONAL に設定する。

次の GCPBackendPolicy マニフェストでは、アクセス ロギングのデフォルトのサンプルレートが変更され、HTTP リクエストの 50% に設定されます。このマニフェストでは、特定の Service リソースの 2 つのオプション フィールドのロギングも有効にします。

Service

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    # Access logging configuration for the load balancer.
    logging:
      enabled: true
      # Log 50% of the requests. The value must be an integer between 0 and
      # 1000000. To get the proportion of requests to log, GKE
      # divides this value by 1000000.
      sampleRate: 500000
      # Log specific optional fields.
      optionalMode: CUSTOM
      optionalFields:
      - tls.cipher
      - orca_load_report.cpu_utilization
  targetRef:
    group: ""
    kind: Service
    name: lb-service

マルチクラスタ サービス

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
  namespace: lb-service-namespace
spec:
  default:
    # Access logging configuration for the load balancer.
    logging:
      enabled: true
      # Log 50% of the requests. The value must be an integer between 0 and
      # 1000000. To get the proportion of requests to log, GKE
      # divides this value by 1000000.
      sampleRate: 500000
      # Log specific optional fields.
      optionalMode: CUSTOM
      optionalFields:
      - tls.cipher
      - orca_load_report.cpu_utilization
  targetRef:
    group: net.gke.io
    kind: ServiceImport
    name: lb-service

このマニフェストには次のフィールドがあります。

  • enable: true: アクセス ロギングを明示的に有効にします。ログは Logging で参照できます。
  • sampleRate: 500000: パケットの 50% がログに記録されるように指定します。0 ~ 1,000,000 の値を使用できます。GKE はこの値を 1,000,000 で割って [0,1] の範囲の浮動小数点値に変換します。このフィールドは、enabletrue に設定されている場合にのみ機能します。sampleRate は省略可能なフィールドですが、構成する場合は enable: true も設定する必要があります。enabletrue に設定され、sampleRate が指定されていない場合、GKE は enablefalse に設定します。
  • optionalMode: CUSTOM: ログエントリに optionalFields のセットを含める必要があることを指定します。
  • optionalFields: tls.cipher, orca_load_report.cpu_utilization: ログエントリに、TLS handshake に使用された暗号の名前と CPU 使用率が使用可能であれば、その両方を含めるように指定します。

単一クラスタ Gateway にトラフィック ベースの自動スケーリングを構成する

GKE クラスタがバージョン 1.31.1-gke.2008000 以降を実行していることを確認します。

単一クラスタ Gateway でトラフィックベースの自動スケーリングと容量ベースのロード バランシングを有効にするには、Service の容量を構成します。Service の容量によって、Pod が自動スケーリングされるか、トラフィックが他の使用可能なクラスタにオーバーフローする前に、Service が受信できるトラフィック容量を指定できます。

Service の容量を構成するには、Service と、関連付けられた GCPBackendPolicy を作成します。GCPBackendPolicy マニフェストでは maxRatePerEndpoint フィールドを使用して、Service 内の Pod ごとに 1 秒あたりのリクエスト数(RPS)の最大値を定義します。次の GCPBackendPolicy マニフェストでは、最大 RPS を 10 に定義しています。

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: store
spec:
  default:
    maxRatePerEndpoint: 10
  targetRef:
    group: ""
    kind: Service
    name: store

トラフィック ベースの自動スケーリングの詳細については、ロードバランサのトラフィックに基づく自動スケーリングをご覧ください。

トラブルシューティング

このセクションでは、ポリシーを使用して Gateway リソースを構成する際に発生する一般的な問題のトラブルシューティングについて説明します。

GCPTrafficDistributionPolicy が有効にならない

現象: ポリシーで定義されたセッション アフィニティまたは局所性設定に従ってトラフィックが分散されない。

理由: 通常、このエラーは、ポリシーが Service に正しくバインドされていない場合、または Gateway コントローラが構成をロードバランサに同期しようとしたときに検証エラーが発生した場合に発生します。

回避策:

  1. ポリシーのステータスを確認する: ポリシーがサービスに適用されているかどうかを確認します。

    kubectl describe gcptrafficdistributionpolicy POLICY_NAME
    

    POLICY_NAME は、ポリシーの名前に置き換えます。

    出力で、Conditions セクションを探します。ステータスが True で、理由が Attached の場合は、構成が有効で適用されていることを示します。ステータスが False の場合は、Reason フィールドと Message フィールドで検証エラー(選択したアフィニティ タイプでサポートされていないアルゴリズムなど)を確認します。

  2. Gateway 構成の同期を確認する: トラフィックを管理する Gateway が、これらの設定をクラウド インフラストラクチャと正常に同期したことを確認します。

    Status セクションで、Programmed 条件の StatusTrue であることを確認します。False の場合は、Gateway コントローラでエラーが発生したことを示します。このエラーは GCPTrafficDistributionPolicy に関連している可能性があります。

    Programmed 条件の横にある Reason フィールドと Message フィールドで、詳細をすぐに確認できます。より詳細なエラー メッセージや同期の失敗の履歴については、出力の下部にある Events を確認してください。

同じ Service に複数の GCPBackendPolicy が接続されている

症状:

GCPBackendPolicyService または ServiceImport に接続すると、次のステータスの状態が発生することがあります。

status:
  conditions:
    - lastTransitionTime: "2023-09-26T20:18:03Z"
      message: conflicted with GCPBackendPolicy "[POLICY_NAME]" of higher precedence, hence not applied
      reason: Conflicted
      status: "False"
      type: Attached

理由:

このステータス状態は、すでに GCPBackendPolicy が接続されている Service または ServiceImport に 2 つ目の GCPBackendPolicy を接続しようとしていることを示します。

GKE Gateway では、同じ ServiceServiceImport に複数の GCPBackendPolicy を接続できません。詳細については、制限事項をご覧ください。

回避策:

すべてのカスタム構成を含む GCPBackendPolicy を 1 つ構成し、Service または ServiceImport に接続します。

トラフィック分割中にセッション アフィニティが無視される

症状:

セッション アフィニティが構成されているにもかかわらず、リクエストが同じバックエンド Pod に一貫して転送されない。

理由:

重み付けトラフィック分割は、セッション アフィニティよりも優先されます。HTTPRoute が複数のバックエンドの重みを定義している場合、ロードバランサはアフィニティ ロジックを適用する前に、重みに基づいてバックエンドを選択します。

回避策:

セッションのスティッキー性が必要な同じ HTTPRoute ルールで、重み付けトラフィック分割を使用しないでください。

Cloud Armor セキュリティ ポリシーが見つからない

症状:

リージョン Gateway で Cloud Armor を有効にすると、次のエラー メッセージが表示されることがあります。

Invalid value for field 'resource': '{
"securityPolicy":"projects/123456789/regions/us-central1/securityPolicies/<policy_name>"}'.
The given security policy does not exist.

理由:

このエラー メッセージは、指定されたリージョンの Cloud Armor セキュリティ ポリシーが Google Cloud プロジェクトに存在しないことを示しています。

回避策:

プロジェクトにリージョン Cloud Armor セキュリティ ポリシーを作成し、GCPBackendPolicy でこのポリシーを参照します。

次のステップ