VM を一時停止または再開する


このドキュメントでは、仮想マシン(VM)インスタンスを一時停止または再開する方法について説明します。

VM インスタンスを残すが、使用していないときに課金されたくない場合は、VM を一時停止できます。VM を一時停止すると、VM がプロジェクト内に保持され、VM のメモリの内容がストレージに移動します。VM が一時停止されている間は、VM のメモリの保持に使用されるストレージに対してのみ課金されます。静的 IP アドレスなどの属性はそのまま維持されるため、VM を再開する際にネットワーク機能が予期したとおりに機能します。再開後、VM のメモリがストレージからインスタンスに戻され、実行中の VM インスタンスに対する課金が開始されます。

インスタンスの一時停止は次の場合に最適です。

  • 夜間や週末などのオフ時間に使用率が低い開発環境やテスト環境。新しい VM インスタンスを作成する場合よりもコストを抑え、短時間で初期化を行うことができます。
  • 仮想デベロッパー ワークステーションや複雑な Java アプリケーションなど、インスタンスの起動が完了してから最初のリクエストを処理するまでに初期化に時間がかかるアプリケーション。

一時停止の仕組み

インスタンスを一時停止すると、ACPI S3 一時停止信号がインスタンスのオペレーティング システムに送信されます。インスタンスの一時停止は、ノートパソコンのカバーを閉じてインスタンスを SUSPENDED 状態にすることに似ています。

インスタンスの一時停止は、次の点でインスタンスの停止とは異なります。

インスタンスに接続されているすべてのリソースはインスタンスへの接続を維持し、課金対象になります。これには永続ディスク、静的 IP アドレス、予約済みの外部 IP アドレスが含まれます。インスタンスが一時停止している場合でも、これらのリソースはすべて料金表に従って課金されます。

ゲスト環境に組み込まれている標準プロセスを使用してインスタンスを一時停止することはできません。Ubuntu 16.04 以降の systemctl suspend コマンドは使用できません。インスタンスを一時停止するために使用できるのは、Google Cloud CLI または REST だけです。

後でインスタンスを再開するときに、インスタンスのメモリやデバイスの状態を復元する必要がない場合は、インスタンスを停止できます。この場合、追加のストレージ料金は発生しません。

準備

  • まだ設定していない場合は、認証を設定します。認証とは、Google Cloud サービスと API にアクセスするために ID を確認するプロセスです。ローカル開発環境からコードまたはサンプルを実行するには、次のように Compute Engine に対する認証を行います。

    Select the tab for how you plan to use the samples on this page:

    Console

    When you use the Google Cloud console to access Google Cloud services and APIs, you don't need to set up authentication.

    gcloud

    1. Install the Google Cloud CLI, then initialize it by running the following command:

      gcloud init
    2. Set a default region and zone.
    3. Go

      ローカル開発環境でこのページの Go サンプルを使用するには、gcloud CLI をインストールして初期化し、ユーザー認証情報を使用してアプリケーションのデフォルト認証情報を設定します。

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. If you're using a local shell, then create local authentication credentials for your user account:

        gcloud auth application-default login

        You don't need to do this if you're using Cloud Shell.

      詳細については Set up authentication for a local development environment をご覧ください。

      Java

      ローカル開発環境でこのページの Java サンプルを使用するには、gcloud CLI をインストールして初期化し、ユーザー認証情報を使用してアプリケーションのデフォルト認証情報を設定します。

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. If you're using a local shell, then create local authentication credentials for your user account:

        gcloud auth application-default login

        You don't need to do this if you're using Cloud Shell.

      詳細については Set up authentication for a local development environment をご覧ください。

      Node.js

      ローカル開発環境でこのページの Node.js サンプルを使用するには、gcloud CLI をインストールして初期化し、ユーザー認証情報を使用してアプリケーションのデフォルト認証情報を設定します。

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. If you're using a local shell, then create local authentication credentials for your user account:

        gcloud auth application-default login

        You don't need to do this if you're using Cloud Shell.

      詳細については Set up authentication for a local development environment をご覧ください。

      PHP

      ローカル開発環境でこのページの PHP サンプルを使用するには、gcloud CLI をインストールして初期化し、ユーザー認証情報を使用してアプリケーションのデフォルト認証情報を設定します。

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. If you're using a local shell, then create local authentication credentials for your user account:

        gcloud auth application-default login

        You don't need to do this if you're using Cloud Shell.

      詳細については Set up authentication for a local development environment をご覧ください。

      Python

      ローカル開発環境でこのページの Python サンプルを使用するには、gcloud CLI をインストールして初期化し、ユーザー認証情報を使用してアプリケーションのデフォルト認証情報を設定します。

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. If you're using a local shell, then create local authentication credentials for your user account:

        gcloud auth application-default login

        You don't need to do this if you're using Cloud Shell.

      詳細については Set up authentication for a local development environment をご覧ください。

      REST

      このページの REST API サンプルをローカル開発環境で使用するには、gcloud CLI に指定した認証情報を使用します。

        Install the Google Cloud CLI, then initialize it by running the following command:

        gcloud init

      詳細については、Google Cloud 認証ドキュメントの REST を使用して認証するをご覧ください。

