创建具有额外非启动磁盘的实例


创建计算实例时,您可以同时创建额外的非启动磁盘并将其挂接到实例。您还可以选择要作为非启动磁盘附加的现有磁盘

如果您要创建多写入者模式下的磁盘,则无法在创建实例的同时创建该磁盘。您必须先创建磁盘,然后才能将磁盘挂接到实例。

准备工作

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

    Select the tab for how you plan to use the samples on this page:

    Console

    When you use the Google Cloud console to access Google Cloud services and APIs, you don't need to set up authentication.

    gcloud

    1. Install the Google Cloud CLI, then initialize it by running the following command:

      gcloud init
    2. Set a default region and zone.
    3. REST

      如需在本地开发环境中使用本页面上的 REST API 示例,请使用您提供给 gcloud CLI 的凭据。

        Install the Google Cloud CLI, then initialize it by running the following command:

        gcloud init

      如需了解详情,请参阅 Google Cloud 身份验证文档中的使用 REST 时进行身份验证

所需的角色

如需获得创建添加了非启动磁盘的实例所需的权限,请让您的管理员为您授予项目的 Compute Instance Admin (v1) (roles/compute.instanceAdmin.v1) IAM 角色。 如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限

此预定义角色包含创建添加了非启动盘的实例所需的权限。如需查看所需的确切权限,请展开所需权限部分:

所需权限

如需创建添加了非启动磁盘的实例,您需要具备以下权限:

  • 针对项目的 compute.instances.create 权限
  • 为实例创建新磁盘:针对项目的 compute.disks.create 权限

您也可以使用自定义角色或其他预定义角色来获取这些权限。

创建具有额外非启动磁盘的实例

如需创建附加了额外非启动磁盘的实例,请按以下步骤操作:

控制台

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

    转到“创建实例”

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

    系统随即会显示创建实例页面,并显示机器配置窗格。

  2. 机器配置窗格中,执行以下操作:

    1. 名称字段中,为实例指定名称。如需了解详情,请参阅资源命名惯例
    2. 可选:在可用区字段中,为此实例选择一个可用区。

      默认选择为任意。如果您不更改此默认选择,Google 会根据机器类型和可用性为您自动选择可用区。

    3. 为您的实例选择机器系列。然后, Google Cloud 控制台会显示适用于您所选机型系列的机器系列。提供以下机器族选项:

      • 通用
      • 计算优化
      • 内存优化
      • 存储优化
      • GPU 数量

    4. 系列列中,选择实例的机器系列。

      如果您在上一步中选择了 GPU 作为机器系列,请选择所需的 GPU 类型。然后,系统会为所选 GPU 类型自动选择机器系列。

    5. 机器类型部分中,为您的实例选择机器类型。

  3. 在导航菜单中,点击操作系统和存储空间。在随即显示的操作系统和存储空间窗格中,执行以下操作:

    1. 如需配置启动磁盘,请点击更改。系统随即会显示启动磁盘窗格,其中包含公共映像标签页。

      1. 为启动磁盘选择公共映像或自定义映像,具体方法如下:
      • 如需选择公共映像,请在公共映像标签页中指定以下内容:

        1. 操作系统列表中,选择操作系统类型。
        2. 版本列表中,选择操作系统版本。
        3. 启动磁盘类型列表中,选择启动磁盘的类型。
        4. 大小 (GB) 字段中,指定启动磁盘的大小。
      • 如需选择自定义映像,请点击自定义映像,然后在随即显示的自定义映像标签页中指定以下内容:

        1. 如需选择映像项目,请点击更改,然后选择包含该映像的项目。
        2. 图片列表中,选择要导入的图片。
        3. 启动磁盘类型列表中,选择启动磁盘的类型。
        4. 大小 (GB) 字段中,指定启动磁盘的大小。
      1. 可选:如需了解高级配置选项,请展开 显示高级配置部分。
      2. 如需确认您的启动磁盘选项并返回操作系统和存储空间窗格,请点击选择
    2. 如需创建新的非启动磁盘并将其挂接到实例,请在额外的存储空间和虚拟机备份部分中,点击添加新磁盘

      在随即显示的添加新磁盘窗格中,执行以下操作:

      1. 名称字段中,为非启动磁盘指定名称。
      2. 磁盘来源类型列表中,为非启动磁盘选择来源类型。
      3. 磁盘类型列表中,为非启动磁盘选择一种类型。
      4. 大小字段中,指定非启动磁盘的大小。
      5. 附件设置部分,执行以下操作:
      6. 模式字段中,选择磁盘挂接模式。
      7. 删除规则字段中,选择一个选项以指定在删除实例时系统对磁盘执行的操作。

      如需详细了解您可以在添加新磁盘时配置的参数,请参阅向实例添加永久性磁盘

  4. 在导航菜单中,点击网络。在显示的网络窗格中,执行以下操作:

    1. 前往防火墙部分。
    2. 如需允许传送到实例的 HTTP 或 HTTPS 流量,请选择允许 HTTP 流量允许 HTTPS 流量

      Compute Engine 会向您的实例中添加网络标记,并创建对应的入站防火墙规则,该规则允许 tcp:80 (HTTP) 或 tcp:443 (HTTPS) 上的所有传入流量。网络标记可将防火墙规则与实例相关联。如需了解详情,请参阅 Cloud 新一代防火墙文档中的防火墙规则概览

  5. 可选:指定其他配置选项。如需了解详情,请参阅实例创建期间的配置选项

  6. 要创建并启动该实例,请点击创建

