Gateway のトラフィック管理

このページでは、Gateway のトラフィック管理の仕組みについて説明します。

このページは、Gateway API を使用してトラフィックのデプロイと管理を行うデベロッパー、オペレーター、ネットワーク スペシャリストを対象としています。

概要

Google Kubernetes Engine(GKE)ネットワーキングは Cloud Load Balancing 上に成り立っています。Cloud Load Balancing では、グローバル トラフィック管理を実現する単一のエニーキャスト IP アドレスが使用されます。Google のトラフィック管理では、グローバルとリージョンのロード バランシング、自動スケーリング、容量管理が提供され、平等で安定した低レイテンシのトラフィックが実現されます。GKE ユーザーは、GKE Gateway Controller を使用して、Google のグローバル トラフィック管理制御を宣言型かつ Kubernetes ネイティブな方法で利用できます。

クラスタ間のトラフィックのスピルオーバーを試すには、容量ベースのロード バランシングのデプロイをご覧ください。トラフィック ベースの自動スケーリングを試すには、ロードバランサのトラフィックに基づく自動スケーリングをご覧ください。

トラフィック管理

ロード バランシング、自動スケーリング、容量管理は、トラフィック管理システムの基盤となります。これらは、連携してシステム負荷を均等にし、安定化を図ります。

  • ロード バランシングは、ロケーション、健全性、さまざまなロード バランシング アルゴリズムに従ってバックエンド Pod 間でトラフィックを分散します。
  • 自動スケーリングは、ワークロードのレプリカをスケーリングして、より多くのトラフィックを引き受ける容量を作成します。
  • 容量管理は、Service の使用状況をモニタリングします。これにより、アプリケーションの可用性やパフォーマンスに影響を及ぼすことなく、トラフィックが容量によってバックエンドへオーバーフローできるようになります。

これらの機能は、目標に応じてさまざまな形に組み合わせることができます。次に例を示します。

  • 低コストの Spot VM を活用する場合は、レイテンシを犠牲にして Spot VM 間でトラフィックを均等に分散するように最適化することをおすすめします。ロード バランシングと容量管理を使用すると、GKE は容量に基づいてリージョンをまたいでトラフィックをオーバーフローし、利用可能なすべての場所で Spot VM を最大限活用します。

  • オーバー プロビジョニングによってユーザー レイテンシを最適化する場合は、負荷が増加しても多数のリージョンに GKE クラスタをデプロイして容量を動的に増やすことができます。ロード バランシングと自動スケーリングを使用すると、トラフィックが急増したときに Pod の数が自動スケーリングされ、トラフィックが他のリージョンにオーバーフローする必要がなくなります。リージョンでは、可能な限りユーザーの近くで負荷を完全に処理できるように容量が増加します。

次の図では、ロード バランシング、自動スケーリング、容量管理が相互に連携する様子を示します。

ロード バランシング、自動スケーリング、容量管理を示す図

図では、gke-us クラスタのワークロードで障害が発生しています。ロード バランシングとヘルスチェックによって、アクティブな接続がドレインされ、トラフィックは 2 番目に近いクラスタにリダイレクトされます。gke-asia のワークロードは容量を超えるトラフィックを受信するため、gke-eu への負荷が取り除かれます。gke-eu は、gke-us と gke-asia のイベントにより、通常より多くの負荷を引き受け、トラフィック容量を増やすために gke-eu は自動スケーリングされます。

Cloud Load Balancing によるトラフィック管理の処理方法については、グローバル容量管理をご覧ください。

トラフィック管理機能と Service Extensions

Gateway、HTTPRoute、Service、Policy リソースは、GKE でトラフィックを管理するための制御を行います。GKE Gateway Controller は、これらのリソースをモニタリングするコントロール プレーンです。

GKE Gateway Service Extensions は、GKE でのトラフィック管理をカスタマイズして拡張します。Extensions は、高度なトラフィック制御用のカスタム ロジックを挿入します。

