為單一專案建立預留項目


本文說明如何建立單一專案保留項目,該項目只能由同一個專案中的虛擬機器 (VM) 執行個體使用。如要進一步瞭解預留項目,請參閱「預留 Compute Engine 可用區資源」。

如要瞭解其他建立預訂的做法,請參閱下列頁面:

  • 如要建立可供多個專案使用的預留項目,請參閱「建立共用預留項目」。

  • 如要在購買依資源計算的承諾使用合約時建立保留項目,請參閱「購買附加保留項目的承諾使用合約」。承諾可為隨選資源費用提供折扣 (稱為承諾使用折扣),前提是您必須購買最低資源量或達到最低支出金額。

事前準備

  • 請詳閱預訂的 規定 限制
  • 如果尚未設定,請先設定驗證機制。驗證是指驗證身分,以便存取 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. After installing the Google Cloud CLI, initialize it by running the following command:

      gcloud init

      If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

    2. Set a default region and zone.

    Terraform

    To use the Terraform samples on this page in a local development environment, install and initialize the gcloud CLI, and then set up Application Default Credentials with your user credentials.

    1. Install the Google Cloud CLI.
    2. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

    3. To initialize the gcloud CLI, run the following command:

      gcloud init
    4. If you're using a local shell, then create local authentication credentials for your user account:

      gcloud auth application-default login

      You don't need to do this if you're using Cloud Shell.

      If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.

    For more information, see Set up authentication for a local development environment.

    REST

    To use the REST API samples on this page in a local development environment, you use the credentials you provide to the gcloud CLI.

      After installing the Google Cloud CLI, initialize it by running the following command:

      gcloud init

      If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

    For more information, see Authenticate for using REST in the Google Cloud authentication documentation.

必要的角色

如要取得建立單一專案預留作業所需的權限,請要求管理員為您授予專案的 Compute Admin (roles/compute.admin) IAM 角色。如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」。

這個預先定義的角色具備建立單一專案預留項目所需的權限。如要查看確切的必要權限,請展開「必要權限」部分:

所需權限

如要建立單一專案預留項目,必須具備下列權限:

  • compute.reservations.create 專案
  • 如要指定執行個體範本: 在執行個體範本中使用 compute.instanceTemplates.useReadOnly

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

建立單一專案預留項目

如要使用預留項目,VM 必須具備與該預留項目完全相符的屬性。如要指定要保留的 VM 屬性,請在本文件中選取下列其中一個部分:

  • 建議做法:指定執行個體範本

    本節說明如何使用執行個體範本定義保留項目的屬性。您可以使用執行個體範本,在同一個位置定義保留項目的屬性,以及可使用保留項目的 VM。

  • 指定現有 VM

    本節說明如何使用現有的 VM 定義保留項目的屬性。您可以使用現有 VM 的屬性,透過建立屬性與參考 VM 相符的 VM 來使用保留項目。

  • 直接指定屬性

    本節說明如何直接定義預訂的屬性。使用這個方法時,您必須手動確認 VM 和預留項目的屬性「完全」相符,否則任何不相符的屬性都會導致無法消費。

根據預設,任何屬性相符的 VM 都能自動使用保留項目。如要控管預留量的用量,請執行下列一項或多項操作:

此外,您可以在建立單一專案預留時,指定密集配置政策。密集配置政策會指定 VM 的位置盡可能彼此靠近,以縮短網路延遲時間。

指定執行個體範本

如要避免在指定執行個體範本時建立預留項目時發生錯誤,請確認下列事項:

  • 請在與執行個體範本內資源相同的區域和區域中建立預留項目。在執行個體範本中指定的任何區域區域資源 (例如機器類型或永久磁碟磁區),都會將範本的使用限制在這些資源所在的位置。舉例來說,如果執行個體範本指定區域 us-central1-a 中現有的永久磁碟磁區,您只能在同一個區域中建立保留項目。如要確認現有範本是否指定任何資源,將範本與特定區域或可用區綁定,請查看執行個體範本的詳細資料,並尋找其中的區域或可用區資源參照。

  • 如果執行個體範本指定了密集配置政策,請務必確保範本指定了密集配置政策的支援機器類型。否則,建立預留項目會失敗。

如要透過指定執行個體範本建立單一專案預留項目,請選取下列任一選項:

主控台

  1. 在 Google Cloud 控制台,前往「Reservations」(預留項目) 頁面。

    前往「預留項目」

  2. 在「On-demand reservations」(隨需預留項目) 分頁 (預設) 中,按一下 「Create reservation」(建立預留項目)

    「Create a reservation」(建立預留項目) 頁面會隨即開啟。

  3. 在「名稱」部分,輸入預訂名稱。

  4. 在「區域」和「可用區」中,選取要保留資源的位置。

  5. 在「Share type」部分,選取「Local」(如果尚未選取)。

  6. 選用步驟:如要允許 Vertex AI 中的自訂訓練工作預測工作使用 GPU VM 的預留項目,請在「Google Cloud 服務」部分,選取「共用預留項目」

  7. 在「Use with VM instance」部分中,選取下列任一選項:

    • 如要讓相符的 VM 自動使用這個預留項目,請選取「Use reservation automatically」 (如果尚未選取)。

    • 如要只在建立已明確指定這個保留項目名稱的相符 VM 時,使用這個保留項目的資源,請選取「Select specific reservation」(選取特定保留項目)

  8. 在「VM 執行個體數量」中,輸入要預留的 VM 數量。

  9. 在「機器設定」專區中,執行下列操作:

    1. 如要從現有的執行個體範本指定 VM 屬性,請選取「Use instance template」

    2. 在「Instance template」(執行個體範本) 欄位中,選取所需的執行個體範本。如果您選取區域執行個體範本,就只能在執行個體範本的區域內預留資源。

  10. 在「自動刪除」部分,您可以啟用自動刪除選項,讓 Compute Engine 在特定日期和時間自動刪除預留項目。自動刪除預留項目有助於避免在停止使用預留項目時產生不必要的費用。

  11. 如要建立預留項目,請點按「Create」(建立)

    「Reservations」(保留項目) 頁面隨即開啟。建立單一專案預留項目可能需要一分鐘才能完成。

gcloud

如要建立單一專案的預留作業,請使用 gcloud compute reservations create 指令

如要指定執行個體範本並不含任何選用標記,以建立單一專案預留,請執行下列指令:

gcloud compute reservations create RESERVATION_NAME \
    --source-instance-template=projects/PROJECT_ID/LOCATION/instanceTemplates/INSTANCE_TEMPLATE_NAME \
    --vm-count=NUMBER_OF_VMS \
    --zone=ZONE

