刪除 Compute Engine 執行個體


本文說明如何刪除 Compute Engine 執行個體。如要進一步瞭解執行個體的生命週期,請參閱 Compute Engine 執行個體生命週期

如果不再需要執行個體,請將其刪除,以免持續產生執行個體和附加資源的費用。

事前準備

必要的角色

如要取得刪除 Compute 執行個體所需的權限,請要求管理員授予您專案的 Compute 執行個體管理員 (v1) (roles/compute.instanceAdmin.v1) IAM 角色。如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」。

這個預先定義的角色具備刪除運算執行個體所需的權限。如要查看確切的必要權限,請展開「必要權限」部分:

所需權限

如要刪除 Compute 執行個體,您必須具備下列權限:

  • compute.instances.delete 執行個體
  • 如要強制刪除已連結的磁碟: compute.disks.delete 磁碟

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

帳單相關注意事項

刪除運算執行個體後,系統會停止收取該執行個體和所連資源的費用,但下列情況除外:

  • 如果您刪除託管在單一用戶群節點上的執行個體,系統仍會向您收取單一用戶群節點的費用。

  • 如果您刪除正在使用預留項目的執行個體,則在發生下列任一情況前,您仍須支付預留資源的費用:

    • Compute Engine 會在您選擇的日期和時間自動刪除預留項目。

    • 你刪除預訂。

    • 減少預留項目中的預留執行個體數量。

  • 如果您有承諾使用折扣,無論是否使用承諾的資源,都必須繼續支付相關費用。

  • 如果您保留附加至執行個體的任何資源 (例如磁碟),則必須繼續支付這些資源的費用,直到刪除資源為止。

詳情請參閱「VM 執行個體定價」。

保留附加資源

在某些情況下,您可能想在刪除運算執行個體前,保留其中一個附加資源。如要保留附加資源,請按照下列步驟操作:

刪除執行個體

刪除運算執行個體時,Compute Engine 會先停止執行個體,再刪除執行個體。

如果同時刪除一或多個執行個體,則必須決定附加磁碟的處理方式:

刪除執行個體和所有附加資源

視刪除運算執行個體時要執行的動作而定,請使用下列選項:

  • 如果您已設定在刪除執行個體時保留附加磁碟,則可以使用 Google Cloud CLI 覆寫這項設定,並強制刪除磁碟。

  • 如果您已在執行個體中啟用正常關機,則可以使用 Google Cloud 主控台、gcloud CLI 或 REST API 刪除執行個體,不必正常關機或結束進行中的正常關機程序。

  • 如要同時刪除多個執行個體,請使用 Google Cloud 控制台,或針對位於相同區域的執行個體使用 gcloud CLI。

如要刪除一或多個執行個體和所有附加資源,請選取下列其中一個選項:

主控台

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

    前往 VM 執行個體

  2. 選取要刪除的執行個體。

  3. 按一下「刪除」圖示

  4. 在對話方塊中執行下列操作:

    1. 選用:如要刪除執行個體而不正常關閉,或結束進行中的正常關閉程序,請選取「Skip graceful shutdown (if applicable)」(略過正常關閉程序 (如適用)) 核取方塊。

    2. 按一下「Delete」(刪除) 確認操作。

gcloud

如要刪除同一區域中的一或多個執行個體,請使用 gcloud compute instances delete 指令

gcloud compute instances delete INSTANCE_NAMES \
    --zone=ZONE

更改下列內容:

  • INSTANCE_NAMES:以空格分隔的執行個體名稱清單,例如 instance-01 instance-02 instance-03

  • ZONE:執行個體所在的區域。

