プリエンプティブ VM インスタンスの作成と起動

このガイドでは、プリエンプティブ仮想マシン(VM)インスタンスを作成して使用する方法について説明します。プリエンプティブ インスタンスは、通常のインスタンスよりはるかに低価格で作成、実行できるインスタンスです。ただし、このインスタンスは、他のタスクのリソースへのアクセスが必要な場合に、Compute Engine によって終了(プリエンプト)される可能性があります。プリエンプティブ インスタンスは、24 時間後には必ず終了されます。プリエンプティブ インスタンスの詳細については、プリエンプティブ インスタンスのドキュメントをご覧ください。

プリエンプティブ インスタンスは、インスタンスのプリエンプションに耐えることができるフォールト トレラント アプリケーションでのみ推奨されています。プリエンプティブ インスタンスを作成することを決める前に、ご使用のアプリケーションでプリエンプションの処理が可能であることを確認してください。プリエンプティブ インスタンスのドキュメントでは、プリエンプティブ インスタンスのリスクと価値について解説しています。

始める前に

プリエンプティブ インスタンスの作成

プリエンプティブ インスタンスを作成するには、Google Cloud Platform Consolegcloud ツール、または API を使用します。

Console

プリエンプティブ インスタンスの作成は通常のインスタンスの作成と同じですが、preemptible プロパティを有効にします。

  1. GCP Console の [VM インスタンス] ページに移動します。

    [VM インスタンス] ページに移動

  2. [インスタンスを作成] をクリックします。
  3. [新しいインスタンスの作成] ページで、インスタンス向けに希望するプロパティを入力します。
  4. [管理、セキュリティ、ディスク、ネットワーク、単一テナンシー] をクリックします。
  5. [可用性ポリシー] で、[プリエンプティブ] オプションを [オン] に設定します。この設定により、インスタンスの自動再起動が無効になり、ホスト メンテナンス アクションが [終了] に設定されます。
  6. [作成] をクリックしてインスタンスを作成します。

gcloud

gcloud compute では、通常のインスタンスを作成する際に使用する instances create コマンドを使用します。ただし、--preemptible フラグを追加します。

gcloud compute instances create [INSTANCE_NAME] --preemptible

ここで、[INSTANCE_NAME] はインスタンスの名前です。

API

API では、インスタンスの作成リクエストを通常どおりに作成しますが、schedulingpreemptible プロパティを含め、その値を true に設定します。次に例を示します。

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances

{
  'machineType': 'zones/[ZONE]/machineTypes/[MACHINE_TYPE]',
  'name': '[INSTANCE_NAME]',
  'scheduling':
  {
    'preemptible': true
  },
  ...
}

プリエンプティブ CPU の割り当て

プリエンプティブ インスタンスは、通常のインスタンスと同じように使用可能な CPU の割り当てを必要とします。プリエンプティブ インスタンスが通常のインスタンスの CPU の割り当てを消費することを回避するために、特別な「プリエンプティブ CPU」の割り当てを要求できます。Compute Engine がそのリージョンでプリエンプティブ CPU の割り当てを付与した後は、すべてのプリエンプティブ インスタンスが割り当てに対してカウントされます。すべての通常のインスタンスは、引き続き通常の CPU の割り当てに対してカウントされます。

プリエンプティブ CPU の割り当てがないリージョンでは、通常の CPU の割り当てを使用してプリエンプティブ インスタンスを起動できます。通常どおり、十分な IP およびディスクの割り当ても必要です。プリエンプティブ CPU の割り当ては、Compute Engine が割り当てを付与しない限り、gcloud ツールまたは GCP Console の割り当てページに表示されません。

割り当ての詳細については、リソースの割り当てのページをご覧ください。

シャットダウン スクリプトを使用したプリエンプションの処理

インスタンスがプリエンプトされている場合、インスタンスを停止する前に、シャットダウン スクリプトを使用して、クリーンアップ アクションを実行します。たとえば、実行中のプロセスを安全に終了し、チェックポイント ファイルを Google Cloud Storage にコピーすることができます。