制限事項

この機能には、次の制限があります。

  • GPU を使用するインスタンスは一時停止できません。
  • ベアメタル インスタンスは一時停止できません。
  • ゲスト環境に組み込まれている標準プロセスを使用してインスタンスを一時停止することはできません。コマンド(例: Ubuntu 16.04 以降の systemctl suspend コマンド)は使用できません。ゲスト内の信号は無視されます。
  • インスタンスを一時停止できる期間は最大 60 日です。この期間を経過すると、VM が自動的に停止します。
  • メモリが 208 GB を超えるインスタンスは一時停止できません。
  • プリエンプティブル インスタンスは一時停止できますが、正常に一時停止する前に終了することがあります。
  • Confidential VM は一時停止できません。
  • CSEK で保護されたディスクがアタッチされている VM は一時停止できません。

ローカル SSD

通常、ローカル SSD を使用する VM インスタンスを一時停止すると、ローカル SSD ドライブ上のすべてのデータが破棄されます。これは、インスタンスを停止する場合と同じ動作です。

詳細については、ローカル SSD のドキュメントをご覧ください。

プリエンプティブル VM

プリエンプティブル VM は一時停止できますが、一時停止オペレーションが完了する前にプリエンプションが発生すると(プリエンプションの事前警告ではありません)、一時停止が終了し、インスタンスがプリエンプトされます。

OS の互換性

Compute Engine で提供されているほとんどのオペレーティング システム(OS)は、一時停止と再開の機能をサポートしていますが、サポートしていない OS もあります。完全なリストについては、OS の詳細ページをご覧ください。

料金

インスタンスを一時停止すると、次のものに対して料金が発生します。

  • インスタンスのメモリ(一時停止された VM インスタンスの料金を参照)。
  • ブートディスクの永続ディスクの使用量、インスタンスにアタッチされている追加ディスク(永続ディスクの料金を参照)。
  • インスタンスに関連付けられている静的 IP
  • VM を一時停止すると、ソフトウェアのライセンス料を節約できることがあります。たとえば、Windows VM を一時停止すると、Windows ライセンス料金は発生しません。他のイメージのライセンス料は利用規約が異なる場合があります。このため、一時停止した場合でも料金が発生することもあります。

インスタンスを一時停止する

インスタンスを一時停止するには、Google Cloud コンソールgcloud CLIAPI またはCloud クライアント ライブラリを使用します。

ゲスト環境に組み込まれている標準プロセスを使用してインスタンスを一時停止することはできません。インスタンスは、Google Cloud コンソール、Google Cloud CLI、または API を使用して一時停止できます。

インスタンスの開始後、すぐに一時停止の操作が行われると失敗する可能性があります。一時停止操作を成功させるには、インスタンスを完全に起動する必要があります(ゲスト エージェントなどのプロセスを含む)。

コンソール

  1. Google Cloud コンソールで [VM インスタンス] ページに移動します。

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

  2. 一時停止するインスタンスを 1 つ以上選択します。

  3. [停止] をクリックします。

  4. プロンプトが表示され、ローカル SSD のデータを破棄する場合は、[SSD のコンテンツを破棄] を選択します。インスタンスが再開されたときに、インスタンス上のローカル SSD データは破棄されています。

gcloud

Google Cloud CLI でインスタンスを一時停止するには:

 gcloud compute instances suspend VM_NAME