gcloud

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. 运行 gcloud compute instances create 命令以创建具有额外的非启动磁盘的实例。

    在创建实例时,您最多可以添加 127 个非启动磁盘。为您创建的每个非启动磁盘指定 --create-disk 标志。

    如需通过公共映像或库存映像创建非启动磁盘,请使用 --create-disk 标志指定 imageimage-familyimage-project 属性。如需创建空白磁盘,请勿添加这些属性。

    您可以选择为以下媒体资源添加属性:

    • 磁盘大小:使用 --size 属性。
    • 磁盘类型:使用 --type 属性。
    • 区域磁盘:添加 replica-zones 属性。
    gcloud compute instances create INSTANCE_NAME \
        --zone=ZONE \
        --image-project=IMAGE_PROJECT \
        IMAGE_FLAG \
        --create-disk DISK_IMAGE,image-project=DISK_IMAGE_PROJECT,size=SIZE_GB,type=DISK_TYPE \
        --create-disk device-name=DISK_NAME,replica-zones=^:^ZONE:REMOTE-ZONE,boot=false
    

    替换以下内容:

    • INSTANCE_NAME:新实例的名称
    • ZONE:要在其中创建实例的可用区
    • IMAGE_PROJECT:包含映像的项目
    • IMAGE_FLAG:指定以下其中一项:

      • 使用 --image IMAGE_NAME 标志指定公共映像或自定义映像的特定版本。例如 --image debian-12-bookworm-v20241112

      • 使用 --image-family IMAGE_FAMILY_NAME 标志指定映像系列。此项会使用映像系列中最新的未弃用的操作系统映像创建实例。例如,如果您指定 --image-family debian-12,则 Compute Engine 在创建实例时会使用 Debian 12 映像系列中最新版本的操作系统映像。

    • 对于额外的磁盘,请替换以下内容:

      • DISK_IMAGE:指定以下其中一项:
        • image=DISK_IMAGE_NAME:您在创建非启动磁盘时要使用的映像的名称
        • image-family=DISK_IMAGE_FAMILY>:创建非启动磁盘时要使用的映像系列
      • DISK_IMAGE_PROJECT:磁盘映像所属的映像项目
      • SIZE_GB(可选):非启动磁盘的大小
      • DISK_TYPE(可选):磁盘类型的完整或部分网址

        例如 https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/diskTypes/hyperdisk-balanced。如需查看一个或多个可用区中可用的磁盘类型,请使用 gcloud compute disk-types list --zones=ZONE_LIST 命令。将 ZONE_LIST 替换为以英文逗号分隔的区域列表。

      • DISK_NAME(可选):实例创建后向客机操作系统显示的磁盘名称。

      • REMOTE_ZONE:磁盘应复制到的可用区

      对于空白磁盘,请勿指定 imageimage-projectimage-family 参数。

      对于可用区磁盘,请勿指定磁盘属性 replica-zones