シャットダウン スクリプトを以下に示します。これは、実行中のプリエンプティブ インスタンスに追加するか、新規作成時にプリエンプティブ インスタンスに追加できます。このスクリプトは、オペレーティング システムの通常の kill コマンドが残りすべてのプロセスを終了する前の、インスタンスがシャットダウンを開始するときに実行されます。対象のプログラムを安全に終了した後、スクリプトは、Google Cloud Storage バケットにチェックポイント ファイルの並列アップロードを実行します。

#!/bin/bash

MY_PROGRAM="[PROGRAM_NAME]" # For example, "apache2" or "nginx"
MY_USER="[LOCAL_USERNAME]"
CHECKPOINT="/home/$MY_USER/checkpoint.out"
GSUTIL_OPTS="-m -o GSUtil:parallel_composite_upload_threshold=32M"
BUCKET_NAME="[BUCKET_NAME]" # For example, "my-checkpoint-files" (without gs://)

echo "Shutting down!  Seeing if ${MY_PROGRAM} is running."

# Find the newest copy of $MY_PROGRAM
PID="$(pgrep -n "$MY_PROGRAM")"

if [[ "$?" -ne 0 ]]; then
  echo "${MY_PROGRAM} not running, shutting down immediately."
  exit 0
fi

echo "Sending SIGINT to $PID"
kill -2 "$PID"

# Portable waitpid equivalent
while kill -0 "$PID"; do
   sleep 1
done

echo "$PID is done, copying ${CHECKPOINT} to gs://${BUCKET_NAME} as ${MY_USER}"

su "${MY_USER}" -c "gsutil $GSUTIL_OPTS cp $CHECKPOINT gs://${BUCKET_NAME}/"

echo "Done uploading, shutting down."

このスクリプトをインスタンスに追加するには、インスタンス上でアプリケーションと連携するようにスクリプトを構成し、そのスクリプトをインスタンスのメタデータに追加します。

  1. シャットダウン スクリプトをローカル ワークステーションにコピーまたはダウンロードします。
  2. ファイルを開いて編集し、以下の変数を変更します。
    • [PROGRAM_NAME] は、シャットダウンするプロセスまたはプログラムの名前です。たとえば、apache2nginx などです。
    • [LOCAL_USER] は、仮想マシンへのログインに使用しているユーザー名です。
    • [BUCKET_NAME] は、プログラムのチェックポイント ファイルの保存先とする Google Cloud Storage バケットの名前です。ここではバケット名が gs:// で始まっていないことにご注意ください。
  3. 変更を保存します。
  4. シャットダウン スクリプトを新しいインスタンスまたは既存のインスタンスに追加します。

このスクリプトの前提条件は次のとおりです。

  • 少なくとも Google Cloud Storage に対する読み取り / 書き込みアクセス権を付与したインスタンスを作成してあること。適切なスコープを指定してインスタンスを作成する方法については、認証のドキュメントをご覧ください。

  • 既存の Google Cloud Storage バケットがあり、そのバケットに対する書き込み権限が付与されていること。

インスタンスがプリエンプティブであるかどうかを確認する

インスタンスがプリエンプティブとして構成されているかどうかを確認するには、GCP Consolegcloud ツール、または API を使用します。

Console


インスタンスがプリエンプティブであるかどうかを確認するには、インスタンスのプロパティを表示します。

  1. [VM インスタンス] ページに移動します。

    [VM インスタンス] ページに移動

  2. プロジェクトを選択し、[続行] をクリックします。
  3. 確認するインスタンスの名前をクリックします。インスタンスの詳細ページが開きます。
  4. プリエンプティブ ステータスは、インスタンスの詳細の [可用性ポリシー] セクションに示されます。

gcloud


gcloud compute では、instances describe を使用してインスタンスに関する情報を取得しますが、その情報にはインスタンスがプリエンプティブであるかどうかが含まれています。

gcloud compute instances describe [INSTANCE_NAME]

ここで、[INSTANCE_NAME] は、インスタンスの名前です。

レスポンス情報には、スケジュール セクションのプリエンプティブ ステータスが含まれます。

...
scheduling:
  automaticRestart: false
  onHostMaintenance: TERMINATE
  preemptible: true