インスタンスの一時停止をリクエストした後に、Compute Engine でインスタンスのすべての必要なデータを保持するために時間がかかることがあります。この間、実行中のインスタンスに対して引き続き料金が発生します。

一時停止されたインスタンスは、SUSPENDED ステータスでマークされます。describe リクエストを実行してインスタンスのステータスを確認します。

gcloud compute instances describe VM_NAME

ローカル SSD データが含まれるインスタンスを一時停止するには、--discard-local-ssd フラグを指定する必要があります。

gcloud compute instances suspend VM_NAME --discard-local-ssd

--discard-local-ssd または --discard-local-ssd=True を使用すると、ローカル SSD の内容は破棄されます。Compute Engine では、--discard-local-ssd=False は現在パブリック プレビュー版です。このフラグを使用すると、一時停止中に最大 32 個のローカル SSD ディスクの内容が保存されます。詳細については、ローカル SSD のドキュメントをご覧ください。

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
)

// suspendInstance suspends a running Google Compute Engine instance.
func suspendInstance(w io.Writer, projectID, zone, instanceName string) error {
	// projectID := "your_project_id"
	// zone := "europe-central2-b"
	// instanceName := "your_instance_name"

	ctx := context.Background()
	instancesClient, err := compute.NewInstancesRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewInstancesRESTClient: %w", err)
	}
	defer instancesClient.Close()

	req := &computepb.SuspendInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
	}

	op, err := instancesClient.Suspend(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to suspend instance: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Instance suspended\n")

	return nil
}

Java


import com.google.cloud.compute.v1.Instance.Status;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.Operation;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class SuspendInstance {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // project: project ID or project number of the Cloud project your instance belongs to.
    // zone: name of the zone your instance belongs to.
    // instanceName: name of the instance your want to suspend.

    String project = "your-project-id";
    String zone = "zone-name";
    String instanceName = "instance-name";

    suspendInstance(project, zone, instanceName);
  }

  // Suspend a running Google Compute Engine instance.
  // For limitations and compatibility on which instances can be suspended,
  // see: https://cloud.google.com/compute/docs/instances/suspend-resume-instance#limitations
  public static void suspendInstance(String project, String zone, String instanceName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Instantiates a client.
    try (InstancesClient instancesClient = InstancesClient.create()) {

      Operation operation = instancesClient.suspendAsync(project, zone, instanceName)
          .get(300, TimeUnit.SECONDS);

      if (operation.hasError() || !instancesClient.get(project, zone, instanceName).getStatus()
          .equalsIgnoreCase(Status.SUSPENDED.toString())) {
        System.out.println("Cannot suspend instance. Try again!");
        return;
      }

      System.out.printf("Instance suspended successfully ! %s", instanceName);
    }
  }
}

Node.js

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const zone = 'europe-central2-b';
// const instanceName = 'YOUR_INSTANCE_NAME';

const compute = require('@google-cloud/compute');

// Suspends a running Google Compute Engine instance.
async function suspendInstance() {
  const instancesClient = new compute.InstancesClient();

  const [response] = await instancesClient.suspend({
    project: projectId,
    zone,
    instance: instanceName,
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.ZoneOperationsClient();

  // Wait for the create operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await operationsClient.wait({
      operation: operation.name,
      project: projectId,
      zone: operation.zone.split('/').pop(),
    });
  }

  console.log('Instance suspended.');
}

suspendInstance();

PHP

use Google\Cloud\Compute\V1\Client\InstancesClient;
use Google\Cloud\Compute\V1\SuspendInstanceRequest;

/**
 * Suspend a running Google Compute Engine instance.
 *
 * @param string $projectId Project ID or project number of the Cloud project your instance belongs to.
 * @param string $zone Name of the zone your instance belongs to.
 * @param string $instanceName Name of the instance you want to suspend.
  *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 * @throws \Google\ApiCore\ValidationException if local error occurs before remote call.
 */
function suspend_instance(
    string $projectId,
    string $zone,
    string $instanceName
) {
    // Suspend the running Compute Engine instance using InstancesClient.
    $instancesClient = new InstancesClient();
    $request = (new SuspendInstanceRequest())
        ->setInstance($instanceName)
        ->setProject($projectId)
        ->setZone($zone);
    $operation = $instancesClient->suspend($request);

    // Wait for the operation to complete.
    $operation->pollUntilComplete();
    if ($operation->operationSucceeded()) {
        printf('Instance %s suspended successfully' . PHP_EOL, $instanceName);
    } else {
        $error = $operation->getError();
        printf('Failed to suspend instance: %s' . PHP_EOL, $error?->getMessage());
    }
}