GKE で Service をデプロイする場合は、次のトラフィック管理機能を使用できます。

  • Service の容量: Pod が自動スケーリングされるか、トラフィックが他の使用可能なクラスタにオーバーフローする前に、Service が受信できるトラフィック容量を指定する
  • トラフィック ベースの自動スケーリング: 1 秒あたりに受信した HTTP リクエストに基づいて、Service 内の Pod を自動スケーリングします。
  • マルチクラスタのロード バランシング: 複数の GKE クラスタまたは複数のリージョンでホストされている Service に対するロード バランシング
  • トラフィック分割: 明示的な重み付けに基づくバックエンド間でのトラフィック分配
  • セッション アフィニティ(GCPTrafficDistributionPolicy): Cookie、ヘッダー、クライアント IP アドレスを使用してセッションを固定し、ステートフル アプリケーションのパフォーマンスを最適化します。
  • クロスオリジン リソース シェアリング(CORS): クロスオリジン リクエストを許可し、セキュリティを強化する
  • エッジ キャッシング: Cloud CDN を使用してコンテンツをキャッシュに保存し、エンドユーザーのレイテンシを改善し、GKE でホストされているアプリケーションのオリジン ロードを削減する
  • Service Extensions を使用したカスタム トラフィック管理: 高度な制御用のカスタム ロジックを挿入してトラフィック管理を拡張します。例:
    • HTTP リクエストとレスポンスのヘッダーとペイロードを変更する
    • カスタム ルーティング ロジックを実装してトラフィック フローを制御する
    • 承認などの機能を実装するため、外部サービスと統合する

トラフィック管理のサポート

利用可能なトラフィック管理機能は、デプロイする GatewayClass によって異なります。機能サポートの一覧については、GatewayClass の機能をご覧ください。次の表は、トラフィック管理に対する GatewayClass のサポートをまとめたものです。

GatewayClass Service の容量 トラフィックの自動スケーリング マルチクラスタのロード バランシング トラフィック分割1 セッション アフィニティ(GCPTrafficDistributionPolicy) CORS エッジ キャッシング
gke-l7-global-external-managed
gke-l7-regional-external-managed
gke-l7-rilb
gke-l7-gxlb
gke-l7-global-external-managed-mc
gke-l7-regional-external-managed-mc
gke-l7-cross-regional-internal-managed-mc
gke-l7-rilb-mc
gke-l7-gxlb-mc
1 一般提供では単一クラスタ Gateway でトラフィック分割がサポートされています。

カスタム指標ベースのロード バランシングによるトラフィック管理

Google Cloud アプリケーション ロードバランサは、カスタム指標に基づいてトラフィックを分散します。これらの指標には、GPU 使用率の負荷や、アプリケーション固有の使用率シグナルなどが含まれます。カスタム指標を使用すると、ワークロードのパフォーマンスをより正確に把握できます。アプリケーションは、Open Request Cost Aggregation(ORCA)標準を使用してこれらの指標をレポートします。詳細については、アプリケーション ロードバランサのカスタム指標をご覧ください。

GKE では、GKE Gateway API を介してこの高度なトラフィック管理機能を統合できます。この API は、生成 AI 推論など、リソース使用量が変動するワークロードに役立ちます。次のポリシーを構成することで、カスタム トラフィック動作を設定できます。

  • GCPBackendPolicy: バックエンド選択のために、ロードバランサのバックエンド サービスがバックエンドにトラフィックを分散する方法を正確に制御できます。このポリシーには、カスタム指標の使用など、さまざまなロード バランシング モードを構成できる特定のフィールドが含まれています。GCPBackendPolicy を使用してバックエンドの選択を構成するには、GCPBackendPolicy を使用してバックエンドの選択を構成するをご覧ください。

  • GCPTrafficDistributionPolicy: エンドポイント レベルのルーティング用に、バックエンド内のエンドポイント選択のセッション アフィニティとロード バランシング アルゴリズムを構成します。永続セッションのスティッキー(STRONG_COOKIE_AFFINITY、HTTP_COOKIE、GENERATED_COOKIE、HEADER_FIELD、CLIENT_IP)と、RING_HASH などの安定したロード バランシング アルゴリズムを構成できます。WEIGHTED_ROUND_ROBIN を選択すると、ロードバランサは報告された指標(カスタム指標を含む)から導出された重みを使用して、個々のインスタンスまたはエンドポイントにトラフィックを分散します。エンドポイント レベルのルーティングとセッション アフィニティを構成するには、エンドポイント レベルのルーティングを構成するとセッション アフィニティを構成するをご覧ください。

