クラスタの自動スケーリングについて


このページでは、Google Kubernetes Engine(GKE)がワークロードの需要に基づいて Standard クラスタのノードプールのサイズを自動的に変更する方法について説明します。需要が高い場合、クラスタのオートスケーラーはノードプールにノードを追加します。クラスタ オートスケーラーの構成方法については、クラスタの自動スケーリングをご覧ください。

Autopilot クラスタを使用すると、ノードプールがノード自動プロビジョニングによって自動的にプロビジョニングされ、またワークロードの要件に合わせて自動的にスケーリングされるため、ノードのプロビジョニングやノードプールの管理について心配する必要はありません。

クラスタ オートスケーラーを使用する理由

GKE クラスタ オートスケーラーは、ワークロードの需要に基づいて、特定のノードプール内のノード数を自動的に変更します。需要が少ない場合、クラスタのオートスケーラーは指定した最小サイズにスケールダウンします。これにより、ワークロードの可用性が向上し、コストも抑えられます。ノードを手動で追加または削除する必要はありません。また、ノードプールを過剰にプロビジョニングする必要もありません。ノードプールの最小サイズと最大サイズを指定するだけで、あとは自動的に設定されます。

クラスタの自動スケーリング時にリソースを削除または移動すると、ワークロードが一時的に中断することがあります。たとえば、ワークロードが 1 つのレプリカを持つコントローラで構成されている場合、現在のノードを削除すると、レプリカのポッドは別のノードに再スケジュールされる可能性があります。クラスタ オートスケーラーを有効にする前に、一時的な中断が許容されるようにワークロードを設計するか、重要なポッドで割り込みが発生しないように設計してください。

クラスタ オートスケーラーのパフォーマンスを向上させるには、イメージ ストリーミングを使用します。これにより、対象となるコンテナ イメージから必要なイメージデータがリモートでストリーミングされると同時に、イメージがローカルのキャッシュに保存され、新しいノードのワークロードが迅速に開始できるようにします。

クラスタ オートスケーラーの仕組み

クラスタ オートスケーラーはノードプール単位で機能します。クラスタ オートスケーラーを使用してノードプールを構成する場合は、ノードプールの最小サイズと最大サイズを指定します。

クラスタ オートスケーラーは、ノードプールの基盤となる Compute Engine マネージド インスタンス グループ(MIG)で仮想マシン(VM)インスタンスを追加または削除して、ノードプールのサイズを自動的に調整します。クラスタ オートスケーラーは、実際のリソース使用率ではなくノードプールのノードで実行されている Pod のリソース リクエスト数に基づいてスケーリングを決定します。Pod とノードのステータスを定期的にチェックし、次の処理を行います。

  • ノードプール内のノード数が不足しているためにポッドのスケジューリングができない場合、クラスタ オートスケーラーはノードプールの最大サイズまでノードを追加します。
  • ノードの使用率が低く、ノードプール内のノード数を少なくしてもすべての Pod のスケジューリングが可能な場合、クラスタ オートスケーラーはノードプールの最小サイズになるまでノードを削除します。クラスタ内の他のノードに移動できないノードに Pod がある場合、クラスタ オートスケーラーはそのノードをスケールダウンしません。Pod を他のノードに移動できるが、タイムアウト期間(現在は 10 分)の経過後にノードを正常にドレインできない場合、ノードは強制終了されます。GKE クラスタの猶予期間は構成できません。スケールダウンの仕組みについて詳しくは、クラスタ オートスケーラーのドキュメントをご覧ください。

Pod がリクエストするリソースが少なすぎる場合(あるいは、実際の要件に対して過小なデフォルト値をそのまま使用している場合)、ノードでリソース不足が発生しても、クラスタ オートスケーラーで状況を改善することができません。クラスタ オートスケーラーが正常に動作するように、すべてのワークロードに明示的なリソース リクエストを行う必要があります。

動作条件