更改下列內容:

  • RESERVATION_NAME:要建立的保留項目名稱。

  • PROJECT_ID:您要保留資源及執行個體範本所在專案的 ID。

  • LOCATION:執行個體範本的位置。請指定下列其中一個值:

    • 全域執行個體範本:global

    • 區域執行個體範本:regions/REGION。將 REGION 替換為執行個體範本所在的區域。如果您指定區域執行個體範本,則只能在範本的區域內保留 VM。

  • INSTANCE_TEMPLATE_NAME:現有執行個體範本的名稱。如果執行個體範本指定了 A3 Mega、A3 High 或 A3 Edge 機型或密集配置政策,則必須加入 --require-specific-reservation 標記。這表示只有明確指定此預留項目的 VM 才能使用。詳情請參閱「從特定預留項目使用 VM」。

  • NUMBER_OF_VMS:要預留的 VM 數量。

  • ZONE:預留資源的所在區域。

舉例來說,如要透過指定全域執行個體範本,為區域 us-central1-a 中的十個 VM 建立保留項目,請執行下列指令:

gcloud compute reservations create my-reservation \
    --source-instance-template=projects/example-project/global/example-instance-template \
    --vm-count=10 \
    --zone=us-central1-a

您也可以選擇執行下列一或多項操作:

  • 如要指定只有已明確指定這個保留項目的 VM 才能使用,請加入 --require-specific-reservation 標記。

    gcloud compute reservations create RESERVATION_NAME \
        --source-instance-template=projects/PROJECT_ID/LOCATION/instanceTemplates/INSTANCE_TEMPLATE_NAME \
        --require-specific-reservation \
        --vm-count=NUMBER_OF_VMS \
        --zone=ZONE
    
  • 如要允許 Vertex AI 中的自訂訓練工作預測工作使用 GPU VM 的預留項目,請將 --reservation-sharing-policy 標記設為 ALLOW_ALL

    gcloud compute reservations create RESERVATION_NAME \
        --source-instance-template=projects/PROJECT_ID/LOCATION/instanceTemplates/INSTANCE_TEMPLATE_NAME \
        --reservation-sharing-policy=ALLOW_ALL \
        --vm-count=NUMBER_OF_VMS \
        --zone=ZONE
    
  • 如要讓 Compute Engine 自動刪除預留項目,請選取下列任一方法:

    • 如要刪除特定日期和時間的預訂,請使用 gcloud beta compute reservations create 指令搭配 --delete-at-time 標記。

      gcloud beta compute reservations create RESERVATION_NAME \
          --delete-at-time=DELETE_AT_TIME \
          --source-instance-template=projects/PROJECT_ID/LOCATION/instanceTemplates/INSTANCE_TEMPLATE_NAME \
          --vm-count=NUMBER_OF_VMS \
          --zone=ZONE
      

      DELETE_AT_TIME 替換為以 RFC 3339 時間戳記格式表示的日期和時間,格式必須如下:none YYYY-MM-DDTHH:MM:SSOFFSET

      更改下列內容:

      • YYYY-MM-DD:日期格式為 4 位數年、2 位數月和 2 位數日,以連字號 (-) 分隔。

      • HH:MM:SS:以 24 小時制時間、2 位數分鐘和 2 位數秒的格式表示時間,並以冒號 (:) 分隔。

      • OFFSET:時區以 世界標準時間 (UTC) 為基準的偏移時間。舉例來說,如要使用太平洋標準時間 (PST),請指定 -08:00。或者,如要使用無偏移,請指定 Z

    • 如要在特定時間後刪除保留項目,請使用 gcloud beta compute reservations create 指令搭配 --delete-after-duration 標記。

      gcloud beta compute reservations create RESERVATION_NAME \
          --delete-after-duration=DELETE_AFTER_DURATION \
          --source-instance-template=projects/PROJECT_ID/LOCATION/instanceTemplates/INSTANCE_TEMPLATE_NAME \
          --vm-count=NUMBER_OF_VMS \
          --zone=ZONE
      

      DELETE_AFTER_DURATION 替換為以天、小時、分鐘或秒為單位的時間長度。舉例來說,如果要指定 30 分鐘,請指定 30m;如果要指定 1 天 2 小時 3 分鐘 4 秒,請指定 1d2h3m4s

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"
)

// Creates the reservation from given template in particular zone
func createReservation(w io.Writer, projectID, zone, reservationName, sourceTemplate string) error {
	// projectID := "your_project_id"
	// zone := "us-west3-a"
	// reservationName := "your_reservation_name"
	// template: existing template path. Following formats are allowed:
	//  	- projects/{project_id}/global/instanceTemplates/{template_name}
	//  	- projects/{project_id}/regions/{region}/instanceTemplates/{template_name}
	//  	- https://www.googleapis.com/compute/v1/projects/{project_id}/global/instanceTemplates/instanceTemplate
	//  	- https://www.googleapis.com/compute/v1/projects/{project_id}/regions/{region}/instanceTemplates/instanceTemplate

	ctx := context.Background()
	reservationsClient, err := compute.NewReservationsRESTClient(ctx)
	if err != nil {
		return err
	}
	defer reservationsClient.Close()

	req := &computepb.InsertReservationRequest{
		Project: projectID,
		ReservationResource: &computepb.Reservation{
			Name: proto.String(reservationName),
			Zone: proto.String(zone),
			SpecificReservation: &computepb.AllocationSpecificSKUReservation{
				Count:                  proto.Int64(2),
				SourceInstanceTemplate: proto.String(sourceTemplate),
			},
		},
		Zone: zone,
	}

	op, err := reservationsClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create reservation: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Reservation created\n")

	return nil
}

Java

import com.google.cloud.compute.v1.AllocationSpecificSKUReservation;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.Reservation;
import com.google.cloud.compute.v1.ReservationsClient;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateReservationForInstanceTemplate {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Cloud project you want to use.
    String projectId = "YOUR_PROJECT_ID";
    // Name of the zone in which you want to create the reservation.
    String zone = "us-central1-a";
    // Name of the reservation you want to create.
    String reservationName = "YOUR_RESERVATION_NAME";
    // The number of virtual machines you want to create.
    int numberOfVms = 3;
    // The URI of the instance template with GLOBAL location
    // to be used for creating the reservation.
    String instanceTemplateUri =
        "projects/YOUR_PROJECT_ID/global/instanceTemplates/YOUR_INSTANCE_TEMPLATE_NAME";
    // The URI of the instance template with REGIONAL location
    // to be used for creating the reservation. For us-central1 region in this case.
    // String instanceTemplateUri =
    // "projects/YOUR_PROJECT_ID/regions/us-central1/instanceTemplates/YOUR_INSTANCE_TEMPLATE_NAME"

    createReservationForInstanceTemplate(
        projectId, reservationName, instanceTemplateUri, numberOfVms, zone);
  }

  // Creates a reservation in a project for the instance template.
  public static Reservation createReservationForInstanceTemplate(
      String projectId, String reservationName, String instanceTemplateUri,
      int numberOfVms, String zone)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (ReservationsClient reservationsClient = ReservationsClient.create()) {
      Reservation reservation =
          Reservation.newBuilder()
              .setName(reservationName)
              .setZone(zone)
              .setSpecificReservation(
                  AllocationSpecificSKUReservation.newBuilder()
                      // Set the number of instances
                      .setCount(numberOfVms)
                      // Set the instance template to be used for creating the reservation.
                      .setSourceInstanceTemplate(instanceTemplateUri)
                      .build())
              .build();

      Operation response =
          reservationsClient.insertAsync(projectId, zone, reservation).get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        return null;
      }
      return reservationsClient.get(projectId, zone, reservationName);
    }
  }
}

