本文档介绍如何通过在 Instance 资源上设置 deletionProtection
属性来保护特定虚拟机实例免遭删除。要详细了解虚拟机实例,请参阅实例文档。
作为工作负载的一部分,可能存在某些对于运行应用或服务至关重要的虚拟机实例,例如运行 SQL Server 的实例、用作许可证管理器的服务器等。这些虚拟机实例可能需要无限期地保持运行,因此需要一种方法来保护这些虚拟机免遭删除。
通过设置 deletionProtection
标志,可以防止意外删除虚拟机实例。如果用户尝试删除您已为其设置 deletionProtection
标志的虚拟机实例,则请求会失败。只有已被授予具有 compute.instances.create
权限的角色的用户才能重置该标志以允许删除资源。
准备工作
- 参阅实例文档。
-
如果您尚未设置身份验证,请进行设置。身份验证是通过其进行身份验证以访问 Google Cloud 服务和 API 的过程。如需从本地开发环境运行代码或示例,您可以按如下方式向 Compute Engine 进行身份验证。
选择标签页以了解您打算如何使用本页面上的示例:
控制台
当您使用 Google Cloud 控制台访问 Google Cloud 服务和 API 时,无需设置身份验证。
gcloud
-
安装 Google Cloud CLI,然后通过运行以下命令初始化 Google Cloud CLI:
gcloud init
- 设置默认区域和可用区。
Go
如需从本地开发环境使用本页面上的 Go 示例,请安装并初始化 gcloud CLI,然后使用用户凭据设置应用默认凭据。
- 安装 Google Cloud CLI。
-
如需初始化 gcloud CLI,请运行以下命令:
gcloud init
-
为您的 Google 账号创建本地身份验证凭据:
gcloud auth application-default login
如需了解详情,请参阅 为本地开发环境设置身份验证。
Java
如需从本地开发环境使用本页面上的 Java 示例,请安装并初始化 gcloud CLI,然后使用用户凭据设置应用默认凭据。
- 安装 Google Cloud CLI。
-
如需初始化 gcloud CLI,请运行以下命令:
gcloud init
-
为您的 Google 账号创建本地身份验证凭据:
gcloud auth application-default login
如需了解详情,请参阅 为本地开发环境设置身份验证。
Node.js
如需从本地开发环境使用本页面上的 Node.js 示例,请安装并初始化 gcloud CLI,然后使用用户凭据设置应用默认凭据。
- 安装 Google Cloud CLI。
-
如需初始化 gcloud CLI,请运行以下命令:
gcloud init
-
为您的 Google 账号创建本地身份验证凭据:
gcloud auth application-default login
如需了解详情,请参阅 为本地开发环境设置身份验证。
PHP
如需从本地开发环境使用本页面上的 PHP 示例,请安装并初始化 gcloud CLI,然后使用用户凭据设置应用默认凭据。
- 安装 Google Cloud CLI。
-
如需初始化 gcloud CLI,请运行以下命令:
gcloud init
-
为您的 Google 账号创建本地身份验证凭据:
gcloud auth application-default login
如需了解详情,请参阅 为本地开发环境设置身份验证。
Python
如需从本地开发环境使用本页面上的 Python 示例,请安装并初始化 gcloud CLI,然后使用用户凭据设置应用默认凭据。
- 安装 Google Cloud CLI。
-
如需初始化 gcloud CLI,请运行以下命令:
gcloud init
-
为您的 Google 账号创建本地身份验证凭据:
gcloud auth application-default login
如需了解详情,请参阅 为本地开发环境设置身份验证。
REST
如需在本地开发环境中使用本页面上的 REST API 示例,请使用您提供给 gcloud CLI 的凭据。
-
规格
删除保护不会阻止以下操作:
删除保护可以应用于常规虚拟机和抢占式虚拟机。
删除保护不能应用于属于托管实例组的虚拟机,但可以应用于属于非托管实例组的实例。
不能在实例模板中指定删除保护。
权限
要执行此任务,您必须已被授予资源的以下权限或以下某个 IAM 角色。
权限
compute.instances.create
角色
compute.admin
compute.instanceAdmin.v1
在实例创建期间设置删除保护
默认情况下,实例会停用删除保护。可使用以下说明启用删除保护。
控制台
在 Google Cloud 控制台中,转到创建实例页面。
展开高级选项部分,然后执行以下操作:
- 展开管理部分。
- 选中启用删除防护复选框。
继续虚拟机创建过程。
gcloud
创建虚拟机实例时,请添加 --deletion-protection
或 no-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-10"),
},
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 (InstancesClient instancesClient = InstancesClient.create()) {
AttachedDisk disk =
AttachedDisk.newBuilder()
.setBoot(true)
.setAutoDelete(true)
.setType(AttachedDisk.Type.PERSISTENT.toString())
.setInitializeParams(
// Describe the size and source image of the boot disk to attach to the instance.
AttachedDiskInitializeParams.newBuilder()
.setSourceImage(sourceImage)
.setDiskSizeGb(diskSizeGb)
.build())
.build();
// Use the default VPC network.
NetworkInterface networkInterface = NetworkInterface.newBuilder()
.setName(networkName)
.build();
// Collect information into the Instance object.
Instance instanceResource =
Instance.newBuilder()
.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.
InsertInstanceRequest insertInstanceRequest = InsertInstanceRequest.newBuilder()
.setProject(projectId)
.setZone(zone)
.setInstanceResource(instanceResource)
.build();
// Wait for the create operation to complete.
Operation response = instancesClient.insertAsync(insertInstanceRequest)
.get(3, TimeUnit.MINUTES);
;
if (response.hasError()) {
System.out.println("Instance creation failed ! ! " + response);
return;
}
System.out.printf("Instance created : %s", instanceName);
System.out.println("Operation Status: " + response.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-10',
},
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 中确定实例是否启用了删除保护。
控制台
转到“虚拟机实例”页面。
如果出现提示,请选择您的项目并点击继续。
在虚拟机实例页面上,下拉列菜单并启用删除防护。
随即出现一个带有删除防护图标的新列。如果虚拟机启用了删除保护,则此图标将显示在实例名称旁边。
gcloud
在 gcloud CLI 中,运行 instances describe
命令并搜索删除保护字段。例如:
gcloud compute instances describe example-instance | grep "deletionProtection"
该工具会返回设置为 true
或 false
的 deletionProtection
属性的值:
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 (InstancesClient instancesClient = InstancesClient.create()) {
Instance instance = instancesClient.get(projectId, zone, instanceName);
boolean deleteProtection = instance.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 = compute_v1.InstancesClient()
instance = instance_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]
为现有实例切换删除保护
无论实例的当前状态如何,您都可以切换现有实例的删除保护。具体而言,您不必在启用或停用删除保护之前停止实例。
控制台
转到“虚拟机实例”页面。
如果出现提示,请选择您的项目并点击继续。
点击要切换删除保护的实例的名称。 此时将显示实例详情页面。
在实例详细信息页面中,完成以下步骤:
- 点击页面顶部的修改按钮。
在删除防护下,勾选复选框以启用删除防护,或取消选中复选框以停用删除防护。
保存更改。
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 (InstancesClient instancesClient = InstancesClient.create()) {
SetDeletionProtectionInstanceRequest request =
SetDeletionProtectionInstanceRequest.newBuilder()
.setProject(projectId)
.setZone(zone)
.setResource(instanceName)
.setDeletionProtection(deleteProtection)
.build();
instancesClient.setDeletionProtectionAsync(request).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 = compute_v1.InstancesClient()
request = compute_v1.SetDeletionProtectionInstanceRequest()
request.project = project_id
request.zone = zone
request.resource = instance_name
request.deletion_protection = delete_protection
operation = instance_client.set_deletion_protection(request)
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
。请勿提供带有请求的请求正文。