トラフィック分配が不均一な場合のトラブルシューティング

このドキュメントでは、Kubernetes Service へのトラフィックの分散が不均一になる問題を解決する方法について説明します。

トラフィックの不均等な分布の症状を特定する

トラフィックの不均等な分散(ホットスポットとも呼ばれます)は、Pod またはノードのサブセットが総ワークロードの不均衡な量を処理し、他の Pod またはノードが十分に活用されていない場合に発生します。

一般的な症状は次のとおりです。

  • パフォーマンスのボトルネック: ネットワーク接続が過剰に使用されている場合、断続的なタイムアウト、HTTP 5xx エラー、パケットロスが発生する可能性があります。
  • リソースの枯渇: 特定の Pod またはノードで、フリートの他の部分よりも CPU またはメモリの使用率が大幅に高くなっています。
  • トラフィックの不均衡パターン:
    • Pod ごとの不均衡: すべての Pod が正常で準備完了と報告されているにもかかわらず、トラフィックが利用可能な Pod の一部にのみヒットします。
    • ノードごとの不均衡: 1 つ以上のノードが他のノードよりも大幅に多くのパケットまたはリクエストを受信します。これは、Pod の配置が不均一な状態で externalTrafficPolicy: Local を使用している場合に発生することがよくあります。
    • スティッキー クライアント セッション: 単一の大容量クライアントからのすべてのリクエストが、常に同じバックエンド Pod にルーティングされます。

Cloud Monitoring を使用した診断

これらの症状を確認するには、次の指標を使用してトラフィック パターンを可視化します。

  • レイヤ 7(Ingress/Gateway)の場合: loadbalancing.googleapis.com/backend/request_count をプロットし、backend_target でグループ化して、異なるバックエンド間のリクエスト量を比較します。

トラフィックの分散が不均一になる一般的な原因を理解する

このセクションでは、Kubernetes Service へのトラフィック分散が不均一になる一般的な原因について説明します。この不均衡により、パフォーマンスのボトルネック、特定の Pod でのリソースの枯渇、アプリケーションの可用性の低下が発生する可能性があります。一部の Pod が他の Pod よりも大幅に多くのトラフィックを受信し、一部の Pod がほとんどまたはまったく受信しないためです。

セッション アフィニティにより分散が不均一になる

セッション アフィニティが有効になっているロードバランサが、同じクライアントからのリクエストを同じバックエンド Pod に一貫してルーティングすると、次の問題が発生します。特定のクライアントが大量のトラフィックを生成すると、その Pod が過負荷になり、他の Pod よりも大幅に負荷が高くなるホットスポットが発生し、他の Pod は使用率が低いままになります。

sessionAffinity フィールドを使用して、Kubernetes Service オブジェクトでセッション アフィニティを構成できます。

sessionAffinity が ClientIP に設定されている場合、Service は、同じクライアント IP アドレスから発信されたすべての接続が同じバックエンド Pod に一貫してルーティングされるようにします。これにより、実際のクライアント IP ベースのセッション アフィニティが提供されます。

sessionAffinity が None(デフォルトの動作)に設定されている場合、通常、レイヤ 4 ロードバランサは、4 タプル(クライアント IP アドレス、宛先 IP アドレス、宛先ポート、プロトコル)や 5 タプル(送信元ポートを含む)などのさまざまなネットワーク パラメータのハッシュを使用して接続を分散します。このハッシュは、同じタプル値を持つ接続を同じバックエンドに一貫してルーティングすることで、ある程度の接続の「スティッキネス」を提供できますが、他のタプル要素が変更された場合に、特定のクライアント IP アドレスからのすべての接続が常に同じ Pod に送信されることを保証するものではありません。

詳細については、セッション アフィニティをご覧ください。

GKE Gateway の場合、GCPTrafficDistributionPolicy CRD はセッション アフィニティを構成します。詳細については、ポリシーを使用してゲートウェイ リソースを構成するをご覧ください。

リージョン外部パススルー ネットワーク ロードバランサの場合は、セッション アフィニティを使用して、特定のバックエンドへの接続のスティッキー セッションを維持できます。ただし、一部のクライアントが他のクライアントよりも多くのトラフィックを生成すると、セッション アフィニティ自体が不均等な分散を引き起こす可能性があることに注意してください。

詳細については、セッション アフィニティとバックエンド サービスベースの外部パススルー ネットワーク ロードバランサの概要をご覧ください。