Node.js

// Import the Compute library
const computeLib = require('@google-cloud/compute');
const compute = computeLib.protos.google.cloud.compute.v1;

// Instantiate a reservationsClient
const reservationsClient = new computeLib.ReservationsClient();
// Instantiate a zoneOperationsClient
const zoneOperationsClient = new computeLib.ZoneOperationsClient();

/**
 * TODO(developer): Update/uncomment these variables before running the sample.
 */
// The ID of the project where you want to reserve resources and where the instance template exists.
const projectId = await reservationsClient.getProjectId();
// The zone in which to reserve resources.
const zone = 'us-central1-a';
// The name of the reservation to create.
// reservationName = 'reservation-01';
// The number of VMs to reserve.
const vmsNumber = 3;

/**
 * The name of an existing instance template.
 * TODO(developer): Uncomment and update instanceTemplateName before running the sample.
 */
// const instanceTemplateName = 'pernament-region-template-name';

/**
 * // The location of the instance template.
 * TODO(developer): Uncomment the `location` variable depending on which template you want to use.
 */

// The location for a regional instance template: regions/{region}. Replace region with the region where the instance template is located.
// If you specify a regional instance template, then you can only reserve VMs within the same region as the template's region.
// const location = `regions/${zone.slice(0, -2)}`;

// The location for a global instance template.
// const location = 'global';

async function callCreateComputeReservationInstanceTemplate() {
  // Create reservation for 3 VMs in zone us-central1-a by specifying a instance template.
  const specificReservation = new compute.AllocationSpecificSKUReservation({
    count: vmsNumber,
    sourceInstanceTemplate: `projects/${projectId}/${location}/instanceTemplates/${instanceTemplateName}`,
  });

  // Create a reservation.
  const reservation = new compute.Reservation({
    name: reservationName,
    specificReservation,
    // To specify that only VMs that specifically target this reservation can consume it,
    // set specificReservationRequired field to true.
    specificReservationRequired: true,
  });

  const [response] = await reservationsClient.insert({
    project: projectId,
    reservationResource: reservation,
    zone,
  });

  let operation = response.latestResponse;

  // Wait for the create reservation operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await zoneOperationsClient.wait({
      operation: operation.name,
      project: projectId,
      zone: operation.zone.split('/').pop(),
    });
  }

  console.log(`Reservation: ${reservationName} created.`);
}

await callCreateComputeReservationInstanceTemplate();

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 create_reservation_from_template(
    project_id: str, reservation_name: str, template: str
) -> compute_v1.Reservation:
    """
    Create a new reservation based on an existing template.

    Args:
        project_id: project ID or project number of the Cloud project you use.
        reservation_name: the name of new reservation.
        template: existing template path. Following formats are allowed:
            - projects/{project_id}/global/instanceTemplates/{template_name}
            - projects/{project_id}/regions/{region}/instanceTemplates/{template_name}
            - https://www.googleapis.com/compute/v1/projects/{project_id}/global/instanceTemplates/instanceTemplate
            - https://www.googleapis.com/compute/v1/projects/{project_id}/regions/{region}/instanceTemplates/instanceTemplate

    Returns:
        Reservation object that represents the new reservation.
    """

    reservations_client = compute_v1.ReservationsClient()
    request = compute_v1.InsertReservationRequest()
    request.project = project_id
    request.zone = "us-central1-a"

    specific_reservation = compute_v1.AllocationSpecificSKUReservation()
    specific_reservation.count = 1
    specific_reservation.source_instance_template = template

    reservation = compute_v1.Reservation()
    reservation.name = reservation_name
    reservation.specific_reservation = specific_reservation

    request.reservation_resource = reservation
    operation = reservations_client.insert(request)
    wait_for_extended_operation(operation, "Reservation creation")

    return reservations_client.get(
        project=project_id, zone="us-central1-a", reservation=reservation_name
    )

REST

如要建立單一專案預留項目,請對 reservations.insert 方法發出 POST 要求。

如要指定執行個體範本並不含任何選用標記,建立單一專案預留項目,請提出下列 POST 要求:

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

{
  "name": "RESERVATION_NAME",
  "specificReservation": {
    "count": "NUMBER_OF_VMS",
    "sourceInstanceTemplate": "projects/PROJECT_ID/LOCATION/instanceTemplates/INSTANCE_TEMPLATE_NAME"
  }
}

更改下列內容:

  • PROJECT_ID:您要保留資源及執行個體範本所在專案的 ID。

  • ZONE:預留資源的所在區域。

  • RESERVATION_NAME:要建立的保留項目名稱。

  • NUMBER_OF_VMS:要預留的 VM 數量。

  • LOCATION:執行個體範本的位置。請指定下列其中一個值:

    • 全域執行個體範本:global

    • 區域執行個體範本:regions/REGION。將 REGION 替換為執行個體範本所在的區域。如果您指定區域執行個體範本,則只能在範本的區域內保留 VM。

  • INSTANCE_TEMPLATE_NAME:現有執行個體範本的名稱。如果執行個體範本指定了 A3 Mega、A3 High 或 A3 Edge 機型或密集配置政策,則必須在要求主體中加入 specificReservationRequired 欄位,並將欄位設為 true。這表示只有明確指定此保留項目的 VM 才能使用。詳情請參閱「從特定保留項目使用 VM」。

舉例來說,如要透過指定全域執行個體範本,為區域 us-central1-a 中的十個 VM 建立保留項目,請提出下列 POST 要求:

POST https://compute.googleapis.com/compute/v1/projects/example-project/zones/us-central1-a/reservations

{
  "name": "my-reservation",
  "specificReservation": {
    "count": "10",
    "sourceInstanceTemplate": "projects/example-project/global/instanceTemplates/example-instance-template"
  }
}