...

API


API を使用してインスタンスがプリエンプティブかどうかを確認するには、GET リクエストをインスタンスの URI に送信します。

GET https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances/[INSTANCE_NAME]

レスポンス情報の scheduling には、以下のプリエンプティブ ステータスが組み込まれています。

{
    "kind": "compute#instance",
    "id": "4468501694759003918",
    "creationTimestamp": "2015-04-15T15:40:59.004-07:00",
    "zone": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-f",
    "status": "RUNNING",
    "name": "example-instance",
    "scheduling":
    {
       "preemptible": true
    },
    ...
 }

別の方法として、インスタンス自体の内部からインスタンスがプリエンプティブかどうかを確認することもできます。それには、メタデータ サーバーでインスタンスのデフォルトのインスタンス メタデータに含まれる scheduling/preemptible の値を確認します。

たとえば、インスタンス内から curl を使用して scheduling/preemptible の値を取得します。

curl "http://metadata.google.internal/computeMetadata/v1/instance/scheduling/preemptible" -H "Metadata-Flavor: Google"
TRUE

この値が TRUE の場合、インスタンスはプリエンプティブであるということになります。

インスタンスがプリエンプトされたかどうかを確認する

インスタンスがプリエンプトされたかどうかを確認するには、Google Cloud Platform Consolegcloud ツール、または API を使用します。

Console


インスタンスがプリエンプトされたかどうかを確認するには、システム アクティビティ ログを調べます。

  1. [ログ] ページに移動します。

    [ログ] ページに移動

  2. プロジェクトを選択し、[続行] をクリックします。
  3. [ラベルまたはテキスト検索でフィルタ] フィールドに compute.instances.preempted を追加します。
  4. 必要に応じて、特定のインスタンスのプリエンプション オペレーションを確認するには、そのインスタンスの名前を入力して表示することもできます。
  5. Enter キーを押して、指定されたフィルタを適用します。GCP Console でログのリストが更新され、インスタンスがプリエンプトされたオペレーションのみが表示されます。
  6. リストでオペレーションを選択し、プリエンプトされたインスタンスに関する詳細を表示します。

gcloud


プロジェクト内のプリエンプション イベントのリストを取得するには、filter パラメータを指定して gcloud compute operations list コマンドを使用します。

gcloud compute operations list \
    --filter="operationType=compute.instances.preempted"

filter パラメータを使用することでさらに結果を絞り込むことができます。たとえば、マネージド インスタンス グループ内のインスタンスのプリエンプション イベントのみを表示するには、次のようにします。

gcloud compute operations list \
    --filter="operationType=compute.instances.preempted AND targetLink:instances/[BASE_INSTANCE_NAME]"

gcloud は、次のようなレスポンスを返します。

NAME                  TYPE                         TARGET                                   HTTP_STATUS STATUS TIMESTAMP
systemevent-xxxxxxxx  compute.instances.preempted  us-central1-f/instances/example-instance-xxx  200         DONE   2015-04-02T12:12:10.881-07:00

compute.instances.preempted というオペレーション タイプは、インスタンスがプリエンプトされたことを示します。operations describe コマンドを使用して、特定のプリエンプション オペレーションに関する情報を取得します。

gcloud compute operations describe \
    systemevent-xxxxxxxx

gcloud は、次のようなレスポンスを返します。

...
operationType: compute.instances.preempted
progress: 100
selfLink: https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-f/operations/systemevent-xxxxxxxx
startTime: '2015-04-02T12:12:10.881-07:00'
status: DONE
statusMessage: Instance was preempted.
...

API


最近のシステム オペレーションのリストを取得するには、ゾーン オペレーションの URI に GET リクエストを送信します。

GET https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/operations

レスポンスには、最近のオペレーションのリストが記載されます。

{
  "kind": "compute#operation",
  "id": "15041793718812375371",
  "name": "systemevent-xxxxxxxx",
  "zone": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-f",
  "operationType": "compute.instances.preempted",
  "targetLink": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-f/instances/example-instance",
  "targetId": "12820389800990687210",
  "status": "DONE",
  "statusMessage": "Instance was preempted.",
  ...
}