次の例は、sessionAffinity: ClientIP を含む Service マニフェストを示しています。

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: LoadBalancer
  sessionAffinity: ClientIP  # This can cause uneven distribution
  ports:
  -   port: 80
    targetPort: 8080
  selector:
    app: my-app

接続プーリングによる不均等な分散

接続プールは、他の Pod に使用可能な容量がある場合でも、ロードバランサが特定の Pod への既存の接続を再利用するときに発生します。一部の接続の存続時間が長い場合や、他の接続よりも大幅に多くのリクエストを処理する場合、この動作によって不均衡が生じる可能性があります。これにより、セッション アフィニティと同様に、トラフィックが特定の Pod に集中し、これらの Pod が過負荷状態になる一方で、他の Pod は使用率が低いままになるホットスポットが作成されます。

ロードバランサは、新しい接続を確立する際のオーバーヘッドを削減してパフォーマンスを向上させるために、接続プーリングを実装します。ただし、接続プーリングを適切に管理しないと、特に長期間の接続を維持するアプリケーションで、トラフィックの分布が不均一になる可能性があります。

接続プールによる不均等な分散を軽減するには、アプリケーション レベルまたはクライアント レベルで次の戦略を実装します。

  • 複数の接続を使用するようにクライアントを構成する: 単一の長時間接続に依存するのではなく、ロードバランサへの複数の接続のプールを開いて管理するようにクライアントを構成します。これにより、ロードバランサは利用可能なバックエンド Pod に新しい接続試行を分散し、全体的なトラフィック分散を改善できます。

  • 接続を定期的に閉じて再度開く: 長期間の接続を自然に維持するアプリケーションの場合は、接続を定期的に閉じて再度開くようにアプリケーションまたはクライアントを構成します。これにより、接続の再確立にわずかなオーバーヘッドが発生しますが、ロードバランサは、後続の接続試行を異なる使用率の低いバックエンド Pod に分散する新しい機会を得ることができます。このアプローチは、接続の終了と再確立がそれほど中断を伴わないサービスに特に効果的です。

  • アグレッシブなコネクション ドレインを実装する: Pod が正常なシャットダウンとコネクション ドレイン用に構成されていることを確認します。Pod が正常に終了すると(デプロイやスケールダウンなど)、ロードバランサは新しい接続の送信を停止し、既存の接続を完了またはドレインできるようにする必要があります。これにより、トラフィックを他の Pod によりスムーズに移行でき、トラフィックが終了中の Pod に集中するのを防ぐことができます。

接続動作を積極的に管理することで、長時間接続でもロードバランサがトラフィックをより均等に分散できるようになります。

5 タプル ハッシュにより分布が不均一になる

これは、セッション アフィニティを明示的に構成していない場合の多くのレイヤ 4 ロードバランサのデフォルトの動作です。同じクライアントから多くの接続が発信されたり、同じポートの組み合わせが使用されたりすると、分布が不均一になります。

ハッシュによる不均衡を解決するには、次の点を考慮してください。

  • レイヤ 7 ロード バランシングを使用する: GKE Ingress と Gateway はリクエスト レベルで動作するため、単一のクライアントからのリクエストを複数のバックエンド Pod に分散できます。

  • クライアントの動作を調整する: 複数の接続またはより大きな送信元ポートのプールを使用するようにクライアントを構成します。

ノード間で Pod の分散が不均等なため、分散が不均等になる

この問題は、Pod がノード間で均等に分散されておらず、ロードバランサがコンテナ ネイティブのロード バランシングを使用していない場合に発生します。Pod の数が多いノードはトラフィックが多くなるため、一部のノードが過負荷になり、他のノードが十分に活用されない可能性があります。

この問題は、externalTrafficPolicy: Local を使用する場合に特に重要です。

外部トラフィック ポリシーの設定が原因で分散が不均一になる

Service の externalTrafficPolicy 設定は、トラフィックのルーティング方法に影響します。

  • Cluster: ロードバランサがクラスタ内の任意のノードにトラフィックを分散できるようにします。使用可能なすべてのノードと Pod に最も均等に分散するには、Cluster 設定を使用します。
  • Local: トラフィックを受信した同じノードで実行されている Pod にのみトラフィックを転送します。Pod をノード間で均等に分散しないと、分散が不均一になる可能性があります。

ノード アフィニティが原因で不均等な分散が発生する

ノード アフィニティを使用して Pod をノードのサブセットに制限すると、特にワークロードがノード間で適切に分散されていない場合に、それらのノードが過負荷になる可能性があります。

Pod が特定のノードに固定されていないことを確認します。