GPU と TPU の GKE ノードの中断を管理する

長時間実行される GKE クラスタのライフサイクル中には、Google Cloud で発生するインフラストラクチャの中断によってワークロードが定期的に中断されます。このような自動イベントは、スケジューリングの決定(プリエンプション イベント)、コントロール プレーンまたはノードの更新(GKE ノードの自動アップグレード(メンテナンス イベント)を含む)、検出された問題の修復(終了イベント)に対応するために発生する可能性があります。

このページでは、GKE でのノード停止の意味、メンテナンス通知のモニタリング方法、GPU と TPU がアタッチされた GKE ノードで停止の影響を最小限に抑える方法について説明します。

このドキュメントは、基盤となる技術インフラストラクチャのライフサイクルを管理するプラットフォームの管理者とオペレーターを対象としています。 Google Cloud のコンテンツで使用されている一般的なロールとタスクの例の詳細については、一般的な GKE ユーザーのロールとタスクをご覧ください。

GKE でインフラストラクチャの中断が意味すること

GKE クラスタは、GKE ノードのライフサイクルを管理します。GKE ノードがプロビジョニングされる Compute Engine VM では、次のような中断が定期的に発生します。

  • 検出された問題の修復TerminationEvent): Google Cloud が問題を検出してクラスタ インフラストラクチャを中断した場合に発生します。TerminationEvent イベントは正常なシャットダウンに対応していません。TerminationEvent イベントは次の問題によってトリガーされます。

    • 自動修復: ヘルスチェックが繰り返し失敗した後で GKE がノードを修復するときに発生します。
    • HostError: 物理マシンのハードウェアまたはソフトウェアのエラーが原因で VM が停止したときに発生します。
  • メンテナンスまたはアップグレード イベントMaintenanceEvent): Google Cloud がメンテナンスを実行するために VM を中断する必要がある場合に発生します。MaintenanceEvent イベントは、次のメンテナンス タスクによってトリガーされます。

    クラスタのライフサイクル中にユーザーと GKE が変更を管理する方法については、変更の種類をご覧ください。

  • スケジューリングの決定への応答PreemptionEvent):Google Cloud が優先度の高いリソースの容量を確保するために VM をプリエンプトする必要がある場合に発生します。PreemptionEvent イベントは次のいずれかです。

    • 削除: 優先度の高い VM を収容するためにプリエンプティブルまたは Spot インフラストラクチャがプリエンプトされたときに発生します。
    • デフラグ: GKE が TPU スライスを収容する目的でそれより小さい TPU スライスをプリエンプトしたときに発生します。デフラグは TPU スライスでのみ行われます。

長時間実行される GKE クラスタのライフサイクル中には、ノードでトレーニング ワークロードまたはサービング ワークロードの定期的な中断が発生する可能性があります。このような中断が AI / ML ワークロードを実行している GKE ノードに影響する場合、GKE は実行中のワークロードとその基盤となるノードの両方を再起動する必要があります。

GPU と TPU で中断管理が必要となる理由

一部の例外を除き、ほとんどの Compute Engine VM のホスト メンテナンス ポリシーライブ マイグレーションに設定されています。つまり、実行中のワークロードで停止が生じることはほとんどありません。ただし、特定のクラスの VM はライブ マイグレーションに対応していません。これには GPUTPU がアタッチされた VM も含まれます。すべてのメンテナンス イベントはスライスレベルで調整されるため、TPU スライス内の VM でホストイベントが発生すると、スライス全体が中断されてから再スケジュールされます。そのため、数百台の VM を含む TPU スライスを作成すると、そのすべての VM が同じメンテナンス イベント スケジュールを受け取ります。

ホストイベントが発生すると、GKE はノードとその Pod を終了させます。Pod が JobDeployment などのより大きなワークロードの一部としてデプロイされている場合、GKE は、影響を受けるノードの Pod を再起動します。

メンテナンス イベントに適切に対応するようにワークロード構成を処理する責任は、ユーザー自身(あるいは使用するフレームワーク)にあります。たとえば、AI トレーニング ジョブの状態を保存することでデータの損失を減らせます。

AI / ML ワークロードでの停止を管理するため、次のことを行えます。

ノードの中断をモニタリングする

次の GKE システム指標は、最後のサンプリング以降の GKE ノードの中断回数を報告します(この指標は 60 秒ごとにサンプリングされます)。

  • kubernetes.io/node/interruption_count

interruption_typeTerminationEventMaintenanceEventPreemptionEvent など)フィールドと interruption_reasonHostErrorEvictionAutoRepair など)フィールドは、ノードが中断された理由を把握するのに役立ちます。

