トレーニングと推論のワークロードを実行しているノードのホスト メンテナンスを行う

このドキュメントでは、Google Kubernetes Engine(GKE)クラスタのノードの基盤となる Compute Engine インスタンスのホスト メンテナンスを行う方法について説明します。このメンテナンスを積極的に管理する必要があるのは、GPU や TPU を含むインスタンスなど、ライブ マイグレーションが行われない特定のタイプの Compute Engine インスタンスのみです。このドキュメントで説明する戦略は、トレーニング ワークロードと推論ワークロードに有効です。個々のノードに対してホスト メンテナンスを手動で実行する必要がある場合や、ワークロードが自動ホスト メンテナンスを許容できる場合は、GKE でホスト メンテナンスを行う方法についてをご覧ください。

これらの戦略では、ノードのグループに対してホスト メンテナンスが実行され、必要に応じて GKE クラスタのアップグレードが開始されます。

トレーニング ワークロードのノードなど、ダウンタイムを 1 回だけ許容できるワークロードのノードには、並列戦略を使用します。推論ワークロードのノードなど、大部分のリソースの可用性を維持しながらダウンタイムのバッチ処理が可能なワークロードのノードには、ローリング戦略を使用します。

並列戦略を使用してトレーニング ワークロードのノードを更新する

この戦略では、アクセラレータを使用するノードのグループに対して同時に変更を行います。この戦略は、トレーニング ワークロードに使用できます。または、変更を行う最も中断の少ない方法が、グループ内のすべてのノードとそれらのノードで実行されるワークロードの完全なダウンタイムの単一ウィンドウである他のタイプのワークロードに使用することもできます。

この戦略は、次の手順の概要に従います。

  1. ワークロードを停止する: ノードプールを選択し、そのノードプールで実行されているワークロードを停止するか、使用可能な他のノードにワークロードを移動します。
  2. ホストのメンテナンスをトリガーする: 選択したすべてのノードに同時にメンテナンス ラベルを適用し、すべてのノードでプロセスが完了するまで待ちます。
  3. GKE バージョンをアップグレードする: ノードの GKE バージョンを変更します。
  4. ワークロードを再起動する: すべてのホスト メンテナンスとアップグレードが完了したら、ワークロードを再起動します。

提供された手順では、単一のノードプールの変更を行います。ただし、複数のノードプールに対して同時に変更を行うように手順を調整できます。これらの手順を開始する前に、このワークロードをこれらのノードで実行する必要がない時間が数時間以上あることを確認してください。

基盤となる Compute Engine インスタンスと GKE ノードの両方で重要な変更を受け取る際の停止を最小限に抑えるため、このダウンタイム期間を使用して、ホストのメンテナンスと GKE バージョンのアップグレードの両方を行います。ただし、GKE ノードのバージョンをアップグレードしない場合は、ホスト メンテナンスのみを実行できます。

始める前の検討事項

始める前に、次の注意事項を確認してください。

  • ワークロードの再デプロイを回避する: PodDisruptionBudgets による不要な遅延を回避するため、すべての手順が完了するまでワークロードを再デプロイしないでください。
  • 停止を計画する: ワークロードが一定期間停止できることを確認します。これらの手順は、主にホスト メンテナンスに必要な時間のため、完了までに数時間かかります。

すべてのノードの更新を同時に実行する

ホストのメンテナンスと、必要に応じて GKE バージョンのアップグレードを行う手順は次のとおりです。

  1. ワークロードを準備する: ワークロードを停止するか、最近のスナップショットまたはチェックポイントが取得されていることを確認します。
  2. ホスト メンテナンスを開始: 選択したノードプール内のすべてのノードにメンテナンス ラベルを適用します。

    kubectl label nodes -l cloud.google.com/gke-nodepool=NODE_POOL_NAME cloud.google.com/perform-maintenance=true --overwrite
    

    Compute Engine は、基盤となるインスタンスのドレインと更新を同時に開始します。この処理には数時間かかることがあります。詳細については、正常終了のプロセスをご覧ください。

  3. ホスト メンテナンスのステータスをモニタリングする: メンテナンスが完了すると、GKE はメンテナンス ラベルを削除します。メンテナンスが完了すると、Cloud Logging に次のメッセージを含むログが表示されます。

    Maintenance window has completed for this instance. All maintenance
    notifications on the instance have been removed.
    
  4. 省略可: GKE ノードのバージョンをアップグレードする: 手順に沿ってノードの GKE バージョンをアップグレードします。