您也可以視需要執行下列任一操作或同時完成兩者:

  • 如要強制刪除連結至一或多個執行個體的磁碟,請加入 --delete-disks 標記:

    gcloud compute instances delete INSTANCE_NAMES \
        --delete-disks=DELETE_DISK_TYPE \
        --zone=ZONE
    

    DELETE_DISK_TYPE 替換為下列其中一個值:

    • 如要刪除附加的開機和非開機永久儲存空間,請按照下列步驟操作:all

    • 如要只刪除附加的開機永久儲存空間,請執行以下操作:boot

    • 如要只刪除非開機永久儲存空間,請執行以下步驟:data

  • 如果您在一或多個執行個體中啟用安全關機,則可以刪除執行個體,不必安全關機,也可以手動結束進行中的安全關機程序。做法是使用加上 --no-graceful-shutdown 旗標的 gcloud beta compute instances delete 指令

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

C#


using Google.Cloud.Compute.V1;
using System.Threading.Tasks;

public class DeleteInstanceAsyncSample
{
    public async Task DeleteInstanceAsync(
        // TODO(developer): Set your own default values for these parameters or pass different values when calling this method.
        string projectId = "your-project-id",
        string zone = "us-central1-a",
        string machineName = "test-machine")
    {

        // Initialize client that will be used to send requests. This client only needs to be created
        // once, and can be reused for multiple requests.
        InstancesClient client = await InstancesClient.CreateAsync();

        // Make the request to delete a VM instance.
        var instanceDeletion = await client.DeleteAsync(projectId, zone, machineName);

        // Wait for the operation to complete using client-side polling.
        await instanceDeletion.PollUntilCompletedAsync();
    }
}

Go

import (
	"context"
	"fmt"
	"io"

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

// deleteInstance sends a delete request to the Compute Engine API and waits for it to complete.
func deleteInstance(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.DeleteInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
	}

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

	return nil
}

Java


import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.compute.v1.DeleteInstanceRequest;
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 DeleteInstance {

  public static void main(String[] args)
      throws IOException, InterruptedException, ExecutionException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    String project = "your-project-id";
    String zone = "zone-name";
    String instanceName = "instance-name";
    deleteInstance(project, zone, instanceName);
  }

  // Delete the instance specified by `instanceName`
  // if it's present in the given project and zone.
  public static void deleteInstance(String project, String zone, String instanceName)
      throws IOException, InterruptedException, ExecutionException, 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()) {

      System.out.printf("Deleting instance: %s ", instanceName);

      // Describe which instance is to be deleted.
      DeleteInstanceRequest deleteInstanceRequest = DeleteInstanceRequest.newBuilder()
          .setProject(project)
          .setZone(zone)
          .setInstance(instanceName).build();

      OperationFuture<Operation, Operation> operation = instancesClient.deleteAsync(
          deleteInstanceRequest);
      // Wait for the operation to complete.
      Operation response = operation.get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        System.out.println("Instance deletion failed ! ! " + response);
        return;
      }
      System.out.println("Operation Status: " + response.getStatus());
    }
  }
}

Node.js

/**
 * TODO(developer): Uncomment 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');

// Delete the instance specified by `instanceName` if it's present in the given project and zone.
async function deleteInstance() {
  const instancesClient = new compute.InstancesClient();

  console.log(`Deleting ${instanceName} from ${zone}...`);

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

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

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

deleteInstance();

PHP

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

/**
 * Delete an instance.
 *
 * @param string $projectId Your Google Cloud project ID.
 * @param string $zone Zone where the instance you want to delete is (like "us-central1-a").
 * @param string $instanceName Unique name for the Compute instance to delete.
 *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 * @throws \Google\ApiCore\ValidationException if local error occurs before remote call.
 */