您也可以選擇執行下列一或多項操作:

  • 如要指定只有已明確指定這項保留項目的 VM 才能使用,請在要求主體中加入 specificReservationRequired 欄位,並將欄位設為 true

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/reservations
    
    {
      "name": "RESERVATION_NAME",
      "specificReservation": {
        "count": "NUMBER_OF_VMS",
        "sourceInstanceTemplate": "projects/PROJECT_ID/LOCATION/instanceTemplates/INSTANCE_TEMPLATE_NAME"
      },
      "specificReservationRequired": true
    }
    
  • 如要允許 Vertex AI 中的自訂訓練工作預測工作使用 GPU VM 的預留項目,請加入 serviceShareType 欄位並將其設為 ALLOW_ALL

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/reservations
    
    {
      "name": "RESERVATION_NAME",
      "reservationSharingPolicy": {
        "serviceShareType": "ALLOW_ALL"
      },
      "specificReservation": {
        "count": "NUMBER_OF_VMS",
        "sourceInstanceTemplate": "projects/PROJECT_ID/LOCATION/instanceTemplates/INSTANCE_TEMPLATE_NAME"
      }
    }
    
  • 如要讓 Compute Engine 自動刪除預留項目,請選取下列任一方法:

    • 如要在特定日期和時間刪除預留項目,請對 beta.reservations.insert 方法發出 POST 要求。在要求主體中加入 deleteAtTime 欄位。

      POST https://compute.googleapis.com/compute/beta/projects/PROJECT_ID/zones/ZONE/reservations
      
      {
        "deleteAtTime": "DELETE_AT_TIME",
        "name": "RESERVATION_NAME",
        "specificReservation": {
          "count": "NUMBER_OF_VMS",
          "sourceInstanceTemplate": "projects/PROJECT_ID/LOCATION/instanceTemplates/INSTANCE_TEMPLATE_NAME"
        }
      }
      

      DELETE_AT_TIME 替換為以 RFC 3339 時間戳記格式表示的日期和時間,格式必須如下:

      YYYY-MM-DDTHH:MM:SSOFFSET
      

      更改下列內容:

      • YYYY-MM-DD:日期格式為 4 位數年、2 位數月和 2 位數日,以連字號 (-) 分隔。

      • HH:MM:SS:以 24 小時制時間、2 位數分鐘和 2 位數秒的格式表示時間,並以冒號 (:) 分隔。

      • OFFSET:時區以 世界標準時間 (UTC) 為基準的偏移時間。舉例來說,如要使用太平洋標準時間 (PST),請指定 -08:00。或者,如要使用無偏移,請指定 Z

    • 如要在特定時間後刪除預留項目,請對 beta.reservations.insert 方法發出 POST 要求。在要求主體中加入 deleteAfterDuration 欄位。

      POST https://compute.googleapis.com/compute/beta/projects/PROJECT_ID/zones/ZONE/reservations
      
      {
        "deleteAfterDuration": {
          "seconds": "DELETE_AFTER_DURATION"
        },
        "name": "RESERVATION_NAME",
        "specificReservation": {
          "count": "NUMBER_OF_VMS",
          "sourceInstanceTemplate": "projects/PROJECT_ID/LOCATION/instanceTemplates/INSTANCE_TEMPLATE_NAME"
        }
      }
      

      DELETE_AFTER_DURATION 替換為秒數。例如,將 86400 指定為 86,400 秒 (1 天)。

指定現有的 VM

您只能根據與 VM 位於相同區域的現有 VM 建立預留資源。

建立預留項目後,您可以建立屬性與參考 VM 相符的 VM,以便使用該預留項目。方法如下:

如要建立使用現有 VM 屬性的單一專案預留項目,請按照下列步驟操作:

  1. 在 Google Cloud 控制台,前往「Reservations」(預留項目) 頁面。

    前往「預留項目」

  2. 按一下 「Create reservation」(建立預留項目)

    「Create a reservation」(建立預留項目) 頁面會隨即開啟。

  3. 在「名稱」部分,輸入預訂名稱。

  4. 在「區域」和「可用區」中,選取要保留資源的位置。

  5. 在「Share type」部分,點選「Local」(如果尚未選取)。

  6. 在「Use with VM instance」部分中,選取下列任一選項:

    • 如要讓相符的 VM 自動使用這個預留項目,請選取「Use reservation automatically」(如果尚未選取)。

    • 如要只在建立已明確指定這個保留項目名稱的相符 VM 時,使用這個保留項目的資源,請選取「Select specific reservation」(選取特定保留項目)

  7. 在「VM 執行個體數量」中,輸入要預留的 VM 數量。

  8. 在「機器設定」專區中,執行下列操作:

    1. 選取「Use existing VM」

    2. 針對「現有 VM」,選取要用來建立預留項目的 VM 屬性。

  9. 選用:如要為符合規定的預訂指定精簡版刊登位置政策,請在「群組刊登位置政策」部分,點選「選取或建立群組刊登位置政策」清單,然後執行下列任一操作:

    • 如要建立要在此保留作業中指定的簡易刊登位置政策,請按照下列步驟操作:

      1. 按一下「建立群組配置政策」

        系統隨即會顯示「建立群組配置政策」窗格。

      2. 在「Policy name」(政策名稱) 中,輸入政策名稱。

      3. 按一下 [建立]。

        建立精簡版刊登位置政策可能需要幾秒鐘才能完成。

    • 否則請選取現有的密集配置政策。

  10. 在「自動刪除」部分,您可以啟用自動刪除選項,讓 Compute Engine 在特定日期和時間自動刪除預留項目。自動刪除預留項目的功能非常實用,可避免在停止使用預留項目時產生不必要的費用。

  11. 如要建立預留項目,請點按「Create」(建立)

    「Reservations」(保留項目) 頁面隨即開啟。預留項目建立作業可能需要一分鐘才能完成。

直接指定屬性

如要直接指定屬性來建立單一專案預訂,請選取下列任一選項:

主控台

  1. 在 Google Cloud 控制台,前往「Reservations」(預留項目) 頁面。

    前往「預留項目」

  2. 在「On-demand reservations」(隨需預留項目) 分頁 (預設) 中,按一下 「Create reservation」(建立預留項目)

    「Create a reservation」(建立預留項目) 頁面會隨即開啟。

  3. 在「名稱」部分,輸入預訂名稱。

  4. 在「區域」和「可用區」中,選取要保留資源的位置。

  5. 在「Share type」部分,點選「Local」(如果尚未選取)。

  6. 選用步驟:如要允許 Vertex AI 中的自訂訓練工作預測工作使用 GPU VM 的預留項目,請在「Google Cloud 服務」部分,選取「共用預留項目」

  7. 在「Use with VM instance」部分中,選取下列任一選項:

    • 如要讓相符的 VM 自動使用這個預留項目,請選取「Use reservation automatically」 (如果尚未選取)。

    • 如要只在建立已明確指定這個保留項目名稱的相符 VM 時,使用這個保留項目的資源,請選取「Select specific reservation」(選取特定保留項目)

  8. 在「VM 執行個體數量」中,輸入要預留的 VM 數量。

  9. 在「機器設定」部分中,選取「指定機器類型」,然後指定下列項目:

    1. 在「機器系列」、「系列」和「機器類型」中,選取機器系列、系列和機器類型。

    2. 選用:如要指定 CPU 平台基本要求,或將 GPU 連結至 N1 VM,請執行下列操作:

      1. 如要展開「CPU Platform and GPU」部分,請按一下 展開箭頭。

      2. 選用:如要指定最低 CPU 平台,請選取「CPU 平台」的選項。

      3. 選用步驟:如要將 GPU 附加至 N1 VM,請按一下 「Add GPU」。接著,針對「GPU 類型」和「GPU 數量」,選取要附加至每個 N1 VM 的 GPU 類型和數量。

  10. 選用:如要將本機 SSD 磁碟連接至預設不包含本機 SSD 磁碟的機器類型,請執行下列操作:

    1. 在「硬碟數量」中,選取要連接的本機 SSD 磁碟數量。

    2. 在「介面類型」部分,選取本機 SSD 磁碟的磁碟介面。

  11. 選用:如要為符合規定的預訂指定精簡版刊登位置政策,請在「群組刊登位置政策」部分,按一下「選取或建立群組刊登位置政策」清單,然後執行下列任一操作:

    • 如要建立要在此預訂中指定的簡易刊登位置政策,請按照下列步驟操作:

      1. 按一下「建立群組配置政策」

        系統隨即會顯示「建立群組配置政策」窗格。

      2. 在「Policy name」(政策名稱) 中,輸入政策名稱。

      3. 按一下 [建立]。

        建立精簡版刊登位置政策可能需要幾秒鐘才能完成。

    • 否則請選取現有的密集配置政策。

  12. 在「自動刪除」部分,您可以啟用自動刪除選項,讓 Compute Engine 在特定日期和時間自動刪除預留項目。自動刪除預留項目有助於避免在停止使用預留項目時產生不必要的費用。

  13. 如要建立預留項目,請點按「Create」(建立)

    「Reservations」(保留項目) 頁面隨即開啟。建立單一專案預留項目可能需要一分鐘才能完成。