プロジェクトのクラスタ内の TPU ノードで発生した中断とその原因の内訳を取得するには、次の PromQL クエリを使用します。

  sum by (interruption_type,interruption_reason)(
    sum_over_time(
      kubernetes_io:node_interruption_count{monitored_resource="k8s_node"}[${__interval}]))

ホスト メンテナンス イベントのみを表示するには、interruption_reasonHW/SW Maintenance 値をフィルタするようにクエリを更新します。次の PromQL クエリを使用します。

  sum by (interruption_type,interruption_reason)(
    sum_over_time(
      kubernetes_io:node_interruption_count{monitored_resource="k8s_node", interruption_reason="HW/SW Maintenance"}[${__interval}]))

ノードプールごとに集計された中断回数を表示するには、次の PromQL クエリを使用します。

  sum by (node_pool_name,interruption_type,interruption_reason)(
    sum_over_time(
      kubernetes_io:node_pool_interruption_count{monitored_resource="k8s_node_pool", interruption_reason="HW/SW Maintenance", node_pool_name=NODE_POOL_NAME }[${__interval}]))

メンテナンス通知をモニタリングする

Compute Engine では、中断を伴うホストイベントがノードとその基盤となる VM でスケジュールされたときと有効になったときに、通知が出されます。通知には、予定されている開始時刻やイベントの種類などの情報が含まれます。

GKE バージョン 1.31.1-gke.2008000 以降では、このセクションで説明するイベントを含む今後のメンテナンス イベントをモニタリングできます。

今後のメンテナンスがスケジュールされているが、有効になっていない

GPU または TPU がアタッチされている VM でメンテナンス イベントがスケジュールされると、Compute Engine からすべての VM に通知が送信され、メンテナンスの時間枠の開始時刻が報告されます。今後のメンテナンスが VM によってスケジュールされたが有効になっていない場合、GKE はノードラベルに scheduled-maintenance-time を追加します。

これらの通知をノードレベルでクエリするには、次のコマンドを実行します。

kubectl get nodes -l cloud.google.com/scheduled-maintenance-time \
    -L cloud.google.com/scheduled-maintenance-time

出力は次のようになります。

NAME                         STATUS    SCHEDULED-MAINTENANCE-TIME
<gke-accelerator-node-name>  Ready     1733083200
<gke-accelerator-node-name>  Ready     1733083200
[...]

SCHEDULED-MAINTENANCE-TIME 列は秒を表し、Unix エポック時間の形式で表示されます。

これらの通知をノード メタデータのレベルでクエリするには、インスタンスでメンテナンス イベント通知を確認します。

高度なメンテナンスに対応するアクセラレータ最適化マシン ファミリーでは、スケジュールされたメンテナンス イベントと開始されたメンテナンス イベントに関する情報を提供する upcoming-maintenance エンドポイントにアクセスできます。

停止の影響を最小限に抑える

Compute Engine は、今後のメンテナンス イベントに関する通知を発行し、メンテナンスの時間枠をスケジュールします。通知時刻からメンテナンスの時間枠の開始時刻までの間に、次のいずれかを選択できます。

  • ホスト メンテナンス イベントを手動で開始する。
  • Compute Engine にメンテナンス イベントをスケジュール通りに開始させる。

ホスト メンテナンス イベントを手動で開始する

スケジュールされたメンテナンス イベントに関する通知が Compute Engine から出されたとき、ユーザーは運用スケジュールに適したタイミング(アクティビティが減少する期間など)に手動でメンテナンスを開始できます。

ノードプール内のノードで、ノードラベル cloud.google.com/perform-maintenancetrue に設定してください。例:

kubectl label nodes <node-name> cloud.google.com/perform-maintenance=true

ユーザーがメンテナンス イベントを開始すると、GKE は次のオペレーションを実行します。

  1. ノードに taint を設定する。
  2. Pod を正常に強制排除する。
  3. スケジュールされた時刻を待つのではなく、メンテナンス イベントを直ちに開始するように Compute Engine にリクエストする。

Compute Engine がスケジュールどおりにメンテナンス イベントを開始する

ホスト メンテナンス イベントを開始しない場合、Compute Engine はスケジュールされたメンテナンス イベントを自動的に開始します。GKE バージョン 1.33 以降では、メンテナンスの時間枠が開始してもノードには taint が設定されず、Pod は強制排除されません。

メンテナンス イベントが開始されると、ノードは終了直前に短い通知時間で 1 回または複数回シャットダウンする可能性があります。このような場合、GKE はワークロードを終了し、Pod を正常に強制排除するために最善を尽くします。

スケジュールされたメンテナンスの開始

