刪除 Compute Engine 執行個體


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

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

事前準備

必要的角色

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

這個預先定義的角色包含刪除運算單元的必要權限。如要查看確切的必要權限,請展開「必要權限」部分:

所需權限

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

  • compute.instances.delete
  • 如要強制刪除已連接的磁碟,請執行下列操作: compute.disks.delete on the disk

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

帳單相關注意事項

刪除運算執行個體後,您就不會再為該執行個體及其連結資源付費,除非發生下列任一情況:

  • 如果您刪除託管在單一用戶群節點上的執行個體,則您會繼續為單一用戶群節點付費,而非該節點上託管的個別執行個體。

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

  • 如果您保留附加至執行個體的任何資源,則會持續產生這些資源的費用,直到您刪除為止。舉例來說,如果您刪除執行個體,但保留連結至該執行個體的磁碟,則仍會產生磁碟費用。

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

保留已附加的資源

在某些情況下,您可能會在刪除運算執行個體之前,先保留其中一個附加資源。您可以執行下列操作來保留已附加的資源:

刪除執行個體

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

如果同時刪除一或多個執行個體,您必須決定要如何處理已連結的磁碟:

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

視您在刪除運算單元時要執行的操作而定,請使用下列選項:

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

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

  • 如要同時刪除多個執行個體,請使用 Google Cloud 控制台,如果是位於同一區的執行個體,則請使用 gcloud 指令列。

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

主控台

  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

  • 如果您已在一個或多個執行個體中啟用正常關機功能,則可刪除執行個體,而無需正常關機,或手動結束正在進行的正常關機程序。如要執行這項操作,請使用 gcloud beta compute instances delete 指令,並加上 --no-graceful-shutdown 旗標:

    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 = compute_v1.InstancesClient()

    print(f"Deleting {machine_name} from {zone}...")
    operation = instance_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:執行個體所在的區域。

您也可以選擇在一個或多個執行個體中啟用優雅關機功能,這樣一來,您就可以刪除執行個體,而不需要優雅關機,也可以手動結束正在進行的優雅關機程序。如要執行這項操作,請使用 gcloud beta compute instances delete 指令,並加上 --no-graceful-shutdown 旗標:

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

後續步驟