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のゼロスケールと相性が良いと感じます。