gcloud

如要建立單一專案的預留作業,請使用 gcloud compute reservations create 指令

如要直接指定屬性建立單一專案預留,且不包含任何選用標記,請執行下列指令:

gcloud compute reservations create RESERVATION_NAME \
    --machine-type=MACHINE_TYPE \
    --vm-count=NUMBER_OF_VMS \
    --zone=ZONE

更改下列內容:

  • RESERVATION_NAME:要建立的保留項目名稱。

  • MACHINE_TYPE:每個 VM 使用的機器類型。如果您指定 A3 Mega、A3 High 或 A3 Edge 機型,則必須加入 --require-specific-reservation 標記。這表示只有明確指定此預留項目的 VM 才能使用。詳情請參閱「從特定預留項目使用 VM」。

  • NUMBER_OF_VMS:要預留的 VM 數量。

  • ZONE:預留資源的所在區域。

舉例來說,如要在區域 us-central1-a 為 10 個 VM 建立保留項目,每個 VM 都使用具有 4 個 vCPU 的 N2 預先定義機器類型,請執行下列指令:

gcloud compute reservations create my-reservation \
    --machine-type=n2-standard-4 \
    --vm-count=10 \
    --zone=us-central1-a

您也可以選擇執行下列一或多項操作:

  • 如要將 GPU 附加至預留的 N1 VM,請加入 --accelerator 標記。

    gcloud compute reservations create RESERVATION_NAME \
        --accelerator=count=NUMBER_OF_ACCELERATORS,type=ACCELERATOR_TYPE
        --machine-type=MACHINE_TYPE \
        --vm-count=NUMBER_OF_VMS \
        --zone=ZONE
    

    更改下列內容:

  • 如要將本機 SSD 磁碟連接至預設不包含本機 SSD 磁碟的機器類型,請加入 --local-ssd 標記。您只能連接 375 GB 的本機 SSD 磁碟。

    gcloud compute reservations create RESERVATION_NAME \
        --local-ssd=count=NUMBER_OF_LOCAL_SSD_DISKS,size=375,interface=INTERFACE_TYPE \
        --machine-type=MACHINE_TYPE \
        --vm-count=NUMBER_OF_VMS \
        --zone=ZONE
    

    更改下列內容:

    • NUMBER_OF_LOCAL_SSD_DISKS:要附加的本機 SSD 磁碟數量。

    • INTERFACE_TYPE:您希望每個本機 SSD 磁碟使用的磁碟介面類型,以及您指定的機器類型支援的類型。請指定下列其中一個值:

      • 針對 NVMe 磁碟介面:nvme

      • 針對 SCSI 磁碟介面:scsi

  • 如要讓保留的 VM 使用特定最低 CPU 平台,而非區域的預設 CPU 平台,請加入 --min-cpu-platform 標記。

    gcloud compute reservations create RESERVATION_NAME \
        --machine-type=MACHINE_TYPE \
        --min-cpu-platform="MIN_CPU_PLATFORM" \
        --vm-count=NUMBER_OF_VMS \
        --zone=ZONE
    

    MIN_CPU_PLATFORM 替換為最低 CPU 平台。如要確保您在預留資源的區域中可使用 CPU 平台,請依區域查看可用的 CPU 平台

  • 如要指定只有已明確指定這個保留項目的 VM 才能使用,請加入 --require-specific-reservation 標記。

    gcloud compute reservations create RESERVATION_NAME \
        --machine-type=MACHINE_TYPE \
        --require-specific-reservation \
        --vm-count=NUMBER_OF_VMS \
        --zone=ZONE
    
  • 如要指定密集配置政策,以縮短 VM 之間的網路延遲時間,請加入 --resource-policies=policy 標記。

    gcloud compute reservations create RESERVATION_NAME \
        --machine-type=MACHINE_TYPE \
        --resource-policies=policy=COMPACT_PLACEMENT_POLICY_NAME \
        --require-specific-reservation \
        --vm-count=NUMBER_OF_VMS \
        --zone=ZONE
    

    COMPACT_PLACEMENT_POLICY_NAME 替換為現有的密集配置政策名稱。此外,為避免在建立指定密集配置政策的單一專案預留項目時發生錯誤,請務必指定下列項目:

    • 密集配置政策的支援機器類型和 VM 數量上限

    • 密集配置政策所在區域內的可用區。

    • --require-specific-reservation 標記。這表示只有明確指定保留項目的 VM 才能使用該保留項目。

  • 如要允許 Vertex AI 中的自訂訓練工作預測工作使用 GPU VM 的預留項目,請將 --reservation-sharing-policy 標記設為 ALLOW_ALL

    gcloud compute reservations create RESERVATION_NAME \
        --machine-type=MACHINE_TYPE \
        --reservation-sharing-policy=ALLOW_ALL \
        --vm-count=NUMBER_OF_VMS \
        --zone=ZONE
    
  • 如要讓 Compute Engine 自動刪除預留項目,請選取下列任一方法:

    • 如要刪除特定日期和時間的預訂,請使用 gcloud beta compute reservations create 指令搭配 --delete-at-time 標記。

      gcloud beta compute reservations create RESERVATION_NAME \
          --delete-at-time=DELETE_AT_TIME \
          --machine-type=MACHINE_TYPE \
          --vm-count=NUMBER_OF_VMS \
          --zone=ZONE
      

      請將 DELETE_AT_TIME 替換為以 RFC 3339 時間戳記格式表示的日期和時間,格式必須如下:

      YYYY-MM-DDTHH:MM:SSOFFSET
      

      更改下列內容:

      • YYYY-MM-DD:日期格式為 4 位數年、2 位數月和 2 位數日,以連字號 (-) 分隔。

      • HH:MM:SS:以 24 小時制時間、2 位數分鐘和 2 位數秒的格式表示時間,並以冒號 (:) 分隔。

      • OFFSET:時區以 世界標準時間 (UTC) 為基準的偏移時間格式。舉例來說,如要使用太平洋標準時間 (PST),請指定 -08:00。或者,如要使用無偏移,請指定 Z

    • 如要在特定時間後刪除保留項目,請使用 gcloud beta compute reservations create 指令搭配 --delete-after-duration 標記。

      gcloud beta compute reservations create RESERVATION_NAME \
          --delete-after-duration=DELETE_AFTER_DURATION \
          --machine-type=MACHINE_TYPE \
          --vm-count=NUMBER_OF_VMS \
          --zone=ZONE
      

      DELETE_AFTER_DURATION 替換為以天、小時、分鐘或秒為單位的時間長度。舉例來說,如果要指定 30 分鐘,請指定 30m;如果要指定 1 天 2 小時 3 分鐘 4 秒,請指定 1d2h3m4s

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"
)