Python

from __future__ import annotations

import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    Waits for the extended (long-running) operation to complete.

    If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result


def suspend_instance(project_id: str, zone: str, instance_name: str) -> None:
    """
    Suspend a running Google Compute Engine instance.
    Args:
        project_id: project ID or project number of the Cloud project your instance belongs to.
        zone: name of the zone your instance belongs to.
        instance_name: name of the instance you want to suspend.
    """
    instance_client = compute_v1.InstancesClient()

    operation = instance_client.suspend(
        project=project_id, zone=zone, instance=instance_name
    )

    wait_for_extended_operation(operation, "suspend instance")

REST

API で、instances.suspend メソッドを使用してリクエストを送信します。

https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/suspend

以下のように置き換えます。

  • PROJECT_ID: プロジェクト ID
  • ZONE: VM のゾーン
  • VM_NAME: 一時停止するインスタンス

インスタンスの一時停止をリクエストした後に、Compute Engine でインスタンスのすべての必要なデータを保持するために時間がかかることがあります。この間、実行中のインスタンスに対して料金が発生します。

Compute Engine は、一時停止されたインスタンスに SUSPENDED ステータスのマークを付けます。GET リクエストを実行してインスタンスのステータスを確認します。

GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME

インスタンスのステータスは、ステータス フィールドに表示されます。例:

...
"zone": "https://content.googleapis.com/compute/v1/projects/example-project/zones/us-central1-a",
"status": "SUSPENDED",
"name": "example-vm",
...

32 個を超えるローカル SSD ディスクを含むインスタンスを一時停止するには、次のように discardLocalSsd クエリ パラメータを指定してローカル SSD データを破棄する必要があります。

https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/suspend?discardLocalSsd=true

詳細については、ローカル SSD のドキュメントをご覧ください。

一時停止されたインスタンスを再開する

インスタンスを再開できるのは、VM が存在するゾーンに十分な容量がある場合のみです。ほとんどの場合、これは問題にはなりませんが、実際に容量の問題が発生した場合は、後で再開リクエストを再試行してください。

一時停止したインスタンスを再開するには、Google Cloud コンソールgcloud CLIAPI、または Cloud クライアント ライブラリを使用します。

コンソール

  1. Google Cloud コンソールで [VM インスタンス] ページに移動します。

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

  2. 再開するインスタンスを 1 つ以上選択します。

  3. [開始 / 再開] をクリックします。

gcloud

Google Cloud CLI でインスタンスを再開するには:

 gcloud compute instances resume VM_NAME

インスタンスの再開をリクエストした後に、Compute Engine でインスタンスに必要なすべてのデータを復元する際に時間がかかることがあります。この間、再開中のインスタンスに対して料金が発生します。

インスタンスが再開されると、RUNNING とマークされます。インスタンスのステータスを確認するには、次のように describe リクエストを実行します。

gcloud compute instances describe VM_NAME

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
)

// resumeInstance resumes a suspended Google Compute Engine instance
// (with unencrypted disks).
func resumeInstance(w io.Writer, projectID, zone, instanceName string) error {
	// projectID := "your_project_id"
	// zone := "europe-central2-b"
	// instanceName := "your_instance_name"

	ctx := context.Background()
	instancesClient, err := compute.NewInstancesRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewInstancesRESTClient: %w", err)
	}
	defer instancesClient.Close()

	getInstanceReq := &computepb.GetInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
	}

	instance, err := instancesClient.Get(ctx, getInstanceReq)
	if err != nil {
		return fmt.Errorf("unable to get instance: %w", err)
	}

	if instance.GetStatus() != "SUSPENDED" {
		return fmt.Errorf(
			"only suspended instances can be resumed, instance %s is in %s state",
			instanceName,
			instance.GetStatus(),
		)
	}

	resumeInstanceReq := &computepb.ResumeInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
	}

	op, err := instancesClient.Resume(ctx, resumeInstanceReq)
	if err != nil {
		return fmt.Errorf("unable to resume instance: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Instance resumed\n")

	return nil
}

