Horizontal Pod Autoscaler
Horizontal Pod AutoscalerはReplication Controller、Deployment、またはReplica SetのPod数を計測されたCPU使用率に基づいて自動でスケールします (他のアプリケーションが提供するカスタムメトリックもサポートしています)。 DaemonSetなどのスケールできないオブジェクトに対して効果がないことに注意してください。
Horizontal Pod AutoscalerはKubernetesのAPIリソースとコントローラとして実装されています。 リソースはコントローラの振る舞いを決定します。 コントローラは計測される平均CPU使用率がユーザに指定された値にマッチするようにReplication ControllerやDeploymentのレプリカ数を定期的に調整します。
How does the Horizontal Pod Autoscaler work?
Horizontal Pod Autoscalerはコントローラマネージャの --horizontal-pod-autoscaler-sync-period フラグで指定される間隔によるコントロールループとして実装されています (デフォルト値は30秒)。
各ループではコントローラマネージャはHorizontalPodAutoscalerの定義にあるメトリクスの使用率をクエリします。 コントローラマネージャはリソースメトリクスAPI (各Podのリソースメトリクス) か、カスタムメトリクスAPI (すべての他のメトリクス)。
- 各Podのリソースメトリクス (CPUのような) は、HorizontalPodAutoscalerのターゲットPodそれぞれについてリソースメトリクスAPIからメトリクスを取得します。 そして、もし目標使用率が設定されていれば、コントローラは各Podのコンテナのリソースリクエストと同等の使用率を計算します。 もし目標値が設定されていれば、その値を直接使います。 コントローラはすべての対象Podの使用率または値 (指定されたターゲットの種類による) の平均をとり、期待するレプリカ数にスケールするために使われる比率を計算します。
もし、Podのいくつかのコンテナのリソースリクエストが設定されていなかった場合、PodのCPU使用量は定義されず、オートスケーラはそのメトリックに対してなにもしません。 後述するalgorithm detailsにオートスケーリングアルゴリズムがどのように動作するかがあるので見てください。
- 各Podのカスタムメトリクスは各Podのリソースメトリクスと同じように機能します。ただし、使用率は使えません。
- オブジェクトメトリクスと外部メトリクスは問題のオブジェクトを記述する単一のメトリックが取得されます。
メトリックは目標値と比較され、上述の比率が提供されます。
autoscaling/v2beta2APIバージョンでは比較される前に値をPod数で分割することもできます。
通常HorizontalPodAutoscalerは一連の集約されたAPIからメトリクスを取得します (metrics.k8s.io、custom.metrics.k8s.io、external.metrics.k8s.io)。
metrics.k8s.io APIは通常metrics-serverで提供され、別に起動される必要が有ります。
metrics-serverのドキュメントを見てください。
HorizontalPodAutoscalerはHeapsterから直接メトリクスを取得することもできます。
Heapsterからのメトリクス取得はKubernetes 1.11で非推奨になりました
詳しくはSupport for metrics APIsを見てください。
オートスケーラはScaleサブリソースを使って関連するスケーラブルコントローラ (Replication Controllers、Deployments、Replica Setsのような) にアクセスします。 Scaleはレプリカ数を動的に設定し、それらの状態を評価することを許可するためのインターフェイスです。 Scaleサブリソースについての詳細はこちらで確認できます。
Algorithm Details
最も基本的な観点から、Horizontal Pod Autoscalerコントローラは期待するメトリック値と現在のメトリック値の比率に基づき操作します。
(期待レプリカ数) = cail[(現在のレプリカ数) * ( (現在のメトリック値) / (期待メトリック値) )]
例えば、現在のメトリック値が200mで、期待するメトリック値が100mとすると、200.0 / 100.0 == 2.0となるためレプリカ数は2倍されます。
逆に、現在が50mの場合は50.0 / 100.0 == 0.5となるためレプリカ数は半減されます。
もし比率が1.0に近い場合はスケーリングはスキップされます(--horizontal-pod-autoscaler-toleranceフラグでグローバルに設定される許容誤差です。デフォルトは0.1)。
targetAverageValueかtargetAverageUtilizationが指定されている時、currentMetricValueはHorizontalPodAutoscalerの対象と鳴っているすべてのPodの平均として計算されます。
どのような場合でも、許容誤差のチェックと最終的な値の決定の前に、Podのreadinessとメトリクスの紛失を考慮します。
削除タイムスタンプ付きのPod (すなわち、シャットダウンが始まったPod) とすべての失敗したPodは破棄されます。
もし特定のPodのメトリクスがない場合、あとで使うように避けられます。 メトリクスが欠落しているPodは最終的なスケーリング量を調整するために使われます。
CPUスケーリングのとき、もしいずれかのPodが準備中またはほとんどの最近のメトリックポイントが準備中のものだった場合、同じくどのPodは避けられます。
技術的制約のため、HorizontalPodAutoscalerコントローラは特定のCPUメトリクスを避けるかどうか決める時、Podが最初に準備完了になる時間を正確に測定できません。
そのかわりにもしPodがunreadyの場合は"not yet ready"とみなし、それが開始するまでの短く設定可能な時間幅でunreadyに移行します。
この値は--horizontal-pod-autoscaler-initial-readiness-delayフラグで設定できます。
デフォルト値は30秒です。
一度Podがreadyになれば、もしそれが長くて設定可能な時間までに開始したらreadyへのどんな移行も初回とみなします。
この値は--horizontal-pod-autoscaler-cpu-initialization-periodフラグで設定できます。
currentMetricValue / desiredMetricValueの基本スケール比は避けられていないまたは上記から破棄されていないPodが計算に使われます。
もしメトリクスの欠損があれば、スケールダウンのときは期待値の100%、スケールアップのときは0%を消費すると仮定してより控えめに平均を再計算します。 これは潜在的なスケールの大きさを減少させます。
さらに、もしnot-yet-readyなPodがあり、欠損したメトリクスやnot-yet-ready Podを考慮せずスケールアップがあるとき、スケールアップの影響を小さくするためnon-yet-ready Podは0%を消費しているとみなします。
not-yet-ready Podと欠損メトリクスを考慮したあとで、使用比を再計算します。 もし新しい比でスケールの方向を反転させたり許容誤差内だった場合、スケーリングをスキップします。 さもなければ新しい比率をスケールに使用します。
もし複数のメトリクスがHorizontalPodAutoscalerで指定されていたら、それぞれのメトリックについて計算して、最大のレプリカ数を選択します。 もしいずれかのメトリクスが期待レプリカ数に変換できない場合(例えばメトリクスAPIからの取得エラー)、スケーリングはスキップされます。
最後に、HorizontalPodAutoscalerがターゲットをスケールする直前に、推奨スケールは保存されます。
コントローラは設定可能なウィンドウ内のすべての推奨を考慮しその中から最高の推奨を選びます。
この値は--horizontal-pod-autoscaler-downscale-stabilization-windowフラグで設定でき、デフォルトは5分です。
これは、スケールダウンは徐々に行われ、メトリック値の急激な変化の影響を取り除きます。
API Object
Horizontal Pod AutoscalerはKubernetesのautoscaling APIグループのAPIリソースです。
現在の安定バージョンのautoscaling/v1ではCPUによるオートスケーリングのみサポートしています。
ベータバージョンのautoscaling/v2beta2ではメモリとカスタムメトリクスによるスケーリングをサポートしています。
autoscaling/v1で動作するとき、autoscaling/v2beta2で導入された新しいフィールドはアノテーションとして保存されます。
APIオブジェクトの詳細はHorizontalPodAutoscaler Objectを参照してください。
Support for Horizontal Pod Autoscaler in kubectl
Horizontal Pod Autoscalerは他のAPIリソースのようにkubectlでサポートされています。
kubectl createコマンドで新しいautoscalerを作成できます。
kubectl get hpaで一覧表示でき、kubectl describe hpaで詳細を表示できます。
最後に、kubectl delete hpaで削除できます。
また、簡単にHorizontal Pod Autoscalerを作成するための特別なkubectl autoscaleコマンドがあります。
例えば、kubectl autoscale rs foo --min=2 --max=5 --cpu-percent=80はレプリカセットfooに対するautoscalerを作成し、ターゲットCPU使用率を80%としてレプリカ数を2から5で調整します。
kubectl autoscaleの詳細なドキュメントはここにあります。
Autoscaling during rolling update
現在のKubernetesでは、Replication Controllerを直接管理したりDeploymentオブジェクトを使ってローリングアップデートができます。 Horizontal Pod Autoscalerは後者のみをサポートしています。 Horizontal Pod AutoscalerはDeploymentオブジェクトにバインドされ、Deploymentオブジェクトのサイズを設定し、DeploymentがReplica Setのサイズ設定に責任を持ちます。
Horizontal Pod AutoscalerはReplication Controllerで直接ローリングアップデートを操作してるときは働きません。すなわち、Horizontal Pod AutoscalerをReplication Controllerにバインドすることはできません(例えばkubectl rolling-update)。
その理由は、ローリングアップデートが新しいReplication Controllerを作る時、Horizontal Pod Autoscalerが新しいReplication Controllerをバインドできないからです。
Support for cooldown/delay
Horizontal Pod Autoscalerを使ってレプリカグループのスケールを管理するとき、メトリクスの評価の動的な性質によりレプリカ数が頻繁に変動する可能性があります。 これはスラッシングとも言われます。
v1.6から、クラスタオペレータはkube-controller-managerのフラグとしてグローバルなHorizontal Pod Autoscalerの設定をチューニングすることでこの問題を緩和できます。
v1.12から新しいアルゴリズムの更新により遅延は必要なくなりました。
--horizontal-pod-autoscaler-downscale-delay: このオプションの値は、現在のダウンスケールが終わったあと、他のダウンスケールが実行前にどれだけ待たないといけないかを指定します。 デフォルト値は5分です。
Note: これらのパラメータをチューニングするとき、クラスタオペレータは発生しうる結果に注意してください。 もし遅延(クールダウン)値が非常に長く設定されていたら、Horizontal Pod Autoscalerがワークロードの変化に反応しないということになります。 短く設定された場合、よくスラッシングが発生してしまいます。
Support for multiple metrics
Kubernetes 1.6で複数のメトリクスによるスケーリングがサポートされました。
autoscaling/v2beta2 APIでHorizontal Pod Autoscaleに複数のメトリクスを指定できます。
そして、Horizontal Pod Autoscalerコントローラはそれぞれのメトリックを評価し、それに基づきスケールを提案します。
最も大きいスケールが適用されます。
Support for custom metrics
Kubernetes 1.2で特殊なアノテーションを用いたアプリケーションメトリクスによるスケーリングがアルファサポートされました。 Kubernetes 1.6で新しいAPIのためアノテーションは廃止されました。 従来のカスタムメトリクス収集方法は引き続き利用できますが、それらのメトリクスはHorizontal Pod Autoscalerでは使えません。 また、スケールのカスタムメトリクスを指定するアノテーションはもうHorizontal Pod Autoscalerコントローラでは使えません。
Support for metrics APIs
標準で、HorizontalPodAutoscalerコントローラは一連のAPIからメトリクスを取得します。 APIにアクセスするために、クラスタ管理者は次のことを確認してください。
- API aggregation layerが有効
- 対応するAPIが登録されている
- リソースメトリクスのための
metrics.k8s.ioAPI。 一般的にmetrics-serverによって提供 クラスタアドオンとして起動できます。 - カスタムメトリクスのための
custom.metrics.k8s.ioAPI。 メトリクスベンダーの"adapter" APIサーバで提供されます。 - 外部メトリクスのための
external.metrics.k8s.ioAPI。 これはおそらく上記のカスタムメトリクスアダプタによって提供されます。
- リソースメトリクスのための
--horizontal-pod-autoscaler-use-rest-clientsがtrueまたはセットされていない。 これがfalseだとHeapsterがオートスケーリングに使われますが非推奨です。
What's next
- 設計ドキュメント: Horizontal Pod Autoscaling
- kubectl autoscaleコマンド: kubectl autoscale
- 使用例