function delete_instance(
    string $projectId,
    string $zone,
    string $instanceName
) {
    // Delete the Compute Engine instance using InstancesClient.
    $instancesClient = new InstancesClient();
    $request = (new DeleteInstanceRequest())
        ->setInstance($instanceName)
        ->setProject($projectId)
        ->setZone($zone);
    $operation = $instancesClient->delete($request);

    // Wait for the operation to complete.
    $operation->pollUntilComplete();
    if ($operation->operationSucceeded()) {
        printf('Deleted instance %s' . PHP_EOL, $instanceName);
    } else {
        $error = $operation->getError();
        printf('Failed to delete 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 delete_instance(project_id: str, zone: str, machine_name: str) -> None:
    """
    Send an instance deletion request to the Compute Engine API and wait for it to complete.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone you want to use. For example: “us-west3-b”
        machine_name: name of the machine you want to delete.
    """
    instance_client = compcompute_v1tInstancesClient    print(f"Deleting {machine_name} from {zone}...")
    operation = instinstance_client.delete      project=project_id, zone=zone, instance=machine_name
    )
    wait_for_extended_operation(operation, "instance deletion")
    print(f"Instance {machine_name} deleted.")

Ruby


require "google/cloud/compute/v1"

# Sends an instance deletion request to the Compute Engine API and waits for it to complete.
#
# @param [String] project project ID or project number of the Cloud project you want to use.
# @param [String] zone name of the zone you want to use. For example: "us-west3-b"
# @param [String] instance_name name of the instance you want to delete.
def delete_instance project:, zone:, instance_name:
  # Initialize client that will be used to send requests. This client only needs to be created
  # once, and can be reused for multiple requests.
  client = ::Google::Cloud::Compute::V1::Instances::Rest::Client.new

  puts "Deleting #{instance_name} from #{zone}..."
  begin
    # Make the request to delete a VM instance.
    operation = client.delete project: project, zone: zone, instance: instance_name
    # Wait for the delete operation to complete.
    operation = wait_until_done operation: operation

    if operation.error?
      warn "Error during deletion:", operation.error
    else
      compute_operation = operation.operation
      warn "Warning during creation:", compute_operation.warnings unless compute_operation.warnings.empty?
      puts "Instance #{instance_name} deleted."
    end
  rescue ::Google::Cloud::Error => e
    warn "Exception during deletion:", e
  end
end

REST

如要刪除執行個體,請對 instances delete 方法發出 DELETE 要求:

DELETE https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME

更改下列內容:

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

  • ZONE:執行個體的區域。

  • INSTANCE_NAME:執行個體名稱。

如果已在執行個體中啟用安全關機功能,您可以選擇刪除執行個體,不必安全關機,也可以手動結束進行中的安全關機程序。如要這麼做,請對 beta instances.delete 方法發出 DELETE 要求。在要求網址中,加入設為 truenoGracefulShutdown 查詢參數:

DELETE https://compute.googleapis.com/compute/beta/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME?noGracefulShutdown=true

刪除執行個體並保留磁碟

根據預設,刪除運算執行個體會一併刪除該執行個體及其連結的資源。不過,使用 gcloud CLI 刪除執行個體時,您可以指定保留附加磁碟,無論磁碟的自動刪除設定為何。

如要刪除同一區域中的一或多個執行個體,同時保留其連結的磁碟,請使用 gcloud compute instances delete 指令並加上 --keep-disks 旗標:

gcloud compute instances delete INSTANCE_NAMES \
    --keep-disks=KEEP_DISK_TYPE \
    --zone=ZONE

更改下列內容:

  • INSTANCE_NAMES:以空格分隔的執行個體名稱清單,例如 instance-01 instance-02 instance-03

  • KEEP_DISK_TYPE:指定下列其中一個值:

    • 如要保留已連結的開機和非開機永久儲存空間,請按照下列步驟操作:all

    • 如要只保留附加的開機永久儲存空間,請按照下列步驟操作:boot

    • 如要只保留已連結的非開機永久儲存空間,請按照下列步驟操作:data

  • ZONE:執行個體所在的區域。

(選用) 如果您在一或多個執行個體中啟用正常關機,可以刪除執行個體,不必正常關機,也可以手動結束進行中的正常關機程序。做法是使用加上 --no-graceful-shutdown 旗標的 gcloud beta compute instances delete 指令

gcloud beta compute instances delete VM_NAMES \
    --keep-disks=KEEP_DISK_TYPE \
    --no-graceful-shutdown \
    --zone=ZONE

後續步驟