クラスタ オートスケーラーは、次のことを前提としてノードプールのサイズを変更します。

  • 複製対象のすべてのポッドを、他のノードで再起動できるものとします。これにより、短い中断が発生する可能性があります。サービスの中断が許可されない場合、クラスタ オートスケーラーの使用はおすすめしません。
  • ユーザーまたは管理者がノードを手動で管理しないものとします。手動で行ったノード管理オペレーションは無効になる可能性があります。
  • 1 つのノードプール内のすべてのノードは同じラベルセットを持つものとします。
  • クラスタ オートスケーラーは、各プール内のインスタンス タイプの相対的なコストを考慮し、最もコストのかからないノードプールを拡張しようとします。コストを削減するために、ノードプールに Spot VM を使用することも考慮されます。
  • クラスタ オートスケーラーは、Pod をスケジューリングする前に init コンテナのリクエストを考慮します。init コンテナのリクエストでは、ノードで利用可能な未割り当てリソースが使用可能であるため、Pod をスケジューリングできない可能性があります。クラスタ オートスケーラーは、Kubernetes で使用されるものと同じリクエスト計算ルールに従います。詳細については、init コンテナの使用をご覧ください。
  • 最初のクラスタまたはノードプールの作成後に手動で追加されたラベルは追跡されません。クラスタ オートスケーラーによって作成されたノードには、ノードプールの作成時に --node-labels で指定されたラベルが割り当てられます。
  • GKE バージョン 1.21 以前では、クラスタ オートスケーラーはノードプールの既存のノードの taint 情報をノードプール全体を表すものと見なします。GKE バージョン 1.22 以降、クラスタ オートスケーラーは、クラスタ内の既存のノードとノードプールからの情報を結合します。クラスタ オートスケーラーは、ノードとノードプールのスケールアップの手動変更を検出します。

ゾーン間での均衡化

ノードプールに同じインスタンス タイプを持つ複数のマネージド インスタンス グループが含まれている場合、クラスタ オートスケーラーは、スケールアップ時にこうしたマネージド インスタンス グループのサイズの均衡化を図ります。これにより、ノードプールの複数のゾーン内にあるマネージド インスタンス グループ間でノードの分配が不均一になる事態を回避できます。GKE はスケールダウン時に自動スケーリング ポリシーを考慮しません。

ロケーション ポリシー

GKE バージョン 1.24.1-gke.800 以降では、GKE クラスタ オートスケーラーのロケーション ポリシーを変更できます。クラスタ オートスケーラーの配布ポリシーは、location_policy フラグに次のいずれかの値を指定することにより制御できます。

  • BALANCED: オートスケーラーは、Pod の要件と各ゾーンのリソースの可用性を考慮します。オートスケーラーは、特定のゾーン内で使用可能な容量や、スケールアップをトリガーした Pod のゾーン アフィニティなど、多くの要因を考慮するため、同様のノードグループのサイズがまったく同じになるとは限りません。
  • ANY: オートスケーラーは、未使用の予約とアカウントの利用を優先させ、使用可能なリソースの現在の制約を考慮します。このポリシーは、Spot VM を使用している場合や、ゾーン間で均等でない VM 予約を使用する場合におすすめします。

予約

GKE バージョン 1.27 以降では、クラスタ オートスケーラーは、スケールアップの決定時に常に予約を考慮します。未使用の予約と一致するノードプールは、ノードプールが最も効率的なものでない場合でも、スケールアップするノードプールを選択する際に優先されます。また、マルチゾーンのスケールアップの均衡化を図る際には、未使用の予約が常に優先されます。

デフォルト値

Spot VM ノードプールの場合、デフォルトのクラスタ オートスケーラー配布ポリシーは ANY です。このポリシーでは、Spot VM がプリエンプトされるリスクが低くなります。

プリエンプティブル以外のノードプールの場合、デフォルトのクラスタ オートスケーラー配布ポリシーは BALANCED です。

ノードプールの最小サイズと最大サイズ

新しいノードプールを作成するときに、クラスタ内の各ノードプールの最小サイズと最大サイズを指定できます。クラスタ オートスケーラーは、これらのスケーリングの制約内で再スケーリングを決定します。最小サイズを更新するには、新しい最小値を指定してから、クラスタを新しい制約内のサイズに手動でサイズ変更します。クラスタ オートスケーラーは、新しい制約に基づいて再スケーリングを決定します。

