停止或重新啟動 Compute Engine 執行個體

本文說明如何手動停止或重新啟動 Compute Engine 執行個體。或者,如要自動停止或重新啟動運算執行個體,請參閱下列內容:

您可以手動停止運算執行個體。停止作業完成後,運算執行個體的狀態會轉換為 TERMINATED,此時您可以重新啟動運算執行個體來繼續工作負載,或永久刪除不再需要的運算執行個體。如要執行下列操作,建議手動停止運算執行個體:

  • 節省成本,同時保留設定:您不想再於運算執行個體上執行工作負載。不過,您想保留運算執行個體和其附加磁碟、配置設定、IP 位址、MAC 位址和中繼資料。如果還需要保留記憶體內資料和應用程式狀態,請改為暫停運算執行個體。

  • 更新屬性:您想修改一或多個屬性,但必須先停止並重新啟動運算執行個體,變更才會生效,例如變更機器類型或卸離磁碟。詳情請參閱「可更新的屬性」。

限制

停止運算執行個體時,須遵守下列限制:

  • 只有在運算執行個體的狀態允許時,才能停止或重新啟動運算執行個體。

  • 只有在運算執行個體所在的可用區有足夠資源時,才能重新啟動運算執行個體。

  • 您無法重新啟動 TPU 運算執行個體。TPU 運算執行個體停止後,只能刪除。

事前準備

  • 如果尚未設定驗證,請先完成設定。驗證程序會確認您的身分,以便授予 Cloud de Confiance by S3NS 服務和 API 的存取權。如要從本機開發環境執行程式碼或範例,您可以選取下列其中一個選項,向 Compute Engine 進行驗證:

    請根據您打算如何使用本頁範例,選取對應的分頁標籤:

    控制台

    使用 Cloud de Confiance 控制台存取 Cloud de Confiance by S3NS 服務和 API 時,您不需要設定驗證機制。

    gcloud

    1. 安裝 Google Cloud CLI,然後 使用聯合身分登入 gcloud CLI。 登入後,執行下列指令來初始化 Google Cloud CLI:

      gcloud init
  • 設定預設區域和可用區。
  • Go

    如要在本機開發環境中使用本頁面的 Go 範例,請安裝並初始化 gcloud CLI,然後使用使用者憑證設定應用程式預設憑證。

    1. 安裝 Google Cloud CLI。

    2. 設定 gcloud CLI,使用您的聯合身分。

      詳情請參閱「 使用聯合身分登入 gcloud CLI」。

    3. 為使用者帳戶建立本機驗證憑證:

      gcloud auth application-default login

      如果傳回驗證錯誤,請確認您已 使用聯合身分登入 gcloud CLI。

    詳情請參閱「 為本機開發環境設定驗證機制」。

    Java

    如要在本機開發環境中使用本頁的 Java 範例,請安裝並初始化 gcloud CLI,然後使用使用者憑證設定應用程式預設憑證。

    1. 安裝 Google Cloud CLI。

    2. 設定 gcloud CLI,使用您的聯合身分。

      詳情請參閱「 使用聯合身分登入 gcloud CLI」。

    3. 為使用者帳戶建立本機驗證憑證:

      gcloud auth application-default login

      如果傳回驗證錯誤,請確認您已 使用聯合身分登入 gcloud CLI。

    詳情請參閱「 為本機開發環境設定驗證機制」。

    Node.js

    如要在本機開發環境中使用本頁的 Node.js 範例,請安裝並初始化 gcloud CLI,然後使用使用者憑證設定應用程式預設憑證。

    1. 安裝 Google Cloud CLI。

    2. 設定 gcloud CLI,使用您的聯合身分。

      詳情請參閱「 使用聯合身分登入 gcloud CLI」。

    3. 為使用者帳戶建立本機驗證憑證:

      gcloud auth application-default login

      如果傳回驗證錯誤,請確認您已 使用聯合身分登入 gcloud CLI。

    詳情請參閱「 為本機開發環境設定驗證機制」。

    PHP

    如要在本機開發環境中使用本頁的 PHP 範例,請安裝並初始化 gcloud CLI,然後使用使用者憑證設定應用程式預設憑證。

    1. 安裝 Google Cloud CLI。

    2. 設定 gcloud CLI,使用您的聯合身分。

      詳情請參閱「 使用聯合身分登入 gcloud CLI」。

    3. 為使用者帳戶建立本機驗證憑證:

      gcloud auth application-default login

      如果傳回驗證錯誤,請確認您已 使用聯合身分登入 gcloud CLI。

    詳情請參閱「 為本機開發環境設定驗證機制」。

    Python

    如要在本機開發環境中使用本頁的 Python 範例,請安裝並初始化 gcloud CLI,然後使用使用者憑證設定應用程式預設憑證。

    1. 安裝 Google Cloud CLI。

    2. 設定 gcloud CLI,使用您的聯合身分。

      詳情請參閱「 使用聯合身分登入 gcloud CLI」。

    3. 為使用者帳戶建立本機驗證憑證:

      gcloud auth application-default login

      如果傳回驗證錯誤,請確認您已 使用聯合身分登入 gcloud CLI。

    詳情請參閱「 為本機開發環境設定驗證機制」。

    REST

    如要在本機開發環境中使用本頁的 REST API 範例,請使用您提供給 gcloud CLI 的憑證。

      安裝 Google Cloud CLI,然後 使用聯合身分登入 gcloud CLI。

    詳情請參閱 Cloud de Confiance 驗證說明文件中的「使用 REST 進行驗證」一節。