ローリング戦略を使用して推論ワークロードのノードを更新する

この戦略では、推論ワークロードを実行している GKE ノードでメンテナンスを手動で行う方法について説明します。サービス可用性を維持するために、ノードをバッチで更新します。この方法は、レプリカの一定割合が一時的にオフラインになることを許容できるワークロードに最適です。

この戦略は、次の手順の概要に従います。

  1. ノードを特定してバッチ処理する: 更新するノードプールを選択します。ワークロードの障害許容度に応じて、ノードをバッチにグループ化します。
  2. バッチを反復処理する: 各バッチで、メンテナンス ラベルを適用し、ラベルが削除されるまでノードのバッチをモニタリングします。
  3. GKE バージョンをアップグレードする: すべてのバッチでホストのメンテナンスが完了したら、GKE ノードのバージョンを変更します。

始める前の検討事項

始める前に、次の注意事項を確認してください。

  • デプロイを理解する: 成功には、ワークロードの分散、レプリカの配置、障害ドメインに関する詳細な知識が必要です。プロセス全体を通して十分なサービング容量を維持してください。
  • バッチサイズの計画: ノードをバッチで更新します。各バッチのサイズは、ワークロードのフォールト トレランスによって決まります。考慮すべき要素には、次のようなものがあります。
    • サービング モデルあたりのレプリカの数。
    • ノードと障害ドメイン間のレプリカの分散。
    • PodDisruptionBudgets は、同時にダウンする Pod の最大数を適用するのに役立ちます。
    • 推奨事項: 管理を簡素化するには、異なるノードプールを異なるレプリカのセットに割り当てることを検討してください。これにより、ノードプール レベルで障害ドメインを分離できます。
  • 時間制約を計算する: 次のタイミング要素を考慮します。
    • 各バッチでホスト メンテナンスの手順が完了するまでに数時間かかることがあります。
    • すべてのメンテナンスが期限内に完了するように、最小バッチサイズを計算します。
      1. MAINTENANCE_BLOCKS = floor(HOURS_TO_MAINTENANCE / 4)HOURS_TO_MAINTENANCE は利用可能な合計時間)。
      2. MIN_PER_BATCH = TOTAL_NODE_COUNT / MAINTENANCE_BLOCKS
    • 選択したバッチサイズは MIN_PER_BATCH 以上である必要があります。
  • 特定のワークロード タイプを確認する: 各構成タイプについて、次の点を考慮します。
    • Mixture of Experts(MOE): バッチ処理戦略で、各モデルに必要な最小レプリカ数を維持するようにします。
    • 分離型サービング: バッチを計画する際は、分離型設定に関与するすべてのレプリカを追跡してください。
    • マルチホスト ノードプール(TPU、MNNVL): これらの構成では、通常、ノードプール全体を一度に停止します。それに応じて、複数のノードプールに障害ドメインを計画します。

ローリング アップデートをバッチで実行する