Java


import com.google.cloud.compute.v1.Instance.Status;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.Operation;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ResumeInstance {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // project: project ID or project number of the Cloud project your instance belongs to.
    // zone: name of the zone your instance belongs to.
    // instanceName: name of the instance your want to resume.

    String project = "your-project-id";
    String zone = "zone-name";
    String instanceName = "instance-name";

    resumeInstance(project, zone, instanceName);
  }

  // Resume a suspended Google Compute Engine instance (with unencrypted disks).
  // Instance state changes to RUNNING, if successfully resumed.
  public static void resumeInstance(String project, String zone, String instanceName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Instantiates a client.
    try (InstancesClient instancesClient = InstancesClient.create()) {

      String currentInstanceState = instancesClient.get(project, zone, instanceName).getStatus();

      // Check if the instance is currently suspended.
      if (!currentInstanceState.equalsIgnoreCase(Status.SUSPENDED.toString())) {
        throw new RuntimeException(
            String.format("Only suspended instances can be resumed. Instance %s is in %s state.",
                instanceName, currentInstanceState));
      }

      Operation operation = instancesClient.resumeAsync(project, zone, instanceName)
          .get(300, TimeUnit.SECONDS);

      if (operation.hasError() || !instancesClient.get(project, zone, instanceName).getStatus()
          .equalsIgnoreCase(
              Status.RUNNING.toString())) {
        System.out.println("Cannot resume instance. Try again!");
        return;
      }

      System.out.printf("Instance resumed successfully ! %s", instanceName);
    }
  }
}

Node.js

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const zone = 'europe-central2-b';
// const instanceName = 'YOUR_INSTANCE_NAME';

const compute = require('@google-cloud/compute');

// Resumes a suspended Google Compute Engine instance (with unencrypted disks).
async function resumeInstance() {
  const instancesClient = new compute.InstancesClient();

  const [instance] = await instancesClient.get({
    project: projectId,
    zone,
    instance: instanceName,
  });

  if (instance.status !== 'SUSPENDED') {
    throw new Error(
      'Only suspended instances can be resumed.' +
        `Instance ${instanceName} is in ${instance.status} state.`
    );
  }

  const [response] = await instancesClient.resume({
    project: projectId,
    zone,
    instance: instanceName,
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.ZoneOperationsClient();

  // Wait for the create operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await operationsClient.wait({
      operation: operation.name,
      project: projectId,
      zone: operation.zone.split('/').pop(),
    });
  }

  console.log('Instance resumed.');
}

resumeInstance();

PHP

use Google\Cloud\Compute\V1\Client\InstancesClient;
use Google\Cloud\Compute\V1\ResumeInstanceRequest;

/**
 * Resume a suspended Google Compute Engine instance (with unencrypted disks).
 *
 * @param string $projectId Project ID or project number of the Cloud project your instance belongs to.
 * @param string $zone Name of the zone your instance belongs to.
 * @param string $instanceName Name of the instance you want to resume.
  *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 * @throws \Google\ApiCore\ValidationException if local error occurs before remote call.
 */
function resume_instance(
    string $projectId,
    string $zone,
    string $instanceName
) {
    // Resume the suspended Compute Engine instance using InstancesClient.
    $instancesClient = new InstancesClient();
    $request = (new ResumeInstanceRequest())
        ->setInstance($instanceName)
        ->setProject($projectId)
        ->setZone($zone);
    $operation = $instancesClient->resume($request);

    // Wait for the operation to complete.
    $operation->pollUntilComplete();
    if ($operation->operationSucceeded()) {
        printf('Instance %s resumed successfully' . PHP_EOL, $instanceName);
    } else {
        $error = $operation->getError();
        printf('Failed to resume instance: %s' . PHP_EOL, $error?->getMessage());
    }
}

Python

from __future__ import annotations

import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    Waits for the extended (long-running) operation to complete.

    If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result