ロケーションに基づくポリシー

ロケーション指定子を使用すると、これらのロケーションに基づくポリシーを特定の Google Cloud ゾーンまたはリージョンに適用できます。ロケーション指定子はカナリア デプロイ、段階的ロールアウト、分離されたリージョンでのポリシー変更のテストで役に立ちます。詳細については、ポリシーを使用してゲートウェイ リソースを構成するをご覧ください。

GKE バックエンドのカスタム指標をモニタリングする

グローバル外部アプリケーション ロードバランサと内部アプリケーション ロードバランサは、GKE バックエンドによって報告されたカスタム指標を観測して、トラフィックの詳細な分析情報を取得できるロギングとモニタリング機能を提供します。詳細については、グローバル外部アプリケーション ロードバランサのロギングとモニタリングをご覧ください。

GKE 指標ラベルを使用すると、GKE サービス、クラスタ、名前空間ごとにカスタム指標をクエリできます。

GKE バックエンドによって報告されたカスタム指標を表示するには、Cloud Monitoring に移動し、network.googleapis.com/loadbalancer/backend/ モニタリング対象リソースのカスタム指標を表示します。GKE 固有のラベルを使用して、これらの指標をクエリしてフィルタできます。

利用可能な指標は次のとおりです。

  • /error_rate: 各バックエンド グループが 1 秒あたりに処理したエラー数。
  • /lb_custom_metric: 定義したカスタム指標に基づく、各バックエンド グループの現在の使用率。
  • /fullness: 各バックエンド グループの現在の使用率(負荷または容量)。ロードバランサは、この値を使用してルーティングを決定します。
  • /rate: 各バックエンド グループが 1 秒あたりに受信したリクエスト数。

これらの指標のモニタリングを強化する GKE 固有のラベルには、gke_service_name、gke_namespace、gke_cluster などがあります。これらのラベルを使用して、GKE サービス、名前空間、クラスタごとの指標データを調べることができます。これらの GKE ラベルは、backend_type が ZONAL_NETWORK_ENDPOINT_GROUP の場合にのみ入力されます。

次の表に、GKE 固有のラベルを示します。

ラベル 種類 説明
gke_service_name 指標ラベルまたはシステムラベル GKE リソースのサービス名(存在する場合)。このフィールドは、`backend_type` が ZONAL_NETWORK_ENDPOINT_GROUP の場合にのみ入力されます。他のバックエンド タイプの場合、このラベルには null エントリがあります。
gke_namespace 指標ラベルまたはシステムラベル GKE リソースの Namespace(存在する場合)。このフィールドは、`backend_type` が ZONAL_NETWORK_ENDPOINT_GROUP の場合にのみ入力されます。他のバックエンド タイプの場合、このラベルには null エントリがあります。
gke_cluster 指標ラベルまたはシステムラベル リソースの GKE クラスタ名(存在する場合)。このフィールドは、`backend_type` が ZONAL_NETWORK_ENDPOINT_GROUP の場合にのみ入力されます。他のバックエンド タイプの場合、このラベルには null エントリがあります。

グローバル外部アプリケーション ロードバランサのログエントリには、HTTP(S) トラフィックのモニタリングとデバッグに役立つ情報が含まれています。

グローバル、リージョン、ゾーンのロード バランシング

ロードバランサが特定のバックエンドに送信するトラフィック量は、Service の容量、ロケーション、正常性によって決まります。ロード バランシングの決定は、グローバル ロードバランサの場合はグローバル レベルで、リージョン ロードバランサの場合はリージョン レベルで行われます。

  • グローバル: トラフィックは、容量に余裕がある正常なバックエンドを持つクライアントに最も近い Google Cloud リージョンに送信されます。リージョンの容量に余裕がある限り、最も近いトラフィックをすべて受信します。リージョンの容量に余裕がない場合、超過したトラフィックは次に最も近いリージョンにオーバーフローします。詳細については、グローバル ロード バランシングをご覧ください。
  • リージョン: トラフィックはロードバランサから特定のリージョンに送信されます。トラフィックは、ゾーンの使用可能な容量に比例してゾーン間でロード バランシングされます。詳細については、リージョン ロード バランシングをご覧ください。
  • ゾーン: 特定のゾーンのトラフィックが決まると、ロードバランサはそのゾーン内のバックエンド全体にトラフィックを均等に分散します。既存の TCP 接続とセッション永続性の設定は維持されるため、将来のリクエストはバックエンド Pod が正常である限り、同じバックエンドに送信されます。詳細については、ゾーン ロード バランシングをご覧ください。

