创建并启动虚拟机实例


本文档介绍如何使用启动磁盘映像、启动磁盘快照或容器映像创建虚拟机 (VM) 实例。某些映像支持安全强化型虚拟机功能,这些功能提供了诸多安全功能,例如符合 UEFI 标准的固件、安全启动以及受 vTPM 保护的测量启动。在安全强化型虚拟机上,默认情况下会启用 vTPM 和完整性监控

在创建虚拟机时,您可为虚拟机创建一个或多个磁盘。也可以在创建虚拟机后为其添加更多磁盘。在您创建虚拟机实例后,Compute Engine 会自动将其启动。

创建虚拟机时,您还可以添加多个网络接口。为了缓解互联网给虚拟机造成的威胁,您可以在向实例添加网络接口时省略外部 IP 地址。在这种情况下,除非您配置了 Cloud NAT,否则只能从同一 VPC 网络或关联网络中的其他虚拟机访问该虚拟机。

如果您是首次创建虚拟机,请参阅《快速入门:使用 Linux 虚拟机》《快速入门:使用 Windows Server 虚拟机》

有关更具体或更复杂的虚拟机创建,请参阅以下资源:

如果自带现有许可,请参阅使用单租户节点自带许可

准备工作

通过映像创建虚拟机实例

本部分介绍如何使用公共操作系统映像自定义映像创建虚拟机。虚拟机包含引导加载程序、启动文件系统和操作系统映像。

查看 Compute Engine 上的可用公共映像列表

在使用公共映像创建虚拟机之前,请先查看 Compute Engine 上的可用公共映像列表。

如需详细了解每个公共映像提供的功能,请参阅按操作系统提供功能支持

控制台

  1. 在 Google Cloud 控制台中,转到映像页面。

    转到“映像”

gcloud

  1. 在 Google Cloud 控制台中,激活 Cloud Shell。

    激活 Cloud Shell

    Cloud Shell 会话随即会在 Google Cloud 控制台的底部启动,并显示命令行提示符。Cloud Shell 是一个已安装 Google Cloud CLI 且已为当前项目设置值的 Shell 环境。该会话可能需要几秒钟时间来完成初始化。

  2. 运行以下命令:

    gcloud compute images list
  3. 请记下映像或映像系列的名称以及包含该映像的项目的名称。

  4. 可选:如需确定映像是否支持安全强化型虚拟机功能,请运行以下命令:

    gcloud compute images describe IMAGE_NAME \
        --project=IMAGE_PROJECT
    

    请替换以下内容:

    如果映像支持安全强化型虚拟机功能,则输出中会显示以下行:type: UEFI_COMPATIBLE

API

  1. 运行以下命令:

    GET https://compute.googleapis.com/compute/v1/projects/IMAGE_PROJECT/global/images/
    
  2. 请记下映像或映像系列的名称以及包含该映像的项目的名称。

  3. 可选:如需确定映像是否支持安全强化型虚拟机功能,请运行以下命令:

    GET https://compute.googleapis.com/compute/v1/projects/IMAGE_PROJECT/global/images/IMAGE_NAME
    

    请替换以下内容:

    如果映像支持安全强化型虚拟机功能,则输出中会显示以下行:type: UEFI_COMPATIBLE

C#

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

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


using Google.Cloud.Compute.V1;
using System;
using System.Threading.Tasks;

public class ListImagesAsyncSample
{
    public async Task ListImagesAsync(
        // TODO(developer): Set your own default values for these parameters or pass different values when calling this method.
        string projectId = "your-project-id")
    {
        // Initialize client that will be used to send requests. This client only needs to be created
        // once, and can be reused for multiple requests.
        ImagesClient client = await ImagesClient.CreateAsync();

        // Make the request to list all non-deprecated images in a project.
        ListImagesRequest request = new ListImagesRequest
        {
            Project = projectId,
            // Listing only non-deprecated images to reduce the size of the reply.
            Filter = "deprecated.state != DEPRECATED",
            // MaxResults indicates the maximum number of items that will be returned per page.
            MaxResults = 100
        };

        // Although the MaxResults parameter is specified in the request, the sequence returned
        // by the ListAsync() method hides the pagination mechanic. The library makes multiple
        // requests to the API for you, so you can simply iterate over all the images.
        await foreach (var image in client.ListAsync(request))
        {
            // The result is an Image collection.
            Console.WriteLine($"Image: {image.Name}");
        }
    }
}

