防止意外删除虚拟机


本文档介绍如何通过在 Instance 资源上设置 deletionProtection 属性来保护特定虚拟机实例免遭删除。要详细了解虚拟机实例,请参阅实例文档。

作为工作负载的一部分,可能存在某些对于运行应用或服务至关重要的虚拟机实例,例如运行 SQL Server 的实例、用作许可证管理器的服务器等。这些虚拟机实例可能需要无限期地保持运行,因此需要一种方法来保护这些虚拟机免遭删除。

通过设置 deletionProtection 标志,可以防止意外删除虚拟机实例。如果用户尝试删除您已为其设置 deletionProtection 标志的虚拟机实例,则请求会失败。只有已被授予具有 compute.instances.create 权限的角色的用户才能重置该标志以允许删除资源。

准备工作

  • 参阅实例文档。
  • 如果您尚未设置身份验证,请进行设置。身份验证是通过其进行身份验证以访问 Google Cloud 服务和 API 的过程。如需从本地开发环境运行代码或示例,您可以通过选择以下选项之一向 Compute Engine 进行身份验证:

    规格

    • 删除保护不会阻止以下操作:

    • 删除保护可以应用于常规虚拟机和抢占式虚拟机。

    • 删除保护不能应用于属于托管实例组的虚拟机,但可以应用于属于非托管实例组的实例。

    • 不能在实例模板中指定删除保护。

    权限

    要执行此任务,您必须已被授予资源的以下权限以下某个 IAM 角色

    权限

    • compute.instances.create

    角色

    • compute.admin
    • compute.instanceAdmin.v1

    在实例创建期间设置删除保护

    默认情况下,实例会停用删除保护。可使用以下说明启用删除保护。

    控制台

    1. 在 Google Cloud 控制台中,前往创建实例页面。

      转到“创建实例”

    2. 展开高级选项部分,然后执行以下操作:

      1. 展开管理部分。
      2. 选中启用删除防护复选框。
    3. 继续虚拟机创建过程。

    gcloud

    创建虚拟机实例时,请添加 --deletion-protectionno-deletion-protection 标志。默认情况下,删除保护处于停用状态,因此,要启用删除保护,请执行以下命令:

    gcloud compute instances create [INSTANCE_NAME] --deletion-protection
    

    其中 [INSTANCE_NAME] 是所需实例的名称。

    如需在创建期间停用删除保护,请运行以下命令:

    gcloud compute instances create [INSTANCE_NAME] --no-deletion-protection
    

    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"
    )
    
    // createInstance sends an instance creation request to the Compute Engine API
    // and waits for it to complete.
    func createInstance(w io.Writer, projectID, zone, instanceName string, deleteProtection bool) error {
    	// projectID := "your_project_id"
    	// zone := "europe-central2-b"
    	// instanceName := "your_instance_name"
    	// deleteProtection := true
    
    	ctx := context.Background()
    	instancesClient, err := compute.NewInstancesRESTClient(ctx)
    	if err != nil {
    		return fmt.Errorf("NewInstancesRESTClient: %w", err)
    	}
    	defer instancesClient.Close()
    
    	req := &computepb.InsertInstanceRequest{
    		Project: projectID,
    		Zone:    zone,
    		InstanceResource: &computepb.Instance{
    			Name: proto.String(instanceName),
    			// Set the delete protection bit.
    			DeletionProtection: proto.Bool(deleteProtection),
    			Disks: []*computepb.AttachedDisk{
    				{
    					// Describe the size and source image of the boot disk to attach to the instance.
    					InitializeParams: &computepb.AttachedDiskInitializeParams{
    						DiskSizeGb:  proto.Int64(10),
    						SourceImage: proto.String("projects/debian-cloud/global/images/family/debian-12"),
    					},
    					AutoDelete: proto.Bool(true),
    					Boot:       proto.Bool(true),
    					Type:       proto.String(computepb.AttachedDisk_PERSISTENT.String()),
    				},
    			},
    			MachineType: proto.String(fmt.Sprintf("zones/%s/machineTypes/e2-small", zone)),
    			NetworkInterfaces: []*computepb.NetworkInterface{
    				{
    					// Use the default VPC network.
    					Name: proto.String("default"),
    				},
    			},
    		},
    	}
    
    	op, err := instancesClient.Insert(ctx, req)
    	if err != nil {
    		return fmt.Errorf("unable to create 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 created\n")
    
    	return nil
    }
    

    Java

    
    import com.google.cloud.compute.v1.AttachedDisk;
    import com.google.cloud.compute.v1.AttachedDiskInitializeParams;
    import com.google.cloud.compute.v1.InsertInstanceRequest;
    import com.google.cloud.compute.v1.Instance;
    import com.google.cloud.compute.v1.InstancesClient;
    import com.google.cloud.compute.v1.NetworkInterface;
    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 CreateInstanceDeleteProtection {
    
      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 you want to use.
        // zone: name of the zone you want to use. For example: “us-west3-b”
        // instanceName: name of the new virtual machine.
        // deleteProtection: boolean value indicating if the new virtual machine should be
        // protected against deletion or not.
        String projectId = "your-project-id-or-number";
        String zone = "zone-name";
        String instanceName = "instance-name";
        boolean deleteProtection = true;
        createInstanceDeleteProtection(projectId, zone, instanceName, deleteProtection);
      }
    
      // Send an instance creation request to the Compute Engine API and wait for it to complete.
      public static void createInstanceDeleteProtection(String projectId, String zone,
          String instanceName, boolean deleteProtection)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
    
        String machineType = String.format("zones/%s/machineTypes/e2-small", zone);
        String sourceImage = String
            .format("projects/debian-cloud/global/images/family/%s", "debian-11");
        long diskSizeGb = 10L;
        String networkName = "default";
    
        // Instance creation requires at least one persistent disk and one network interface.
        try (InstInstancesClienttancesClient = InstInstancesClientate()) {
    
          AttaAttachedDiskk =
              AttaAttachedDiskBuilder()
                  .setBoot(true)
                  .setAutoDelete(true)
                  .setType(AttaAttachedDiske.PERSISTENT.toString())
                  .setIsetInitializeParams                // Describe the size and source image of the boot disk to attach to the instance.
                      AttaAttachedDiskInitializeParamsBuilder()
                          .setSourceImage(sourceImage)
                          .setDiskSizeGb(diskSizeGb)
                          .build())
                  .build();
    
          // Use the default VPC network.
          NetwNetworkInterfaceworkInterface = NetwNetworkInterfaceBuilder()
              .setName(networkName)
              .build();
    
          // Collect information into the Instance object.
          InstInstancetanceResource =
              InstInstanceBuilder()
                  .setName(instanceName)
                  .setMachineType(machineType)
                  .addDisks(disk)
                  .addNetworkInterfaces(networkInterface)
                  // Set the "Delete protection" bit.
                  .setDeletionProtection(deleteProtection)
                  .build();
    
          System.out.printf("Creating instance: %s at %s %n", instanceName, zone);
    
          // Prepare the request to insert an instance.
          InseInsertInstanceRequestertInstanceRequest = InseInsertInstanceRequestBuilder()
              .setProject(projectId)
              .setZone(zone)
              .setInstanceResource(instanceResource)
              .build();
    
          // Wait for the create operation to complete.
          OperOperationponse = instancesClient.insertAsync(insertInstanceRequest)
              .get(3, TimeUnit.MINUTES);
          ;
    
          if (respresponse.hasError()        System.out.println("Instance creation failed ! ! " + response);
            return;
          }
          System.out.printf("Instance created : %s", instanceName);
          System.out.println("Operation Status: " + respresponse.getStatus()   }
      }
    }

    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 deleteProtection = true;
    
    const compute = require('@google-cloud/compute');
    
    // Send an instance creation request to the Compute Engine API and wait for it to complete.
    async function createInstance() {
      const instancesClient = new compute.InstancesClient();
    
      const [response] = await instancesClient.insert({
        project: projectId,
        zone,
        instanceResource: {
          name: instanceName,
          // Set the delete protection bit.
          deletionProtection: deleteProtection,
          disks: [
            {
              // Describe the size and source image of the boot disk to attach to the instance.
              initializeParams: {
                diskSizeGb: '10',
                sourceImage:
                  'projects/debian-cloud/global/images/family/debian-11',
              },
              autoDelete: true,
              boot: true,
              type: 'PERSISTENT',
            },
          ],
          machineType: `zones/${zone}/machineTypes/e2-small`,
          networkInterfaces: [
            {
              // Use the default VPC network.
              name: 'default',
            },
          ],
        },
      });
      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 created.');
    }
    
    createInstance();

    Python

    from __future__ import annotations
    
    import re
    import sys
    from typing import Any
    import warnings
    
    from google.api_core.extended_operation import ExtendedOperation
    from google.cloud import compute_v1
    
    
    def get_image_from_family(project: str, family: str) -> compute_v1.Image:
        """
        Retrieve the newest image that is part of a given family in a project.
    
        Args:
            project: project ID or project number of the Cloud project you want to get image from.
            family: name of the image family you want to get image from.
    
        Returns:
            An Image object.
        """
        image_client = compute_v1.ImagesClient()
        # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
        newest_image = image_client.get_from_family(project=project, family=family)
        return newest_image
    
    
    def disk_from_image(
        disk_type: str,
        disk_size_gb: int,
        boot: bool,
        source_image: str,
        auto_delete: bool = True,
    ) -> compute_v1.AttachedDisk:
        """
        Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
        source for the new disk.
    
        Args:
             disk_type: the type of disk you want to create. This value uses the following format:
                "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
                For example: "zones/us-west3-b/diskTypes/pd-ssd"
            disk_size_gb: size of the new disk in gigabytes
            boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
            source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
                of the publicly available images or an image from one of your projects.
                This value uses the following format: "projects/{project_name}/global/images/{image_name}"
            auto_delete: boolean flag indicating whether this disk should be deleted with the VM that uses it
    
        Returns:
            AttachedDisk object configured to be created using the specified image.
        """
        boot_disk = compute_v1.AttachedDisk()
        initialize_params = compute_v1.AttachedDiskInitializeParams()
        initialize_params.source_image = source_image
        initialize_params.disk_size_gb = disk_size_gb
        initialize_params.disk_type = disk_type
        boot_disk.initialize_params = initialize_params
        # Remember to set auto_delete to True if you want the disk to be deleted when you delete
        # your VM instance.
        boot_disk.auto_delete = auto_delete
        boot_disk.boot = boot
        return boot_disk
    
    
    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 create_instance(
        project_id: str,
        zone: str,
        instance_name: str,
        disks: list[compute_v1.AttachedDisk],
        machine_type: str = "n1-standard-1",
        network_link: str = "global/networks/default",
        subnetwork_link: str = None,
        internal_ip: str = None,
        external_access: bool = False,
        external_ipv4: str = None,
        accelerators: list[compute_v1.AcceleratorConfig] = None,
        preemptible: bool = False,
        spot: bool = False,
        instance_termination_action: str = "STOP",
        custom_hostname: str = None,
        delete_protection: bool = False,
    ) -> compute_v1.Instance:
        """
        Send an instance creation 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 to create the instance in. For example: "us-west3-b"
            instance_name: name of the new virtual machine (VM) instance.
            disks: a list of compute_v1.AttachedDisk objects describing the disks
                you want to attach to your new instance.
            machine_type: machine type of the VM being created. This value uses the
                following format: "zones/{zone}/machineTypes/{type_name}".
                For example: "zones/europe-west3-c/machineTypes/f1-micro"
            network_link: name of the network you want the new instance to use.
                For example: "global/networks/default" represents the network
                named "default", which is created automatically for each project.
            subnetwork_link: name of the subnetwork you want the new instance to use.
                This value uses the following format:
                "regions/{region}/subnetworks/{subnetwork_name}"
            internal_ip: internal IP address you want to assign to the new instance.
                By default, a free address from the pool of available internal IP addresses of
                used subnet will be used.
            external_access: boolean flag indicating if the instance should have an external IPv4
                address assigned.
            external_ipv4: external IPv4 address to be assigned to this instance. If you specify
                an external IP address, it must live in the same region as the zone of the instance.
                This setting requires `external_access` to be set to True to work.
            accelerators: a list of AcceleratorConfig objects describing the accelerators that will
                be attached to the new instance.
            preemptible: boolean value indicating if the new instance should be preemptible
                or not. Preemptible VMs have been deprecated and you should now use Spot VMs.
            spot: boolean value indicating if the new instance should be a Spot VM or not.
            instance_termination_action: What action should be taken once a Spot VM is terminated.
                Possible values: "STOP", "DELETE"
            custom_hostname: Custom hostname of the new VM instance.
                Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
            delete_protection: boolean value indicating if the new virtual machine should be
                protected against deletion or not.
        Returns:
            Instance object.
        """
        instance_client = compute_v1.InstancesClient()
    
        # Use the network interface provided in the network_link argument.
        network_interface = compute_v1.NetworkInterface()
        network_interface.network = network_link
        if subnetwork_link:
            network_interface.subnetwork = subnetwork_link
    
        if internal_ip:
            network_interface.network_i_p = internal_ip
    
        if external_access:
            access = compute_v1.AccessConfig()
            access.type_ = compute_v1.AccessConfig.Type.ONE_TO_ONE_NAT.name
            access.name = "External NAT"
            access.network_tier = access.NetworkTier.PREMIUM.name
            if external_ipv4:
                access.nat_i_p = external_ipv4
            network_interface.access_configs = [access]
    
        # Collect information into the Instance object.
        instance = compute_v1.Instance()
        instance.network_interfaces = [network_interface]
        instance.name = instance_name
        instance.disks = disks
        if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
            instance.machine_type = machine_type
        else:
            instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
    
        instance.scheduling = compute_v1.Scheduling()
        if accelerators:
            instance.guest_accelerators = accelerators
            instance.scheduling.on_host_maintenance = (
                compute_v1.Scheduling.OnHostMaintenance.TERMINATE.name
            )
    
        if preemptible:
            # Set the preemptible setting
            warnings.warn(
                "Preemptible VMs are being replaced by Spot VMs.", DeprecationWarning
            )
            instance.scheduling = compute_v1.Scheduling()
            instance.scheduling.preemptible = True
    
        if spot:
            # Set the Spot VM setting
            instance.scheduling.provisioning_model = (
                compute_v1.Scheduling.ProvisioningModel.SPOT.name
            )
            instance.scheduling.instance_termination_action = instance_termination_action
    
        if custom_hostname is not None:
            # Set the custom hostname for the instance
            instance.hostname = custom_hostname
    
        if delete_protection:
            # Set the delete protection bit
            instance.deletion_protection = True
    
        # Prepare the request to insert an instance.
        request = compute_v1.InsertInstanceRequest()
        request.zone = zone
        request.project = project_id
        request.instance_resource = instance
    
        # Wait for the create operation to complete.
        print(f"Creating the {instance_name} instance in {zone}...")
    
        operation = instance_client.insert(request=request)
    
        wait_for_extended_operation(operation, "instance creation")
    
        print(f"Instance {instance_name} created.")
        return instance_client.get(project=project_id, zone=zone, instance=instance_name)
    
    
    def create_protected_instance(
        project_id: str, zone: str, instance_name: str
    ) -> compute_v1.Instance:
        """
        Create a new VM instance with Debian 10 operating system and delete protection
        turned on.
    
        Args:
            project_id: project ID or project number of the Cloud project you want to use.
            zone: name of the zone to create the instance in. For example: "us-west3-b"
            instance_name: name of the new virtual machine (VM) instance.
    
        Returns:
            Instance object.
        """
        newest_debian = get_image_from_family(project="debian-cloud", family="debian-11")
        disk_type = f"zones/{zone}/diskTypes/pd-standard"
        disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
        instance = create_instance(
            project_id, zone, instance_name, disks, delete_protection=True
        )
        return instance
    
    

    REST

    使用 API 创建虚拟机实例时,在请求正文中添加 deletionProtection 属性。例如:

    POST https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances
    
    {
      "name": "[INSTANCE_NAME]",
      "deletionProtection": "true",
      ...
    }
    

    要停用删除保护,请将 deletionProtection 设置为 false

    确定实例是否启用了删除保护

    您可以在 gcloud tool 或 API 中确定实例是否启用了删除保护。

    控制台

    1. 转到“虚拟机实例”页面。

      转到虚拟机实例

    2. 如果出现提示,请选择您的项目并点击继续

    3. 虚拟机实例页面上,下拉菜单并启用删除防护

      虚拟机删除选项。

    4. 随即出现一个带有删除防护图标的新列。如果虚拟机启用了删除保护,则此图标将显示在实例名称旁边。

    gcloud

    在 gcloud CLI 中,运行 instances describe 命令并搜索删除保护字段。例如:

    gcloud compute instances describe example-instance | grep "deletionProtection"
    

    该工具会返回设置为 truefalsedeletionProtection 属性的值:

    deletionProtection: false
    

    Go

    import (
    	"context"
    	"fmt"
    	"io"
    
    	compute "cloud.google.com/go/compute/apiv1"
    	computepb "cloud.google.com/go/compute/apiv1/computepb"
    )
    
    // getDeleteProtection prints the state of delete protection flag of given instance.
    func getDeleteProtection(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.GetInstanceRequest{
    		Project:  projectID,
    		Zone:     zone,
    		Instance: instanceName,
    	}
    
    	instance, err := instancesClient.Get(ctx, req)
    	if err != nil {
    		return fmt.Errorf("unable to get instance: %w", err)
    	}
    
    	fmt.Fprintf(w, "Instance %s has DeleteProtection value: %v", instanceName, instance.GetDeletionProtection())
    
    	return nil
    }
    

    Java

    
    import com.google.cloud.compute.v1.Instance;
    import com.google.cloud.compute.v1.InstancesClient;
    import java.io.IOException;
    
    public class GetDeleteProtection {
    
      public static void main(String[] args) throws IOException {
        // TODO(developer): Replace these variables before running the sample.
        // project: 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”
        // instanceName: name of the new virtual machine.
        String projectId = "your-project-id-or-number";
        String zone = "zone-name";
        String instanceName = "instance-name";
        getDeleteProtection(projectId, zone, instanceName);
      }
    
      // Returns the state of delete protection flag of given instance.
      public static boolean getDeleteProtection(String projectId, String zone,
          String instanceName) throws IOException {
    
        try (InstInstancesClienttancesClient = InstInstancesClientate()) {
          InstInstancetance = instancesClient.get(projectId, zone, instanceName);
          boolean deleteProtection = instinstance.getDeletionProtection()    System.out.printf("Retrieved Delete Protection setting for instance: %s : %s", instanceName,
              deleteProtection);
    
          return deleteProtection;
        }
      }
    }
    

    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');
    
    // Print the state of delete protection flag of given instance.
    async function getDeleteProtection() {
      const instancesClient = new compute.InstancesClient();
    
      const [instance] = await instancesClient.get({
        project: projectId,
        zone,
        instance: instanceName,
      });
    
      console.log(
        `Instance ${instanceName} has deletionProtection value: ${instance.deletionProtection}`
      );
    }
    
    getDeleteProtection();

    Python

    from google.cloud import compute_v1
    
    
    def get_delete_protection(project_id: str, zone: str, instance_name: str) -> bool:
        """
        Returns the state of delete protection flag of given instance.
        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”
            instance_name: name of the virtual machine to check.
        Returns:
            The boolean value of the delete protection setting.
        """
        instance_client = compcompute_v1tInstancesClient   instance = instinstance_client.get      project=project_id, zone=zone, instance=instance_name
        )
        return instance.deletion_protection
    
    

    REST

    在 API 中,发出 GET 请求并查找 deletionProtection 字段:

    GET https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances/[INSTANCE_NAME]
    

    为现有实例切换删除保护

    无论实例的当前状态如何,您都可以切换现有实例的删除保护。具体而言,您不必在启用或停用删除保护之前停止实例。

    控制台

    1. 转到“虚拟机实例”页面。

      转到虚拟机实例

    2. 如果出现提示,请选择您的项目并点击继续

    3. 点击要切换删除保护的实例的名称。 此时将显示实例详情页面。

    4. 在实例详细信息页面中,完成以下步骤:

      1. 点击页面顶部的修改按钮。
      2. 删除防护下,勾选复选框以启用删除防护,或取消选中复选框以停用删除防护。

        虚拟机删除复选框。

      3. 保存更改。

    gcloud

    使用 gcloud CLI,运行带有 --deletion-protection--no-deletion-protection 标志的 update 命令:

    gcloud compute instances update [INSTANCE_NAME] \
        [--deletion-protection | --no-deletion-protection]
    

    例如,要为名为 example-vm 的实例启用删除保护,请执行以下命令:

    gcloud compute instances update example-vm --deletion-protection
    

    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"
    )
    
    // setDeleteProtection updates the delete protection setting of given instance.
    func setDeleteProtection(w io.Writer, projectID, zone, instanceName string, deleteProtection bool) error {
    	// projectID := "your_project_id"
    	// zone := "europe-central2-b"
    	// instanceName := "your_instance_name"
    	// deleteProtection := true
    
    	ctx := context.Background()
    	instancesClient, err := compute.NewInstancesRESTClient(ctx)
    	if err != nil {
    		return fmt.Errorf("NewInstancesRESTClient: %w", err)
    	}
    	defer instancesClient.Close()
    
    	req := &computepb.SetDeletionProtectionInstanceRequest{
    		Project:            projectID,
    		Zone:               zone,
    		Resource:           instanceName,
    		DeletionProtection: proto.Bool(deleteProtection),
    	}
    
    	op, err := instancesClient.SetDeletionProtection(ctx, req)
    	if err != nil {
    		return fmt.Errorf("unable to set deletion protection: %w", err)
    	}
    
    	if err = op.Wait(ctx); err != nil {
    		return fmt.Errorf("unable to wait for the operation: %w", err)
    	}
    
    	fmt.Fprintf(w, "Instance updated\n")
    
    	return nil
    }
    

    Java

    
    import com.google.cloud.compute.v1.InstancesClient;
    import com.google.cloud.compute.v1.SetDeletionProtectionInstanceRequest;
    import java.io.IOException;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;
    
    public class SetDeleteProtection {
    
      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 you want to use.
        // zone: name of the zone you want to use. For example: “us-west3-b”
        // instanceName: name of the new virtual machine.
        // deleteProtection: boolean value indicating if the new virtual machine should be
        // protected against deletion or not.
        String projectId = "your-project-id-or-number";
        String zone = "zone-name";
        String instanceName = "instance-name";
        boolean deleteProtection = true;
        setDeleteProtection(projectId, zone, instanceName, deleteProtection);
      }
    
      // Updates the "Delete Protection" setting of given instance.
      public static void setDeleteProtection(String projectId, String zone,
          String instanceName, boolean deleteProtection)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
    
        try (InstInstancesClienttancesClient = InstInstancesClientate()) {
    
          SetDSetDeletionProtectionInstanceRequestuest =
              SetDSetDeletionProtectionInstanceRequestBuilder()
                  .setProject(projectId)
                  .setZone(zone)
                  .setResource(instanceName)
                  .setDeletionProtection(deleteProtection)
                  .build();
    
          instancesClient.setDsetDeletionProtectionAsyncuest).get(3, TimeUnit.MINUTES);
          ;
          // Retrieve the updated setting from the instance.
          System.out.printf("Updated Delete Protection setting: %s",
              instancesClient.get(projectId, zone, instanceName).getDeletionProtection());
        }
      }
    }
    

    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 deleteProtection = True;
    
    const compute = require('@google-cloud/compute');
    
    // Update the delete protection setting of given instance.
    async function setDeleteProtection() {
      const instancesClient = new compute.InstancesClient();
    
      const [response] = await instancesClient.setDeletionProtection({
        project: projectId,
        zone,
        // Set the delete protection bit.
        deletionProtection: deleteProtection,
        resource: 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 updated.');
    }
    
    setDeleteProtection();

    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 set_delete_protection(
        project_id: str, zone: str, instance_name: str, delete_protection: bool
    ) -> None:
        """
        Updates the delete protection setting of given instance.
        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”
            instance_name: name of the instance to update.
            delete_protection: boolean value indicating if the virtual machine should be
                protected against deletion or not.
        """
        instance_client = compcompute_v1tInstancesClient    request = compcompute_v1DSetDeletionProtectionInstanceRequest   request.project = project_id
        request.zone = zone
        request.resource = instance_name
        request.deletion_protection = delete_protection
    
        operation = instinstance_client.set_deletion_protectionuest)
        wait_for_extended_operation(operation, "changing delete protection setting")
    
    

    REST

    在 API 中,使用 deletionProtection 查询参数发出对 setDeletionProtection 方法的 POST 请求。例如:

    POST https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances/[INSTANCE_NAME]/setDeletionProtection?deletionProtection=true
    

    如需停用删除保护,请将 deletionProtection 设置为 false。请勿提供带有请求的请求正文。

    后续步骤