def resume_instance(project_id: str, zone: str, instance_name: str) -> None:
    """
    Resume a suspended Google Compute Engine instance (with unencrypted disks).
    Args:
        project_id: project ID or project number of the Cloud project your instance belongs to.
        zone: name of the zone your instance belongs to.
        instance_name: name of the instance you want to resume.
    """
    instance_client = compute_v1.InstancesClient()

    instance = instance_client.get(
        project=project_id, zone=zone, instance=instance_name
    )
    if instance.status != compute_v1.Instance.Status.SUSPENDED.name:
        raise RuntimeError(
            f"Only suspended instances can be resumed. "
            f"Instance {instance_name} is in {instance.status} state."
        )

    operation = instance_client.resume(
        project=project_id, zone=zone, instance=instance_name
    )

    wait_for_extended_operation(operation, "instance resumption")

REST

instances.resume メソッドにリクエストを送信します。

https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/resume

以下のように置き換えます。

  • PROJECT_ID: このリクエストのプロジェクト ID。
  • ZONE: VM のゾーン
  • VM_NAME: 再開するインスタンス

インスタンスの再開をリクエストした後に、Compute Engine でインスタンスに必要なすべてのデータを復元する際に時間がかかることがあります。この間、再開中のインスタンスに対して料金が発生します。

再開が完了すると、Compute Engine によりそのインスタンスに RUNNING ステータスのマークが付けられます。GET リクエストを実行してインスタンスのステータスを確認します。

GET https://compute.googleapis.com/compute/v1/projects/example-project/zones/us-central1-a/instances/example-instance

インスタンスのステータスは、ステータス フィールドに表示されます。次に例を示します。

...
"zone": "https://content.googleapis.com/compute/v1/projects/example-project/zones/us-central1-a",
"status": "RUNNING",
"name": "example-instance",
...

一時停止プロセス

一時停止リクエストを行うと、ACPI 一時停止信号が VM インスタンスに送信されます。数分以内に VM が ACPI S3 一時停止信号に応答しない場合、Compute Engine は一時停止をキャンセルし、VM を RUNNING 状態に戻します。

以下の表に、VM インスタンスの一時停止がその関連リソースに及ぼす影響について説明します。

リソース サポート
メモリ 一時停止できるのは、メモリが 208 GB 以下の VM のみです。
ローカル SSD ローカル SSD のデータは破棄されます。
永続ディスク 永続ディスク(HDD と SSD)は保持されます。
IP アドレス 一時停止時に VM インスタンスのエフェメラル IP は解放されますが、静的 IP は解放されません。エフェメラル IP を保持する場合は、それを昇格します。
VM 構成(マシンタイプ、メタデータ、ラベルなど) エフェメラル IP アドレスを除くすべての VM 構成は保持され、インスタンスの再開時に復元されます。

一時停止と再開をサポートする Debian VM の構成

Debian 8 と 9 を実行している VM は一時停止と再開が可能ですが、事前に構成を行う必要があります。Debian インスタンスを構成するには、次のいずれかの手順(オプション A または B)を行います。可能であれば、ACPID を構成することをおすすめします(オプション A)。

オプション A

このオプションでは、スリープボタン イベントを処理するように ACPID を構成し、スリープ イベントを処理するシェル スクリプトを追加します。

  1. ssh を使用して VM インスタンスに接続します。

    gcloud compute ssh VM_NAME
    
  2. VM インスタンスで、acpi フォルダの下にディレクトリを作成します。

    sudo mkdir -p /etc/acpi/events/
    
  3. スリープボタン イベントを処理するように ACPID を構成します。

    cat <<EOF | sudo tee /etc/acpi/events/sleepbtn-acpi-support
    event=button[ /]sleep
    action=/etc/acpi/sleepbtn-acpi-support.sh
    EOF
    
  4. スリープ イベントを処理するスクリプトを作成します。

    cat <<EOF | sudo tee /etc/acpi/sleepbtn-acpi-support.sh
    #!/bin/sh
    echo mem > /sys/power/state
    EOF
    
  5. スクリプトの権限を設定します。

    sudo chmod 755 /etc/acpi/sleepbtn-acpi-support.sh
    
  6. ACPID を再起動します。

    sudo systemctl restart acpid.service
    

オプション B

  1. ssh を使用して VM インスタンスに接続します。

    gcloud compute ssh VM_NAME
    
  2. VM インスタンスに dbus をインストールします。

    sudo apt-get install dbus
    
  3. logind を再起動します。

    sudo systemctl restart systemd-logind.service
    

次のステップ