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

このドキュメントでは、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 は十分に活用されなくなります。

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

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 設定は、トラフィックのルーティング方法に影響します。

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

ノード アフィニティが原因で分散が不均一になる

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

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