レスポンスを絞り込んでプリエンプション オペレーションのみを表示するには、API リクエストに operationType="compute.instances.preempted" というフィルタを追加します。特定のインスタンスのプリエンプション オペレーションを確認するには、次のように targetLink パラメータをフィルタに追加します。operationType="compute.instances.preempted" AND targetLink="https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances/[INSTANCE_NAME]"

別の方法として、インスタンス自体の内部からインスタンスがプリエンプトされたかどうかを確認することもできます。これは、Compute Engine のプリエンプションのためにシャットダウン スクリプトの通常のシャットダウンとは異なるシャットダウンを処理する場合に便利です。これを行うには、メタデータ サーバーでインスタンスのデフォルトのインスタンス メタデータに含まれる preempted の値を確認します。

たとえば、インスタンス内から curl を使用して preempted の値を取得します。

curl "http://metadata.google.internal/computeMetadata/v1/instance/preempted" -H "Metadata-Flavor: Google"
TRUE

この値が TRUE の場合、インスタンスは Compute Engine によってプリエンプトされており、プリエンプトされていない場合は FALSE になります。

これをシャットダウン スクリプトの外部で使用する場合は、?wait_for_change=true を URL の末尾に追加します。これにより、HTTP GET リクエストが待機中になり、メタデータが変更されてインスタンスがプリエンプトされたときにのみ結果が返されます。

curl "http://metadata.google.internal/computeMetadata/v1/instance/preempted?wait_for_change=true" -H "Metadata-Flavor: Google"
TRUE

おすすめの方法

以下に、プリエンプティブ VM インスタンスを最大限に活用するために役立ついくつかのおすすめの方法を紹介します。

より小さいマシンの形を選ぶ

プリエンプティブ VM インスタンス用のリソースは、Google Cloud Platform の余分なバックアップ容量から取得されます。一般的に、小さいマシンタイプの方が大きいタイプより簡単にプリエンプティブ容量を多く取得できます。また、経験的に、コア数が 32 未満の小さいマシンタイプの方が、より大きいマシンタイプよりもプリエンプト率が低くなっています。

事前定義されたタイプの中間にあるカスタム マシンタイプを使用すると、予備の容量をより多く取得できる場合もあります。たとえば、vCPU 数が 48 のカスタム マシンタイプの方が、n1-standard-64 よりも容量が多くなる可能性があります。

大きなプリエンプティブ VM クラスタはオフピーク時に実行する

Google Cloud Platform データセンターの負荷は、ロケーションと時間帯によって異なりますが、一般的には夜間および週末に最も低くなります。そのため、大きなプリエンプティブ VM クラスタを実行する時間としては夜間や週末が最適です。

耐障害性と対プリエンプション性を備えたアプリケーションを設計する

時間が異なればプリエンプションのパターンが変化するという事実に備えることが重要です。たとえば、ゾーンで部分的な停止の問題が発生している場合、復旧の一部として移動する必要がある通常のインスタンス用の余地を作るために多数のプリエンプティブ インスタンスがプリエンプトされる可能性があります。この短い時間のプリエンプション レートは他の日とはまったく異なるように見えます。プリエンプションが常に小さなグループで実行されることを前提としている場合は、そのようなイベントに対する備えがないことがあります。VM インスタンスを停止することによってプリエンプション イベント発生中のアプリケーションの動作をテストできます。

プリエンプトされたインスタンスの再作成を試行する

プリエンプトされた場合、通常のインスタンスにフォールバックする前にプリエンプティブ インスタンスを 1 回または 2 回再試行すると効果的なことがあります。実際の要件によっては、クラスタ内で通常のインスタンスとプリエンプティブ インスタンスを組み合わせて適切なペースで作業が続行されるようにすると有効な場合があります。

シャットダウン スクリプトを使用する

ジョブの進行状況を保存できるシャットダウン スクリプトを使用してシャットダウンとプリエンプションの通知を管理すると、最初からやり直す代わりに停止した時点を選択できます。

次のステップ

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Compute Engine ドキュメント