Terraform

如需生成 Terraform 代码,您可以使用 Google Cloud 控制台中的等效代码组件。
  1. 在 Google Cloud 控制台中,前往虚拟机实例页面。

    转到虚拟机实例

  2. 点击创建实例
  3. 指定所需的参数。
  4. 在页面顶部或底部,点击等效代码,然后点击 Terraform 标签页以查看 Terraform 代码。

Go

试用此示例之前,请按照《Compute Engine 快速入门:使用客户端库》中的 Go 设置说明进行操作。 如需了解详情,请参阅 Compute Engine Go API 参考文档

如需向 Compute Engine 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
	"google.golang.org/protobuf/proto"
)

// createWithAdditionalDisk create a new VM instance with Debian 10 operating system and a 11 GB additional empty disk.
func createWithAdditionalDisk(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()

	imagesClient, err := compute.NewImagesRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewImagesRESTClient: %w", err)
	}
	defer imagesClient.Close()

	// List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details.
	newestDebianReq := &computepb.GetFromFamilyImageRequest{
		Project: "debian-cloud",
		Family:  "debian-12",
	}
	newestDebian, err := imagesClient.GetFromFamily(ctx, newestDebianReq)
	if err != nil {
		return fmt.Errorf("unable to get image from family: %w", err)
	}

	req := &computepb.InsertInstanceRequest{
		Project: projectID,
		Zone:    zone,
		InstanceResource: &computepb.Instance{
			Name: proto.String(instanceName),
			Disks: []*computepb.AttachedDisk{
				{
					InitializeParams: &computepb.AttachedDiskInitializeParams{
						DiskSizeGb:  proto.Int64(10),
						SourceImage: newestDebian.SelfLink,
						DiskType:    proto.String(fmt.Sprintf("zones/%s/diskTypes/pd-standard", zone)),
					},
					AutoDelete: proto.Bool(true),
					Boot:       proto.Bool(true),
					Type:       proto.String(computepb.AttachedDisk_PERSISTENT.String()),
				},
				{
					InitializeParams: &computepb.AttachedDiskInitializeParams{
						DiskSizeGb: proto.Int64(11),
						DiskType:   proto.String(fmt.Sprintf("zones/%s/diskTypes/pd-standard", zone)),
					},
					AutoDelete: proto.Bool(true),
					Boot:       proto.Bool(false),
					Type:       proto.String(computepb.AttachedDisk_PERSISTENT.String()),
				},
			},
			MachineType: proto.String(fmt.Sprintf("zones/%s/machineTypes/n1-standard-1", zone)),
			NetworkInterfaces: []*computepb.NetworkInterface{
				{
					Name: proto.String("global/networks/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

试用此示例之前,请按照《Compute Engine 快速入门:使用客户端库》中的 Java 设置说明进行操作。 如需了解详情,请参阅 Compute Engine Java API 参考文档

如需向 Compute Engine 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证


import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.compute.v1.AttachedDisk;
import com.google.cloud.compute.v1.AttachedDisk.Type;
import com.google.cloud.compute.v1.AttachedDiskInitializeParams;
import com.google.cloud.compute.v1.Image;
import com.google.cloud.compute.v1.ImagesClient;
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.Vector;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateInstancesAdvanced {

  /**
   * Create an AttachedDisk object to be used in VM instance creation. Uses an image as the source
   * for the new disk.
   *
   * @param diskType 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"
   * @param diskSizeGb size of the new disk in gigabytes
   * @param boot boolean flag indicating whether this disk should be used as a boot disk of an
   * instance
   * @param sourceImage 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}"
   * @return AttachedDisk object configured to be created using the specified image.
   */
  private static AttachedDisk diskFromImage(String diskType, int diskSizeGb, boolean boot,
      String sourceImage) {
    AttachedDisk disk =
        AttachedDisk.newBuilder()
            .setBoot(boot)
            // Remember to set auto_delete to True if you want the disk to be deleted when
            // you delete your VM instance.
            .setAutoDelete(true)
            .setType(Type.PERSISTENT.toString())
            .setInitializeParams(
                AttachedDiskInitializeParams.newBuilder()
                    .setSourceImage(sourceImage)
                    .setDiskSizeGb(diskSizeGb)
                    .setDiskType(diskType)
                    .build())
            .build();
    return disk;
  }


  /**
   * Create an AttachedDisk object to be used in VM instance creation. The created disk contains no
   * data and requires formatting before it can be used.
   *
   * @param diskType 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"
   * @param diskSizeGb size of the new disk in gigabytes
   * @return AttachedDisk object configured to be created as an empty disk.
   */
  private static AttachedDisk emptyDisk(String diskType, int diskSizeGb) {
    AttachedDisk disk =
        AttachedDisk.newBuilder()
            .setBoot(false)
            // Remember to set auto_delete to True if you want the disk to be deleted when
            // you delete your VM instance.
            .setAutoDelete(true)
            .setType(Type.PERSISTENT.toString())
            .setInitializeParams(
                AttachedDiskInitializeParams.newBuilder()
                    .setDiskSizeGb(diskSizeGb)
                    .setDiskType(diskType)
                    .build())
            .build();
    return disk;
  }

  /**
   * Send an instance creation request to the Compute Engine API and wait for it to complete.
   *
   * @param project project ID or project number of the Cloud project you want to use.
   * @param zone name of the zone to create the instance in. For example: "us-west3-b"
   * @param instanceName name of the new virtual machine (VM) instance.
   * @param disks a list of compute_v1.AttachedDisk objects describing the disks you want to attach
   * to your new instance.
   * @param machineType 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"
   * @param network 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.
   * @param subnetwork name of the subnetwork you want the new instance to use. This value uses the
   * following format: "regions/{region}/subnetworks/{subnetwork_name}"
   * @return Instance object.
   */
  private static Instance createWithDisks(String project, String zone, String instanceName,
      Vector<AttachedDisk> disks, String machineType, String network, String subnetwork)
      throws IOException, InterruptedException, ExecutionException, TimeoutException {
    try (InstancesClient instancesClient = InstancesClient.create()) {
      // Use the network interface provided in the networkName argument.
      NetworkInterface networkInterface;
      if (subnetwork != null) {
        networkInterface = NetworkInterface.newBuilder()
            .setName(network).setSubnetwork(subnetwork)
            .build();
      } else {
        networkInterface = NetworkInterface.newBuilder()
            .setName(network).build();
      }

      machineType = String.format("zones/%s/machineTypes/%s", zone, machineType);

      // Bind `instanceName`, `machineType`, `disk`, and `networkInterface` to an instance.
      Instance instanceResource =
          Instance.newBuilder()
              .setName(instanceName)
              .setMachineType(machineType)
              .addAllDisks(disks)
              .addNetworkInterfaces(networkInterface)
              .build();

      System.out.printf("Creating instance: %s at %s ", instanceName, zone);

      // Insert the instance in the specified project and zone.
      InsertInstanceRequest insertInstanceRequest = InsertInstanceRequest.newBuilder()
          .setProject(project)
          .setZone(zone)
          .setInstanceResource(instanceResource).build();

      OperationFuture<Operation, Operation> operation = instancesClient.insertAsync(
          insertInstanceRequest);

      // Wait for the operation to complete.
      Operation response = operation.get(3, TimeUnit.MINUTES);

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

      return instancesClient.get(project, zone, instanceName);
    }
  }

  /**
   * Create a new VM instance with Debian 11 operating system and a 11 GB additional empty disk.
   *
   * @param project project ID or project number of the Cloud project you want to use.
   * @param zone name of the zone to create the instance in. For example: "us-west3-b"
   * @param instanceName name of the new virtual machine (VM) instance.
   * @return Instance object.
   */
  public static Instance createWithAdditionalDisk(String project, String zone, String instanceName)
      throws IOException, InterruptedException, ExecutionException, TimeoutException {
    try (ImagesClient imagesClient = ImagesClient.create()) {
      // List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
      Image image = imagesClient.getFromFamily("debian-cloud", "debian-11");
      String diskType = String.format("zones/%s/diskTypes/pd-standard", zone);
      Vector<AttachedDisk> disks = new Vector<>();
      disks.add(diskFromImage(diskType, 10, true, image.getSelfLink()));
      disks.add(emptyDisk(diskType, 11));
      return createWithDisks(project, zone, instanceName, disks, "n1-standard-1",
          "global/networks/default", null);
    }
  }

Node.js

试用此示例之前,请按照《Compute Engine 快速入门:使用客户端库》中的 Node.js 设置说明进行操作。 如需了解详情,请参阅 Compute Engine Node.js API 参考文档

如需向 Compute Engine 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证

/**
 * 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');

// Create a new VM instance with Debian 10 operating system and a 11 GB additional empty disk.
async function createWithAdditionalDisk() {
  const instancesClient = new compute.InstancesClient();
  const imagesClient = new compute.ImagesClient();

  // List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details.
  const [newestDebian] = await imagesClient.getFromFamily({
    project: 'debian-cloud',
    family: 'debian-11',
  });

  const [response] = await instancesClient.insert({
    project: projectId,
    zone,
    instanceResource: {
      name: instanceName,
      disks: [
        {
          initializeParams: {
            diskSizeGb: '10',
            sourceImage: newestDebian.selfLink,
            diskType: `zones/${zone}/diskTypes/pd-standard`,
          },
          autoDelete: true,
          boot: true,
          type: 'PERSISTENT',
        },
        {
          initializeParams: {
            diskSizeGb: '11',
            diskType: `zones/${zone}/diskTypes/pd-standard`,
          },
          autoDelete: true,
          boot: false,
          type: 'PERSISTENT',
        },
      ],
      machineType: `zones/${zone}/machineTypes/n1-standard-1`,
      networkInterfaces: [
        {
          name: 'global/networks/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.');
}

createWithAdditionalDisk();

Python

试用此示例之前,请按照《Compute Engine 快速入门:使用客户端库》中的 Python 设置说明进行操作。 如需了解详情,请参阅 Compute Engine Python API 参考文档

如需向 Compute Engine 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证

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 empty_disk(
    disk_type: str, disk_size_gb: int, boot: bool = False, auto_delete: bool = True
) -> compute_v1.AttachedDisk():
    """
    Create an AttachedDisk object to be used in VM instance creation. The created disk contains
    no data and requires formatting before it can be used.

    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
        auto_delete: boolean flag indicating whether this disk should be deleted with the VM that uses it

    Returns:
        AttachedDisk object configured to be created as an empty disk.
    """
    disk = compute_v1.AttachedDisk()
    initialize_params = compute_v1.AttachedDiskInitializeParams()
    initialize_params.disk_type = disk_type
    initialize_params.disk_size_gb = disk_size_gb
    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.
    disk.auto_delete = auto_delete
    disk.boot = boot
    return 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_with_additional_disk(
    project_id: str, zone: str, instance_name: str
) -> compute_v1.Instance:
    """
    Create a new VM instance with Debian 10 operating system on a 20 GB disk
    and a 25 GB additional empty disk.

    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-12")
    disk_type = f"zones/{zone}/diskTypes/pd-standard"
    disks = [
        disk_from_image(disk_type, 20, True, newest_debian.self_link),
        empty_disk(disk_type, 25),
    ]
    instance = create_instance(project_id, zone, instance_name, disks)
    return instance

REST

通过对每个额外磁盘使用 initializeParams 属性,您可以在创建实例时创建多达 127 个非启动磁盘。使用公共映像或私有映像创建额外磁盘。 如需添加空白磁盘,请定义不带 sourceImage 值的 initializeParams 条目。 添加磁盘属性 replicaZones 以创建区域级磁盘,而不是可用区级磁盘。

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

{
   "machineType":"zones/MACHINE_TYPE_ZONE/machineTypes/MACHINE_TYPE",
   "name":"VM_NAME",
   
   "disks":[
      {
         "initializeParams":{
            "sourceImage":"projects/IMAGE_PROJECT/global/images/IMAGE"
         },
         "boot":true
      },
      {
         "initializeParams":{
            "diskSizeGb":"SIZE_GB",
            "sourceImage":"projects/DISK_IMAGE_PROJECT/global/images/DISK_IMAGE",
            "diskType":"DISK_TYPE"
         }
      },
      {
         "initializeParams":{
            "diskSizeGb":"SIZE_GB",
            "diskType":"DISK_TYPE"
         },
      },
      {
         "boot": false,
         "deviceName":"DISK_NAME",
         "initializeParams": {
            "diskType": "DISK_TYPE",
            "replicaZones": [
               "projects/PROJECT_ID/zones/ZONE",
               "projects/PROJECT_ID/zones/REMOTE_ZONE"
            ]
         }
      }
   ],
   
   
   "networkInterfaces":[
      {
         "network":"global/networks/NETWORK_NAME"
      }
   ],
   
  
   "shieldedInstanceConfig":{
      "enableSecureBoot":"ENABLE_SECURE_BOOT"
   }
}

替换以下内容:

  • PROJECT_ID:要在其中创建虚拟机的项目的 ID
  • ZONE:要在其中创建虚拟机的可用区
  • MACHINE_TYPE_ZONE:包含新虚拟机将使用的机器类型的可用区
  • MACHINE_TYPE:新虚拟机的预定义自定义机器类型
  • VM_NAME:新虚拟机的名称
  • IMAGE_PROJECT:包含映像的项目
    例如,如果您将 debian-10 指定为映像系列,请将 debian-cloud 指定为映像项目。
  • IMAGE:指定以下其中一项:
    • IMAGE:公共映像的特定版本

      例如,"sourceImage": "projects/debian-cloud/global/images/debian-10-buster-v20200309"

    • IMAGE_FAMILY映像系列

      此项表示通过最新的未弃用的操作系统映像创建虚拟机。例如,如果您指定 "sourceImage": "projects/debian-cloud/global/images/family/debian-10",则 Compute Engine 会通过 Debian 10 映像系列中最新版本的操作系统映像创建虚拟机。

  • 对于额外的磁盘,请替换以下内容:

    • SIZE_GB:磁盘大小
    • DISK_IMAGE
    • DISK_IMAGE_FAMILY:为非启动磁盘指定来源映像或映像系列:
      • DISK_IMAGE:要用作非启动磁盘的映像的名称。例如 "sourceImage": "projects/DISK_IMAGE_PROJECT/global/images/DISK_IMAGE"
      • DISK_IMAGE_FAMILY:要用作非启动磁盘的映像系列。 例如 "sourceImage": "projects/DISK_IMAGE_PROJECT/global/images/family/DISK_IMAGE_FAMILY"
    • DISK_TYPE:磁盘类型的类型的完整或部分网址。例如 https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/diskTypes/hyperdisk-balanced
    • DISK_NAME:可选。创建虚拟机后向访客操作系统显示的磁盘名称。
    • REMOTE_ZONE:要将区域磁盘复制到的可用区

    对于空白磁盘,请勿指定 sourceImage 属性。

    对于可用区磁盘,请勿指定 replicaZones 属性。

  • NETWORK_NAME:您要用于虚拟机的 VPC 网络。您可以指定 default 来使用默认网络。
  • ENABLE_SECURE_BOOT(可选):如果您选择了支持安全强化型虚拟机功能的映像,则 Compute Engine 会默认启用虚拟可信平台模块 (vTPM)完整性监控。默认情况下,Compute Engine 不会启用安全启动

    如果为 enableSecureBoot 指定 true,则 Compute Engine 会创建一个启用了所有三项安全强化型虚拟机功能的虚拟机。在 Compute Engine 启动您的虚拟机后,如需修改安全强化型虚拟机选项,您必须停止该虚拟机。

在使用磁盘之前,格式化并装载磁盘