グローバル ロード バランシングとトラフィックのオーバーフロー

独自のクラスタで次のコンセプトを試す場合は、容量ベースのロード バランシングをご覧ください。

通常の条件下では、トラフィックはクライアントに最も近いバックエンドに送信されます。トラフィックは、クライアントに最も近い Google のポイント オブ プレゼンス(PoP)で終端され、Google のバックボーンを通過して、最も近いバックエンド(ネットワーク レイテンシによって決まります)に到達します。リージョンのバックエンドの容量が残っていない場合、トラフィックは、余力のある正常なバックエンドを持つ次に近いクラスタにオーバーフローします。ゾーン内の正常でないバックエンド Pod が 50% を超える場合、トラフィックは、構成された容量に関係なく他のゾーンまたはリージョンに徐々にフェイル オーバーします。

トラフィックのオーバーフローは、次の状態の場合にのみ発生します。

  • マルチクラスタ Gateway を使用している。
  • 複数のクラスタに同じ Service をデプロイし、マルチクラスタ Gateway によって処理している。
  • トラフィックがある 1 つのクラスタの Service の容量を超えるものの、その他のクラスタの Service の容量は超えないように Service の容量を構成している。

次の図では、グローバル ロード バランシングがトラフィック オーバーフローでどのように機能するかを示します。

トラフィックのオーバーフローによるグローバル ロード バランシング

図の中で:

  • Multi-cluster Gateway は、store Service に対してグローバル インターネット ロード バランシングを行います。Service は、2 つの GKE クラスタ(us-west1 と europe-west1)にまたがってデプロイされます。各クラスタでは、2 つのレプリカが実行されています。
  • 各 Service は max-rate-per-endpoint="10" で構成されています。つまり、各 Service の合計容量は、2 レプリカ * 10 RPS = 20 RPS です。
  • Google の北米の PoP は 6 RPS です。すべてのトラフィックは、容量があり最も近く正常なバックエンドである us-west1 の GKE クラスタに送信されます。
  • ヨーロッパの PoP は、30 累積 RPS を受け取ります。最も近いバックエンドは europe-west1 にありますが、容量は 20 RPS しかありません。us-west1 のバックエンドには過剰な容量があることから、10 RPS が us-west1 にオーバーフローして、合計 16 RPS を受信し、各 Pod に 8 RPS が分散されます。

トラフィック オーバーフローの防止

トラフィックをオーバーフローさせると、パフォーマンスや可用性に影響する可能性のあるアプリケーションの容量超過を防ぐことができます。

ただし、トラフィックをオーバーフローさせる必要がない場合もあります。たとえば、レイテンシの影響を受けやすいアプリケーションの場合、遠いバックエンドへのトラフィックのオーバーフローからメリットは得られません。

トラフィックのオーバーフローは、次のいずれかの方法を使用することで防止できます。

  • 単一クラスタでのみ Service をホストできる単一クラスタ Gateway のみを使用します。

  • マルチクラスタ Gateway を使用する場合でも、複数のクラスタをまたいでデプロイされるアプリケーションのレプリカは、個別の Service としてデプロイできます。Gateway の観点からは、これによりマルチクラスタ ロード バランシングが有効になりますが、クラスタ間で Service のすべてのエンドポイントが集約されるわけではありません。

  • 絶対不可欠な場合を除き、実際に超過することがないように、Service の容量を十分高いレベルに設定します。

リージョン内のロード バランシング

リージョン内では、トラフィックがバックエンドの使用可能な容量に従ってゾーンに分散されます。これはオーバーフローを使用せず、各ゾーンの Service 容量に正比例されてロード バランシングを行います。個々のフローまたはセッションは常に単一のバックエンド Pod に送信され、分割されません。

次の図では、リージョン内でトラフィックがどのように分散されるかを示します。

リージョン内で分散されたトラフィック