ローリング アップデートを実行する手順は次のとおりです。

  1. メンテナンスを行うノードを特定する: メンテナンスを行うすべてのノードを特定し、このリストを保存します。ノードを特定するには、次のいずれかの方法を使用するか、手動で選択します。

    • アクセラレータ(TPU または GPU)を使用するクラスタ内のすべてのノードを取得します。

      kubectl get nodes -o json | jq -r '.items[] | select(.spec.taints[]? | select(.key=="nvidia.com/gpu" or .key=="google.com/tpu")) | .metadata.name'
      
    • 特定のノードプール内のすべてのノードを取得します。

      kubectl get nodes -l cloud.google.com/gke-nodepool=NODE_POOL_NAME --no-headers -o custom-columns=":metadata.name"
      

      NODE_POOL_NAME は、ノードプールの名前に置き換えます。

    • 特定のラベルを持つすべてのノードを取得します。

      kubectl get nodes -l LABEL -o jsonpath='{.items[*].metadata.name}'
      

      LABEL は、ノードラベルに置き換えます。

  2. ノードをバッチに分割: 識別されたノードを等しいバッチに分割します。前の始める前にセクションの時間制約を計算するリスト項目で説明されている数式を使用して、バッチサイズを決定します。

  3. ホストのメンテナンスを実行する: バッチごとに、次の手順を完了します。

    1. ノードのバッチを選択して、メンテナンス ラベルを適用します。

      kubectl label nodes LIST_OF_NODES_IN_BATCH cloud.google.com/perform-maintenance=true --overwrite
      

      LIST_OF_NODES_IN_BATCH は、バッチ内のノードのスペース区切りリストに置き換えます。例: node-1 node-2 node-3

    2. ホスト メンテナンスのステータスをモニタリングします。メンテナンスが完了すると、GKE はメンテナンス ラベルを削除します。メンテナンスが完了すると、ロギングに次のメッセージを含むログが記録されます。

      Maintenance window has completed for this instance. All maintenance
      notifications on the instance have been removed.
      
    3. すべてのバッチのホスト メンテナンスが完了するまで、残りのバッチごとに前の 2 つの手順を繰り返します。

  4. 省略可: GKE ノードのバージョンをアップグレードする: この手順は、すべてのノードのホスト メンテナンスが完了した後にのみ実行します。これにより、メンテナンスがまだ完了していないホストに GKE ノードがデプロイされるシナリオを回避できます。次のセクションの手順をご覧ください。

ノードの GKE バージョンをアップグレードする

同時にアップグレードするノードの数を検討します。並列戦略では、ノードプール全体または複数のノードプールで同時にホスト メンテナンスを実行しました。ローリング戦略では、ホストのメンテナンスをバッチで実行しました。ノードグループのサイズに基づいて、使用するアップグレード方法を決定します。

  • 並列戦略: ノードプールごとにゾーンあたり 100 個以下のノードがある場合は、サージ アップグレードを使用します。ノードプールにゾーンあたり 100 個を超えるノードがある場合は、ノードプールを削除して再作成します。
  • ローリング戦略: バッチに 100 個以下のノードがある場合は、ゾーンごと、ノードプールごと、またはノードごとにサージ アップグレードを使用します。バッチに 100 個を超えるノードがある場合は、ゾーンごと、ノードプールごとにノードを削除して再作成します。

サージ アップグレードを使用する

  1. サージ アップグレードを構成します。maxUnavailable 設定を使用して、ノードプール内のゾーンごとに同時に使用不可にできるノードの数を決定します。たとえば、ノードプール内の 1 つのゾーンに 18 個のノードがある場合は、maxUnavailable フィールドの値を 18 に設定します。

    この設定は、余剰容量のない予約の容量を使用する場合に最適です。この設定を使用する理由の詳細については、リソースが制限された環境でのアップグレードをご覧ください。

  2. 次のコマンドを実行して、ノードプールをアップグレードします。複数のノードプールをアップグレードする場合は、ノードプールごとに次のコマンドを実行します。

    gcloud container clusters upgrade CLUSTER_NAME \
        --node-pool NODE_POOL_NAME \
        --cluster-version VERSION \
        --location CONTROL_PLANE_LOCATION \
        --quiet
    

    次のように置き換えます。

    • CLUSTER_NAME: クラスタの名前。
    • NODE_POOL_NAME: ノードプールの名前。
    • VERSION: ノードプールの推奨される自動アップグレード ターゲット。詳細については、Standard クラスタのノードプールのアップグレード情報を取得するをご覧ください。クラスタに推奨される自動アップグレードのターゲットがない場合は、GKE リリースノートの最新のバージョン アップデート エントリを確認してください。
    • CONTROL_PLANE_LOCATION: クラスタのコントロール プレーンのロケーション。

ノードを削除して再作成する

ノードプールを削除し、新しいバージョンを使用して再作成します。

  1. ノードプールを削除します。

    gcloud container node-pools delete NODE_POOL_NAME \
        --cluster CLUSTER_NAME \
        --location CONTROL_PLANE_LOCATION
    
  2. --cluster-version フラグを使用して新しいバージョンを渡し、ノードプールを再作成します。ノードプールの推奨される自動アップグレード ターゲットを渡します。詳細については、Standard クラスタのノードプールのアップグレード情報を取得するをご覧ください。クラスタに推奨される自動アップグレードのターゲットがない場合は、GKE リリースノートの最新のバージョン アップデート エントリを確認してください。