Go

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

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

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	"google.golang.org/api/iterator"
	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
	"google.golang.org/protobuf/proto"
)

// printImagesList prints a list of all non-deprecated image names available in given project.
func printImagesList(w io.Writer, projectID string) error {
	// projectID := "your_project_id"
	ctx := context.Background()
	imagesClient, err := compute.NewImagesRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewImagesRESTClient: %w", err)
	}
	defer imagesClient.Close()

	// Listing only non-deprecated images to reduce the size of the reply.
	req := &computepb.ListImagesRequest{
		Project:    projectID,
		MaxResults: proto.Uint32(3),
		Filter:     proto.String("deprecated.state != DEPRECATED"),
	}

	// Although the `MaxResults` parameter is specified in the request, the iterator returned
	// by the `list()` method hides the pagination mechanic. The library makes multiple
	// requests to the API for you, so you can simply iterate over all the images.
	it := imagesClient.List(ctx, req)
	for {
		image, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return err
		}
		fmt.Fprintf(w, "- %s\n", image.GetName())
	}
	return nil
}

Java

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

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


import com.google.cloud.compute.v1.Image;
import com.google.cloud.compute.v1.ImagesClient;
import com.google.cloud.compute.v1.ImagesClient.ListPage;
import com.google.cloud.compute.v1.ListImagesRequest;
import java.io.IOException;
  // Prints a list of all non-deprecated image names available in given project.
  public static void listImages(String project) throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the `instancesClient.close()` method on the client to
    // safely clean up any remaining background resources.
    try (ImagesClient imagesClient = ImagesClient.create()) {

      // Listing only non-deprecated images to reduce the size of the reply.
      ListImagesRequest imagesRequest = ListImagesRequest.newBuilder()
          .setProject(project)
          .setMaxResults(100)
          .setFilter("deprecated.state != DEPRECATED")
          .build();

      // Although the `setMaxResults` parameter is specified in the request, the iterable returned
      // by the `list()` method hides the pagination mechanic. The library makes multiple
      // requests to the API for you, so you can simply iterate over all the images.
      int imageCount = 0;
      for (Image image : imagesClient.list(imagesRequest).iterateAll()) {
        imageCount++;
        System.out.println(image.getName());
      }
      System.out.printf("Image count in %s is: %s", project, imageCount);
    }
  }

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 compute = require('@google-cloud/compute');

async function listImages() {
  const imagesClient = new compute.ImagesClient();

  // Listing only non-deprecated images to reduce the size of the reply.
  const images = imagesClient.listAsync({
    project: projectId,
    maxResults: 3,
    filter: 'deprecated.state != DEPRECATED',
  });

  // Although the `maxResults` parameter is specified in the request, the iterable returned
  // by the `listAsync()` method hides the pagination mechanic. The library makes multiple
  // requests to the API for you, so you can simply iterate over all the images.
  for await (const image of images) {
    console.log(` - ${image.name}`);
  }
}

listImages();

PHP

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

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

use Google\Cloud\Compute\V1\ImagesClient;

/**
 * Prints a list of all non-deprecated image names available in given project.
 *
 * @param string $projectId Project ID or project number of the Cloud project you want to list images from.
 *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 */