図の中で:

  • Service が GKE のリージョン クラスタにデプロイされます。この Service には 4 つの Pod があり、これらの Pod がゾーン間で均等にデプロイされていません。Pod はゾーン A には 3 個、ゾーン B には 1 個、ゾーン C には 0 個です。
  • Service は maxRatePerEndpoint=10 で構成されています。ゾーン A の合計容量は 30 RPS、ゾーン B の合計容量は 10 RPS、ゾーン C には Pod がないため、合計容量は 0 RPS です。
  • Gateway は、さまざまなクライアントから合計 16 RPS のトラフィックを受信します。このトラフィックは、各ゾーンの残りの容量に比例して、ゾーン間で分散されます。
  • 個々のソースまたはクライアントからのトラフィック フローは、セッション永続性設定に従い単一のバックエンド Pod に常にロードバランスされます。トラフィック分割は異なるソースのトラフィック フローに分散されるため、個々のフローが分割されることはありません。そのため、バックエンド間でトラフィックを細かく分散するには、ソースまたはクライアントの多様性を最小限に抑える必要があります。

たとえば、受信トラフィックが 16 RPS から 60 RPS に急増すると、次のいずれかの状況が発生します。

  • 単一クラスタ ゲートウェイを使用している場合、このトラフィックがオーバーフローする先のクラスタやリージョンはありません。トラフィックは、受信トラフィックが合計容量を超えても、相対的なゾーン容量に従って引き続き分散されます。その結果、ゾーン A は 45 RPS、ゾーン B は 15 RPS を受信します。
  • 複数のクラスタに分散された Service でマルチクラスタ ゲートウェイを使用する場合、グローバル ロード バランシングとトラフィック オーバーフローで説明されているように、トラフィックは他のクラスタと他のリージョンにオーバーフローします。ゾーン A は 30 RPS を受信、ゾーン B は 10 RPS を受信し、20 RPS のオーバーフローで別のクラスタに送られます。

ゾーン内のロード バランシング

トラフィックは、あるゾーンに送信されると、そのゾーン内のすべてのバックエンドに均等に分散されます。HTTP セッションは、セッション アフィニティの設定に応じて持続します。バックエンドが利用不能にならない限り、既存の TCP 接続は別のバックエンドに移動しません。つまり、限られた容量が原因で新しい接続がオーバーフローしても、その前から続いている接続は、同一のバックエンド Pod に対して継続します。ロードバランサでは、新しい接続よりも既存の接続の維持が優先されます。

標準のロード バランシングはバックエンド間でトラフィックを均等に分散しますが、RING_HASH アルゴリズムはリクエストを特定の Pod に一貫してマッピングします。RING_HASH は、Pod の追加または削除時のリクエストの再シャッフルを最小限に抑えるため、キャッシュミスに敏感なステートフル ワークロードに適した安定したオプションです。必要に応じて minimumHashRingSize を構成してハッシュリングのサイズを調整できます。リングサイズを大きくすると、特に大規模なクラスタで、リクエストをバックエンドに均等に分散できます。

Service の容量

Service の容量では、Service 内の Pod ごとに 1 秒あたりのリクエスト数(RPS)を定義できます。この値は、Service が受信できる Pod あたりの平均最大 RPS を表します。この値は Service で構成可能で、トラフィックベースの自動スケーリングと容量ベースのロード バランシングを決定するために使用されます。

要件

Service の容量には、次の要件と制限があります。

  • トラフィック管理のサポートで定義されている GatewayClass リソースと Ingress タイプでのみサポートされます。
  • トラフィック ベースの自動スケーリングまたはマルチクラスタ ゲートウェイを使用している場合にのみ、ロード バランシングに影響します。こうした機能を使用していない場合、Service の容量はネットワーク トラフィックに影響しません。

Service の容量を構成する

単一クラスタ Gateway

GKE クラスタがバージョン 1.31.1-gke.2008000 以降を実行していることを確認します。以前のバージョンでは、「マルチクラスタ Gateway」タブで説明されているように、networking.gke.io/max-rate-per-endpoint アノテーションを使用できます。

単一クラスタ Gateway を使用して Service の容量を構成するには、Service と関連付けられた GCPBackendPolicy を作成します。次のマニフェストを使用して Service を作成します。

apiVersion: v1
kind: Service
metadata:
  name: store