// Creates the reservation with accelerated image
func createBaseReservation(w io.Writer, projectID, zone, reservationName string) error {
	// projectID := "your_project_id"
	// zone := "us-west3-a"
	// reservationName := "your_reservation_name"

	ctx := context.Background()
	reservationsClient, err := compute.NewReservationsRESTClient(ctx)
	if err != nil {
		return err
	}
	defer reservationsClient.Close()

	// Creating reservation based on direct properties
	req := &computepb.InsertReservationRequest{
		Project: projectID,
		ReservationResource: &computepb.Reservation{
			Name: proto.String(reservationName),
			Zone: proto.String(zone),
			SpecificReservation: &computepb.AllocationSpecificSKUReservation{
				Count: proto.Int64(2),
				// Properties, which allows customising instances
				InstanceProperties: &computepb.AllocationSpecificSKUAllocationReservedInstanceProperties{
					// Attaching GPUs to the reserved VMs
					// Read more: https://cloud.google.com/compute/docs/gpus#n1-gpus
					GuestAccelerators: []*computepb.AcceleratorConfig{
						{
							AcceleratorCount: proto.Int32(1),
							AcceleratorType:  proto.String("nvidia-tesla-t4"),
						},
					},
					// Including local SSD disks
					LocalSsds: []*computepb.AllocationSpecificSKUAllocationAllocatedInstancePropertiesReservedDisk{
						{
							DiskSizeGb: proto.Int64(375),
							Interface:  proto.String("NVME"),
						},
					},
					MachineType: proto.String("n1-standard-2"),
					// Specifying minimum CPU platform
					// Read more: https://cloud.google.com/compute/docs/instances/specify-min-cpu-platform
					MinCpuPlatform: proto.String("Intel Skylake"),
				},
			},
		},
		Zone: zone,
	}

	op, err := reservationsClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create reservation: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Reservation created\n")

	return nil
}

Java

import com.google.cloud.compute.v1.AcceleratorConfig;
import com.google.cloud.compute.v1.AllocationSpecificSKUAllocationAllocatedInstancePropertiesReservedDisk;
import com.google.cloud.compute.v1.AllocationSpecificSKUAllocationReservedInstanceProperties;
import com.google.cloud.compute.v1.AllocationSpecificSKUReservation;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.Reservation;
import com.google.cloud.compute.v1.ReservationsClient;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateReservation {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Cloud project you want to use.
    String projectId = "YOUR_PROJECT_ID";
    // Name of the zone in which you want to create the disk.
    String zone = "us-central1-a";
    // Name of the reservation you want to create.
    String reservationName = "YOUR_RESERVATION_NAME";
    // Number of instances in the reservation.
    int numberOfVms = 3;

    createReservation(projectId, reservationName, numberOfVms, zone);
  }

  // Creates reservation with optional flags
  public static Reservation createReservation(
      String projectId, String reservationName, int numberOfVms, String zone)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Create the reservation with optional properties:
    // Machine type of the instances in the reservation.
    String machineType = "n1-standard-2";
    // Number of accelerators to be attached to the instances in the reservation.
    int numberOfAccelerators = 1;
    // Accelerator type to be attached to the instances in the reservation.
    String acceleratorType = "nvidia-tesla-t4";
    // Minimum CPU platform to be attached to the instances in the reservation.
    String minCpuPlatform = "Intel Skylake";
    // Local SSD size in GB to be attached to the instances in the reservation.
    int localSsdSize = 375;
    // Local SSD interfaces to be attached to the instances in the reservation.
    String localSsdInterface1 = "NVME";
    String localSsdInterface2 = "SCSI";
    boolean specificReservationRequired = true;
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (ReservationsClient reservationsClient = ReservationsClient.create()) {
      Reservation reservation =
          Reservation.newBuilder()
              .setName(reservationName)
              .setZone(zone)
              .setSpecificReservationRequired(specificReservationRequired)
              .setSpecificReservation(
                  AllocationSpecificSKUReservation.newBuilder()
                      // Set the number of instances
                      .setCount(numberOfVms)
                      // Set instance properties
                      .setInstanceProperties(
                          AllocationSpecificSKUAllocationReservedInstanceProperties.newBuilder()
                              .setMachineType(machineType)
                              .setMinCpuPlatform(minCpuPlatform)
                              .addGuestAccelerators(
                                  AcceleratorConfig.newBuilder()
                                      .setAcceleratorCount(numberOfAccelerators)
                                      .setAcceleratorType(acceleratorType)
                                      .build())
                              .addLocalSsds(
                            AllocationSpecificSKUAllocationAllocatedInstancePropertiesReservedDisk
                                      .newBuilder()
                                      .setDiskSizeGb(localSsdSize)
                                      .setInterface(localSsdInterface1)
                                      .build())
                              .addLocalSsds(
                            AllocationSpecificSKUAllocationAllocatedInstancePropertiesReservedDisk
                                      .newBuilder()
                                      .setDiskSizeGb(localSsdSize)
                                      .setInterface(localSsdInterface2)
                                      .build())
                              .build())
                      .build())
              .build();

      Operation response =
          reservationsClient.insertAsync(projectId, zone, reservation).get(7, TimeUnit.MINUTES);

      if (response.hasError()) {
        return null;
      }
      return reservationsClient.get(projectId, zone, reservationName);
    }
  }
}

Node.js

// Import the Compute library
const computeLib = require('@google-cloud/compute');
const compute = computeLib.protos.google.cloud.compute.v1;

// Instantiate a reservationsClient
const reservationsClient = new computeLib.ReservationsClient();
// Instantiate a zoneOperationsClient
const zoneOperationsClient = new computeLib.ZoneOperationsClient();

/**
 * TODO(developer): Update/uncomment these variables before running the sample.
 */