必要的角色

如要取得停止或重新啟動運算執行個體所需的權限,請要求管理員授予您專案的 Compute 執行個體管理員 (v1) (roles/compute.instanceAdmin.v1) IAM 角色。如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。

這個預先定義的角色具備停止或重新啟動運算執行個體所需的權限。如要查看確切的必要權限,請展開「Required permissions」(必要權限) 部分:

所需權限

必須具備下列權限,才能停止或重新啟動運算執行個體:

  • 如要停止運算執行個體: compute.instances.stop 在運算執行個體上
  • 如要從訪客 OS 停止運算執行個體: compute.instances.setMetadata 如果運算執行個體使用執行個體層級公開安全殼層金鑰,則在該執行個體上。
  • 如要重新啟動運算執行個體: compute.instances.start 在運算執行個體上
  • 如要重新啟動使用加密金鑰的運算執行個體: compute.instances.startWithEncryptionKey 在運算執行個體上

您或許還可透過自訂角色或其他預先定義的角色取得這些權限。

停止運算執行個體

如要停止運算執行個體,請採用下列其中一種方法。最適合您用途的方法,取決於運算執行個體是否連接本機 SSD 磁碟,以及您要如何處理關機指令碼:

  • 從 Cloud de Confiance停止運算執行個體。您可以透過 Cloud de Confiance同時停止一或多個運算執行個體。如果運算執行個體已連接本機 SSD 磁碟,您可以選擇捨棄或保留 (預先發布版) 本機 SSD 資料。運算執行個體中的所有關機指令碼都必須在運算執行個體停止前完成執行。如需操作說明,請參閱下列任一文章:

  • 從訪客 OS 停止運算執行個體。這種做法可確保關機指令碼在運算執行個體停止前執行完畢。如果您已啟用正常關機功能,可以略過或結束正常關機程序。不過,從客體 OS 停止運算執行個體時,除非先將資料備份至持久儲存空間,否則系統會捨棄任何已連接本機 SSD 磁碟上的資料。如需操作說明,請參閱「從訪客 OS 停止運算執行個體」。

停止沒有本機 SSD 磁碟的運算執行個體

如要停止未連接本機 SSD 磁碟的運算執行個體,請參閱下列選項:

  • 如果您已在運算執行個體中啟用正常關機功能,可以略過或結束進行中的正常關機程序,藉此節省費用。如要這麼做,請使用 Cloud de Confiance 控制台、gcloud CLI 或 REST API。

  • 如要同時停止多個運算執行個體,請使用Cloud de Confiance 控制台。如果運算執行個體位於相同可用區,則可使用 gcloud CLI。

如要停止一或多個運算執行個體,請選取下列其中一個選項:

控制台

  1. 前往 Cloud de Confiance 控制台的「VM instances」(VM 執行個體) 頁面。

    前往 VM 執行個體

  2. 選取要停止的執行中運算執行個體。

  3. 按一下「 停止」。如果沒有「Stop」(停止) 選項,請按一下「More actions」(更多動作),然後選取「Stop」(停止)。

  4. 然後在隨即顯示的對話方塊中,執行以下操作:

    1. 選用:如要停止運算執行個體,但不正常關機,或要結束進行中的正常關機程序,請勾選「Skip graceful shutdown (if applicable)」(略過正常關機 (如適用)) 核取方塊。

    2. 按一下「停止」確認操作。