spec:
  ports:
  - port: 8080
    targetPort: 8080
    name: http
  selector:
    app: store
  type: ClusterIP

maxRatePerEndpoint フィールドに最大 RPS を指定して、GCPBackendPolicy オブジェクトを構成します。次のマニフェストを使用して、GCPBackendPolicy オブジェクトを構成します。

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

複数クラスタ Gateway

マルチクラスタ Gateway を使用して Service の容量を構成するには、networking.gke.io/max-rate-per-endpoint アノテーションを使用して Service を作成します。次のマニフェストを使用して、最大 RPS を持つ Service を作成します。

apiVersion: v1
kind: Service
metadata:
  name: store
  annotations:
    networking.gke.io/max-rate-per-endpoint: "RATE_PER_SECOND"
spec:
  ports:
  - port: 8080
    targetPort: 8080
    name: http
  selector:
    app: store
  type: ClusterIP

RATE_PER_SECOND は、この Service 内の 1 つの Pod が受信する 1 秒あたりの最大 HTTP / HTTPS リクエストに置き換えます。

maxRatePerEndpoint 値は、Service の Pod 数に基づいて Service の動的な容量を作り出します。Service の容量の合計値は、次の式に示すように、maxRatePerEndpoint 値にレプリカ数を掛けて計算されます。

Total Service capacity = maxRatePerEndpoint * number of replicas

オートスケーラーが Service 内の Pod 数をスケールアップすると、それに応じて Service の合計容量が算出されます。Service が 0 個の Pod にスケールダウンされると、容量はゼロになり、ロードバランサからトラフィックを受信しなくなります。

Service の容量とスタンドアロン NEG

スタンドアロン NEG を使用すると Service の容量を構成することもできますが、maxRatePerEndpoint 設定は使用されません。スタンドアロン NEG を使用する場合、maxRatePerEndpoint は、NEG をバックエンド サービス リソースに追加するときに手動で構成します。gcloud compute backend-services add-backend コマンドを使用すると、--max-rate-per-endpoint フラグで NEG の容量を個別に構成できます。

これは、次のどのワークフローにも有用です。

スタンドアロン NEG を使用して Service の容量を構成しても、機能の違いはありません。トラフィックの自動スケーリングとトラフィックのスピルオーバーの両方がサポートされています。

Service の容量を確認する

maxRatePerEndpoint の値を決定するには、アプリケーションのパフォーマンス特性とロード バランシングの目標を理解する必要があります。アプリケーションのパフォーマンス特性を定義するには、次の手法が効果的です。

  • Service の容量を設定することなく構成した場合は、テスト環境と本番環境の両方でアプリケーションを確認します。
  • Cloud Monitoring を使用して、トラフィック リクエストとパフォーマンスのサービスレベル目標(SLO)との間の対応関係を作成します。

  • ロードバランサ指標(RPS レベルをマッピングする https や request_count など)を使用します。

  • アプリケーションのパフォーマンスに関する SLO を定義します。パフォーマンスを「悪い」または「不安定」と見なすかどうかに応じて、これらは次のいずれかになります。次のすべては、Cloud Monitoring ロードバランサの指標から収集できます。

    • レスポンス エラーコード
    • レスポンスのレイテンシまたは合計レイテンシ
    • バックエンドの非健全性の度合いまたはダウンタイム
  • テスト環境と本番環境の両方で、トラフィック負荷がかかった状態のアプリケーションを確認します。テスト環境では、リクエスト負荷が増加する中でアプリケーションに負荷をかけ、トラフィックの増加に伴って各種パフォーマンス指標がどのように影響を受けるかを確認します。本番環境では、現実的なトラフィック パターンのレベルを確認します。

Service のデフォルト容量

明示的に構成されていない場合でも、GKE リソースに接続されているすべての Service には、デフォルトの Service 容量が構成されています。詳細については、Service のデフォルト容量をご覧ください。

次の表に、デフォルトの容量を示します。

ロード バランシングのリソースタイプ デフォルトの maxRatePerEndpoint
Ingress(内部、外部) 1 RPS
Gateway(すべての GatewayClass) 100,000,000 RPS
MultiClusterIngress 100,000,000 RPS

トラフィック ベースの自動スケーリング

