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

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

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

始める前に

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

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

Console


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

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

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

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

gcloud


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

gcloud compute instances create [INSTANCE_NAME] --preemptible

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

API


API では、インスタンスを作成するリクエストを通常どおり作成しますが、scheduling の下に preemptible プロパティを追加し、それを 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. Enter を押して、指定されたフィルタを適用します。ログのリストが更新され、インスタンスがプリエンプトされたオペレーションのみが表示されます。
  5. リストのオペレーションを選択し、プリエンプトされたインスタンスに関する詳細を表示します。

gcloud


gcloud compute では、operations list コマンドを使用して、最新のシステム オペレーションのリストを取得します。

gcloud compute operations list

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

NAME                  TYPE                         TARGET                                   HTTP_STATUS STATUS TIMESTAMP
systemevent-xxxxxxxx  compute.instances.preempted  us-central1-f/instances/example-instance 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]/global/operations

レスポンスには、最新オペレーションのリストが含まれます。インスタンスがプリエンプトされた場合、オペレーションには compute.instances.preempted というオペレーション タイプと、インスタンスがプリエンプトされたことを示すステータス メッセージが含まれます。

{
  "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.",
  ...
}

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

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

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

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

これをシャットダウン スクリプトの外部で使用する場合は、URL に ?wait_for_change=true を追加します。そうすると 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 ドキュメント