gcloud

如要停止位於同一可用區的一或多個運算執行個體,請使用 gcloud compute instances stop 指令:

gcloud compute instances stop INSTANCE_NAMES \
    --zone=ZONE

更改下列內容:

  • INSTANCE_NAMES:要停止的運算執行個體名稱清單,以空格分隔。例如,指定 instance-01 instance-02 instance-03。

  • ZONE:運算執行個體所在的可用區。

如要略過或結束進行中的正常關機程序,請使用相同指令並加上 --no-graceful-shutdown 旗標:

gcloud compute instances stop INSTANCE_NAMES \
    --no-graceful-shutdown \
    --zone=ZONE

Go

import (
	"context"
	"fmt"
	"io"

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

// stopInstance stops a started Google Compute Engine instance
func stopInstance(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.StopInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
	}

	op, err := instancesClient.Stop(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to stop 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 stopped\n")

	return nil
}

Java


import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.Operation.Status;
import com.google.cloud.compute.v1.StopInstanceRequest;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class StopInstance {

  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 stop.
     */
    String project = "your-project-id";
    String zone = "zone-name";
    String instanceName = "instance-name";

    stopInstance(project, zone, instanceName);
  }

  // Stops a started Google Compute Engine instance.
  public static void stopInstance(String project, String zone, String instanceName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    /* Initialize client that will be used to send requests. This client only needs to be created
       once, and can be reused for multiple requests. After completing all of your requests, call
       the `instancesClient.close()` method on the client to safely
       clean up any remaining background resources. */
    try (InstancesClient instancesClient = InstancesClient.create()) {

      StopInstanceRequest stopInstanceRequest = StopInstanceRequest.newBuilder()
          .setProject(project)
          .setZone(zone)
          .setInstance(instanceName)
          .build();

      OperationFuture<Operation, Operation> operation = instancesClient.stopAsync(
          stopInstanceRequest);
      Operation response = operation.get(3, TimeUnit.MINUTES);

      if (response.getStatus() == Status.DONE) {
        System.out.println("Instance stopped successfully ! ");
      }
    }
  }
}

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');

