GKE でホスト メンテナンスを行う方法を理解する

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

このドキュメントでは、GKE でのノード停止の意味、Compute Engine メンテナンス通知のモニタリング方法、GKE ノードで停止の影響を最小限に抑える方法について説明します。

このドキュメントは、次のマシンタイプに適用されます。

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

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

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

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

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

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

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

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

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

ライブ マイグレーションをサポートしていないノードで中断管理が必要となる理由

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

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

メンテナンス イベントを管理する

このドキュメントの残りの部分では、MaintenanceEvent の中断を管理する方法について説明します。

ホスト メンテナンス イベント中のノードの停止の管理は、3 段階のワークフローで行われます。

  1. スケジュールされたホスト メンテナンスを検出する: GKE ノードラベル、メタデータ エンドポイント、ログを使用します。
  2. 検出されたメンテナンスに対応する: メンテナンスがスケジュールされている場合は、インフラストラクチャとワークロードを評価し、ユースケースに最適なアクションを決定します。システムにメンテナンス イベントを自動的に処理させる、ホスト メンテナンスを手動で開始する、メンテナンス戦略をオーケストレートするなど、適切なアクションを実行します。
  3. メンテナンス イベントの結果を確認する: Compute Engine がスケジュールどおりにメンテナンス イベントを開始したとき、または手動で開始したときに、メンテナンス イベントが正しく開始されたことを確認します。

スケジュールされたホスト メンテナンスを検出する

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

今後のメンテナンス イベントをモニタリングして検出するには、GKE と Compute Engine の両方からの通知を表示する必要があります。

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

  • GKE で今後のメンテナンスを表示する: GKE バージョン 1.31.1-gke.2008000 以降では、今後のメンテナンス イベントをモニタリングできます。次のマシンタイプと GKE バージョンで、今後のイベントをモニタリングできます。

    • GPU または TPU がアタッチされているマシンタイプの場合、1.31.1-gke.2008000 以降
    • 18 TiB を超える SSD を備えた Z3 マシンタイプの場合、1.32.4-gke.1376000 以降
    • H4D マシンタイプの場合、1.32.6-gke.1060000 以降
    • c4a-highmem-96-metal の場合、1.35.0-gke.2232000 以降

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

    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 エンドポイントにアクセスできます。

検出されたメンテナンスに対応する

クラスタ内の 1 つ以上のノードで今後のスケジュールされたメンテナンスの通知が表示された場合は、次のディシジョン ツリーを使用して、中断に対処する最適な方法を決定します。

  1. 自動メンテナンス: Compute Engine にメンテナンス イベントをスケジュールどおりに開始させます。VM はバックグラウンドで自動的にライブ マイグレーションされるため、中断は最小限に抑えられます。

    1. ホスト VM がライブ マイグレーションをサポートしている場合は、メンテナンス イベントを自動的に実行することをおすすめします。
    2. ワークロードがアイドル フレキシブル ノードで実行されている場合は、オポチュニスティック メンテナンスを構成することで、メンテナンスのタイミングを自動的に最適化できます。これにより、必要な更新は自然なアイドル期間中にのみトリガーされます。
  2. ホスト メンテナンス イベントを手動で開始する: 次の質問を評価して、停止を手動で処理する最適な方法を判断します。

    1. 影響を受けるノードは単一の VM ですか、分離された VM ですか?

      • はい(単一または分離された VM を実行している場合):
        • 正確なタイミング制御が必要ない場合は、Compute Engine にメンテナンス イベントをスケジュールどおりに開始させます(デフォルトの自動)。
        • 予期しないプリエンプションを回避する必要がある場合は、トラフィックが少ない時間帯など、都合のよい時間に個々のノードでホスト メンテナンス イベントを手動で開始します。
      • いいえ(アクセラレータのノードプールを実行している場合): 次のステップのいずれかのオプションを選択します。
    2. ユースケースに基づいて、次のいずれかのオプションを選択します。

      • アクセラレータ プールで結合された AI/ML トレーニング タスクが実行されている場合: 並列戦略を実装します。トレーニング状態をチェックポイントに保存し、プールを正常にシャットダウンして、再起動する前にホストの更新と GKE クラスタのアップグレードを同時に実行します。

      • アクセラレータ プールで高可用性の AI/ML サービング エンドポイントまたは推論エンドポイントを実行している場合: ローリング戦略を実装します。アクティブなレプリカを使用して SLA を保護しながら、ゾーンまたはプールの境界内でローリング バッチでスケジュールされたホストのメンテナンスとバージョン アップグレードを調整します。

単一の VM または分離された VM でホスト メンテナンス イベントを手動で開始する

アクティビティが少ない時間帯など、スケジュールに合わせて再スケジュール可能なメンテナンスを手動で開始できます。これを行うには、次の条件を満たす場合に cloud.google.com/perform-maintenance=true ラベルを適用します。

  • Compute Engine は、スケジュールされたメンテナンス イベントに関する通知を発行します。
  • 基盤となる Compute Engine メンテナンス イベントは再スケジュール可能です。イベントが再スケジュール可能かどうかを確認するには、イベント メタデータcan_reschedule=TRUE 通知を探します。イベントが再スケジュール可能でない場合、cloud.google.com/perform-maintenance=true ラベルを設定しても効果はなく、メンテナンスは元のスケジュールどおりに実行されます。

上記の条件が満たされたら、ノードプール内のノードで、ノードラベル 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 がスケジュールどおりにメンテナンス イベントを開始する

メンテナンス イベントが開始されると、ノードは終了直前に短い通知時間で 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 ノードの中断回数を報告します(この指標は 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}]))

中断を最小限に抑えるための高度な構成

このセクションでは、中断を最小限に抑えるようにクラスタとワークロードを構成するための追加のツールについて説明します。

停止処理を有効にする

apiVersion: v1
kind: ConfigMap
metadata:
  name: gke-disruption-handling
  namespace: kube-system
data:
  maintenance-experience.yaml: |
    gracefulTermination: true

停止処理を有効にするには、この ConfigMap を含む maintenance-config.yaml というファイルを作成します。次のコマンドを使用して、ConfigMap をクラスタに適用します。

kubectl apply -f my-configmap.yaml

ワークロードを正常に終了するように 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 設定の値まで、使用可能なノードの数が一時的に減少することがあります。

次のステップ