Kubernetesのオートスケーラーが統一された制御プレーンの欠如により競合する
HPA、VPA、KEDAなどの独立したKubernetesコントローラーは、しばしば同じリソースをめぐって競合し、不安定さを引き起こします。これらの競合を解決するには、統合され自律的なアプローチが必要です。
英語の原文から自動翻訳されました。
サイト信頼性エンジニア(SRE)が checkout-api のようなサービスの適切なサイズを尋ねると、自社のインフラから矛盾した回答が返ってくることがあります。Horizontal Pod Autoscaler (HPA) はCPU負荷を理由に11個のレプリカを要求する一方で、Vertical Pod Autoscaler (VPA) はポッドが過剰にプロビジョニングされていると主張します。同時に、KEDAはKafkaのバックログを解消するために24個のレプリカを要求し、Karpenterは膨らんだリソース要求に基づいて新しいノードを追加します。この混乱は、5つの異なるコントローラーが論理的には孤立して動作しているものの、システムの実際のニーズに対する完全なビューを誰も持っていないために発生します。
何が起きたか
現代のKubernetes運用は、Unixの哲学に基づく専門化されたツール群に依存しています。これは、単一のタスクをうまくこなす小さくモジュール化されたコンポーネントです。HPAは水平方向の弾力性を管理し、VPAは垂直方向のサイズ調整を担当し、KEDAはイベントソースをレプリカ数に変換し、Karpenterのようなノードオートスケーラーは物理的な容量を管理します。Argo CDなどのGitOpsツールは、バージョン管理からベースラインの状態を強制適用します。従来のUnixパイプラインでは、ツールがデータを順次処理し、ある段階の不変な出力を次の段階へ渡します。しかし、Kubernetesのオートスケーラーは並行して動作し、互いのアクションを見通せないまま .spec.replicas や .resources.requests といった同じAPIフィールドを変更します。
このアーキテクチャ上のギャップにより、ワークロードの容量決定は断片化したプロセスとなります。パフォーマンスとコストの最適解を求める単一のカップリングされた数学的方程式を解く代わりに、システムは問題をデカップリングされた複数のコントローラーに分割します。各コントローラーは自身の特定のドメインに対する排他的な制御を想定するため、効率ではなくスラッシング(頻繁な切り替えによる性能低下)が発生します。その結果、レイテンシ、コスト、容量のトレードオフを理解する単一のエンティティが存在しないクラスターとなり、運用上の不安定性が生じます。
仕組み
競合は、独立した制御ループが相互依存する変数を操作することで生じ、4つの一般的な障害モードを作り出します。第一に、HPAとVPAは「分母の崩壊」を通じて衝突します。HPAは実際の使用量宣言されたリソース要求で割ることで目標レプリカ数を計算します。VPAが浪費を減らすためにリソース要求を下げる際、分母が縮小します。そのため、わずかなトラフィック増加でも利用率パーセンテージがHPAの閾値を超え、積極的なスケールアウトがトリガーされます。より多くのポッドが負荷を共有するとポッドあたりの使用量が低下し、VPAはさらに要求を縮小しようとするため、微小なコンテナによるデススパイラル(悪循環)が生じます。
第二に、ネイティブのHPAとKEDAはマルチライター競合状態に入ります。イベントキューが急増すると、KEDAはバックログを解消するためにデプロイメントをスケールアップします。しかし、ワーカーポッドがI/O集約的でCPU使用率が低い場合、HPAは低利用率を検知してデプロイメントを再びスケールダウンします。APIサーバーは交互のリスケールイベントを記録しますが、実際の処理スループットは停滞します。第三に、GitOpsエンジンはドリフトのピンポン現象を引き起こします。スパイク中にHPAがデプロイメントをスケールすると、GitOpsツールはアプリケーションを非同期としてフラグ付けします。自動同期が有効になっている場合、システムはデプロイメントをベースラインにリセットし、ピーク需要時にアプリケーションの容量を枯渇させます。
最後に、ノードオートスケーラーはこれらの非効率を増幅します。Karpenterのようなツールは、実際の消費量ではなく、宣言されたコンテナ要求に基づいて厳密に物理インスタンスをプロビジョニングします。コンテナが1つのCPUコアを要求しても実際には150ミリコアしか使用しない場合、スケジューラーはコア全体を予約します。これにより、上流のサイズ設定エラーが巨大なクラウド請求書へと拡大し、激しいプロビジョニングにもかかわらず平均クラスターCPU利用率は8%前後にとどまります。
主要な詳細
- 5つの異なるコントローラー(HPA、VPA、KEDA、Karpenter、GitOps)は、同じワークロードに対してしばしば矛盾したサイズ推奨を提供します。
- VPAがリソース要求を削減するとHPAで使用される利用率パーセンテージが人工的に膨張するため、HPAとVPAは競合します。
- KEDAとHPAは同じ
/scaleサブリソースへの書き込みをめぐって競走し、CPU使用率がキュー深度と一致しない場合にレプリカ数が振動します。 - GitOpsツールはHPAによる動的スケーリング変更を元に戻す可能性があり、現在のトラフィック負荷に対応できないベースライン構成を復元します。
- ノードオートスケーラーは実際の使用量ではなく宣言された要求に基づいて容量をプロビジョニングするため、著しい過剰プロビジョニングと低いクラスター利用率を招きます。
- 現在のオートスケーラーは、アクションを調整するための中枢神経系を持たない自動化された反射として機能しています。
なぜ重要なのか
ソフトウェアエンジニアやプラットフォームチームにとって、これらの競合は信頼性の低いサービスと膨張したコストに直結します。競合するコントローラーによって引き起こされるスラッシングは、反応型スケーリングが閾値超過を待ってから行動を起こすため、需要急増時のレイテンシスパイクにつながります。この反応的な性質により、新しい計算リソースはパフォーマンスが既に劣化した後にのみ初期化されることになり、サービスレベルオブジェクト(SLO)違反を招きます。さらに、GitOpsが本番環境の実態を正確に反映できないことは宣言型インフラの原則を破綻させ、将来のロールアウトをリスク高く監査困難なものにします。
金銭的な影響も同様に深刻です。ノードオートスケーラーはHPA-VPA競合を防ぐためにしばしば膨張した宣言要求に依存するため、クラスターは大量の未使用容量を抱えて稼働します。エンジニアは機能開発に集中する代わりに、閾値の手動チューニングやGit差分の整合性に多大な時間を費やします。統一された制御プレーンの欠如は、すべてのスケーリング判断がグローバルなシステム状態を損なう可能性のある局所的な最適化であることを意味し、チームがコスト効率と高可用性を同時に達成することを妨げます。
できること
- 同じリソースを対象とする同時実行コントローラーについてクラスターを監査し、特に同じデプロイメントでのHPAとVPAの同時使用を確認してください。
- GitOpsの自動同期ポリシーが正当なスケーリングイベントを元に戻していないか評価し、レプリカ数の差異無視設定を慎重に行ってください。
- 宣言されたリソース要求と実際の使用量の比率を監視し、ノードオートスケーラーが過剰な容量をプロビジョニングしている箇所を特定してください。
- キューベースのワークロードにはイベント駆動型スケーリングのみを使用し、それらの特定のサービスではCPUベースのHPAを無効にして、スケーリングシグナルを集約してください。
- 歴史的な消費パターンを分析し、トラフィックスパイクの前に容量をウォームアップする予測型スケーリング戦略を実装してください。
- 複数のシグナルを取り込み、水平方向および垂直方向のサイズ設定に関する共同判断を行うことができる統一された制御プレーンを提供するソリューションを探してください。