function list_all_images(string $projectId)
{
    $imagesClient = new ImagesClient();
    // Listing only non-deprecated images to reduce the size of the reply.
    $optionalArgs = ['maxResults' => 100, 'filter' => 'deprecated.state != DEPRECATED'];

    /**
     * Although the maxResults parameter is specified in the request, the iterateAllElements() method
     * hides the pagination mechanic. The library makes multiple requests to the API for you,
     * so you can simply iterate over all the images.
     */
    $pagedResponse = $imagesClient->list($projectId, $optionalArgs);
    print('=================== Flat list of images ===================' . PHP_EOL);
    foreach ($pagedResponse->iterateAllElements() as $element) {
        printf(' - %s' . PHP_EOL, $element->getName());
    }
}

Python

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

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

import google.cloud.compute_v1 as compute_v1

def print_images_list(project: str) -> str:
    """
    Prints a list of all non-deprecated image names available in given project.

    Args:
        project: project ID or project number of the Cloud project you want to list images from.

    Returns:
        The output as a string.
    """
    images_client = compute_v1.ImagesClient()
    # Listing only non-deprecated images to reduce the size of the reply.
    images_list_request = compute_v1.ListImagesRequest(
        project=project, max_results=100, filter="deprecated.state != DEPRECATED"
    )
    output = []

    # Although the `max_results` parameter is specified in the request, the iterable returned
    # by the `list()` method hides the pagination mechanic. The library makes multiple
    # requests to the API for you, so you can simply iterate over all the images.
    for img in images_client.list(request=images_list_request):
        print(f" -  {img.name}")
        output.append(f" -  {img.name}")
    return "\n".join(output)

Ruby

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

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


require "google/cloud/compute/v1"

# Prints a list of all non-deprecated image names available in given project.
#
# @param [String] project project ID or project number of the Cloud project you want to list images from.
def print_images_list project:
  client = ::Google::Cloud::Compute::V1::Images::Rest::Client.new

  # Make the request to list all non-deprecated images in a project.
  request = {
    project: project,
    # max_results indicates the maximum number of items that will be returned per page.
    max_results: 100,
    # Listing only non-deprecated images to reduce the size of the reply.
    filter: "deprecated.state != DEPRECATED"
  }

  # Although the `max_results` parameter is specified in the request, the iterable returned
  # by the `list` method hides the pagination mechanic. The library makes multiple
  # requests to the API for you, so you can simply iterate over all the images.
  client.list(request).each do |image|
    puts " - #{image.name}"
  end
end

通过公共映像创建虚拟机实例

Google、开源社区及第三方供应商会提供和维护公共操作系统映像。默认情况下,所有 Google Cloud 项目都可以从公共操作系统映像创建虚拟机。但是,如果 Google Cloud 项目有一个定义的可信映像列表,则您只能使用该列表中的映像来创建虚拟机。

如果您使用本地 SSD 创建安全强化型虚拟机映像,则无法使用完整性监控虚拟可信平台模块 (vTPM)

控制台

  1. 在 Google Cloud 控制台中,前往虚拟机实例页面。

    转到虚拟机实例

  2. 选择您的项目并点击继续

  3. 点击创建实例

  4. 为您的虚拟机指定名称。如需了解详情,请参阅资源命名惯例

  5. 可选操作:更改此虚拟机的可用区。Compute Engine 会随机列出每个区域内的可用区,以鼓励跨多个可用区使用。

  6. 为您的虚拟机选择机器配置

  7. 启动磁盘部分,点击更改,然后执行以下操作:

    1. 公共映像标签页中,选择以下内容:
      • 操作系统
      • 操作系统版本
      • 启动磁盘类型
      • 启动磁盘大小
    2. 可选:对于高级配置选项,点击显示高级配置
    3. 如需确认您的启动磁盘选项,请点击选择
  8. 防火墙部分中,如需允许 HTTP 或 HTTPS 流量流向虚拟机,请选择允许 HTTP 流量允许 HTTPS 流量。选择其中一项后,Compute Engine 会向您的虚拟机添加一个网络标记,以将防火墙规则与该虚拟机相关联。然后,Compute Engine 会创建相应的入站防火墙规则,该规则允许 tcp:80 (HTTP) 或 tcp:443 (HTTPS) 上的所有传入流量。

  9. 可选操作:如果您选择了支持安全强化型虚拟机功能的操作系统映像,则可以修改安全强化型虚拟机设置:如需修改安全强化型虚拟机设置,请展开网络、磁盘、安全、管理、单独租用部分中的安全部分,然后根据需要执行以下操作:

  10. 要创建并启动该虚拟机,请点击创建

