HPAの「ゼロスケール」が標準機能に

Kubernetes v1.37では、これまでアドオンや外部コンポーネント、あるいはAlpha機能ゲートの有効化が必要だったHPAによるゼロスケール機能が、Beta版としてデフォルトで有効化されました(出典)。これは、特にキューイングされたタスクを処理するサービスや、特定のイベントに応じてのみ動作するバッチジョブなどにおいて、リソースの無駄をなくし、運用コストを大幅に削減できる画期的な一歩だと感じます。

HPAがゼロレプリカまでワークロードをスケールダウンさせ、メトリックの変化に応じて再びスケールアップすることが可能になりました。

この機能の最大のメリットは、Podがアイドル状態のときにリソースを解放し、コストを最適化できる点です。専用CPUやGPUなど、高価なリソースを予約しているPodが多いほど、その節約効果は大きくなるでしょう。私が個人プロダクトで使っているGCPのCloud RunやAWSのLambdaでも同様のゼロスケール機能がありますが、Kubernetes環境でこれが標準で実現できるのは、オンプレミスや独自のクラウド環境でKubernetesを使っている開発者にとって朗報ではないでしょうか。

ゼロスケールに必要な新しいメトリックの考え方

HPAは通常、CPUやメモリ使用量に基づいてスケールを判断します。しかし、レプリカ数がゼロになった場合、計測対象のPodが存在しないため、これらのメトリックではスケールアップのトリガーを見つけることができません(出典)。

そこで重要になるのが、「オブジェクトメトリック」や「外部メトリック」です。これらはPodの稼働状況に依存しないメトリックであり、例えば「キューの長さ」などが該当します。キューの長さは、ワーカーPodが稼働していなくても独立して存在し続けるため、HPAはPodがゼロの状態でもキューの長さを監視し、新たなタスクが投入された際にPodを起動させることが可能です。

メトリックの種類 スケールダウン/アップのトリガー ゼロスケール対応
CPU/メモリ使用量 実行中のPodのリソース使用率 ❌(Podがゼロになると計測不可)
オブジェクトメトリック Kubernetesオブジェクトの状態(例: Ingressのトラフィック量) ✅
外部メトリック Kubernetes外部のシステムの状態(例: キューの長さ) ✅

外部メトリックの設定例:PrometheusとPrometheus Adapter

主記事では、Prometheusメトリックである queue_consumer_lag を使用した外部メトリックの設定例が紹介されています。Kubernetesで外部メトリックを利用するには、Prometheus Adapterのようなメトリックアダプターが必要です(出典)。Prometheus Adapterの externalRules に以下のような設定を追加することで、指定したメトリックをExternal Metrics API経由でHPAに公開できます。

externalRules:
  - seriesQuery: '{__name__="queue_consumer_lag",name!=""}'
    metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (name)
    resources:
      template: "/namespaces/{{.Namespace}}/queue_lags/{{.Label.name}}"

この設定により、queue_consumer_lag の値がHPAから参照可能となり、キューの長さに応じてワーカーPodがゼロからスケールアウトできるようになります。自分のサービスにこのような外部メトリックを組み込めば、かなり効率的なリソース運用ができそうです。

注意点:コールドスタート時間とHTTPワークロード

ゼロスケールの大きなトレードオフは、コールドスタート時間です。HPAがメトリックを検知し、Podをスケジューリングし、アプリケーションが起動するまでの間、サービスに遅延が生じる可能性があります(出典)。耐久性のあるキューで処理を待機させられるワークロード(例: 非同期処理)には非常に有効ですが、HTTPなどのリクエスト駆動型ワークロードでは、Podが準備状態になるまでリクエストをバッファリングする機能がKubernetes Serviceにはないため、別途バッファリングレイヤーが必要になります。

これは、SaaSのバックエンドAPIやWebアプリケーションでゼロスケールを適用する際には、API Gatewayやメッセージキューサービス(Kafkaなど)の導入を検討する必要があることを意味します。私の個人プロダクトでも、リアルタイム性が求められるサービスではこのコールドスタートが課題になりそうですが、バッチ処理や一時的なデータ処理には積極的に採用したい機能です。

補足として、Kubernetes v1.37では「Dynamic Resource Allocation (DRA)」もGAに昇格し、従来の拡張リソースAPI(例: example.com/gpu)経由のリクエストをDRAドライバで処理できるようになりました(出典)。これもGPUのような高価なリソースの管理を効率化する点で、今回のHPAのゼロスケールと相性が良いと感じます。