スケジュールされたメンテナンスが開始すると、Compute Engine で http://metadata.google.internal/computeMetadata/v1/instance/attributes/ ディレクトリ内のメタデータが更新され、メタデータ ラベルが次のように更新されます。

  • maintenance-eventTERMINATE_ON_HOST_MAINTENANCE に設定されます。
  • upcoming-maintenance で、maintenance_statusONGOING に設定されます。

スケジュールされたホスト メンテナンス イベントの GKE による処理は、手動でトリガーするか、GKE に自動的に処理させるかによって変わります。

ワークロードを正常に終了するように GKE を構成する

このセクションでは、アプリケーションのライフサイクルを管理し、ワークロードの中断を最小限に抑えるように GKE を構成します。猶予期間を構成しない場合、猶予期間はデフォルトで 30 秒になります。

GKE はベストエフォートでこれらの Pod を正常に終了し、ユーザーが定義した終了アクション(トレーニング状態の保存など)を実行します。また、猶予期間の開始時に Pod に SIGTERM シグナルを送信します。猶予期間の終了までに Pod が終了しなかった場合、GKE は Pod 内のコンテナでまだ実行中のプロセスにフォローアップの SIGKILL シグナルを送信します。

正常終了期間を構成するには、Pod マニフェストの spec.terminationGracePeriodSeconds フィールドで終了猶予期間(秒単位)を設定します。たとえば、通知時間を 10 分にするには、次のように Pod マニフェストの spec.terminationGracePeriodSeconds フィールドを 600 秒に設定します。

    spec:
      terminationGracePeriodSeconds: 600

進行中のタスクが通知期間内に完了できるように、終了猶予期間には十分な時間を設定することをおすすめします。ワークロードで Orbax を使用して MaxText、Pax、JAX などの ML フレームワークを利用している場合、ワークロードはシャットダウンの SIGTERM シグナルをキャプチャして、チェックポイント プロセスを開始できます。詳細については、TPU の Autocheckpoint をご覧ください。

正常終了のプロセス

手動で開始するメンテナンス イベントが開始されると、Compute Engine は maintenance-event メタデータキーを更新することで、間もなくマシンがシャットダウンされることを通知します。GKE は正常終了を開始します。

次のワークフローは、ノードのシャットダウンが迫ったときに、GKE がノードの正常終了を実行する方法を示しています。

  1. 60 秒以内に、次の処理が行われます。
    1. ワークロードがこれから停止されることを示すため、システム コンポーネントが cloud.google.com/active-node-maintenance ノードラベル(ONGOING に設定済み)を適用します。
    2. 新しい Pod がノードでスケジュールされないよう、GKE がノード taint を適用します。この taint には cloud.google.com/impending-node-termination:NoSchedule キーがあります。突然の終了ではないため、この taint を許容するようにワークロードを変更することはおすすめしません。
  2. maintenance-handler コンポーネントが Pod の強制排除を開始します。ワークロード Pod が強制排除されてから、システム Pod(kube-system など)が強制排除されます。
  3. シャットダウンが迫っていることを通知するため、ノードで実行されているワークロード Pod に GKE が SIGTERM シャットダウン シグナルを送信します。このアラートにより、Pod は進行中のタスクを完了できます。GKE は、ベスト エフォートでこれらの Pod を正常に停止します。
  4. 強制排除が完了すると、GKE は cloud.google.com/active-node-maintenance ラベルの値を terminating に更新し、ノードの終了の準備ができたことを示します。

その後、ノードが終了されて交換ノードが割り当てられます。プロセスが完了すると、GKE はこのラベルと taint をクリアします。GPU または TPU を使用するワークロードの終了時間枠を長くするには、ホスト メンテナンス イベントを手動で開始するの説明に従って操作してください。

アクティブな正常終了の進行状況をモニタリングする

次の正常終了イベントによって GKE ログをフィルタできます。

  • ノードの終了(Compute Engine のホスト メンテナンス イベントなど)が迫ったことによる中断を VM が検出すると、GKE はワークロードの停止時に cloud.google.com/active-node-maintenanceONGOING に設定し、ワークロードが完了してノードが終了の準備が整ったときに terminating に設定します。
  • 新しいワークロードのスケジューリングを制限する際、GKE は cloud.google.com/impending-node-termination:NoSchedule taint を適用します。

機会活用型メンテナンスで実行中のワークロードの中断を最小限に抑える

GPU または TPU を使用するノードがアイドル状態であることを GKE が検出したときにメンテナンスを自動的にトリガーすることで、実行中のワークロードの中断を最小限に抑えることが可能です。この機能を有効にするには、新しいノードプールを作成します。既存のノードプールで機会活用型メンテナンスを有効にすることはできません。