現在のノードプール サイズ クラスタ オートスケーラーのアクション スケーリングの制約
指定した最小値を下回っている クラスタ オートスケーラーは、保留中の Pod をプロビジョニングするためにスケールアップします。スケールダウンが無効になります。 ノードプールは、指定した値以下にスケールダウンされません。
指定した最小サイズと最大サイズの範囲内 クラスタ オートスケーラーは、需要に応じてスケールアップまたはスケールダウンします。 ノードプールは、指定したサイズの制限内に収まります。
指定した最大値を超えている クラスタ オートスケーラーは、安全に削除できるノードのみをスケールダウンします。スケールアップが無効になります。 ノードプールは、指定した値を超えてスケーリングすることはありません。

Standard クラスタでは、クラスタ オートスケーラーがクラスタをゼロノードまで自動的にスケールダウンすることはありません。システム Pod を実行するには、クラスタ内で 1 つ以上のノードが常に使用可能である必要があります。また、ノードを手動で削除したために現在のノード数がゼロになっている場合は、クラスタ オートスケーラーとノードの自動プロビジョニングにより、ゼロノード クラスタからスケールアップされます。

オートスケーラーの決定の詳細については、クラスタ オートスケーラーの制限をご覧ください。

自動スケーリングの制限

クラスタ オートスケーラーがノードプールをスケーリングするときに使用するノードの最小数と最大数を設定できます。--min-nodes フラグと --max-nodes フラグを使用して、ゾーンあたりのノードの最小数と最大数を設定します。

GKE バージョン 1.24 以降では、新しいクラスタに --total-min-nodes フラグと --total-max-nodes フラグを使用できます。これらのフラグは、すべてのゾーンのノードプール内にあるノードの最小数と最大数を設定します。

最小ノード数と最大ノード数の例

次のコマンドでは、6 ノードから構成される自動スケーリングのマルチゾーン クラスタを 3 つのゾーンに作成します。各ゾーンの最小ノード数は 1、最大ノード数は 4 になります。

gcloud container clusters create example-cluster \
    --num-nodes=2 \
    --zone=us-central1-a \
    --node-locations=us-central1-a,us-central1-b,us-central1-f \
    --enable-autoscaling --min-nodes=1 --max-nodes=4

この例では、クラスタの合計サイズは 3~12 ノードで、これらのノードは 3 つのゾーンに分散しています。いずれかのゾーンで障害が発生すると、クラスタの合計サイズは 2~8 ノードになります。

合計ノード数の例

GKE バージョン 1.24 以降で利用可能な次のコマンドは、最初に 3 つのゾーンに 6 つのノードを持つ自動スケーリング マルチゾーン クラスタを、すべてのゾーンで、ノードプール内の最小 3 つ、最大 12 個のノードで作成します。

gcloud container clusters create example-cluster \
    --num-nodes=2 \
    --zone=us-central1-a \
    --node-locations=us-central1-a,us-central1-b,us-central1-f \
    --enable-autoscaling --total-min-nodes=3 --total-max-nodes=12

この例では、ゾーン間の分散に関係なく、クラスタの合計サイズを 3~12 ノードにできます。

自動スケーリング プロファイル

ノードを削除するタイミングを決定することは、使用率の最適化とリソースの可用性とのトレードオフです。使用率の低いノードを削除するとクラスタの使用率は向上しますが、新しいワークロードの実行の際に、リソースが再度プロビジョニングされるのを待機しなければならない状況が生じる可能性があります。

このような決定を行うときに使用する自動スケーリング プロファイルを指定できます。利用可能なプロファイルは以下のとおりです。

  • balanced: Standard クラスタのデフォルト プロファイル。balanced プロファイルは、Autopilot クラスタでは使用できません。
  • optimize-utilization: クラスタ内で余剰リソースを保持するよりも使用率の最適化を優先させます。このプロファイルを有効にすると、クラスタ オートスケーラーはクラスタをより積極的にスケールダウンします。GKE は、ノードをより多く、より迅速に削除できます。GKE は、すでに CPU、メモリ、または GPU が大量に割り当てられているノードで Pod をスケジュールすることを優先します。ただし、同じ Deployment、StatefulSet、Service に属する Pod のノード間の分散など、他の要因はスケジューリングに影響します。

