刪除 Compute Engine 執行個體

本文說明如何永久刪除 Compute Engine 執行個體。

如果不再需要運算執行個體,請將其刪除,以免產生運算執行個體和附加資源的費用。刪除的運算執行個體無法復原。如要進一步瞭解運算執行個體從建立到刪除的狀態,請參閱「Compute Engine 執行個體生命週期」。

刪除執行個體對帳單費用的影響

刪除運算執行個體後,您就不會再產生該執行個體和其附加資源的費用,但下列情況除外:

  • 如果刪除託管於單一租戶節點的運算執行個體,仍須支付單一租戶節點的費用。

  • 如果刪除使用預留項目建立的運算執行個體,您仍須支付預留資源的費用,直到發生下列任一情況:

    • 您刪除預留項目,或 Compute Engine 執行自動作業時刪除。

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

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

  • 如果保留任何附加至運算執行個體的資源 (例如磁碟或外部 IP 位址),則須持續支付這些資源的費用,直到刪除為止。

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

事前準備

保留附加資源

如要在刪除運算執行個體前,保留附加至該執行個體的資源,可以採取下列一或多項做法:

必要的角色

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

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

所需權限

必須具備下列權限,才能刪除運算執行個體:

  • compute.instances.delete 在運算執行個體上
  • 如要強制刪除已連接的磁碟,請在磁碟上執行 compute.disks.delete

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

刪除運算執行個體

刪除運算執行個體時,Compute Engine 會先停止運算執行個體,然後再刪除。如果同時刪除一或多個運算執行個體,則必須決定如何處理附加的磁碟:

  • 刪除磁碟:您可以刪除開機磁碟、非開機磁碟,或所有附加至運算執行個體的磁碟。如果您將磁碟設為在刪除時保留,可以選擇覆寫這項設定,強制刪除磁碟。

    如需操作說明,請參閱「刪除運算執行個體和所有附加資源」。

  • 保留磁碟:您可以保留開機磁碟、非開機磁碟,或所有附加至運算執行個體的磁碟。

    如需操作說明,請參閱「刪除運算執行個體並保留磁碟」。

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

如要在特定情境下刪除運算執行個體 (例如強制刪除附加磁碟、略過或結束正常關機,或同時刪除多個執行個體),請使用適當的方法:

  • 強制刪除磁碟:如果您已設定在 Compute Engine 刪除運算執行個體時保留連接的磁碟,則可使用 Google Cloud CLI 覆寫這項設定,並強制刪除磁碟。

  • 略過或結束正常關機:如果您已在運算執行個體中啟用正常關機功能,則可使用Cloud de Confiance 控制台、gcloud CLI 或 REST API 刪除運算執行個體,而不必正常關機,或結束進行中的正常關機程序。

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

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

控制台

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

    前往 VM 執行個體

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

  3. 按一下「刪除」圖示 。如果沒有「Delete」(刪除) 選項,請按一下「More actions」(更多動作),然後選取「Delete」(刪除)。

  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 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

    compute_operation = operation.operation
    if operation.error?
      warn "Error during deletion:", compute_operation.error.errors.map { |e| "#{e.code}: #{e.message}" }
    else
      warn "Warning during deletion:", 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.s3nsapis.fr/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME

更改下列內容:

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

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

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

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

DELETE https://compute.s3nsapis.fr/compute/v1/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 compute instances delete VM_NAMES \
    --keep-disks=KEEP_DISK_TYPE \
    --no-graceful-shutdown \
    --zone=ZONE

後續步驟