プリエンプティブル VM を使用してフォールト トレラント ワークロードを実行する


このページでは、Google Kubernetes Engine(GKE)でプリエンプティブル VM を使用する方法について説明します。

概要

プリエンプティブル VM は、最長持続時間が 24 時間で、可用性が保証されない Compute Engine VM インスタンスです。プリエンプティブル VM は、Spot VM と同様の機能を備えていますが、作成後 24 時間しか持続しません。

Spot VM との比較

プリエンプティブル VM には、次のような Spot VM との多くの類似点があります。

最大有効期限がない Spot VM とは異なり、プリエンプティブル VM は作成後最大 24 時間しか持続しません。

新しいクラスタとノードプールでプリエンプティブル VM を有効にして、nodeSelector またはノード アフィニティを使用してスケジューリングを制御できます。また、ノードがプリエンプトされたときのシステム ワークロードの問題を回避するために、taint と toleration を使用できます。

プリエンプティブル VM の終了と正常なシャットダウン

Compute Engine がプリエンプティブル VM によって使用されたリソースを再利用する必要がある場合、プリエンプション通知が GKE に送信されます。プリエンプティブル VM は、終了通知を受け取ってから 30 秒後に終了します。

GKE バージョン 1.20 以降を実行しているクラスタでは、kubelet グレースフル ノード シャットダウン機能がデフォルトで有効になります。kubelet は終了通知を認識し、ノードで実行中の Pod を正常に終了します。

kubelet ではベストエフォート方式で、システム以外の Pod が正常に終了するために 25 秒の猶予が与えられます。その後、システム Pod(優先順位が system-cluster-critical または system-node-critical のもの)が正常に終了するために 5 秒の猶予があります。

Pod が正常に終了している間、kubelet が Failed ステータスと Shutdown 理由を終了する Pod に割り当てます。終了した Pod 数がしきい値に達すると、ガベージ コレクションによって Pod がクリーンアップされます。

次のコマンドを使用して、シャットダウンされる Pod を手動で削除することもできます。

kubectl get pods --all-namespaces | grep -i shutdown | awk '{print $1, $2}' | xargs -n2 kubectl delete pod -n

Kubernetes の動作の変更

GKE でプリエンプティブル VM を使用すると、Kubernetes によって提供される次のような保証と制約が変更されます。

  • 1.20 よりも前のバージョンの GKE を実行しているクラスタでは、kubelet グレースフル ノード シャットダウ機能がデフォルトで無効になっています。Compute Engine からプリエンプション通知を受け取ってから 30 秒後に、GKE は Pod の猶予期間なしでプリエンプティブル VM をシャットダウンします。

  • プリエンプティブル VM の再利用は自発的なものではなく、PodDisruptionBudgets の保証の対象外です。構成した PodDisruptionBudget 以上に可用性が低くなる場合があります。

制限事項

プリエンプティブル VM を含むクラスタまたはノードプールを作成する

プリエンプティブル VM を含むクラスタやノードプールを作成するには、gcloud コマンドライン ツールか Cloud Console を使用できます。

gcloud

プリエンプティブル VM を含むクラスタを作成するには、次のコマンドを実行します。

gcloud container clusters create CLUSTER_NAME \
    --preemptible

CLUSTER_NAME は、使用するクラスタの名前に置き換えます。

プリエンプティブル VM を持つノードプールを作成するには、次のコマンドを実行します。

gcloud container node-pools create POOL_NAME \
    --cluster=CLUSTER_NAME \
    --preemptible

POOL_NAME は、新しいノードプールの名前に置き換えます。

Console

  1. Cloud Console で Google Kubernetes Engine ページに移動します。

    Google Kubernetes Engine に移動

  2. [ 作成] をクリックします。

  3. 必要に応じてクラスタを構成します。

  4. ナビゲーション パネルの [ノードプール] で、構成するノードプールの [ノード] をクリックします。

  5. [プリエンプティブル ノードを有効にする] チェックボックスをオンにします。

  6. [作成] をクリックします。

nodeSelector を使用してプリエンプティブル VM 上で Pod をスケジューリングする

GKE は、プリエンプティブル VM を使用するノードに cloud.google.com/gke-preemptible=true ノードラベルを追加します。Deployment で nodeSelector を使用して、Pod をプリエンプティブル VM 上にスケジューリングするよう GKE に指示できます。

たとえば、次の Deployment では、プリエンプティブル VM をフィルタします。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-app
  template:
    metadata:
      labels:
        app: hello-app
    spec:
      containers:
      - name: hello-app
        image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
        resources:
          requests:
            cpu: 200m
      nodeSelector:
        cloud.google.com/gke-preemptible: "true"

プリエンプティブル VM にノード taints を使用する

プリエンプティブル VM を使用するノードを taint することで、対応する容認機能を備えた Pod のみが GKE によってそうしたノードに配置されるようにできます。

プリエンプティブル VM を使用するノードプールにノード taint を追加するには、次のコマンドのように、ノードプール作成時に --node-taints フラグを使用します。

gcloud container node-pools create POOL2_NAME \
    --node-taints=cloud.google.com/gke-preemptible="true":NoSchedule

これで、Node taint を許容する Pod だけが、このノードにスケジュールされるようになります。

関連する容認機能を Pod に追加するには、デプロイを変更して、次の記述を Pod 仕様に追加します。

tolerations:
- key: cloud.google.com/gke-preemptible
  operator: Equal
  value: "true"
  effect: NoSchedule

GPU プリエンプティブル VM のノード taints

プリエンプティブル VM では、GPU の使用がサポートされています。プリエンプティブル VM を使用する GPU ノードプールを追加する前に、クラスタには、プリエンプティブル VM を使用しない他のノードプールを 1 つ以上作成する必要があります。オンデマンド ノードプールを使用すると、GKE が DNS などのシステム コンポーネントを安全に配置できます。

プリエンプティブル VM を使用する GPU ノードプールがある新しいクラスタを作成する場合、またはプリエンプティブル VM を使用する新しい GPU ノードプールをオンデマンド ノードプールをまだ備えていないクラスタに追加する場合、GKE によって nvidia.com/gpu=present:NoSchedule taint がノードに自動的に追加されることはありません。システム Pod が、GKE によってプリエンプティブル VM にスケジューリングされことはあります。この場合は、中断が発生する可能性があります。GPU ノードは、非 GPU ノードより高コストであるため、この動作によってリソースの消費も増加します。

次のステップ