トラフィック ベースの自動スケーリングは、ロードバランサからのトラフィック シグナルをネイティブに統合して Pod を自動スケーリングする GKE の機能です。トラフィック ベースの自動スケーリングは、単一クラスタ Gateway でのみサポートされます。

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

トラフィック ベースの自動スケーリングには次の利点があります。

  • CPU やメモリを厳密にバインドしていないアプリケーションには、CPU やメモリの使用量に反映されていない容量制限が存在する場合があります。
  • トラフィック、すなわち 1 秒あたりのリクエスト数(RPS)は、場合によってはもっと簡単な指標で、ページビューや 1 日のアクティブ ユーザー(DAU)などのアプリの使用状況やビジネス指標に適合します。
  • トラフィックは、瞬間需要を表す先行指標です。対して、CPU やメモリは遅行指標になります。
  • CPU、メモリ、トラフィックの自動スケーリングの指標を組み合わせることで、複数のディメンションを使用して、容量が適切にプロビジョニングされるように、アプリケーションの自動スケーリングの全体的な方法が提供されます。

次の図では、トラフィック ベースの自動スケーリングの仕組みを示します。

トラフィック ベースの自動スケーリング

図の中で:

  • Service のオーナーは、Deployment の Service の容量とターゲットの使用率を構成します。
  • Gateway は、クライアントから store Service に送信されるトラフィックを受信します。Gateway は、使用率テレメトリーを GKE Pod オートスケーラーに送信します。使用率は、個々の Pod が受信した実際のトラフィックを Pod の構成済み容量で割った値になります。
  • GKE Pod オートスケーラーは、構成されたターゲット使用率に従って Pod をスケールアップまたはスケールダウンします。

自動スケーリングの動作

次の図では、ロードバランサを介して 10 RPS を受信するアプリケーションで、トラフィック ベースの自動スケーリングがどのように機能するかを示します。

トラフィック ベースの自動スケーリング(10 RPS)

この図で、Service のオーナーは、ストア Service の容量を 10 RPS に構成しています。つまり、各 Pod は最大 10 RPS を受信できます。HorizontalPodAutoscaler は、averageValue が 70 に設定され構成されています。つまり、ターゲット使用率が Pod あたり 10 RPS の 70% であることを意味します。

オートスケーラーは、次の式が満たされるようにレプリカをスケールしようとします。

replicas = ceiling[ current traffic / ( averageValue * maxRatePerEndpoint) ]

図では、この計算式は次のように求められます。

ceiling[ 10 rps / (0.7 * 10 rps) ] = ceiling[ 1.4 ] = 2 replicas

10 RPS のトラフィックでは、2 つのレプリカになります。各レプリカは 5 RPS を受信しますが、これは目標使用率の 7 RPS を下回ります。

トラフィック分割

トラフィック分割では、Service に送信される HTTP リクエストの割合を定義する明示的な比率(重み付けと呼ばれます)を使用します。HTTPRoute リソースでは、Service のリストに対する重み付けを構成できます。Service 間の相対的な重み付けでは、Service 間のトラフィック分割が定義されます。これは、ロールアウト中、変更のカナリア処理中、または緊急時にトラフィックを分割する際に便利です。

次の図では、トラフィック分割の構成例を示します。

トラフィック分割の構成

図の中で:

  • Service のオーナーは、トラフィックの 90% を store-v1、10% を store-v2 に分割するルールを使用して、1 つのルートに対して 2 つの Service を構成します。
  • Gateway は、クライアントからストア アプリケーションの URL に送信されるトラフィックを受信し、構成済みのルールに従ってトラフィックが分割されます。トラフィックの 90% が store-v1 にルーティングされ、10% が store-v2 にルーティングされます。

トラフィック分割は、同じクラスタ内の Service 間でも、異なるクラスタ内の Service 間でもサポートされます。サポートされているトラフィック分割には次の 2 種類があります。

  • Service 間のトラフィック分割: このアプローチは、アプリケーション バージョンのロールアウトのトラフィックを分割するために使用されます。このトラフィック分割の使用例では、store-v1 と store-v2 の 2 つの Deployment があり、それぞれに独自の Service(store-v1 と store-v2)があります。store-v2 が完全にロールアウトされるまでトラフィックを徐々にシフトするように、2 つの Service 間で重み付けが構成されます。

  • ServiceImport 間でのトラフィック分割: このアプローチは、メンテナンス、移行、緊急時に特定のクラスタ間でトラフィックをシフトするために使用されます。ServiceImport は、マルチクラスタ Service を表し、異なるクラスタで異なる Service 間のトラフィック分割を可能にします。ゲートウェイによる Blue/Green マルチクラスタ ルーティングの演習では、クラスタをまたいでトラフィックを分割する方法を説明します。