async function stopInstance() {
  const instancesClient = new compute.InstancesClient();

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

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

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

stopInstance();

PHP

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

/**
 * Stops 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 stop.
  *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 * @throws \Google\ApiCore\ValidationException if local error occurs before remote call.
 */
function stop_instance(
    string $projectId,
    string $zone,
    string $instanceName
) {
    // Stop the Compute Engine instance using InstancesClient.
    $instancesClient = new InstancesClient();
    $request = (new StopInstanceRequest())
        ->setInstance($instanceName)
        ->setProject($projectId)
        ->setZone($zone);
    $operation = $instancesClient->stop($request);

    // Wait for the operation to complete.
    $operation->pollUntilComplete();
    if ($operation->operationSucceeded()) {
        printf('Instance %s stopped successfully' . PHP_EOL, $instanceName);
    } else {
        $error = $operation->getError();
        printf('Failed to stop 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 stop_instance(project_id: str, zone: str, instance_name: str) -> None:
    """
    Stops 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 your want to stop.
    """
    instance_client = compute_v1.InstancesClient()

    operation = instance_client.stop(
        project=project_id, zone=zone, instance=instance_name
    )
    wait_for_extended_operation(operation, "instance stopping")

REST

如要停止運算執行個體,請向 instances.stop 方法發出 POST 要求:

POST https://compute.s3nsapis.fr/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME/stop

更改下列內容:

  • INSTANCE_NAME:運算執行個體的名稱。

  • PROJECT_ID:運算執行個體所在的專案 ID。

  • ZONE:運算執行個體所在的可用區。

如要略過或結束進行中的正常關機程序,請在要求網址中加入 noGracefulShutdown=true 查詢參數:

POST https://compute.s3nsapis.fr/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/stop?noGracefulShutdown=true

停止含有本機 SSD 磁碟的運算執行個體

如要停止已連接本機 SSD 磁碟的運算執行個體,最佳方法取決於您的用途。請使用下列其中一種方式:

  • 如果您已在運算執行個體中啟用正常關機功能,可以略過或結束進行中的正常關機程序,藉此節省費用。如要這麼做,請使用 Cloud de Confiance 控制台、gcloud CLI 或 REST API。

  • 如要保留本機 SSD 資料 (不含使用 Titanium SSD 的機型),請使用 gcloud CLI 或 REST API。

  • 如要同時停止多個運算執行個體,請使用Cloud de Confiance 控制台。如果運算執行個體位於相同可用區,則可使用 gcloud CLI。

如要停止一或多個已連接本機 SSD 磁碟的運算執行個體,請選取下列其中一個選項:

控制台

  1. 前往 Cloud de Confiance 控制台的「VM instances」(VM 執行個體) 頁面。

    前往 VM 執行個體

  2. 選取要停止的執行中運算執行個體。

  3. 按一下「 停止」。如果沒有「Stop」(停止) 選項,請按一下「More actions」(更多動作),然後選取「Stop」(停止)。

  4. 然後在隨即顯示的對話方塊中,執行以下操作:

    1. 選用:如要停止運算執行個體,但不正常關機,或結束進行中的正常關機程序,請勾選「Skip graceful shutdown (if applicable)」(略過正常關機 (如適用)) 核取方塊。

    2. 按一下「停止」確認操作。

gcloud

在同一可用區中,停止一或多個連接本機 SSD 磁碟的運算執行個體時,請按照下列方式指定要捨棄或保留本機 SSD 資料:

  • 如要捨棄本機 SSD 資料,請使用 gcloud compute instances stop 指令並加上 --discard-local-ssd=true 旗標:

    gcloud compute instances stop INSTANCE_NAMES \
        --discard-local-ssd=true \
        --zone=ZONE
    
  • 如要保留本機 SSD 資料,請使用 gcloud beta compute instances stop 指令搭配 --discard-local-ssd=false 旗標:

    gcloud beta compute instances stop INSTANCE_NAMES \
        --discard-local-ssd=false \
        --zone=ZONE
    

更改下列內容:

  • INSTANCE_NAMES:要停止的運算執行個體名稱清單,以空格分隔。例如,指定 instance-01 instance-02 instance-03。

  • ZONE:運算執行個體所在的可用區。

如要略過或結束正在進行的正常關機程序,請在指令中加入 --no-graceful-shutdown 旗標:

gcloud compute instances stop INSTANCE_NAMES \
    --discard-local-ssd=DISCARD_LOCAL_SSD \
    --no-graceful-shutdown \
    --zone=ZONE

將 DISCARD_LOCAL_SSD 替換為 true,即可捨棄本機 SSD 磁碟中的資料;或替換為 false,即可保留資料。如果指定 false,則必須使用 gcloud beta compute instances stop 指令。

REST

在同一可用區中,停止一或多個連接本機 SSD 磁碟的運算執行個體時,請按照下列方式指定要捨棄或保留本機 SSD 資料:

  • 如要捨棄本機 SSD 資料,請向 instances.stop 方法發出 POST 要求。在要求網址中,加入設為 true 的 discardLocalSsd 查詢參數:

    POST https://compute.s3nsapis.fr/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME/stop?discardLocalSsd=true
    
  • 如要保留本機 SSD 資料,請向 beta.instances.stop 方法發出 POST 要求。在要求網址中,加入設為 false 的 discardLocalSsd 查詢參數:

    POST https://compute.s3nsapis.fr/compute/beta/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME/stop?discardLocalSsd=false
    

更改下列內容:

  • PROJECT_ID:運算執行個體所在的專案 ID。

  • ZONE:運算執行個體所在的可用區。

  • INSTANCE_NAME:運算執行個體的名稱。

如要略過或結束進行中的正常關機程序,請在要求網址中加入 noGracefulShutdown=true 查詢參數:

POST https://compute.s3nsapis.fr/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/stop?discardLocalSsd=DISCARD_LOCAL_SSD&noGracefulShutdown=true

將 DISCARD_LOCAL_SSD 替換為 true,即可捨棄本機 SSD 磁碟中的資料;或替換為 false,即可保留資料。如果指定 false,則必須向 beta.instances.stop 方法發出 POST 要求。

從訪客 OS 停止運算執行個體

如果運算執行個體已連接本機 SSD 磁碟,關閉客體 OS 會自動捨棄本機 SSD 資料。如要保留這類資料,請先手動將資料複製到永久儲存空間,再停止運算執行個體。

如要從訪客 OS 停止運算執行個體,請選取下列其中一個選項:

Linux

  1. 如果您尚未連線至運算執行個體,請先完成這項操作。

  2. 如要從運算執行個體的客體 OS 停止執行個體,請選取下列其中一種方法:

    • 如要在所有關機指令碼執行完畢後,才完全關閉客體 OS,請執行下列指令:

      sudo shutdown -h now
      
    • 如要強制關閉客體 OS,請執行下列指令:

      sudo poweroff
      

Windows

  1. 如果尚未連線,請使用下列其中一種方法連線至運算執行個體:

  2. 如要從運算執行個體的客體 OS 停止執行個體,請選取下列其中一種方法:

    • 如要在所有關機指令碼執行完畢後,才完全關閉客體 OS,請執行下列指令:

      shutdown /s
      
    • 如要強制關閉客體 OS,請執行下列指令:

      shutdown /f
      

重新啟動運算執行個體

您可以重新啟動已完全停止的運算執行個體,也就是運算執行個體狀態為 TERMINATED 時。如果您在停止運算執行個體時選擇保留本機 SSD 資料,則可能需要在重新啟動運算執行個體後,重新掛接本機 SSD 磁碟。詳情請參閱「格式化及掛接本機 SSD 裝置」。

如要重新啟動運算執行個體,請使用下列其中一種方法。最適合您用途的方法,取決於運算執行個體的磁碟是否使用客戶提供的加密金鑰 (CSEK) 加密:

重新啟動沒有 CSEK 加密磁碟的運算執行個體

如要同時重新啟動不同可用區的多個運算執行個體,請使用 Cloud de Confiance 控制台。如果運算執行個體位於相同可用區,您可以使用 gcloud CLI。否則,請針對其他重新啟動情境,選取下列其中一個選項:

控制台

  1. 前往 Cloud de Confiance 控制台的「VM instances」(VM 執行個體) 頁面。

    前往 VM 執行個體

  2. 選取要重新啟動的運算執行個體。

  3. 按一下「 啟動 / 重新啟用」。

gcloud

如要重新啟動位於同一可用區的一或多個運算執行個體,請使用 gcloud compute instances start 指令:

gcloud compute instances start INSTANCE_NAMES \
    --zone=ZONE

更改下列內容:

  • INSTANCE_NAMES:要重新啟動的運算執行個體名稱清單,以空格分隔。例如,指定 instance-01 instance-02 instance-03。

  • ZONE:運算執行個體所在的可用區。

Go

import (
	"context"
	"fmt"
	"io"

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

// startInstance starts a stopped Google Compute Engine instance (with unencrypted disks).
func startInstance(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.StartInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
	}

	op, err := instancesClient.Start(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to start 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 started\n")

	return nil
}

Java


import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.Operation.Status;
import com.google.cloud.compute.v1.StartInstanceRequest;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class StartInstance {

  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 start. */
    String project = "your-project-id";
    String zone = "zone-name";
    String instanceName = "instance-name";

    startInstance(project, zone, instanceName);
  }

  // Starts a stopped Google Compute Engine instance (with unencrypted disks).
  public static void startInstance(String project, String zone, String instanceName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    /* Initialize client that will be used to send requests. This client only needs to be created
       once, and can be reused for multiple requests. After completing all of your requests, call
       the `instancesClient.close()` method on the client to safely
       clean up any remaining background resources. */
    try (InstancesClient instancesClient = InstancesClient.create()) {

      // Create the request.
      StartInstanceRequest startInstanceRequest = StartInstanceRequest.newBuilder()
          .setProject(project)
          .setZone(zone)
          .setInstance(instanceName)
          .build();

      OperationFuture<Operation, Operation> operation = instancesClient.startAsync(
          startInstanceRequest);

      // Wait for the operation to complete.
      Operation response = operation.get(3, TimeUnit.MINUTES);

      if (response.getStatus() == Status.DONE) {
        System.out.println("Instance started successfully ! ");
      }
    }
  }
}

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');

async function startInstance() {
  const instancesClient = new compute.InstancesClient();

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

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

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

startInstance();

PHP

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

/**
 * Starts a stopped 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 stop.
  *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 * @throws \Google\ApiCore\ValidationException if local error occurs before remote call.
 */
function start_instance(
    string $projectId,
    string $zone,
    string $instanceName
) {
    // Start the Compute Engine instance using InstancesClient.
    $instancesClient = new InstancesClient();
    $request = (new StartInstanceRequest())
        ->setInstance($instanceName)
        ->setProject($projectId)
        ->setZone($zone);
    $operation = $instancesClient->start($request);

    // Wait for the operation to complete.
    $operation->pollUntilComplete();
    if ($operation->operationSucceeded()) {
        printf('Instance %s started successfully' . PHP_EOL, $instanceName);
    } else {
        $error = $operation->getError();
        printf('Failed to start 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 start_instance(project_id: str, zone: str, instance_name: str) -> None:
    """
    Starts a stopped 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 your want to start.
    """
    instance_client = compute_v1.InstancesClient()

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

    wait_for_extended_operation(operation, "instance start")

REST

如要重新啟動運算執行個體,請向 instances.start 方法發出 POST 要求:

 POST https://compute.s3nsapis.fr/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME/start

更改下列內容:

  • INSTANCE_NAME:運算執行個體的名稱。

  • PROJECT_ID:運算執行個體所在的專案 ID。

  • ZONE:運算執行個體所在的可用區。

重新啟動具有 CSEK 加密磁碟的運算執行個體

如果停止的運算執行個體,其連接的磁碟是以客戶提供的加密金鑰加密,則重新啟動該執行個體時,必須提供加密金鑰資訊。

如要同時重新啟動不同可用區的多個運算執行個體,請使用 Cloud de Confiance 控制台。如果運算執行個體位於相同可用區,您可以使用 gcloud CLI。否則,請針對其他重新啟動情境,選取下列其中一個選項:

控制台

  1. 前往 Cloud de Confiance 控制台的「VM instances」(VM 執行個體) 頁面。

    前往 VM 執行個體

  2. 選取要重新啟動的運算執行個體。

  3. 按一下「 啟動 / 重新啟用」。

  4. 然後在隨即顯示的對話方塊中,執行以下操作:

    1. 為附加至運算執行個體的每個加密磁碟指定加密金鑰。

    2. 按一下「啟動」。

gcloud

如要重新啟動一或多個運算執行個體,且這些執行個體使用位於相同可用區的加密磁碟,請使用 gcloud compute instances start 指令並搭配 --csek-key-file 旗標。如果您使用的是 RSA 包裝金鑰,請改用 gcloud beta compute instances start 指令和 --csek-key-file 旗標:

gcloud compute instances start INSTANCE_NAMES \
    --csek-key-file=ENCRYPTION_KEY_FILE \
    --zone=ZONE

更改下列內容:

  • INSTANCE_NAMES:要重新啟動的運算執行個體名稱清單,以空格分隔。例如,指定 instance-01 instance-02 instance-03。

  • ENCRYPTION_KEY_FILE:JSON 檔案的相對路徑,該檔案包含客戶提供的加密金鑰。只有在運算執行個體使用相同的客戶提供的加密金鑰時,才能同時重新啟動多個運算執行個體。檔案格式請參閱「金鑰檔案格式」。

  • ZONE:運算執行個體所在的可用區。

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
	"google.golang.org/protobuf/proto"
)

// startInstanceWithEncKey starts a stopped Google Compute Engine instance (with encrypted disks).
func startInstanceWithEncKey(w io.Writer, projectID, zone, instanceName, key string) error {
	// projectID := "your_project_id"
	// zone := "europe-central2-b"
	// instanceName := "your_instance_name"
	// key := "your_encryption_key"

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

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

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

	req := &computepb.StartWithEncryptionKeyInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
		InstancesStartWithEncryptionKeyRequestResource: &computepb.InstancesStartWithEncryptionKeyRequest{
			Disks: []*computepb.CustomerEncryptionKeyProtectedDisk{
				{
					Source: proto.String(instance.GetDisks()[0].GetSource()),
					DiskEncryptionKey: &computepb.CustomerEncryptionKey{
						RawKey: proto.String(key),
					},
				},
			},
		},
	}

	op, err := instancesClient.StartWithEncryptionKey(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to start instance with encryption key: %w", err)
	}

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

	fmt.Fprintf(w, "Instance with encryption key started\n")

	return nil
}

Java


import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.compute.v1.CustomerEncryptionKey;
import com.google.cloud.compute.v1.CustomerEncryptionKeyProtectedDisk;
import com.google.cloud.compute.v1.GetInstanceRequest;
import com.google.cloud.compute.v1.Instance;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.InstancesStartWithEncryptionKeyRequest;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.Operation.Status;
import com.google.cloud.compute.v1.StartWithEncryptionKeyInstanceRequest;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class StartEncryptedInstance {

  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 start.
       key: bytes object representing a raw base64 encoded key to your machines boot disk.
            For more information about disk encryption see:
            https://cloud.google.com/compute/docs/disks/customer-supplied-encryption#specifications
     */
    String project = "your-project-id";
    String zone = "zone-name";
    String instanceName = "instance-name";
    String key = "raw-key";

    startEncryptedInstance(project, zone, instanceName, key);
  }

  // Starts a stopped Google Compute Engine instance (with encrypted disks).
  public static void startEncryptedInstance(String project, String zone, String instanceName,
      String key)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    /* Initialize client that will be used to send requests. This client only needs to be created
       once, and can be reused for multiple requests. After completing all of your requests, call
       the `instancesClient.close()` method on the client to safely
       clean up any remaining background resources. */
    try (InstancesClient instancesClient = InstancesClient.create()) {

      GetInstanceRequest getInstanceRequest = GetInstanceRequest.newBuilder()
          .setProject(project)
          .setZone(zone)
          .setInstance(instanceName).build();

      Instance instance = instancesClient.get(getInstanceRequest);

      // Prepare the information about disk encryption.
      CustomerEncryptionKeyProtectedDisk protectedDisk = CustomerEncryptionKeyProtectedDisk
          .newBuilder()
          /* Use raw_key to send over the key to unlock the disk
             To use a key stored in KMS, you need to provide:
             `kms_key_name` and `kms_key_service_account`
           */
          .setDiskEncryptionKey(CustomerEncryptionKey.newBuilder()
              .setRawKey(key).build())
          .setSource(instance.getDisks(0).getSource())
          .build();

      InstancesStartWithEncryptionKeyRequest startWithEncryptionKeyRequest =
          InstancesStartWithEncryptionKeyRequest.newBuilder()
              .addDisks(protectedDisk).build();

      StartWithEncryptionKeyInstanceRequest encryptionKeyInstanceRequest =
          StartWithEncryptionKeyInstanceRequest.newBuilder()
              .setProject(project)
              .setZone(zone)
              .setInstance(instanceName)
              .setInstancesStartWithEncryptionKeyRequestResource(startWithEncryptionKeyRequest)
              .build();

      OperationFuture<Operation, Operation> operation = instancesClient.startWithEncryptionKeyAsync(
          encryptionKeyInstanceRequest);
      Operation response = operation.get(3, TimeUnit.MINUTES);

      if (response.getStatus() == Status.DONE) {
        System.out.println("Encrypted instance started successfully ! ");
      }
    }
  }

}

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 key = 'YOUR_KEY_STRING'

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

async function startInstanceWithEncryptionKey() {
  const instancesClient = new compute.InstancesClient();

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

  const [response] = await instancesClient.startWithEncryptionKey({
    project: projectId,
    zone,
    instance: instanceName,
    instancesStartWithEncryptionKeyRequestResource: {
      disks: [
        {
          source: instance.disks[0].source,
          diskEncryptionKey: {
            rawKey: key,
          },
        },
      ],
    },
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.ZoneOperationsClient();

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

  console.log('Instance with encryption key started.');
}

startInstanceWithEncryptionKey();

PHP

use Google\Cloud\Compute\V1\Client\InstancesClient;
use Google\Cloud\Compute\V1\CustomerEncryptionKey;
use Google\Cloud\Compute\V1\CustomerEncryptionKeyProtectedDisk;
use Google\Cloud\Compute\V1\GetInstanceRequest;
use Google\Cloud\Compute\V1\InstancesStartWithEncryptionKeyRequest;
use Google\Cloud\Compute\V1\StartWithEncryptionKeyInstanceRequest;

/**
 * Starts a stopped Google Compute Engine instance (with encrypted 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 stop.
 * @param string $key Bytes object representing a raw base64 encoded key to your instance's boot disk.
 *                    For more information about disk encryption see:
 *                    https://cloud.google.com/compute/docs/disks/customer-supplied-encryption#specifications
 *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 * @throws \Google\ApiCore\ValidationException if local error occurs before remote call.
 */
function start_instance_with_encryption_key(
    string $projectId,
    string $zone,
    string $instanceName,
    string $key
) {
    // Initiate the InstancesClient.
    $instancesClient = new InstancesClient();

    // Get data about the instance.
    $request = (new GetInstanceRequest())
        ->setInstance($instanceName)
        ->setProject($projectId)
        ->setZone($zone);
    $instanceData = $instancesClient->get($request);

    // Use `setRawKey` to send over the key to unlock the disk
    // To use a key stored in KMS, you need to use `setKmsKeyName` and `setKmsKeyServiceAccount`
    $customerEncryptionKey = (new CustomerEncryptionKey())
        ->setRawKey($key);

    /** @var \Google\Cloud\Compute\V1\AttachedDisk */
    $disk = $instanceData->getDisks()[0];

    // Prepare the information about disk encryption.
    $diskData = (new CustomerEncryptionKeyProtectedDisk())
        ->setSource($disk->getSource())
        ->setDiskEncryptionKey($customerEncryptionKey);

    // Set request with one disk.
    $instancesStartWithEncryptionKeyRequest = (new InstancesStartWithEncryptionKeyRequest())
        ->setDisks(array($diskData));

    // Start the instance with encrypted disk.
    $request2 = (new StartWithEncryptionKeyInstanceRequest())
        ->setInstance($instanceName)
        ->setInstancesStartWithEncryptionKeyRequestResource($instancesStartWithEncryptionKeyRequest)
        ->setProject($projectId)
        ->setZone($zone);
    $operation = $instancesClient->startWithEncryptionKey($request2);

    // Wait for the operation to complete.
    $operation->pollUntilComplete();
    if ($operation->operationSucceeded()) {
        printf('Instance %s started successfully' . PHP_EOL, $instanceName);
    } else {
        $error = $operation->getError();
        printf('Starting instance failed: %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 start_instance_with_encryption_key(
    project_id: str, zone: str, instance_name: str, key: bytes
) -> None:
    """
    Starts a stopped Google Compute Engine instance (with encrypted 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 your want to start.
        key: bytes object representing a raw base64 encoded key to your machines boot disk.
            For more information about disk encryption see:
            https://cloud.google.com/compute/docs/disks/customer-supplied-encryption#specifications
    """
    instance_client = compute_v1.InstancesClient()

    instance_data = instance_client.get(
        project=project_id, zone=zone, instance=instance_name
    )

    # Prepare the information about disk encryption
    disk_data = compute_v1.CustomerEncryptionKeyProtectedDisk()
    disk_data.source = instance_data.disks[0].source
    disk_data.disk_encryption_key = compute_v1.CustomerEncryptionKey()
    # Use raw_key to send over the key to unlock the disk
    # To use a key stored in KMS, you need to provide `kms_key_name` and `kms_key_service_account`
    disk_data.disk_encryption_key.raw_key = key
    enc_data = compute_v1.InstancesStartWithEncryptionKeyRequest()
    enc_data.disks = [disk_data]

    operation = instance_client.start_with_encryption_key(
        project=project_id,
        zone=zone,
        instance=instance_name,
        instances_start_with_encryption_key_request_resource=enc_data,
    )

    wait_for_extended_operation(operation, "instance start (with encrypted disk)")

REST

如要重新啟動使用加密磁碟的運算執行個體,請向 instances.startWithEncryptionKey 方法提出 POST 要求:

POST  https://compute.s3nsapis.fr/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME/startWithEncryptionKey

{
  "disks": [
    {
      "source": "DISK_URL",
      "diskEncryptionKey": {
        "ENCRYPTION_TYPE": "ENCRYPTION_KEY"
      }
    }
  ]
}

更改下列內容:

  • PROJECT_ID:運算執行個體所在的專案 ID。

  • ZONE:運算執行個體所在的可用區。

  • INSTANCE_NAME:運算執行個體的名稱。

  • DISK_URL:資源網址,對應至以客戶提供的加密金鑰加密的附加磁碟完整資源名稱。

  • ENCRYPTION_TYPE:您使用的磁碟加密類型,可以是下列其中一項:rawKey、kmsKeyName 或 rsaEncryptedKey。如果使用 rsaEncryptedKey 類型,請向 beta.instances.startWithEncryptionKey 方法發出 POST 要求。

  • ENCRYPTION_KEY:用於加密附加至運算執行個體的永久磁碟的加密金鑰。rawKey 或 rsaEncryptedKey 金鑰必須採用 Base64 編碼。此外,如要準備 rsaEncryptedKey 金鑰,請參閱「RSA 金鑰封裝」。

後續步驟