optimize-utilization 自動スケーリング プロファイルを使用すると、クラスタ オートスケーラーが使用率の低いノードを特定して削除しやすくなります。この最適化を実現するために、GKE により Pod 仕様のスケジューラ名が gke.io/optimize-utilization-scheduler に設定されます。カスタム スケジューラを指定する Pod は影響を受けません。

次のコマンドを使用すると、既存のクラスタで optimize-utilization 自動スケーリング プロファイルが有効になります。

gcloud container clusters update CLUSTER_NAME \
    --autoscaling-profile optimize-utilization

Pod のスケジューリングと停止の考慮

スケールダウンする場合、クラスタ オートスケーラーは、Pod に設定されているスケジューリング ルールとエビクション ルールを考慮します。この制限により、オートスケーラーによってノードが削除されるのを防ぐことができます。次のいずれかの条件を持つ Pod が含まれていると、ノードの削除を防ぐことができます。

  • Pod のアフィニティまたは反アフィニティ ルールにより、再スケジューリングが防止される。
  • Pod が、Deployment、StatefulSet、Job、ReplicaSet などのコントローラによって管理されていない。
  • Pod にローカル ストレージがあり、GKE コントロール プレーン バージョンが 1.22 未満である。コントロール プレーン バージョン 1.22 以降の GKE クラスタでは、ローカル ストレージを使用する Pod でスケールダウンがブロックされなくなりました。
  • Pod に "cluster-autoscaler.kubernetes.io/safe-to-evict": "false" アノテーションがある。
  • ノードの削除が、構成された PodDisruptionBudget を超える可能性があります。

クラスタ オートスケーラーの詳細と中断を防ぐ方法については、クラスタ オートスケーラーに関するよくある質問をご覧ください。

GKE での TPU の自動スケーリング

GKE は、ML ワークロードを高速化するために Tensor Processing Unit(TPU)をサポートしています。単一ホストの TPU スライス ノードプールとマルチホストの TPU スライス ノードプールはどちらも、自動スケーリングと自動プロビジョニングをサポートしています。

GKE クラスタで --enable-autoprovisioning フラグを指定すると、GKE は、TPU のバージョンとトポロジが保留中のワークロードの要件を満たしている単一ホストまたはマルチホストの TPU スライス ノードプールを作成または削除します。

--enable-autoscaling を使用すると、GKE はタイプに基づいてノードプールを次のようにスケーリングします。

  • 単一ホストの TPU スライス ノードプール: GKE は、既存のノードプールで TPU ノードを追加または削除します。ノードプールには、0 からノードプールの最大サイズまでの任意の数の TPU ノードが含まれます。最大サイズは、--max-nodes フラグと --total-max-nodes フラグによって決まります。ノードプールがスケーリングされると、ノードプール内のすべての TPU ノードのマシンタイプとトポロジは同じになります。単一ホストの TPU スライス ノードプールを作成する方法については、ノードプールを作成するをご覧ください。

  • マルチホスト TPU スライス ノードプール: GKE は、ノードプールを 0 から TPU トポロジを満たすために必要なノード数までアトミックにスケールアップします。たとえば、マシンタイプが ct5lp-hightpu-4t でトポロジが 16x16 の TPU ノードプールの場合、ノードプールには 64 個のノードが含まれます。GKE オートスケーラーは、このノードプールのノード数が 0 または 64 になるように調整します。スケールダウンすると、GKE はスケジュールされたすべての Pod を強制排除し、ノードプール全体が 0 になるようにドレインします。マルチホスト TPU スライス ノードプールの作成方法については、ノードプールを作成するをご覧ください。

追加情報

クラスタ オートスケーラーの詳細については、オープンソースの Kubernetes プロジェクトの自動スケーリングに関する FAQ をご覧ください。

制限事項

クラスタ オートスケーラーには次の制限があります。

既知の問題

  • GKE コントロール プレーンのバージョンが 1.22 より前の場合、GKE クラスタ オートスケーラーは空の(ゼロノード)クラスタですべてのノードプールのスケールアップを停止します。この動作は、GKE バージョン 1.22 以降では生じません。

次のステップ