// The ID of the project where you want to reserve resources.
const projectId = await reservationsClient.getProjectId();
// The zone in which to reserve resources.
const zone = 'us-central1-a';
// The name of the reservation to create.
// reservationName = 'reservation-01';
// The number of VMs to reserve.
const vmsNumber = 3;
// Machine type to use for each VM.
const machineType = 'n1-standard-4';

async function callCreateComputeReservationFromProperties() {
  // Create specific reservation for 3 VMs that each use an N1 predefined machine type with 4 vCPUs.
  const specificReservation = new compute.AllocationSpecificSKUReservation({
    count: vmsNumber,
    instanceProperties: {
      machineType,
      // To have the reserved VMs use a specific minimum CPU platform instead of the zone's default CPU platform.
      minCpuPlatform: 'Intel Skylake',
      // If you want to attach GPUs to your reserved N1 VMs, update and uncomment guestAccelerators if needed.
      // guestAccelerators: [
      //   {
      //     // The number of GPUs to add per reserved VM.
      //     acceleratorCount: 1,
      //     // Supported GPU model for N1 VMs. Ensure that your chosen GPU model is available in the zone,
      //     // where you want to reserve resources.
      //     acceleratorType: 'nvidia-tesla-t4',
      //   },
      // ],
      // If you want to add local SSD disks to each reserved VM, update and uncomment localSsds if needed.
      // You can specify up to 24 Local SSD disks. Each Local SSD disk is 375 GB.
      // localSsds: [
      //   {
      //     diskSizeGb: 375,
      //     // The type of interface you want each Local SSD disk to use. Specify one of the following values: NVME or SCSI.
      //     // Make sure that the machine type you specify for the reserved VMs supports the chosen disk interfaces.
      //     interface: 'NVME',
      //   },
      // ],
    },
  });

  // Create a reservation.
  const reservation = new compute.Reservation({
    name: reservationName,
    zone,
    specificReservation,
    // To specify that only VMs that specifically target this reservation can consume it,
    // set specificReservationRequired field to true.
    specificReservationRequired: true,
  });

  const [response] = await reservationsClient.insert({
    project: projectId,
    reservationResource: reservation,
    zone,
  });

  let operation = response.latestResponse;

  // Wait for the create reservation operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await zoneOperationsClient.wait({
      operation: operation.name,
      project: projectId,
      zone: operation.zone.split('/').pop(),
    });
  }

  console.log(`Reservation: ${reservationName} created.`);
}

await callCreateComputeReservationFromProperties();

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 create_compute_reservation(
    project_id: str,
    zone: str = "us-central1-a",
    reservation_name="your-reservation-name",
) -> compute_v1.Reservation:
    """Creates a compute reservation in GCP.
    Args:
        project_id (str): The ID of the Google Cloud project.
        zone (str): The zone to create the reservation.
        reservation_name (str): The name of the reservation to create.
    Returns:
        Reservation object that represents the new reservation.
    """

    instance_properties = compute_v1.AllocationSpecificSKUAllocationReservedInstanceProperties(
        machine_type="n1-standard-1",
        # Optional. Specifies the minimum CPU platform for the VM instance.
        min_cpu_platform="Intel Ivy Bridge",
        # Optional. Specifies amount of local ssd to reserve with each instance.
        local_ssds=[
            compute_v1.AllocationSpecificSKUAllocationAllocatedInstancePropertiesReservedDisk(
                disk_size_gb=375, interface="NVME"
            ),
            compute_v1.AllocationSpecificSKUAllocationAllocatedInstancePropertiesReservedDisk(
                disk_size_gb=375, interface="SCSI"
            ),
        ],
        # Optional. Specifies the GPUs allocated to each instance.
        # guest_accelerators=[
        #     compute_v1.AcceleratorConfig(
        #         accelerator_count=1, accelerator_type="nvidia-tesla-t4"
        #     )
        # ],
    )

    reservation = compute_v1.Reservation(
        name=reservation_name,
        specific_reservation=compute_v1.AllocationSpecificSKUReservation(
            count=3,  # Number of resources that are allocated.
            # If you use source_instance_template, you must exclude the instance_properties field.
            # It can be a full or partial URL.
            # source_instance_template="projects/[PROJECT_ID]/global/instanceTemplates/my-instance-template",
            instance_properties=instance_properties,
        ),
    )

    # Create a client
    client = compute_v1.ReservationsClient()

    operation = client.insert(
        project=project_id,
        zone=zone,
        reservation_resource=reservation,
    )
    wait_for_extended_operation(operation, "Reservation creation")

    reservation = client.get(
        project=project_id, zone=zone, reservation=reservation_name
    )

    print("Name: ", reservation.name)
    print("STATUS: ", reservation.status)
    print(reservation.specific_reservation)
    # Example response:
    # Name:  your-reservation-name
    # STATUS:  READY
    # count: 3
    # instance_properties {
    #   machine_type: "n1-standard-1"
    #   local_ssds {
    #     disk_size_gb: 375
    #     interface: "NVME"
    #   }
    # ...

    return reservation

Terraform

如要建立單一專案預留項目,請使用 google_compute_reservation Terraform 資源

舉例來說,如要為具有 2 個 vCPU 的 N2 預先定義機器類型建立單一專案保留項目,請使用下列資源:


resource "google_compute_reservation" "default" {
  name = "gce-reservation-local"
  zone = "us-central1-a"

  /**
   * To specify a single-project reservation, omit the share_settings block
   * (default) or set the share_type field to LOCAL.
   */
  share_settings {
    share_type = "LOCAL"
  }

  specific_reservation {
    count = 1
    instance_properties {
      machine_type = "n2-standard-2"
    }
  }

  /**
   * To let VMs with affinity for any reservation consume this reservation, omit
   * the specific_reservation_required field (default) or set it to false.
   */
  specific_reservation_required = false
}

如要進一步瞭解如何使用 Terraform,請參閱「使用 Terraform 與 Google Cloud」。

REST

如要建立單一專案預留項目,請對 reservations.insert 方法發出 POST 要求。

如要直接指定屬性,不含任何選用欄位,藉此建立單一專案保留項目,請提出下列 POST 要求:

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

{
  "name": "RESERVATION_NAME",
  "specificReservation": {
    "count": "NUMBER_OF_VMS",
    "instanceProperties": {
      "machineType": "MACHINE_TYPE"
    }
  }
}

更改下列內容:

  • PROJECT_ID:您要保留資源的專案 ID。

  • ZONE:預留資源的所在區域。

  • RESERVATION_NAME:要建立的保留項目名稱。

  • NUMBER_OF_VMS:要預留的 VM 數量。

  • MACHINE_TYPE:每個 VM 使用的機器類型。如果您指定 A3 Mega、A3 High 或 A3 Edge 機型,則必須在要求主體中加入 specificReservationRequired 欄位,並將欄位設為 true。這表示只有明確指定保留項目的 VM 才能使用該保留項目。詳情請參閱「從特定預留項目使用 VM」。