gcloud

  1. 在 Google Cloud 控制台中,激活 Cloud Shell。

    激活 Cloud Shell

    Cloud Shell 会话随即会在 Google Cloud 控制台的底部启动,并显示命令行提示符。Cloud Shell 是一个已安装 Google Cloud CLI 且已为当前项目设置值的 Shell 环境。该会话可能需要几秒钟时间来完成初始化。

  2. 选择公共映像。请记下映像或映像系列的名称以及包含该映像的项目的名称。

  3. 使用 gcloud compute instances create 命令从映像系列或操作系统映像的特定版本创建虚拟机。

    如果您指定可选的 --shielded-secure-boot 标志,则 Compute Engine 会创建一个启用了以下所有三项安全强化型虚拟机功能的虚拟机:

    在 Compute Engine 启动您的虚拟机后,您必须停止该虚拟机以修改安全强化型虚拟机选项。

    gcloud compute instances create VM_NAME \
        [--image=IMAGE | --image-family=IMAGE_FAMILY] \
        --image-project=IMAGE_PROJECT
        --machine-type=MACHINE_TYPE

    请替换以下内容:

    • VM_NAME:新虚拟机的名称
    • IMAGEIMAGE_FAMILY:指定以下其中一项:

      • IMAGE:公共映像的特定版本

        例如 --image=debian-10-buster-v20200309

      • IMAGE_FAMILY映像系列

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

    • IMAGE_PROJECT:包含映像的项目

    • MACHINE_TYPE:新虚拟机的预定义自定义机器类型

      如需获取可用区中可用的机器类型列表,请使用带有 --zones 标志的 gcloud compute machine-types list 命令

  4. 验证 Compute Engine 是否已创建该虚拟机:

    gcloud compute instances describe VM_NAME
    

    VM_NAME 替换为虚拟机名称。

Terraform

如需创建虚拟机,您可以使用 google_compute_instance 资源


# Create a VM instance from a public image
# in the `default` VPC network and subnet

resource "google_compute_instance" "default" {
  name         = "my-vm"
  machine_type = "n1-standard-1"
  zone         = "us-central1-a"

  boot_disk {
    initialize_params {
      image = "ubuntu-minimal-2210-kinetic-amd64-v20230126"
    }
  }

  network_interface {
    network = "default"
    access_config {}
  }
}

如需了解如何应用或移除 Terraform 配置,请参阅基本 Terraform 命令

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

    转到虚拟机实例

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

API

  1. 选择公共映像。请记下映像或映像系列的名称以及包含该映像的项目的名称。
  2. 使用 instances.insert 方法从映像系列或操作系统映像的特定版本创建虚拟机:

    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
          }
       ],
    
       "networkInterfaces":[
          {
             "network":"global/networks/NETWORK_NAME"
          }
       ],
    
       "shieldedInstanceConfig":{
          "enableSecureBoot":"ENABLE_SECURE_BOOT"
       }
    }
    

    替换以下内容:

    • PROJECT_ID:要在其中创建虚拟机的项目的 ID
    • ZONE:要在其中创建虚拟机的可用区
    • MACHINE_TYPE_ZONE:包含新虚拟机将使用的机器类型的可用区
    • MACHINE_TYPE:新虚拟机的预定义自定义机器类型
    • VM_NAME:新虚拟机的