機会活用型メンテナンスを使用して新しいノードプールを作成する

次のコマンドは、機会活用型メンテナンスを有効にしてノードプールを作成する方法を示しています。

gcloud beta container node-pools create NODE_POOL_NAME \
    --cluster CLUSTER_NAME \
    --accelerator ACCELERATOR_ARG \
    --machine-type MACHINE_TYPE \
    --num-nodes NODE_COUNT \
    --zone ZONE \
    --project=PROJECT_ID \
    --opportunistic-maintenance=node-idle-time=NODE_IDLE_TIME,min-nodes=MIN_NODES,window=WINDOW

次の値を置き換えます。

  • NODE_POOL_NAME: GKE ノードプールの名前。
  • CLUSTER_NAME: GKE クラスタの名前。
  • NODE_IDLE_TIME : メンテナンスがトリガーされる前にノードがアイドル状態(アクセラレータを使用するワークロードが実行されていない状態)を維持できる時間。値は秒単位の期間を表し、小数点以下 9 桁まで指定できます。最後に「s」を付けます(例: 80000s)。
  • MIN_NODES : ノードプールで使用可能にする必要があるノードの最小数。このオプションでは、実行中のノード数がこの値(10 など)を下回る場合にメンテナンスがブロックされます。
  • WINDOW : 機会活用型メンテナンスを実行できる時間枠(秒単位)。値の末尾は「s」です。たとえば、値が 14 日(1209600s)の場合、機会活用型メンテナンスは、予定されているメンテナンス日の 2 週間前からのみ実行できます。値が 28 日(2419200s)の場合、定期メンテナンスの時間枠内であれば、いつでも機会活用型メンテナンスを実行できます。Compute Engine ホストのメンテナンスの時間枠は、GKE クラスタのメンテナンスの実行タイミングを決定し、個別に構成される GKE メンテナンスの時間枠とは異なります。

機会活用型メンテナンスの構成例

次に例を示します。4 つのノードを含むノードプールがあり、機会活用型メンテナンス構成が --opportunistic-maintenance=node-idle-time=600s,window=2419200s,min-nodes=3 に設定されているとします。このシナリオでは、次の処理が行われます。

  • node1 で GPU ワークロードが実行されている。このノードはアイドル状態ではないため、スキップされます。
  • node2 が 60 秒間アイドル状態です。このノードは十分な時間アイドル状態になっていないため、スキップされます。
  • node3 が 600 秒間アイドル状態です。このノードはアイドル状態の要件を満たしています。
  • node4 が 600 秒間アイドル状態です。このノードはアイドル状態の要件を満たしています。

node3node4 の両方がアイドル状態の要件を満たしています。ただし、min-nodes オプションの値が 3 に設定されているため、これらのノードの 1 つだけが機会活用型メンテナンスをトリガーします。

機会活用型メンテナンスでノードの構成と状態を確認する

次のコマンドを実行して、ノードに機会活用型メンテナンスが構成されているかどうかを確認します。

kubectl describe node NODE_NAME | grep node.gke.io/opportunistic-config

NODE_NAME は、確認するノードの名前に置き換えます。

機会活用型メンテナンスが構成されているノードが現在メンテナンス中かどうかを確認します。

kubectl describe node NODE_NAME | grep node.gke.io/maintenance-state

ノードが機会活用型メンテナンスによってトリガーされた場合、maintenance-state アノテーションは opportunistic-triggeredtrue として表示します。

制限事項

機会活用型メンテナンスには、次の制限事項があります。

  • この機能は、GPU ノードプールと TPU ノードプールでのみ使用できます。
  • クラスタ オートスケーラーはすでにアイドル状態のノードをスケールダウンしているため、機会活用型メンテナンスはクラスタの自動スケーリングと互換性がありません。
  • マルチホスト TPU ノードプールの場合、これらのノードプールはアトミックであるため、min-nodes-per-pool 設定の値は 0 にする必要があります。
  • サポートされている最小の GKE バージョンは 1.33.3-gke.1118000 です。
  • can_reschedule=TRUE 通知を含む計画メンテナンスのみがサポートされます。
  • この機能を無効にするには、対応するフラグを指定せずにノードプールを再作成する必要があります。または、cloud.google.com/opportunistic-disable=true を使用して、特定のノードでこの機能を手動で無効にすることもできます。
  • まれに、ノードでメンテナンスが完了するまでに時間がかかることがあります。この機能を使用しているお客様は、min-nodes-per-pool 設定の値まで、使用可能なノードの数が一時的に減少することがあります。

次のステップ