舉例來說,如要在區域 us-central1-a 為 10 個 VM 建立保留項目,每個 VM 都使用具有 4 個 vCPU 的 N2 預先定義機器類型,請提出下列 POST 要求:

POST https://compute.googleapis.com/compute/v1/projects/example-project/zones/us-central1-a/reservations

{
  "name": "my-reservation",
  "specificReservation": {
    "count": "10",
    "instanceProperties": {
      "machineType": "n2-standard-4",
    }
  }
}

您也可以選擇執行下列一或多項操作:

  • 如要將 GPU 附加至已保留的 N1 VM,請在要求主體中加入 guestAccelerators 欄位。

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/reservations
    
    {
      "name": "RESERVATION_NAME",
      "specificReservation": {
        "count": "NUMBER_OF_VMS",
        "instanceProperties": {
          "guestAccelerators": [
            {
              "acceleratorCount": NUMBER_OF_ACCELERATORS,
              "acceleratorType": "ACCELERATOR_TYPE"
            }
          ],
          "machineType": "MACHINE_TYPE"
        }
      }
    }
    

    更改下列內容:

  • 如要將本機 SSD 磁碟連結至預設不包含本機 SSD 磁碟的機器類型,請在要求主體中加入 localSsds 欄位。您只能連接 375 GB 的本機 SSD 磁碟。

    舉例來說,如要將兩個本機 SSD 磁碟連接至要預留的機器類型,請提出以下要求:

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/reservations
    
    {
      "name": "RESERVATION_NAME",
      "specificReservation": {
        "count": "NUMBER_OF_VMS",
        "instanceProperties": {
          "localSsds": [
            {
              "diskSizeGb": "375",
              "interface": "INTERFACE_TYPE"
            },
            {
              "diskSizeGb": "375",
              "interface": "INTERFACE_TYPE"
            }
          ],
          "machineType": "MACHINE_TYPE"
        }
      }
    }
    

    INTERFACE_TYPE 替換為您希望每個本機 SSD 磁碟使用的磁碟介面類型,以及您指定的機型支援的類型。請指定下列其中一個值:

    • 針對 NVMe 磁碟介面:NVME

    • 針對 SCSI 磁碟介面:SCSI

  • 如要讓保留的 VM 使用特定最低 CPU 平台,而非區域的預設 CPU 平台,請在要求主體中加入 minCpuPlatform 欄位。

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/reservations
    
    {
      "name": "RESERVATION_NAME",
      "specificReservation": {
        "count": "NUMBER_OF_VMS",
        "instanceProperties": {
          "machineType": "MACHINE_TYPE",
          "minCpuPlatform": "MIN_CPU_PLATFORM"
        }
      }
    }
    

    MIN_CPU_PLATFORM 替換為最低 CPU 平台。如要確保您在預留資源的區域中可使用 CPU 平台,請依區域查看可用的 CPU 平台

  • 如要指定密集配置方式政策,以縮短預留 VM 之間的網路延遲時間,請在要求主體中加入 resourcePolicies 欄位。

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/reservations
    
    {
      "name": "RESERVATION_NAME",
      "resourcePolicies": {
        "policy" : "projects/example-project/regions/REGION/resourcePolicies/COMPACT_PLACEMENT_POLICY_NAME"
      },
      "specificReservation": {
        "count": "NUMBER_OF_VMS",
        "instanceProperties": {
          "machineType": "MACHINE_TYPE"
        }
      },
      "specificReservationRequired": true
    }
    

    更改下列內容:

    • REGION:密集配置政策所在的區域。您只能在指定位置政策的區域內建立預訂。

    • COMPACT_PLACEMENT_POLICY_NAME:現有密集配置政策的名稱。

    此外,為避免在建立指定精簡版刊登位置政策的單一專案預留項目時發生錯誤,請務必指定下列項目:

    • 密集配置政策的支援機器類型

    • specificReservationRequired 欄位設為 true。這表示只有明確指定此保留項目的 VM 才能使用。

  • 如要指定只有已明確指定這項保留項目的 VM 才能使用,請在要求主體中加入 specificReservationRequired 欄位,並將欄位設為 true

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/reservations
    
    {
      "name": "RESERVATION_NAME",
      "specificReservation": {
        "count": "NUMBER_OF_VMS",
        "instanceProperties": {
          "machineType": "MACHINE_TYPE"
        }
      },
      "specificReservationRequired": true
    }
    
  • 如要允許 Vertex AI 中的自訂訓練工作預測工作使用 GPU VM 的預留項目,請加入 serviceShareType 欄位並將其設為 ALLOW_ALL

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/reservations
    
    {
      "name": "RESERVATION_NAME",
      "reservationSharingPolicy": {
        "serviceShareType": "ALLOW_ALL"
      },
      "specificReservation": {
        "count": "NUMBER_OF_VMS",
        "instanceProperties": {
          "machineType": "MACHINE_TYPE"
        }
      }
    }
    
  • 如要讓 Compute Engine 自動刪除預留項目,請選取下列任一方法:

    • 如要在特定日期和時間刪除預留項目,請對 beta.reservations.insert 方法發出 POST 要求。在要求主體中加入 deleteAtTime 欄位。

      POST https://compute.googleapis.com/compute/beta/projects/PROJECT_ID/zones/ZONE/reservations
      
      {
        "deleteAtTime": "DELETE_AT_TIME",
        "name": "RESERVATION_NAME",
        "specificReservation": {
          "count": "NUMBER_OF_VMS",
          "instanceProperties": {
            "machineType": "MACHINE_TYPE"
          }
        }
      }
      

      請將 DELETE_AT_TIME 替換為以 RFC 3339 時間戳記格式表示的日期和時間,格式必須如下:

      YYYY-MM-DDTHH:MM:SSOFFSET
      

      更改下列內容:

      • YYYY-MM-DD:日期格式為 4 位數年、2 位數月和 2 位數日,以連字號 (-) 分隔。

      • HH:MM:SS:以 24 小時制時間、2 位數分鐘和 2 位數秒的格式表示時間,並以冒號 (:) 分隔。

      • OFFSET:時區以 世界標準時間 (UTC) 為基準的偏移時間。舉例來說,如要使用太平洋標準時間 (PST),請指定 -08:00。或者,如要使用無偏移,請指定 Z

    • 如要在特定時間後刪除預留項目,請對 beta.reservations.insert 方法發出 POST 要求。在要求主體中加入 deleteAfterDuration 欄位。

      POST https://compute.googleapis.com/compute/beta/projects/PROJECT_ID/zones/ZONE/reservations
      
      {
        "deleteAfterDuration": {
          "seconds": "DELETE_AFTER_DURATION"
        },
        "name": "RESERVATION_NAME",
        "specificReservation": {
          "count": "NUMBER_OF_VMS",
          "instanceProperties": {
            "machineType": "MACHINE_TYPE"
          }
        }
      }
      

      DELETE_AFTER_DURATION 替換為秒數。例如,將 86400 指定為 86,400 秒 (1 天)。

疑難排解

瞭解如何排解建立預訂問題

後續步驟