重み付けと容量

重み付けと容量の両方で、さまざまな Service に送信されるトラフィックの量を制御します。効果は似ていますが、動作は異なり、ユースケースも異なります。2 つは一緒に使用しますが、目的は異なります。

重み

重み付けは、トラフィックの明示的な制御です。 受信トラフィックやバックエンドの使用状況から独立した、トラフィックの正確な割合を定義します。トラフィック分割の例では、store-v2 が上限に達したか、すべてのレプリカで障害が発生した場合でも、トラフィックの 10% が store-v2 に割り当てられ、トラフィックがドロップされる可能性があります。これは、重み付けによって使用率や正常性によってトラフィックの割合が変化しないためです。

重み付けは、次のユースケースに最も適しています。

  • ロールアウトのために異なるバージョンの Service 間でトラフィックをシフトする。
  • 明示的なトラフィック分割を使用して Service を手動でオンボーディングする。
  • 緊急時やメンテナンスの目的で、バックエンドのセットからトラフィックをシフトする。

容量

容量は、暗黙的にトラフィックを制御します。受信トラフィックの量、バックエンド使用率、トラフィックの送信元のロケーションに応じて、トラフィックの割合を間接的に定義します。容量は Service 固有のプロパティであり、通常、頻繁には更新されません。

容量は、次のユースケースに最も適しています。

  • トラフィックの急増時のバックエンドの過剰使用を防止する。
  • トラフィックに関連する自動スケーリングのレートを制御する。

トラフィックをオーバーフローするように Service の容量を構成することで、必要な動作が常に得られるとは限りません。グローバル ロード バランシングの例を検討します。Service の容量では、トラフィックをオーバーフローしてバックエンドの使用率が高くなりすぎないようにしていますが、オーバーフローしたリクエストはリモート リージョンに転送されるため、レイテンシが増加する可能性があります。

アプリケーションが過剰な利用からそれほど影響を受けない場合は、トラフィックが別のリージョンにオーバーフローすることがないように、Service の容量を非常に大きく構成することをおすすめします。アプリケーションの可用性やレイテンシが過剰な使用の影響を受けやすい場合は、過剰に使用されるバックエンドで超過トラフィックを吸収するより、他のクラスタやリージョンにトラフィックをオーバーフローさせるほうが良い場合があります。アプリケーションの Service の容量を構成する方法の詳細は、Service の容量を決定するをご覧ください。

セッション アフィニティ

セッション アフィニティ(スティッキー セッションとも呼ばれます)により、特定のクライアントからのリクエストが常に同じバックエンド Pod にルーティングされます。これは、ローカル キャッシュ保存のメリットを活かせるステートフル アプリケーションのパフォーマンス最適化です。たとえば、特定の Pod でユーザー セッション データを維持することが不可欠な e コマースのショッピング カートやゲーム セッションなどがあります。

GKE Gateway は、GCPTrafficDistributionPolicy リソースを使用して、Google Cloud アプリケーション ロードバランサ インスタンスで使用可能なすべてのセッション アフィニティ タイプ(STRONG_COOKIE_AFFINITY(ステートフル セッション永続性)、HTTP_COOKIE、GENERATED_COOKIE、HEADER_FIELD、CLIENT_IP)をサポートしています。

セッション アフィニティを構成するには、デフォルトの方法である GCPTrafficDistributionPolicy を使用することをおすすめします。ただし、既存の構成で CLIENT_IP と GENERATED_COOKIE のセッション アフィニティ タイプに GCPBackendPolicy を使用できます。両方のポリシーが同じ Service をターゲットとしている場合、GCPTrafficDistributionPolicy が優先されます。GCPTrafficDistributionPolicy を使用して、RING_HASH などの安定したロード バランシング アルゴリズムを構成することもできます。

次のステップ