예약 사용


이 문서에서는 Compute Engine을 사용하여 다음 작업을 실행하는 방법을 설명합니다.

  • 예약된 가상 머신(VM) 인스턴스를 사용합니다.

  • 예약 사용을 확인합니다.

  • 예약 사용 보고서를 봅니다.

VM을 사용하는 다른 Google Cloud 제품의 예약을 사용하는 방법에 대한 자세한 내용은 다음 제품의 예약 문서를 참조하세요.

시작하기 전에

  • 예약에 대해서는 요구사항제한사항을 참조하세요.
  • 아직 인증을 설정하지 않았다면 설정합니다. 인증은 Google Cloud 서비스 및 API에 액세스하기 위해 ID를 확인하는 프로세스입니다. 로컬 개발 환경에서 코드 또는 샘플을 실행하려면 다음 옵션 중 하나를 선택하여 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. Go

      로컬 개발 환경에서 이 페이지의 Go 샘플을 사용하려면 gcloud CLI를 설치 및 초기화한 다음 사용자 인증 정보로 애플리케이션 기본 사용자 인증 정보를 설정하세요.

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. 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.

      자세한 내용은 다음을 참조하세요: Set up authentication for a local development environment.

      Java

      로컬 개발 환경에서 이 페이지의 Java 샘플을 사용하려면 gcloud CLI를 설치 및 초기화한 다음 사용자 인증 정보로 애플리케이션 기본 사용자 인증 정보를 설정하세요.

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. 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.

      자세한 내용은 다음을 참조하세요: Set up authentication for a local development environment.

      Node.js

      로컬 개발 환경에서 이 페이지의 Node.js 샘플을 사용하려면 gcloud CLI를 설치 및 초기화한 다음 사용자 인증 정보로 애플리케이션 기본 사용자 인증 정보를 설정하세요.

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. 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.

      자세한 내용은 다음을 참조하세요: Set up authentication for a local development environment.

      Python

      로컬 개발 환경에서 이 페이지의 Python 샘플을 사용하려면 gcloud CLI를 설치 및 초기화한 다음 사용자 인증 정보로 애플리케이션 기본 사용자 인증 정보를 설정하세요.

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. 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.

      자세한 내용은 다음을 참조하세요: Set up authentication for a local development environment.

      REST

      로컬 개발 환경에서 이 페이지의 REST API 샘플을 사용하려면 gcloud CLI에 제공한 사용자 인증 정보를 사용합니다.

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

        gcloud init

      자세한 내용은 Google Cloud 인증 문서의 REST 사용을 위한 인증을 참고하세요.

필요한 역할

예약 사용에 필요한 권한을 얻으려면 관리자에게 프로젝트에 대한 Compute 인스턴스 관리자(v1)(roles/compute.instanceAdmin.v1) IAM 역할을 부여해 달라고 요청하세요. 역할 부여에 대한 자세한 내용은 프로젝트, 폴더, 조직에 대한 액세스 관리를 참조하세요.

이 사전 정의된 역할에는 예약을 사용하는 데 필요한 권한이 포함되어 있습니다. 필요한 정확한 권한을 보려면 필수 권한 섹션을 펼치세요.

필수 권한

예약을 사용하려면 다음 권한이 필요합니다.

  • 예약 만들기: 프로젝트에 대한 compute.reservations.create 권한
  • VM 만들기:
    • 프로젝트에 대한 compute.instances.create 권한
    • 커스텀 이미지를 사용하여 VM 만들기: 이미지에 대한 compute.images.useReadOnly 권한
    • 스냅샷을 사용하여 VM 만들기: 스냅샷에 대한 compute.snapshots.useReadOnly 권한
    • 인스턴스 템플릿을 사용하여 VM 만들기: 인스턴스 템플릿에 대한 compute.instanceTemplates.useReadOnly 권한
    • VM에 기존 네트워크 할당: 프로젝트에 대한 compute.networks.use 권한
    • VM의 고정 IP 주소 지정: 프로젝트에 대한 compute.addresses.use 권한
    • 기존 네트워크 사용 시 VM에 외부 IP 주소 할당: 프로젝트에 대한 compute.networks.useExternalIp 권한
    • VM의 서브넷 지정: 프로젝트 또는 선택한 서브넷에 대한 compute.subnetworks.use 권한
    • VPC 네트워크를 사용할 때 VM에 외부 IP 주소 할당: 프로젝트 또는 선택한 서브넷에 대한 compute.subnetworks.useExternalIp 권한
    • VM에 VM 인스턴스 메타데이터 설정: 프로젝트에 대한 compute.instances.setMetadata 권한
    • VM에 태그 설정: VM에 대한 compute.instances.setTags 권한
    • VM에 라벨 설정: VM에 대한 compute.instances.setLabels 권한
    • VM에 사용할 서비스 계정 설정: VM에 대한 compute.instances.setServiceAccount 권한
    • VM의 새 디스크 만들기: 프로젝트에 대한 compute.disks.create 권한
    • 기존 디스크를 읽기 전용 또는 읽기-쓰기 모드로 연결: 디스크에 대한 compute.disks.use 권한
    • 기존 디스크를 읽기 전용 모드로 연결: 디스크에 대한 compute.disks.useReadOnly 권한
  • 인스턴스 템플릿 만들기: 프로젝트에 대한 compute.instanceTemplates.create 권한

커스텀 역할이나 다른 사전 정의된 역할을 사용하여 이 권한을 부여받을 수도 있습니다.

예약된 VM 사용

가상 머신(VM) 인스턴스를 만들면 VM 및 예약의 속성이 일치하는 경우에만 VM에서 예약을 사용하기 시작합니다. 또한 VM의 예약 어피니티 속성을 다음 옵션 중 하나로 설정해야 합니다.

  • 일치하는 예약 사용—VM이 일치하는 속성이 있는 예약을 자동으로 사용할 수 있습니다(기본값).

    이 옵션은 많은 수의 VM을 생성하고 삭제하며, 가능할 때마다 예약을 사용하려는 경우에 유용합니다. 이 시나리오에서는 속성이 예약과 일치하는지 여부에 관계없이 VM을 만들 수 있습니다. 일치하면 VM은 예약의 사용 순서에 따라 예약을 사용하기 시작합니다.

  • 특정 예약 사용: VM이 특정 예약만 사용할 수 있습니다. 예약을 자동으로 사용할 수 없습니다.

    이 옵션은 예를 들어 일정한 용량을 특정 이벤트의 백업으로 유지하려는 경우에 유용합니다. 이 시나리오에서는 VM 속성과 특정 예약 속성이 일치하는 경우에만 VM을 만들 수 있습니다.

  • 예약을 전혀 사용할 수 없음: VM이 예약을 사용할 수 없습니다.

    이 옵션은 예약된 리소스를 사용하지 않으려는 임시 VM을 만드는 경우 등에 유용합니다.

일치하는 예약에서 VM 사용

이 소비 모델의 경우 기존 VM과 새 VM에서 속성이 예약에 지정된 VM 속성과 일치하면 예약을 자동으로 사용합니다.

이 소비 모델을 사용하는 경우 현재 프로젝트의 VM이 공유 예약을 사용하기 전에 먼저 모든 단일 프로젝트 예약을 사용합니다. 예약이 자동으로 사용되는 방법에 대한 자세한 내용은 사용 순서를 참조하세요.

예약을 생성할 때 특정 예약이 필요함을 나타내는 플래그 또는 옵션을 사용하지 않는 한 이 모델이 기본 소비 모델입니다.

콘솔

  1. 예약을 만들고 모든 예약을 사용하도록 구성된 예약 어피니티 속성이 있는 VM에서 이 예약의 리소스를 사용할 수 있도록 하려면(기본값) 다음 단계를 따르세요.

    1. 만들려는 예약 유형을 선택합니다.

      • 독립형 예약을 만들려면 다음을 수행합니다.

        1. Google Cloud console에서 예약 페이지로 이동합니다.

          예약으로 이동

        2. 온디맨드 예약 탭(기본값)에서 예약 만들기를 클릭합니다.

          예약 만들기 페이지가 열립니다.

      • 약정에 연결된 예약을 만들려면 다음을 수행합니다.

        1. Google Cloud 콘솔에서 약정 사용 할인 페이지로 이동합니다.

          약정 사용 할인으로 이동

          약정 목록 페이지가 열립니다.

        2. 약정 구매를 클릭합니다.

          약정 사용 할인 구매 페이지가 열립니다.

        3. 약정 속성을 지정합니다. 그런 다음 예약 섹션에서 항목 추가를 클릭합니다.

          새 예약 추가 섹션이 표시됩니다.

          연결된 예약이 있는 약정을 구매하는 방법에 대한 자세한 내용은 예약이 연결된 약정 구매를 참조하세요.

    2. 이름 필드에 예약 이름을 입력합니다. 이 예시에서는 reservation-01를 입력합니다.

    3. 리소스를 예약할 리전영역을 선택합니다. 이 예시에서는 us-central1을 리전으로, us-central1-a를 영역으로 선택합니다.

    4. 원하는 공유 유형을 선택합니다.

      • 단일 프로젝트에 대한 예약을 만들려면 로컬을 선택합니다.
      • 여러 프로젝트 간에 공유 예약을 만들려면 공유를 선택합니다. 이 예약을 다른 프로젝트와 공유하려면 프로젝트 추가를 클릭하고 현재 프로젝트의 조직에서 원하는 프로젝트를 선택합니다.
    5. 일치하는 VM에서 이 예약을 자동으로 사용할 수 있도록 하려면 VM 인스턴스와 함께 사용 섹션에서 예약 자동 사용을 선택합니다.

    6. VM 인스턴스 수 필드에 예약할 VM 수를 입력합니다. 이 예시에서는 2을 입력합니다.

    7. 각 VM별로 예약할 리소스를 지정합니다.

      • 기존 인스턴스 템플릿과 일치하는 VM을 예약하려면 인스턴스 템플릿 사용을 선택하고 목록에서 인스턴스 템플릿을 선택합니다.
      • 또는 머신 유형 지정을 선택하고 다음을 지정합니다.
        1. 머신 계열, 시리즈, 머신 유형 필드에서 머신 계열, 시리즈, 머신 유형을 선택합니다.
        2. 선택사항: 최소 CPU 플랫폼 또는 GPU를 지정합니다.
          1. CPU 플랫폼 및 GPU 섹션을 확장하려면 확장 화살표를 클릭합니다.
          2. 선택사항: 최소 CPU 플랫폼을 지정하려면 CPU 플랫폼 목록에서 옵션을 선택합니다.
          3. 선택사항: GPU를 추가하려면 GPU 추가를 클릭합니다. 그런 다음 GPU 유형 필드와 GPU 수 필드에서 각 VM의 GPU 유형과 수를 선택합니다.
        3. 선택사항: 로컬 SSD를 추가합니다.
          1. 디스크 수 필드에서 각 VM의 로컬 SSD 수를 선택합니다.
          2. 인터페이스 유형 필드에서 로컬 SSD의 인터페이스를 선택합니다.

      이 예시에서는 머신 유형 지정을 선택합니다. 그런 다음 General-purpose 머신 계열 및 N2 시리즈에 대해 n2-standard-32 머신 유형을 선택하고 최소 CPU 플랫폼 Intel Cascade Lake를 선택합니다.

    8. 예약 만들기를 완료합니다.

      • 독립형 예약을 만드는 경우 만들기를 클릭합니다.

      • 약정에 연결된 예약을 만드는 경우 다음 안내를 따르세요.

        1. 이 예약의 속성 지정을 완료하려면 완료를 클릭합니다.
        2. 약정 및 연결된 예약 만들기를 완료하려면 구매를 클릭합니다.
  2. 동일한 프로젝트 또는 예약이 공유된 프로젝트에서 공개 예약을 타겟팅하는 VM을 만듭니다.

    영역, 머신 유형(머신 계열, vCPU, 메모리), 최소 CPU 플랫폼, GPU 크기 및 유형, 로컬 SSD 인터페이스 및 크기를 포함하여 VM의 속성이 reservation-01의 VM 속성과 일치하는지 확인합니다.

    VM을 만드는 방법에 대한 자세한 내용은 VM 만들기 및 시작을 참조하세요.

    1. Google Cloud 콘솔에서 인스턴스 만들기 페이지로 이동합니다.

      인스턴스 만들기로 이동

      인스턴스 만들기 페이지가 열립니다.

    2. VM의 이름을 지정합니다.

    3. 다음 섹션에서는 선택적인 속성을 포함하여 예약의 모든 속성과 정확하게 일치하는 구성을 선택합니다. 이 예시에서는 다음 VM 속성이 reservation-01과 일치하는지 확인해야 합니다.

      • 리전: us-central1
      • 영역: us-central1-a
      • 머신 유형: n2-standard-32
      • 최소 CPU 플랫폼: Intel Cascade Lake
      • GPU: 없음
      • 로컬 SSD: 없음
    4. 고급 옵션 섹션을 펼친 후 관리 섹션을 펼칩니다. 예약 목록에서 생성된 예약 자동 사용을 선택합니다.

    5. 만들기를 클릭하여 VM을 만듭니다.

gcloud

  1. reservation-01 공개 예약을 생성합니다.

    gcloud compute reservations create reservation-01 \
        --vm-count=2 \
        --machine-type=n2-standard-32 \
        --min-cpu-platform="Intel Cascade Lake" \
        --zone=us-central1-a
    
  2. 모든 공개 예약을 타겟팅하고 영역, 머신 유형(머신 계열, vCPU, 메모리), 최소 CPU 플랫폼, GPU 크기 및 유형, 로컬 SSD 크기 및 인터페이스를 비롯한 reservation-01의 VM 속성과 일치하는 VM을 만듭니다.

    gcloud compute instances create instance-1 \
        --machine-type=n2-standard-32 \
        --min-cpu-platform="Intel Cascade Lake" \
        --zone=us-central1-a \
        --reservation-affinity=any
    

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

// consumeAnyReservation creates instance, consuming any available reservation
func consumeAnyReservation(w io.Writer, projectID, zone, instanceName, sourceTemplate string) error {
	// projectID := "your_project_id"
	// zone := "us-west3-a"
	// instanceName := "your_instance_name"
	// sourceTemplate: 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()

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

	req := &computepb.InsertInstanceRequest{
		Project:                projectID,
		Zone:                   zone,
		SourceInstanceTemplate: proto.String(sourceTemplate),
		InstanceResource: &computepb.Instance{
			Name: proto.String(instanceName),
			// specifies that any matching reservation should be consumed
			ReservationAffinity: &computepb.ReservationAffinity{
				ConsumeReservationType: proto.String("ANY_RESERVATION"),
			},
		},
	}

	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 from reservation\n")

	return nil
}

자바

import static com.google.cloud.compute.v1.ReservationAffinity.ConsumeReservationType.ANY_RESERVATION;

import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.compute.v1.AttachedDisk;
import com.google.cloud.compute.v1.AttachedDiskInitializeParams;
import com.google.cloud.compute.v1.InsertInstanceRequest;
import com.google.cloud.compute.v1.Instance;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.NetworkInterface;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.ReservationAffinity;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ConsumeAnyMatchingReservation {

  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";
    // Zone where the VM instance will be created.
    String zone = "us-central1-a";
    // Name of the VM instance you want to query.
    String instanceName = "YOUR_INSTANCE_NAME";
    // machineType: machine type of the VM being created.
    // *   For a list of machine types, see https://cloud.google.com/compute/docs/machine-types
    String machineTypeName = "n1-standard-4";
    // sourceImage: path to the operating system image to mount.
    // *   For details about images you can mount, see https://cloud.google.com/compute/docs/images
    String sourceImage = "projects/debian-cloud/global/images/family/debian-11";
    // diskSizeGb: storage size of the boot disk to attach to the instance.
    long diskSizeGb = 10L;
    // networkName: network interface to associate with the instance.
    String networkName = "default";
    // Minimum CPU platform of the instances.
    String minCpuPlatform = "Intel Skylake";

    createInstanceAsync(projectId, zone, instanceName, machineTypeName, sourceImage,
        diskSizeGb, networkName, minCpuPlatform);
  }

  // Create a virtual machine targeted with the reserveAffinity field.
  // In this consumption model, existing and new VMs automatically consume a reservation
  // if their properties match the VM properties specified in the reservation.
  public static Instance createInstanceAsync(String projectId, String zone,
      String instanceName, String machineTypeName, String sourceImage,
      long diskSizeGb, String networkName, String minCpuPlatform)
      throws IOException, InterruptedException, ExecutionException, TimeoutException {
    String machineType = String.format("zones/%s/machineTypes/%s", zone, machineTypeName);
    // 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 (InstancesClient instancesClient = InstancesClient.create()) {
      AttachedDisk disk =
          AttachedDisk.newBuilder()
              .setBoot(true)
              .setAutoDelete(true)
              .setType(AttachedDisk.Type.PERSISTENT.toString())
              .setDeviceName("disk-1")
              .setInitializeParams(
                  AttachedDiskInitializeParams.newBuilder()
                      .setSourceImage(sourceImage)
                      .setDiskSizeGb(diskSizeGb)
                      .build())
              .build();

      NetworkInterface networkInterface = NetworkInterface.newBuilder()
          .setName(networkName)
          .build();

      ReservationAffinity reservationAffinity =
          ReservationAffinity.newBuilder()
              .setConsumeReservationType(ANY_RESERVATION.toString())
              .build();

      Instance instanceResource =
          Instance.newBuilder()
              .setName(instanceName)
              .setMachineType(machineType)
              .addDisks(disk)
              .addNetworkInterfaces(networkInterface)
              .setMinCpuPlatform(minCpuPlatform)
              .setReservationAffinity(reservationAffinity)
              .build();

      InsertInstanceRequest insertInstanceRequest = InsertInstanceRequest.newBuilder()
          .setProject(projectId)
          .setZone(zone)
          .setInstanceResource(instanceResource)
          .build();

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

      Operation response = operation.get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        return null;
      }
      return instancesClient.get(projectId, zone, instanceName);
    }
  }
}

Node.js

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

// Instantiate a reservationsClient
const instancesClient = new computeLib.InstancesClient();
// 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 create instance.
const projectId = await instancesClient.getProjectId();
// The zone in which to create instance.
const zone = 'us-central1-a';
// The name of the instance to create.
// const instanceName = 'instance-01';
// Machine type to use for VM.
const machineType = 'n1-standard-4';

// Create instance to consume reservation if their properties match the VM properties
async function callCreateInstanceToConsumeAnyReservation() {
  // Describe the size and source image of the boot disk to attach to the instance.
  const disk = new compute.Disk({
    boot: true,
    autoDelete: true,
    type: 'PERSISTENT',
    initializeParams: {
      diskSizeGb: '10',
      sourceImage: 'projects/debian-cloud/global/images/family/debian-12',
    },
  });

  //  Define networkInterface
  const networkInterface = new compute.NetworkInterface({
    name: 'global/networks/default',
  });

  // Define reservationAffinity
  const reservationAffinity = new compute.ReservationAffinity({
    consumeReservationType: 'ANY_RESERVATION',
  });

  // Create an instance
  const instance = new compute.Instance({
    name: instanceName,
    machineType: `zones/${zone}/machineTypes/${machineType}`,
    minCpuPlatform: 'Intel Skylake',
    disks: [disk],
    networkInterfaces: [networkInterface],
    reservationAffinity,
  });

  const [response] = await instancesClient.insert({
    project: projectId,
    instanceResource: instance,
    zone,
  });

  let operation = response.latestResponse;

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

  console.log(`Instance ${instanceName} created.`);
}

await callCreateInstanceToConsumeAnyReservation();

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 consume_any_project_reservation(
    project_id: str,
    zone: str,
    reservation_name: str,
    instance_name: str,
    machine_type: str = "n1-standard-1",
    min_cpu_platform: str = "Intel Ivy Bridge",
) -> compute_v1.Instance:
    """
    Creates a specific reservation in a single project and launches a VM
    that consumes the newly created reservation.
    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.
        instance_name (str): The name of the instance to create.
        machine_type (str): The machine type for the instance.
        min_cpu_platform (str): The minimum CPU platform for the instance.
    """
    instance_properties = (
        compute_v1.AllocationSpecificSKUAllocationReservedInstanceProperties(
            machine_type=machine_type,
            min_cpu_platform=min_cpu_platform,
        )
    )

    reservation = compute_v1.Reservation(
        name=reservation_name,
        specific_reservation=compute_v1.AllocationSpecificSKUReservation(
            count=3,
            instance_properties=instance_properties,
        ),
    )

    # Create a reservation client
    client = compute_v1.ReservationsClient()
    operation = client.insert(
        project=project_id,
        zone=zone,
        reservation_resource=reservation,
    )
    wait_for_extended_operation(operation, "Reservation creation")

    instance = compute_v1.Instance()
    instance.name = instance_name
    instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
    instance.min_cpu_platform = min_cpu_platform
    instance.zone = zone

    # Set the reservation affinity to target any matching reservation
    instance.reservation_affinity = compute_v1.ReservationAffinity(
        consume_reservation_type="ANY_RESERVATION",  # Type of reservation to consume
    )
    # Define the disks for the instance
    instance.disks = [
        compute_v1.AttachedDisk(
            boot=True,  # Indicates that this is a boot disk
            auto_delete=True,  # The disk will be deleted when the instance is deleted
            initialize_params=compute_v1.AttachedDiskInitializeParams(
                source_image="projects/debian-cloud/global/images/family/debian-11",
                disk_size_gb=10,
            ),
        )
    ]
    instance.network_interfaces = [
        compute_v1.NetworkInterface(
            network="global/networks/default",  # The network to use
            access_configs=[
                compute_v1.AccessConfig(
                    name="External NAT",  # Name of the access configuration
                    type="ONE_TO_ONE_NAT",  # Type of access configuration
                )
            ],
        )
    ]
    # Create a request to insert the instance
    request = compute_v1.InsertInstanceRequest()
    request.zone = zone
    request.project = project_id
    request.instance_resource = instance

    vm_client = compute_v1.InstancesClient()
    operation = vm_client.insert(request)
    wait_for_extended_operation(operation, "instance creation")
    print(f"Instance {instance_name} that targets any open reservation created.")

    return vm_client.get(project=project_id, zone=zone, instance=instance_name)

REST

  1. reservation-01 공개 예약을 생성합니다.

    POST https://compute.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/reservations
    
    {
      "name": "reservation-01",
      "specificReservation": {
        "count": "2",
        "instanceProperties": {
          "machineType": "n2-standard-32",
          "minCpuPlatform": "Intel Cascade Lake",
        }
      }
    }
    
  2. 모든 공개 예약을 타겟팅하고 영역, 머신 유형(머신 계열, vCPU, 메모리), 최소 CPU 플랫폼, GPU 크기 및 유형, 로컬 SSD 크기 및 인터페이스를 비롯한 reservation-01의 VM 속성과 일치하는 VM을 만듭니다.

    POST https://compute.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/instances
    
    {
      "name": "instance-1",
      "machineType": "zones/us-central1-a/machineTypes/n2-standard-32",
      "minCpuPlatform": "Intel Cascade Lake",
      "disks": [
        {
          "boot": true,
          "initializeParams": {
            "sourceImage": "projects/debian-cloud/global/images/family/debian-12"
          }
        }
      ],
      "networkInterfaces": [
        {
          "network": "global/networks/default"
        }
      ],
      "reservationAffinity": {
        "consumeReservationType": "ANY_RESERVATION"
      }
    }
    

특정 예약에서 VM 사용

이 사용 모델에서는 이름으로 특정 예약을 타겟팅하는 새로운 VM만 해당 예약을 사용하며 예약은 자동으로 사용되지 않습니다.

예약을 생성할 때 다음 방법 중 하나를 사용하여 VM이 특정 예약을 타겟팅하도록 지정합니다.

  • Google Cloud 콘솔에서 특정 예약 선택 체크박스를 선택합니다.
  • gcloud CLI에 --require-specific-reservation 플래그를 포함합니다.
  • Compute Engine API에서 specificReservationRequired 필드를 true로 설정합니다.
  • Terraform에서 specific_reservation_required 필드를 true로 설정합니다.

그런 다음 해당 예약을 명시적으로 타겟팅하는 VM을 생성합니다. VM 속성 및 예약 속성이 일치하는 경우에만 특정 예약을 대상으로 하는 VM을 만들 수 있습니다. 그렇지 않으면 VM 만들기가 실패합니다.

인스턴스 템플릿을 사용해 리전 관리형 인스턴스 그룹에서 VM을 만들려면 해당 영역별로 이름이 같은 동일한 예약을 생성합니다. 그런 다음 그룹의 인스턴스 템플릿에서 이름으로 예약을 타겟팅합니다.

예를 들어 reservation-02라는 특정 예약을 생성한 다음 해당 예약을 타겟팅하고 예약의 VM 속성과 일치하는 VM을 만듭니다.

사용할 VM 유형에 따라 특정 단일 프로젝트 예약 사용 또는 특정 공유 예약 사용 단계를 따릅니다.

특정 단일 프로젝트 예약 사용

특정 단일 프로젝트 예약을 사용하려면 다음 옵션 중 하나를 선택합니다.

콘솔

  1. 예약을 만들고 이름으로 예약을 명시적으로 타겟팅하는 VM에서만 이 예약의 리소스를 사용할 수 있도록 하려면 다음 단계를 따르세요.

    1. 다음 옵션 중 하나를 선택합니다.

      • 독립형 예약을 만들려면 다음을 수행합니다.

        1. Google Cloud console에서 예약 페이지로 이동합니다.

          예약으로 이동

        2. 온디맨드 예약 탭(기본값)에서 예약 만들기를 클릭합니다.

          예약 만들기 페이지가 열립니다.

      • 약정에 연결된 예약을 만들려면 다음을 수행합니다.

        1. Google Cloud 콘솔에서 약정 사용 할인 페이지로 이동합니다.

          약정 사용 할인으로 이동

        2. 약정 구매를 클릭합니다.

          약정 사용 할인 구매 페이지가 열립니다.

        3. 약정 속성을 지정합니다. 그런 다음 예약 섹션에서 항목 추가를 클릭합니다.

          새 예약 추가 섹션이 표시됩니다.

          연결된 예약이 있는 약정을 구매하는 방법에 대한 자세한 내용은 예약이 연결된 약정 구매를 참조하세요.

    2. 이름 필드에 예약 이름을 입력합니다. 이 예시에서는 reservation-02를 입력합니다.

    3. 리소스를 예약할 리전영역을 선택합니다. 이 예시에서는 us-central1을 리전으로, us-central1-a를 영역으로 선택합니다.

    4. 예약이 단일 프로젝트 예약임을 지정하려면 공유 유형로컬을 선택합니다.

    5. 이름을 통해 이 예약을 명시적으로 타겟팅하는 일치하는 VM만 이 예약을 사용할 수 있도록 하려면 VM 인스턴스와 함께 사용 섹션에서 특정 예약 선택을 선택합니다.

    6. VM 인스턴스 수 필드에 예약할 VM 수를 입력합니다. 이 예시에서는 10을 입력합니다.

    7. 각 VM별로 예약할 리소스를 지정합니다.

      • 기존 인스턴스 템플릿과 일치하는 VM을 예약하려면 인스턴스 템플릿 사용을 선택하고 목록에서 인스턴스 템플릿을 선택합니다.
      • 또는 머신 유형 지정을 선택하고 다음을 지정합니다.
        1. 머신 계열, 시리즈, 머신 유형 필드에서 머신 계열, 시리즈, 머신 유형을 선택합니다.
        2. 선택사항: 최소 CPU 플랫폼 또는 GPU를 지정합니다.
          1. CPU 플랫폼 및 GPU 섹션을 확장하려면 확장 화살표를 클릭합니다.
          2. 선택사항: 최소 CPU 플랫폼을 지정하려면 CPU 플랫폼 목록에서 옵션을 선택합니다.
          3. 선택사항: GPU를 추가하려면 GPU 추가를 클릭합니다. 그런 다음 GPU 유형 필드와 GPU 수 필드에서 각 VM의 GPU 유형과 수를 선택합니다.
        3. 선택사항: 로컬 SSD를 추가합니다.
          1. 디스크 수 필드에서 각 VM의 로컬 SSD 수를 선택합니다.
          2. 인터페이스 유형 필드에서 로컬 SSD의 인터페이스를 선택합니다.

      이 예시에서는 머신 유형 지정을 선택합니다. 그런 다음 General-purpose 머신 계열 및 N2 시리즈에 대해 n2-standard-32 머신 유형을 선택하고 최소 CPU 플랫폼 Intel Cascade Lake를 선택합니다.

    8. 예약 만들기를 완료합니다.

      • 독립형 예약을 만드는 경우 만들기를 클릭합니다.

      • 약정에 연결된 예약을 만드는 경우 다음 안내를 따르세요.

        1. 이 예약의 속성 지정을 완료하려면 완료를 클릭합니다.
        2. 약정 및 연결된 예약 만들기를 완료하려면 구매를 클릭합니다.
  2. 동일한 프로젝트에서 이름으로 특정 예약을 타겟팅하는 VM을 만듭니다.

    영역, 머신 유형(머신 계열, vCPU, 메모리), 최소 CPU 플랫폼, GPU 크기 및 유형, 로컬 SSD 인터페이스 및 크기를 포함하여 VM의 속성이 특정 예약의 VM 속성과 일치하는지 확인합니다.

    VM을 만드는 방법에 대한 자세한 내용은 VM 만들기 및 시작을 참조하세요.

    1. Google Cloud 콘솔에서 인스턴스 만들기 페이지로 이동합니다.

      인스턴스 만들기로 이동

    2. 이름 필드에 VM의 이름을 입력합니다.

    3. 다음 섹션에서는 선택적인 속성을 포함하여 예약의 모든 속성과 정확하게 일치하는 구성을 선택합니다. 이 예시에서는 다음 VM 속성이 reservation-02과 일치하는지 확인해야 합니다.

      • 리전: us-central1
      • 영역: us-central1-a
      • 머신 유형: n2-standard-32
      • 최소 CPU 플랫폼: Intel Cascade Lake
      • GPU: 없음
      • 로컬 SSD: 없음
    4. 고급 옵션 섹션을 펼친 후 다음을 수행합니다.

      1. 관리 섹션을 펼칩니다.

      2. 예약 섹션의 애플리케이션 정책 목록에서 특정 예약 선택을 선택합니다.

      3. VM에 사용하려는 것과 일치하는 VM 속성이 포함된 예약을 선택합니다. 이 예시에서는 reservation-02를 선택합니다.

    5. 만들기를 클릭하여 VM을 만듭니다.

gcloud

  1. --require-specific-reservation 플래그로 reservation-02라는 예약을 생성합니다. 이렇게 예약된 리소스는 이름으로 이 예약을 명시적으로 타겟팅하는 VM에서만 사용할 수 있습니다.

    gcloud compute reservations create reservation-02 \
        --machine-type=n2-standard-32 \
        --min-cpu-platform="Intel Cascade Lake" \
        --vm-count=10 \
        --zone=us-central1-a \
        --require-specific-reservation
    
  2. --reservation-affinity--reservation 플래그를 사용하여 이름으로 reservation-02를 타겟팅하는 VM을 만듭니다.

    영역, 머신 유형(머신 계열, vCPU, 메모리), 최소 CPU 플랫폼, GPU 크기 및 유형, 로컬 SSD 인터페이스 및 크기를 포함하여 VM의 속성이 예약의 VM 속성과 일치하는지 확인합니다.

    gcloud compute instances create instance-2 \
        --machine-type=n2-standard-32 \
        --min-cpu-platform="Intel Cascade Lake" \
        --zone=us-central1-a \
        --reservation-affinity=specific \
        --reservation=reservation-02
    

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

// consumeSpecificReservation creates instance, consuming specific reservation
// Note: respective reservation should have SpecificReservationRequired: true
func consumeSpecificReservation(w io.Writer, projectID, zone, instanceName, reservationName string) error {
	// projectID := "your_project_id"
	// zone := "us-west3-a"
	// reservationName := "your_reservation_name"
	// instanceName := "your_instance_name"

	ctx := context.Background()
	machineType := fmt.Sprintf("zones/%s/machineTypes/%s", zone, "n2-standard-32")
	sourceImage := "projects/debian-cloud/global/images/family/debian-12"

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

	req := &computepb.InsertInstanceRequest{
		Project: projectID,
		Zone:    zone,
		InstanceResource: &computepb.Instance{
			Disks: []*computepb.AttachedDisk{
				{
					InitializeParams: &computepb.AttachedDiskInitializeParams{
						DiskSizeGb:  proto.Int64(10),
						SourceImage: proto.String(sourceImage),
					},
					AutoDelete: proto.Bool(true),
					Boot:       proto.Bool(true),
					Type:       proto.String(computepb.AttachedDisk_PERSISTENT.String()),
				},
			},
			MachineType:    proto.String(machineType),
			MinCpuPlatform: proto.String("Intel Cascade Lake"),
			Name:           proto.String(instanceName),
			NetworkInterfaces: []*computepb.NetworkInterface{
				{
					Name: proto.String("global/networks/default"),
				},
			},
			// specifies particular reservation, which should be consumed
			ReservationAffinity: &computepb.ReservationAffinity{
				ConsumeReservationType: proto.String("SPECIFIC_RESERVATION"),
				Key:                    proto.String("compute.googleapis.com/reservation-name"),
				Values:                 []string{reservationName},
			},
		},
	}

	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 from reservation\n")

	return nil
}

자바

import static com.google.cloud.compute.v1.ReservationAffinity.ConsumeReservationType.SPECIFIC_RESERVATION;

import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.compute.v1.AttachedDisk;
import com.google.cloud.compute.v1.AttachedDiskInitializeParams;
import com.google.cloud.compute.v1.InsertInstanceRequest;
import com.google.cloud.compute.v1.Instance;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.NetworkInterface;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.ReservationAffinity;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ConsumeSingleProjectReservation {
  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 where the reservation is located.
    String zone = "us-central1-a";
    // Name of the reservation you want to query.
    String reservationName = "YOUR_RESERVATION_NAME";
    // Name of the VM instance you want to query.
    String instanceName = "YOUR_INSTANCE_NAME";
    // machineType: machine type of the VM being created.
    // *   For a list of machine types, see https://cloud.google.com/compute/docs/machine-types
    String machineTypeName = "n1-standard-4";
    // sourceImage: path to the operating system image to mount.
    // *   For details about images you can mount, see https://cloud.google.com/compute/docs/images
    String sourceImage = "projects/debian-cloud/global/images/family/debian-11";
    // diskSizeGb: storage size of the boot disk to attach to the instance.
    long diskSizeGb = 10L;
    // networkName: network interface to associate with the instance.
    String networkName = "default";
    // Minimum CPU platform of the instances.
    String minCpuPlatform = "Intel Skylake";

    createInstanceAsync(projectId, zone, instanceName, reservationName, machineTypeName,
        sourceImage, diskSizeGb, networkName, minCpuPlatform);
  }

  // Create a virtual machine targeted with the reserveAffinity field.
  // Ensure that the VM's properties match the reservation's VM properties.
  public static Instance createInstanceAsync(String projectId, String zone, String instanceName,
      String reservationName, String machineTypeName, String sourceImage, long diskSizeGb,
      String networkName, String minCpuPlatform)
      throws IOException, InterruptedException, ExecutionException, TimeoutException {
    String machineType = String.format("zones/%s/machineTypes/%s", zone, machineTypeName);
    // 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 (InstancesClient instancesClient = InstancesClient.create()) {
      AttachedDisk disk =
          AttachedDisk.newBuilder()
              .setBoot(true)
              .setAutoDelete(true)
              .setType(AttachedDisk.Type.PERSISTENT.toString())
              .setDeviceName("disk-1")
              .setInitializeParams(
                  AttachedDiskInitializeParams.newBuilder()
                      .setSourceImage(sourceImage)
                      .setDiskSizeGb(diskSizeGb)
                      .build())
              .build();

      NetworkInterface networkInterface = NetworkInterface.newBuilder()
          .setName(networkName)
          .build();

      ReservationAffinity reservationAffinity =
          ReservationAffinity.newBuilder()
              .setConsumeReservationType(SPECIFIC_RESERVATION.toString())
              .setKey("compute.googleapis.com/reservation-name")
              // Set specific reservation
              .addValues(reservationName)
              .build();

      Instance instanceResource =
          Instance.newBuilder()
              .setName(instanceName)
              .setMachineType(machineType)
              .addDisks(disk)
              .addNetworkInterfaces(networkInterface)
              .setMinCpuPlatform(minCpuPlatform)
              .setReservationAffinity(reservationAffinity)
              .build();

      InsertInstanceRequest insertInstanceRequest = InsertInstanceRequest.newBuilder()
          .setProject(projectId)
          .setZone(zone)
          .setInstanceResource(instanceResource)
          .build();

      OperationFuture<Operation, Operation> operation = instancesClient.insertAsync(
          insertInstanceRequest);
      Operation response = operation.get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        return null;
      }
      return instancesClient.get(projectId, zone, instanceName);
    }
  }
}

Node.js

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

// Instantiate a reservationsClient
const instancesClient = new computeLib.InstancesClient();
// 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 create instance.
const projectId = await instancesClient.getProjectId();
// The zone in which to create instance.
const zone = 'us-central1-a';
// The name of the instance to create.
// const instanceName = 'instance-01';
// The name of the reservation to consume.
// Ensure that the specificReservationRequired field in reservation properties is set to true.
// const reservationName = 'reservation-01';
// Machine type to use for VM.
const machineType = 'n1-standard-4';

// Create instance to consume a specific single-project reservation
async function callCreateInstanceToConsumeSingleProjectReservation() {
  // Describe the size and source image of the boot disk to attach to the instance.
  // Ensure that the VM's properties match the reservation's VM properties,
  // including the zone, machine type (machine family, vCPUs, and memory),
  // minimum CPU platform, GPU amount and type, and local SSD interface and size
  const disk = new compute.Disk({
    boot: true,
    autoDelete: true,
    type: 'PERSISTENT',
    initializeParams: {
      diskSizeGb: '10',
      sourceImage: 'projects/debian-cloud/global/images/family/debian-12',
    },
  });

  //  Define networkInterface
  const networkInterface = new compute.NetworkInterface({
    name: 'global/networks/default',
  });

  // Define reservationAffinity
  const reservationAffinity = new compute.ReservationAffinity({
    consumeReservationType: 'SPECIFIC_RESERVATION',
    key: 'compute.googleapis.com/reservation-name',
    values: [reservationName],
  });

  // Create an instance
  const instance = new compute.Instance({
    name: instanceName,
    machineType: `zones/${zone}/machineTypes/${machineType}`,
    minCpuPlatform: 'Intel Skylake',
    disks: [disk],
    networkInterfaces: [networkInterface],
    reservationAffinity,
  });

  const [response] = await instancesClient.insert({
    project: projectId,
    instanceResource: instance,
    zone,
  });

  let operation = response.latestResponse;

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

  console.log(`Instance ${instanceName} created.`);
}

await callCreateInstanceToConsumeSingleProjectReservation();

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 consume_specific_single_project_reservation(
    project_id: str,
    zone: str,
    reservation_name: str,
    instance_name: str,
    machine_type: str = "n1-standard-1",
    min_cpu_platform: str = "Intel Ivy Bridge",
) -> compute_v1.Instance:
    """
    Creates a specific reservation in a single project and launches a VM
    that consumes the newly created reservation.
    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.
        instance_name (str): The name of the instance to create.
        machine_type (str): The machine type for the instance.
        min_cpu_platform (str): The minimum CPU platform for the instance.
    """
    instance_properties = (
        compute_v1.AllocationSpecificSKUAllocationReservedInstanceProperties(
            machine_type=machine_type,
            min_cpu_platform=min_cpu_platform,
        )
    )

    reservation = compute_v1.Reservation(
        name=reservation_name,
        specific_reservation=compute_v1.AllocationSpecificSKUReservation(
            count=3,
            instance_properties=instance_properties,
        ),
        # Only VMs that target the reservation by name can consume from this reservation
        specific_reservation_required=True,
    )

    # Create a reservation client
    client = compute_v1.ReservationsClient()
    operation = client.insert(
        project=project_id,
        zone=zone,
        reservation_resource=reservation,
    )
    wait_for_extended_operation(operation, "Reservation creation")

    instance = compute_v1.Instance()
    instance.name = instance_name
    instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
    instance.min_cpu_platform = min_cpu_platform
    instance.zone = zone

    # Set the reservation affinity to target the specific reservation
    instance.reservation_affinity = compute_v1.ReservationAffinity(
        consume_reservation_type="SPECIFIC_RESERVATION",  # Type of reservation to consume
        key="compute.googleapis.com/reservation-name",  # Key for the reservation
        values=[reservation_name],  # Reservation name to consume
    )
    # Define the disks for the instance
    instance.disks = [
        compute_v1.AttachedDisk(
            boot=True,  # Indicates that this is a boot disk
            auto_delete=True,  # The disk will be deleted when the instance is deleted
            initialize_params=compute_v1.AttachedDiskInitializeParams(
                source_image="projects/debian-cloud/global/images/family/debian-11",
                disk_size_gb=10,
            ),
        )
    ]
    instance.network_interfaces = [
        compute_v1.NetworkInterface(
            network="global/networks/default",  # The network to use
            access_configs=[
                compute_v1.AccessConfig(
                    name="External NAT",  # Name of the access configuration
                    type="ONE_TO_ONE_NAT",  # Type of access configuration
                )
            ],
        )
    ]
    # Create a request to insert the instance
    request = compute_v1.InsertInstanceRequest()
    request.zone = zone
    request.project = project_id
    request.instance_resource = instance

    vm_client = compute_v1.InstancesClient()
    operation = vm_client.insert(request)
    wait_for_extended_operation(operation, "instance creation")
    print(f"Instance {instance_name} with specific reservation created successfully.")

    return vm_client.get(project=project_id, zone=zone, instance=instance_name)

REST

  1. specificReservationRequired 필드를 true로 설정하여 reservation-02라는 예약을 생성합니다.

    POST https://compute.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/reservations
    
    {
      "name":"reservation-02",
      "specificReservation":{
        "count":"10",
        "instanceProperties":{
          "machineType":"n2-standard-32",
          "minCpuPlatform": "Intel Cascade Lake",
        }
      },
      "specificReservationRequired": true
    }
    
  2. reservationAffinity 필드를 사용하여 이름으로 reservation-02을 타겟팅하는 VM을 생성합니다.

    영역, 머신 유형(머신 계열, vCPU, 메모리), 최소 CPU 플랫폼, GPU 크기 및 유형, 로컬 SSD 인터페이스 및 크기를 포함하여 VM의 속성이 예약의 VM 속성과 일치하는지 확인합니다.

    POST https://compute.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/instances
    
    {
      "name": "instance-2",
      "machineType": "zones/us-central1-a/machineTypes/n2-standard-32",
      "minCpuPlatform": "Intel Cascade Lake",
      "disks": [
        {
          "boot": true,
          "initializeParams": {
            "sourceImage": "projects/debian-clouid/global/images/family/debian-12"
          }
        }
      ],
      "networkInterfaces": [
        {
          "network": "global/networks/default"
        }
      ],
      "reservationAffinity": {
        "consumeReservationType": "SPECIFIC_RESERVATION",
        "key": "compute.googleapis.com/reservation-name",
        "values": [
          "reservation-02"
        ]
      }
    }
    

특정 공유 예약 사용

특정 공유 예약을 사용하려면 다음 옵션 중 하나를 선택합니다.

콘솔

  1. 공유 예약을 만들고 이름으로 해당 예약을 명시적으로 타겟팅하는 VM에서만 이 예약의 리소스를 사용할 수 있도록 하려면 다음 단계를 따르세요.

    1. 다음 옵션 중 하나를 선택합니다.

      • 독립형 예약을 만들려면 다음을 수행합니다.

        1. Google Cloud console에서 예약 페이지로 이동합니다.

          예약으로 이동

        2. 온디맨드 예약 탭(기본값)에서 예약 만들기를 클릭합니다.

          예약 만들기 페이지가 열립니다.

      • 약정에 연결된 예약을 만들려면 다음을 수행합니다.

        1. Google Cloud 콘솔에서 약정 사용 할인 페이지로 이동합니다.

          약정 사용 할인으로 이동

        2. 약정 구매를 클릭합니다.

          약정 사용 할인 구매 페이지가 열립니다.

        3. 약정 속성을 지정합니다. 그런 다음 예약 섹션에서 항목 추가를 클릭합니다.

          새 예약 추가 섹션이 표시됩니다.

          연결된 예약이 있는 약정을 구매하는 방법에 대한 자세한 내용은 예약이 연결된 약정 구매를 참조하세요.

    2. 이름 필드에 예약 이름을 입력합니다. 이 예시에서는 reservation-02를 입력합니다.

    3. 리소스를 예약할 리전영역을 선택합니다. 이 예시에서는 us-central1을 리전으로, us-central1-a를 영역으로 선택합니다.

    4. 예약을 공유 예약으로 지정하려면 공유 유형으로 공유를 선택합니다.

    5. 프로젝트 추가를 클릭하고 예약을 공유하려는 현재 프로젝트의 조직에서 프로젝트를 선택합니다.

    6. 이름을 통해 이 예약을 명시적으로 타겟팅하는 일치하는 VM만 이 예약을 사용할 수 있도록 하려면 VM 인스턴스와 함께 사용 섹션에서 특정 예약 선택을 선택합니다.

    7. VM 인스턴스 수 필드에 예약할 VM 수를 입력합니다. 이 예시에서는 10을 입력합니다.

    8. 각 VM별로 예약할 리소스를 지정합니다.

      • 기존 인스턴스 템플릿과 일치하는 VM을 예약하려면 인스턴스 템플릿 사용을 선택하고 목록에서 인스턴스 템플릿을 선택합니다.
      • 또는 머신 유형 지정을 선택하고 다음을 지정합니다.
        1. 머신 계열, 시리즈, 머신 유형 필드에서 머신 계열, 시리즈, 머신 유형을 선택합니다.
        2. 선택사항: 최소 CPU 플랫폼 또는 GPU를 지정합니다.
          1. CPU 플랫폼 및 GPU 섹션을 확장하려면 확장 화살표를 클릭합니다.
          2. 선택사항: 최소 CPU 플랫폼을 지정하려면 CPU 플랫폼 목록에서 옵션을 선택합니다.
          3. 선택사항: GPU를 추가하려면 GPU 추가를 클릭합니다. 그런 다음 GPU 유형 필드와 GPU 수 필드에서 각 VM의 GPU 유형과 수를 선택합니다.
        3. 선택사항: 로컬 SSD를 추가합니다.
          1. 디스크 수 필드에서 각 VM의 로컬 SSD 수를 선택합니다.
          2. 인터페이스 유형 필드에서 로컬 SSD의 인터페이스를 선택합니다.

      이 예시에서는 머신 유형 지정을 선택합니다. 그런 다음 General-purpose 머신 계열 및 N2 시리즈에 대해 n2-standard-32 머신 유형을 선택하고 최소 CPU 플랫폼 Intel Cascade Lake를 선택합니다. 1. 예약 만들기를 완료합니다.

      • 독립형 예약을 만드는 경우 만들기를 클릭합니다.

      • 약정에 연결된 예약을 만드는 경우 다음 안내를 따르세요.

        1. 이 예약의 속성 지정을 완료하려면 완료를 클릭합니다.
        2. 약정 및 연결된 예약 만들기를 완료하려면 구매를 클릭합니다.
  2. 동일한 프로젝트 또는 예약이 공유된 프로젝트에서 이름으로 특정 예약을 타겟팅하는 VM을 만듭니다.

    영역, 머신 유형(머신 계열, vCPU, 메모리), 최소 CPU 플랫폼, GPU 크기 및 유형, 로컬 SSD 인터페이스 및 크기를 포함하여 VM의 속성이 특정 예약의 VM 속성과 일치하는지 확인합니다.

    1. Google Cloud 콘솔에서 인스턴스 만들기 페이지로 이동합니다.

      인스턴스 만들기로 이동

      인스턴스 만들기 페이지가 열립니다.

    2. VM의 이름을 지정합니다.

    3. 다음 섹션에서는 선택적인 속성을 포함하여 예약의 모든 속성과 정확하게 일치하는 구성을 선택합니다. 이 예시에서는 다음 VM 속성이 reservation-02과 일치하는지 확인해야 합니다.

      • 리전: us-central1
      • 영역: us-central1-a
      • 머신 유형: n2-standard-32
      • 최소 CPU 플랫폼: Intel Cascade Lake
      • GPU: 없음
      • 로컬 SSD: 없음
    4. 고급 옵션 섹션을 펼친 후 관리 섹션을 펼칩니다. 예약 목록에서 특정 예약 선택을 선택한 후 다음을 수행합니다.

      1. 현재 프로젝트와 예약이 공유된 예약 프로젝트를 선택합니다. 이 예시에서는 reservation-02를 만들기 위해 사용된 프로젝트를 선택합니다.
      2. 이 VM에 사용하려는 공유 예약의 예약 이름을 선택합니다. 이 예시에서는 reservation-02를 선택합니다.
    5. 만들기를 클릭하여 VM을 만듭니다.

gcloud

  1. --require-specific-reservation 플래그로 reservation-02라는 예약을 생성합니다. 이렇게 예약된 리소스는 이름으로 이 예약을 명시적으로 타겟팅하는 VM에서만 사용할 수 있습니다.

    gcloud compute reservations create reservation-02 \
        --machine-type=n2-standard-32 \
        --min-cpu-platform="Intel Cascade Lake" \
        --vm-count=10 \
        --zone=us-central1-a \
        --project=my-owner-project \
        --share-setting=projects \
        --share-with=project-1,project-2 \
        --require-specific-reservation
    
  2. --reservation-affinity--reservation 플래그를 사용하여 이름으로 reservation-02를 타겟팅하는 VM을 만듭니다. 이 예약을 공유하는 소비자 프로젝트에서 이 예약을 사용하려면 예약을 만든 프로젝트인 my-owner-project도 지정해야 합니다.

    영역, 머신 유형(머신 계열, vCPU, 메모리), 최소 CPU 플랫폼, GPU 크기 및 유형, 로컬 SSD 인터페이스 및 크기를 포함하여 VM의 속성이 예약의 VM 속성과 일치하는지 확인합니다.

    gcloud compute instances create instance-2 \
        --machine-type=n2-standard-32 \
        --min-cpu-platform="Intel Cascade Lake" \
        --zone=us-central1-a \
        --reservation-affinity=specific \
        --reservation=projects/my-owner-project/reservations/reservation-02
    

Go

import (
	"context"
	"fmt"
	"io"

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

// consumeSpecificSharedReservation consumes specific shared reservation in particular zone
func consumeSpecificSharedReservation(w io.Writer, client InstanceClientInterface, projectID, baseProjectId, zone, instanceName, reservationName string) error {
	// client, err := compute.NewInstancesRESTClient(ctx)
	// projectID := "your_project_id". Project where reservation is created.
	// baseProjectId := "shared_project_id". Project where instance will be consumed and created.
	// zone := "us-west3-a"
	// reservationName := "your_reservation_name"
	// instanceName := "your_instance_name"

	ctx := context.Background()
	machineType := fmt.Sprintf("zones/%s/machineTypes/%s", zone, "n2-standard-32")
	sourceImage := "projects/debian-cloud/global/images/family/debian-12"
	sharedReservation := fmt.Sprintf("projects/%s/reservations/%s", baseProjectId, reservationName)

	req := &computepb.InsertInstanceRequest{
		Project: projectID,
		Zone:    zone,
		InstanceResource: &computepb.Instance{
			Disks: []*computepb.AttachedDisk{
				{
					InitializeParams: &computepb.AttachedDiskInitializeParams{
						DiskSizeGb:  proto.Int64(10),
						SourceImage: proto.String(sourceImage),
					},
					AutoDelete: proto.Bool(true),
					Boot:       proto.Bool(true),
					Type:       proto.String(computepb.AttachedDisk_PERSISTENT.String()),
				},
			},
			MachineType:    proto.String(machineType),
			MinCpuPlatform: proto.String("Intel Cascade Lake"),
			Name:           proto.String(instanceName),
			NetworkInterfaces: []*computepb.NetworkInterface{
				{
					Name: proto.String("global/networks/default"),
				},
			},
			// specifies particular reservation, which should be consumed
			ReservationAffinity: &computepb.ReservationAffinity{
				ConsumeReservationType: proto.String("SPECIFIC_RESERVATION"),
				Key:                    proto.String("compute.googleapis.com/reservation-name"),
				Values:                 []string{sharedReservation},
			},
		},
	}

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

	if op != nil {
		if err = op.Wait(ctx); err != nil {
			return fmt.Errorf("unable to wait for the operation: %w", err)
		}
	}
	fmt.Fprintf(w, "Instance created from shared reservation\n")

	return nil
}

자바

import static com.google.cloud.compute.v1.ReservationAffinity.ConsumeReservationType.SPECIFIC_RESERVATION;

import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.compute.v1.AttachedDisk;
import com.google.cloud.compute.v1.AttachedDiskInitializeParams;
import com.google.cloud.compute.v1.InsertInstanceRequest;
import com.google.cloud.compute.v1.Instance;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.NetworkInterface;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.ReservationAffinity;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ConsumeSpecificSharedReservation {
  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 the reservation is located.
    String zone = "us-central1-a";
    // Name of the reservation you want to query.
    String reservationName = "YOUR_RESERVATION_NAME";
    // Name of the VM instance you want to query.
    String instanceName = "YOUR_INSTANCE_NAME";
    // machineType: machine type of the VM being created.
    // *   For a list of machine types, see https://cloud.google.com/compute/docs/machine-types
    String machineTypeName = "n1-standard-4";
    // sourceImage: path to the operating system image to mount.
    // *   For details about images you can mount, see https://cloud.google.com/compute/docs/images
    String sourceImage = "projects/debian-cloud/global/images/family/debian-11";
    // diskSizeGb: storage size of the boot disk to attach to the instance.
    long diskSizeGb = 10L;
    // networkName: network interface to associate with the instance.
    String networkName = "default";
    // Minimum CPU platform of the instances.
    String minCpuPlatform = "Intel Skylake";

    createInstanceAsync(projectId, zone, instanceName, reservationName, machineTypeName,
        sourceImage, diskSizeGb, networkName, minCpuPlatform);
  }

  // Create a virtual machine targeted with the reserveAffinity field.
  // Ensure that the VM's properties match the reservation's VM properties.
  public static Instance createInstanceAsync(String projectId, String zone, String instanceName,
      String reservationName, String machineTypeName, String sourceImage, long diskSizeGb,
      String networkName, String minCpuPlatform)
      throws IOException, InterruptedException, ExecutionException, TimeoutException {
    String machineType = String.format("zones/%s/machineTypes/%s", zone, machineTypeName);
    // To consume this reservation from any consumer projects that this reservation is shared with,
    // you must also specify the owner project of the reservation - the path to the reservation.
    String reservationPath =
        String.format("projects/%s/reservations/%s", projectId, reservationName);
    // 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 (InstancesClient instancesClient = InstancesClient.create()) {
      AttachedDisk disk =
          AttachedDisk.newBuilder()
              .setBoot(true)
              .setAutoDelete(true)
              .setType(AttachedDisk.Type.PERSISTENT.toString())
              .setDeviceName("disk-1")
              .setInitializeParams(
                  AttachedDiskInitializeParams.newBuilder()
                      .setSourceImage(sourceImage)
                      .setDiskSizeGb(diskSizeGb)
                      .build())
              .build();

      NetworkInterface networkInterface = NetworkInterface.newBuilder()
          .setName(networkName)
          .build();

      ReservationAffinity reservationAffinity =
          ReservationAffinity.newBuilder()
              .setConsumeReservationType(SPECIFIC_RESERVATION.toString())
              .setKey("compute.googleapis.com/reservation-name")
              // Set specific reservation
              .addValues(reservationPath)
              .build();

      Instance instanceResource =
          Instance.newBuilder()
              .setName(instanceName)
              .setMachineType(machineType)
              .addDisks(disk)
              .addNetworkInterfaces(networkInterface)
              .setMinCpuPlatform(minCpuPlatform)
              .setReservationAffinity(reservationAffinity)
              .build();

      InsertInstanceRequest insertInstanceRequest = InsertInstanceRequest.newBuilder()
          .setProject(projectId)
          .setZone(zone)
          .setInstanceResource(instanceResource)
          .build();

      OperationFuture<Operation, Operation> operation = instancesClient.insertAsync(
          insertInstanceRequest);
      Operation response = operation.get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        return null;
      }
      return instancesClient.get(projectId, zone, instanceName);
    }
  }
}

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 consume_specific_shared_project_reservation(
    owner_project_id: str,
    shared_project_id: str,
    zone: str,
    reservation_name: str,
    instance_name: str,
    machine_type: str = "n1-standard-1",
    min_cpu_platform: str = "Intel Ivy Bridge",
) -> compute_v1.Instance:
    """
    Creates a specific reservation in a single project and launches a VM
    that consumes the newly created reservation.
    Args:
        owner_project_id (str): The ID of the Google Cloud project.
        shared_project_id: The ID of the owner project of the reservation in the same zone.
        zone (str): The zone to create the reservation.
        reservation_name (str): The name of the reservation to create.
        instance_name (str): The name of the instance to create.
        machine_type (str): The machine type for the instance.
        min_cpu_platform (str): The minimum CPU platform for the instance.
    """
    instance_properties = (
        compute_v1.AllocationSpecificSKUAllocationReservedInstanceProperties(
            machine_type=machine_type,
            min_cpu_platform=min_cpu_platform,
        )
    )

    reservation = compute_v1.Reservation(
        name=reservation_name,
        specific_reservation=compute_v1.AllocationSpecificSKUReservation(
            count=3,
            instance_properties=instance_properties,
        ),
        # Only VMs that target the reservation by name can consume from this reservation
        specific_reservation_required=True,
        share_settings=compute_v1.ShareSettings(
            share_type="SPECIFIC_PROJECTS",
            project_map={
                shared_project_id: compute_v1.ShareSettingsProjectConfig(
                    project_id=shared_project_id
                )
            },
        ),
    )

    # Create a reservation client
    client = compute_v1.ReservationsClient()
    operation = client.insert(
        project=owner_project_id,
        zone=zone,
        reservation_resource=reservation,
    )
    wait_for_extended_operation(operation, "Reservation creation")

    instance = compute_v1.Instance()
    instance.name = instance_name
    instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
    instance.min_cpu_platform = min_cpu_platform
    instance.zone = zone

    # Set the reservation affinity to target the specific reservation
    instance.reservation_affinity = compute_v1.ReservationAffinity(
        consume_reservation_type="SPECIFIC_RESERVATION",  # Type of reservation to consume
        key="compute.googleapis.com/reservation-name",
        # To consume this reservation from any consumer projects, specify the owner project of the reservation
        values=[f"projects/{owner_project_id}/reservations/{reservation_name}"],
    )
    # Define the disks for the instance
    instance.disks = [
        compute_v1.AttachedDisk(
            boot=True,  # Indicates that this is a boot disk
            auto_delete=True,  # The disk will be deleted when the instance is deleted
            initialize_params=compute_v1.AttachedDiskInitializeParams(
                source_image="projects/debian-cloud/global/images/family/debian-11",
                disk_size_gb=10,
            ),
        )
    ]
    instance.network_interfaces = [
        compute_v1.NetworkInterface(
            network="global/networks/default",  # The network to use
            access_configs=[
                compute_v1.AccessConfig(
                    name="External NAT",  # Name of the access configuration
                    type="ONE_TO_ONE_NAT",  # Type of access configuration
                )
            ],
        )
    ]
    # Create a request to insert the instance
    request = compute_v1.InsertInstanceRequest()
    request.zone = zone
    # The instance will be created in the shared project
    request.project = shared_project_id
    request.instance_resource = instance

    vm_client = compute_v1.InstancesClient()
    operation = vm_client.insert(request)
    wait_for_extended_operation(operation, "instance creation")
    print(f"Instance {instance_name} from project {owner_project_id} created.")
    # The instance is created in the shared project, so we return it from there.
    return vm_client.get(project=shared_project_id, zone=zone, instance=instance_name)

REST

  1. specificReservationRequired 필드를 true로 설정하여 reservation-02라는 예약을 생성합니다.

    POST https://compute.googleapis.com/compute/v1/projects/my-owner-project/zones/us-central1-a/reservations
    
    {
      "name":"reservation-02",
      "specificReservation":{
        "count":"10",
        "instanceProperties":{
          "machineType":"n2-standard-32",
          "minCpuPlatform": "Intel Cascade Lake"
        }
      },
      "shareSettings": {
        "shareType": "SPECIFIC_PROJECTS",
        "projectMap": {
          "project-1": {
            "projectId": "project-1"
          },
          "project-2": {
            "projectId": "project-2"
          }
        }
      },
      "specificReservationRequired": true
    }
    
  2. reservationAffinity 필드를 사용하여 이름으로 reservation-02을 타겟팅하는 VM을 생성합니다. 이 예약을 공유하는 소비자 프로젝트에서 이 예약을 사용하려면 예약의 소유자 프로젝트인 my-owner-project도 지정해야 합니다.

    영역, 머신 유형(머신 계열, vCPU, 메모리), 최소 CPU 플랫폼, GPU 크기 및 유형, 로컬 SSD 인터페이스 및 크기를 포함하여 VM의 속성이 예약의 VM 속성과 일치하는지 확인합니다.

    POST https://compute.googleapis.com/compute/v1/projects/project-2/zones/us-central1-a/instances
    
    {
      "name": "instance-2",
      "machineType": "zones/us-central1-a/machineTypes/n2-standard-32",
      "minCpuPlatform": "Intel Cascade Lake",
      "disks": [
        {
          "boot": true,
          "initializeParams": {
            "sourceImage": "projects/debian-clouid/global/images/family/debian-12"
          }
        }
      ],
      "networkInterfaces": [
        {
          "network": "global/networks/default"
        }
      ],
      "reservationAffinity": {
        "consumeReservationType": "SPECIFIC_RESERVATION",
        "key": "compute.googleapis.com/reservation-name",
        "values": [
          "projects/my-owner-project/reservations/reservation-02"
        ]
      }
    }
    

예약을 사용하지 않고 VM 만들기

자동으로 사용되는 예약을 만들면 프로젝트에서 일치하는 속성이 있는 실행 중인 모든 VM에서 예약을 사용할 수 있습니다. 하나 이상의 VM에서 예약을 사용하지 못하도록 하려면 다음을 수행합니다.

  • 이 섹션에 설명된 대로 예약을 명시적으로 사용하지 않도록 VM의 예약 어피니티 속성을 설정합니다.

  • VM이 예약의 VM 속성과 일치하지 않는지 확인합니다.

예약을 명시적으로 사용하지 않는 VM을 만들려면 다음 방법 중 하나를 선택합니다.

예약을 사용하지 않는 VM 만들기

예약을 명시적으로 사용하지 않는 VM을 만들려면 다음 옵션 중 하나를 선택합니다.

콘솔

  1. Google Cloud 콘솔에서 인스턴스 만들기 페이지로 이동합니다.

    인스턴스 만들기로 이동

  2. 이름 필드에 VM의 이름을 입력합니다.

  3. 리전영역 목록에서 VM을 만들 리전과 영역을 선택합니다.

  4. 머신 구성 섹션에서 VM에 사용할 머신 유형을 지정합니다.

  5. 고급 옵션 섹션을 펼친 후 다음을 수행합니다.

    1. 관리 섹션을 펼칩니다.

    2. 예약 섹션의 애플리케이션 정책 목록에서 사용 안함을 선택합니다.

  6. 만들기를 클릭합니다.

gcloud

예약을 명시적으로 사용하지 않는 VM을 만들려면 --reservation-affinity=none 플래그와 함께 gcloud compute instances create 명령어를 사용합니다.

gcloud compute instances create VM_NAME \
    --machine-type=MACHINE_TYPE \
    --reservation-affinity=none \
    --zone=ZONE

다음을 바꿉니다.

  • VM_NAME: VM의 이름입니다.

  • MACHINE_TYPE: VM에 사용할 머신 유형입니다.

  • ZONE: VM을 만들 영역입니다.

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

// createInstanceNotConsumeReservation creates VM, without consuming reservation
func createInstanceNotConsumeReservation(w io.Writer, projectID, zone, instanceName string) error {
	ctx := context.Background()
	machineType := fmt.Sprintf("zones/%s/machineTypes/%s", zone, "n2-standard-32")
	sourceImage := "projects/debian-cloud/global/images/family/debian-12"

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

	req := &computepb.InsertInstanceRequest{
		Project: projectID,
		Zone:    zone,
		InstanceResource: &computepb.Instance{
			Disks: []*computepb.AttachedDisk{
				{
					InitializeParams: &computepb.AttachedDiskInitializeParams{
						DiskSizeGb:  proto.Int64(10),
						SourceImage: proto.String(sourceImage),
					},
					AutoDelete: proto.Bool(true),
					Boot:       proto.Bool(true),
					Type:       proto.String(computepb.AttachedDisk_PERSISTENT.String()),
				},
			},
			MachineType:    proto.String(machineType),
			MinCpuPlatform: proto.String("Intel Cascade Lake"),
			Name:           proto.String(instanceName),
			NetworkInterfaces: []*computepb.NetworkInterface{
				{
					Name: proto.String("global/networks/default"),
				},
			},
			ReservationAffinity: &computepb.ReservationAffinity{
				ConsumeReservationType: proto.String("NO_RESERVATION"),
			},
		},
	}

	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
}

자바

import static com.google.cloud.compute.v1.ReservationAffinity.ConsumeReservationType.NO_RESERVATION;

import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.compute.v1.AttachedDisk;
import com.google.cloud.compute.v1.AttachedDiskInitializeParams;
import com.google.cloud.compute.v1.InsertInstanceRequest;
import com.google.cloud.compute.v1.Instance;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.NetworkInterface;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.ReservationAffinity;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateInstanceWithoutConsumingReservation {
  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 you want to use.
    String zone = "us-central1-a";
    // Name of the VM instance you want to query.
    String instanceName = "YOUR_INSTANCE_NAME";
    // machineType: machine type of the VM being created.
    // *   This value uses the format zones/{zone}/machineTypes/{type_name}.
    // *   For a list of machine types, see https://cloud.google.com/compute/docs/machine-types
    String machineTypeName = "n1-standard-1";
    // sourceImage: path to the operating system image to mount.
    // *   For details about images you can mount, see https://cloud.google.com/compute/docs/images
    String sourceImage = "projects/debian-cloud/global/images/family/debian-11";
    // diskSizeGb: storage size of the boot disk to attach to the instance.
    long diskSizeGb = 10L;
    // networkName: network interface to associate with the instance.
    String networkName = "default";

    createInstanceWithoutConsumingReservationAsync(projectId, zone, instanceName,
        machineTypeName, sourceImage, diskSizeGb, networkName);
  }

  // Create a virtual machine that explicitly doesn't consume reservations
  public static Instance createInstanceWithoutConsumingReservationAsync(
      String project, String zone, String instanceName,
      String machineTypeName, String sourceImage, long diskSizeGb, String networkName)
      throws IOException, InterruptedException, ExecutionException, TimeoutException {
    String machineType = String.format("zones/%s/machineTypes/%s", zone, machineTypeName);

    // 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 (InstancesClient instancesClient = InstancesClient.create()) {
      AttachedDisk disk =
          AttachedDisk.newBuilder()
              .setBoot(true)
              .setAutoDelete(true)
              .setType(AttachedDisk.Type.PERSISTENT.toString())
              .setDeviceName("disk-1")
              .setInitializeParams(
                  AttachedDiskInitializeParams.newBuilder()
                      .setSourceImage(sourceImage)
                      .setDiskSizeGb(diskSizeGb)
                      .build())
              .build();

      NetworkInterface networkInterface = NetworkInterface.newBuilder()
          .setName(networkName)
          .build();

      ReservationAffinity reservationAffinity =
          ReservationAffinity.newBuilder()
              .setConsumeReservationType(NO_RESERVATION.toString())
              .build();

      Instance instanceResource =
          Instance.newBuilder()
              .setName(instanceName)
              .setMachineType(machineType)
              .addDisks(disk)
              .addNetworkInterfaces(networkInterface)
              .setReservationAffinity(reservationAffinity)
              .build();

      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()) {
        return null;
      }
      return instancesClient.get(project, zone, instanceName);
    }
  }
}

Node.js

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

// Instantiate a reservationsClient
const instancesClient = new computeLib.InstancesClient();
// 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 create instance.
const projectId = await instancesClient.getProjectId();
// The zone in which to create instance.
const zone = 'us-central1-a';
// The name of the instance to create.
// const instanceName = 'instance-01';
// Machine type to use for VM.
const machineType = 'n1-standard-4';

// Create a VM that explicitly doesn't consume reservations
async function callCreateInstanceToNotConsumeReservation() {
  // Describe the size and source image of the boot disk to attach to the instance.
  const disk = new compute.Disk({
    boot: true,
    autoDelete: true,
    type: 'PERSISTENT',
    initializeParams: {
      diskSizeGb: '10',
      sourceImage: 'projects/debian-cloud/global/images/family/debian-12',
    },
  });

  //  Define networkInterface
  const networkInterface = new compute.NetworkInterface({
    name: 'global/networks/default',
  });

  // Define reservationAffinity
  const reservationAffinity = new compute.ReservationAffinity({
    consumeReservationType: 'NO_RESERVATION',
  });

  // Create an instance
  const instance = new compute.Instance({
    name: instanceName,
    machineType: `zones/${zone}/machineTypes/${machineType}`,
    minCpuPlatform: 'Intel Skylake',
    disks: [disk],
    networkInterfaces: [networkInterface],
    reservationAffinity,
  });

  const [response] = await instancesClient.insert({
    project: projectId,
    instanceResource: instance,
    zone,
  });

  let operation = response.latestResponse;

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

  console.log(`Instance ${instanceName} created.`);
}

await callCreateInstanceToNotConsumeReservation();

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_vm_not_consume_reservation(
    project_id: str, zone: str, instance_name: str, machine_type: str = "n2-standard-2"
) -> compute_v1.Instance:
    """Creates a VM that explicitly doesn't consume reservations
    Args:
        project_id (str): The ID of the Google Cloud project.
        zone (str): The zone where the VM will be created.
        instance_name (str): The name of the instance to create.
        machine_type (str, optional): The machine type for the instance.
    Returns:
        compute_v1.Instance: The created instance.
    """
    instance = compute_v1.Instance()
    instance.name = instance_name
    instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
    instance.zone = zone

    instance.disks = [
        compute_v1.AttachedDisk(
            boot=True,  # Indicates that this is a boot disk
            auto_delete=True,  # The disk will be deleted when the instance is deleted
            initialize_params=compute_v1.AttachedDiskInitializeParams(
                source_image="projects/debian-cloud/global/images/family/debian-11",
                disk_size_gb=10,
            ),
        )
    ]

    instance.network_interfaces = [
        compute_v1.NetworkInterface(
            network="global/networks/default",  # The network to use
            access_configs=[
                compute_v1.AccessConfig(
                    name="External NAT",  # Name of the access configuration
                    type="ONE_TO_ONE_NAT",  # Type of access configuration
                )
            ],
        )
    ]

    # Set the reservation affinity to not consume any reservation
    instance.reservation_affinity = compute_v1.ReservationAffinity(
        consume_reservation_type="NO_RESERVATION",  # Prevents the instance from consuming reservations
    )

    # Create a request to insert the instance
    request = compute_v1.InsertInstanceRequest()
    request.zone = zone
    request.project = project_id
    request.instance_resource = instance

    vm_client = compute_v1.InstancesClient()
    operation = vm_client.insert(request)
    wait_for_extended_operation(operation, "Instance creation")

    print(f"Creating the {instance_name} instance in {zone}...")

    return vm_client.get(project=project_id, zone=zone, instance=instance_name)

REST

예약을 명시적으로 사용하지 않는 VM을 만들려면 instances.insert 메서드POST 요청을 수행합니다. 요청 본문에 NO_RESERVATION으로 설정된 consumeReservationType 필드를 포함합니다.

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

{
  "name": "VM_NAME",
  "machineType": "zones/ZONE/machineTypes/MACHINE_TYPE",
  "disks": [
    {
      "boot": true,
      "initializeParams": {
        "sourceImage": "projects/IMAGE_PROJECT/global/images/IMAGE"
      }
    }
  ],
  "networkInterfaces": [
    {
      "network": "global/networks/default"
    }
  ],
  "reservationAffinity": {
    "consumeReservationType": "NO_RESERVATION"
  }
}

다음을 바꿉니다.

  • PROJECT_ID: VM을 만들 프로젝트의 ID입니다.

  • ZONE: VM을 만들 영역입니다.

  • VM_NAME: VM의 이름입니다.

  • MACHINE_TYPE: VM에 사용할 머신 유형입니다.

  • IMAGE_PROJECT: OS 이미지가 포함된 이미지 프로젝트입니다(예: debian-cloud). 지원되는 이미지 프로젝트에 대한 자세한 내용은 공개 이미지를 참조하세요.

  • IMAGE: 다음 중 하나를 지정합니다.

    • OS 이미지의 특정 버전입니다(예: debian-12-bookworm-v20240617).

    • 이미지 계열이며 형식은 family/IMAGE_FAMILY여야 합니다. 중단되지 않은 최신 OS 이미지를 지정합니다. 예를 들어 family/debian-12를 지정하면 Debian 12 이미지 계열의 최신 버전이 사용됩니다. 이미지 계열 사용에 대한 자세한 내용은 이미지 계열 권장사항을 참조하세요.

VM 만들기에 대한 자세한 내용은 Compute Engine 인스턴스 만들기 및 시작을 참고하세요.

예약을 사용하지 않는 인스턴스 템플릿 만들기

예약을 명시적으로 사용하지 않는 VM을 만드는 인스턴스 템플릿을 만들려면 다음 옵션 중 하나를 선택합니다.

콘솔

  1. Google Cloud 콘솔에서 인스턴스 템플릿 만들기 페이지로 이동합니다.

    인스턴스 템플릿 만들기로 이동

  2. 이름 필드에 인스턴스 템플릿의 이름을 입력합니다.

  3. 위치 섹션에서 리전(기본값) 또는 전역 인스턴스 템플릿을 만들지 여부를 지정합니다.

  4. 머신 구성 섹션에서 템플릿을 사용하여 만든 VM에 사용할 머신 유형을 지정합니다.

  5. 고급 옵션 섹션을 펼친 후 다음을 수행합니다.

    1. 관리 섹션을 펼칩니다.

    2. 예약 섹션의 애플리케이션 정책 목록에서 사용 안함을 선택합니다.

  6. 만들기를 클릭합니다.

gcloud

예약을 명시적으로 사용하지 않는 VM을 만드는 인스턴스 템플릿을 만들려면 --reservation-affinity=none 플래그와 함께 gcloud compute instances-templates create 명령어를 사용합니다.

예를 들어 예약을 명시적으로 사용하지 않는 VM을 만드는 전역 인스턴스 템플릿을 만들려면 다음 명령어를 실행합니다.

gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME \
    --machine-type=MACHINE_TYPE \
    --reservation-affinity=none

다음을 바꿉니다.

  • INSTANCE_TEMPLATE_NAME: 인스턴스 템플릿의 이름입니다.

  • MACHINE_TYPE: 인스턴스 템플릿을 사용하여 만든 VM에 사용할 머신 유형입니다.

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

// createInstanceNotConsumeReservation creates a new instance template, which won't consume reservations
func createTemplateNotConsumeReservation(w io.Writer, projectID, templateName string) error {
	// projectID := "your_project_id"
	// templateName := "your_template_name"

	ctx := context.Background()
	instanceTemplatesClient, err := compute.NewInstanceTemplatesRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewInstanceTemplatesRESTClient: %w", err)
	}
	defer instanceTemplatesClient.Close()

	req := &computepb.InsertInstanceTemplateRequest{
		Project: projectID,
		InstanceTemplateResource: &computepb.InstanceTemplate{
			Name: proto.String(templateName),
			Properties: &computepb.InstanceProperties{
				// The template describes the size and source image of the boot disk
				// to attach to the instance.
				Disks: []*computepb.AttachedDisk{
					{
						InitializeParams: &computepb.AttachedDiskInitializeParams{
							DiskSizeGb:  proto.Int64(250),
							SourceImage: proto.String("projects/debian-cloud/global/images/family/debian-11"),
						},
						AutoDelete: proto.Bool(true),
						Boot:       proto.Bool(true),
					},
				},
				MachineType: proto.String("e2-standard-4"),
				// The template connects the instance to the `default` network,
				// without specifying a subnetwork.
				NetworkInterfaces: []*computepb.NetworkInterface{
					{
						Name: proto.String("global/networks/default"),
						// The template lets the instance use an external IP address.
						AccessConfigs: []*computepb.AccessConfig{
							{
								Name:        proto.String("External NAT"),
								Type:        proto.String(computepb.AccessConfig_ONE_TO_ONE_NAT.String()),
								NetworkTier: proto.String(computepb.AccessConfig_PREMIUM.String()),
							},
						},
					},
				},
				ReservationAffinity: &computepb.ReservationAffinity{
					ConsumeReservationType: proto.String("NO_RESERVATION"),
				},
			},
		},
	}

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

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

	fmt.Fprintf(w, "Instance template created\n")

	return nil
}

자바

import static com.google.cloud.compute.v1.ReservationAffinity.ConsumeReservationType.NO_RESERVATION;

import com.google.cloud.compute.v1.AccessConfig;
import com.google.cloud.compute.v1.AttachedDisk;
import com.google.cloud.compute.v1.AttachedDiskInitializeParams;
import com.google.cloud.compute.v1.InsertInstanceTemplateRequest;
import com.google.cloud.compute.v1.InstanceProperties;
import com.google.cloud.compute.v1.InstanceTemplate;
import com.google.cloud.compute.v1.InstanceTemplatesClient;
import com.google.cloud.compute.v1.NetworkInterface;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.ReservationAffinity;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateTemplateWithoutConsumingReservation {
  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 template you want to query.
    String templateName = "YOUR_INSTANCE_TEMPLATE_NAME";
    String machineType = "e2-standard-4";
    String sourceImage = "projects/debian-cloud/global/images/family/debian-11";

    createTemplateWithoutConsumingReservationAsync(
        projectId, templateName, machineType, sourceImage);
  }


  // Create a template that explicitly doesn't consume any reservations.
  public static InstanceTemplate createTemplateWithoutConsumingReservationAsync(
      String projectId, String templateName, String machineType, String sourceImage)
      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 (InstanceTemplatesClient instanceTemplatesClient = InstanceTemplatesClient.create()) {
      AttachedDisk attachedDisk = AttachedDisk.newBuilder()
          .setInitializeParams(AttachedDiskInitializeParams.newBuilder()
              .setSourceImage(sourceImage)
              .setDiskType("pd-balanced")
              .setDiskSizeGb(250)
              .build())
          .setAutoDelete(true)
          .setBoot(true)
          .build();

      NetworkInterface networkInterface = NetworkInterface.newBuilder()
          .setName("global/networks/default")
          .addAccessConfigs(AccessConfig.newBuilder()
              .setName("External NAT")
              .setType(AccessConfig.Type.ONE_TO_ONE_NAT.toString())
              .setNetworkTier(AccessConfig.NetworkTier.PREMIUM.toString())
              .build())
          .build();

      ReservationAffinity reservationAffinity =
          ReservationAffinity.newBuilder()
              .setConsumeReservationType(NO_RESERVATION.toString())
              .build();

      InstanceProperties instanceProperties = InstanceProperties.newBuilder()
          .addDisks(attachedDisk)
          .setMachineType(machineType)
          .setReservationAffinity(reservationAffinity)
          .addNetworkInterfaces(networkInterface)
          .build();

      InsertInstanceTemplateRequest insertInstanceTemplateRequest = InsertInstanceTemplateRequest
          .newBuilder()
          .setProject(projectId)
          .setInstanceTemplateResource(InstanceTemplate.newBuilder()
              .setName(templateName)
              .setProperties(instanceProperties)
              .build())
          .build();

      Operation response = instanceTemplatesClient.insertAsync(insertInstanceTemplateRequest)
          .get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        return null;
      }
      return instanceTemplatesClient.get(projectId, templateName);
    }
  }
}

Node.js

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

// Instantiate an instanceTemplatesClient
const instanceTemplatesClient = new computeLib.InstanceTemplatesClient();
// Instantiate a globalOperationsClient
const globalOperationsClient = new computeLib.GlobalOperationsClient();

/**
 * TODO(developer): Update/uncomment these variables before running the sample.
 */
// The ID of the project where you want to create template.
const projectId = await instanceTemplatesClient.getProjectId();
// The name of the template to create.
// const templateName = 'instance-01';

// Create an instance template that creates VMs that don't explicitly consume reservations
async function callCreateTemplateToNotConsumeReservation() {
  // Define the boot disk for the instance template
  const disk = new compute.AttachedDisk({
    initializeParams: new compute.AttachedDiskInitializeParams({
      sourceImage:
        'projects/debian-cloud/global/images/debian-12-bookworm-v20240815',
      diskSizeGb: '100',
      diskType: 'pd-balanced',
    }),
    autoDelete: true,
    boot: true,
    type: 'PERSISTENT',
  });

  // Define the network interface for the instance template
  const network = new compute.NetworkInterface({
    network: `projects/${projectId}/global/networks/default`,
  });

  // Define reservationAffinity
  const reservationAffinity = new compute.ReservationAffinity({
    consumeReservationType: 'NO_RESERVATION',
  });

  // Define instance template
  const instanceTemplate = new compute.InstanceTemplate({
    name: templateName,
    properties: {
      disks: [disk],
      machineType: 'e2-medium',
      // The template connects the instance to the `default` network,
      // without specifying a subnetwork.
      networkInterfaces: [network],
      reservationAffinity,
    },
  });

  const [response] = await instanceTemplatesClient.insert({
    project: projectId,
    instanceTemplateResource: instanceTemplate,
  });

  let operation = response.latestResponse;

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

  console.log(`Template ${templateName} created.`);
}

await callCreateTemplateToNotConsumeReservation();

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_instance_template_not_consume_reservation(
    project_id: str,
    template_name: str,
    machine_type: str = "n1-standard-1",
) -> compute_v1.InstanceTemplate:
    """
    Creates an instance template that creates VMs that don't explicitly consume reservations

    Args:
        project_id: project ID or project number of the Cloud project you use.
        template_name: name of the new template to create.
        machine_type: machine type for the instance.
    Returns:
        InstanceTemplate object that represents the new instance template.
    """

    template = compute_v1.InstanceTemplate()
    template.name = template_name
    template.properties.machine_type = machine_type
    # The template describes the size and source image of the boot disk
    # to attach to the instance.
    template.properties.disks = [
        compute_v1.AttachedDisk(
            boot=True,
            auto_delete=True,  # The disk will be deleted when the instance is deleted
            initialize_params=compute_v1.AttachedDiskInitializeParams(
                source_image="projects/debian-cloud/global/images/family/debian-11",
                disk_size_gb=10,
            ),
        )
    ]
    # The template connects the instance to the `default` network,
    template.properties.network_interfaces = [
        compute_v1.NetworkInterface(
            network="global/networks/default",
            access_configs=[
                compute_v1.AccessConfig(
                    name="External NAT",
                    type="ONE_TO_ONE_NAT",
                )
            ],
        )
    ]
    # The template doesn't explicitly consume reservations
    template.properties.reservation_affinity = compute_v1.ReservationAffinity(
        consume_reservation_type="NO_RESERVATION"
    )

    template_client = compute_v1.InstanceTemplatesClient()
    operation = template_client.insert(
        project=project_id, instance_template_resource=template
    )

    wait_for_extended_operation(operation, "instance template creation")

    return template_client.get(project=project_id, instance_template=template_name)

REST

예약을 명시적으로 사용하지 않는 VM을 만드는 인스턴스 템플릿을 만들려면 다음 방법 중 하나로 POST 요청을 수행합니다.

요청 본문에 consumeReservationType 필드를 포함하고 NO_RESERVATION으로 설정합니다.

예를 들어 예약을 명시적으로 사용하지 않는 VM을 만드는 전역 인스턴스 템플릿을 만들려면 다음과 같이 요청합니다.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/InstanceTemplates

{
  "name": "INSTANCE_TEMPLATE_NAME",
  "properties": {
    "machineType": "MACHINE_TYPE",
    "disks": [
      {
        "boot": true,
        "initializeParams": {
          "sourceImage": "projects/IMAGE_PROJECT/global/images/IMAGE"
        }
      }
    ],
    "networkInterfaces": [
      {
        "network": "global/networks/default"
      }
    ],
    "reservationAffinity": {
      "consumeReservationType": "NO_RESERVATION"
    }
  }
}

다음을 바꿉니다.

  • PROJECT_ID: 인스턴스 템플릿을 만들 프로젝트의 ID입니다.

  • INSTANCE_TEMPLATE_NAME: 인스턴스 템플릿의 이름입니다.

  • MACHINE_TYPE: 인스턴스 템플릿을 사용하여 만든 VM에 사용할 머신 유형입니다.

  • IMAGE_PROJECT: OS 이미지가 포함된 이미지 프로젝트입니다(예: debian-cloud). 지원되는 이미지 프로젝트에 대한 자세한 내용은 공개 이미지를 참조하세요.

  • IMAGE: 다음 중 하나를 지정합니다.

    • OS 이미지의 특정 버전입니다(예: debian-12-bookworm-v20240617).

    • 이미지 계열이며 형식은 family/IMAGE_FAMILY여야 합니다. 중단되지 않은 최신 OS 이미지를 지정합니다. 예를 들어 family/debian-12를 지정하면 Debian 12 이미지 계열의 최신 버전이 사용됩니다. 이미지 계열 사용에 대한 자세한 내용은 이미지 계열 권장사항을 참조하세요.

인스턴스 템플릿 만들기에 대한 자세한 내용은 인스턴스 템플릿 만들기를 참조하세요.

VM 속성이 예약과 일치하는지 테스트

VM이 예약을 자동으로 사용할 수 있는지 여부를 테스트하려면 예약 사본을 특정 예약으로 만든 다음 만들려는 VM이 해당 예약을 사용할 수 있는지 확인하면 됩니다. VM을 성공적으로 만들 수 있으면 VM이 일치하는 예약만 올바르게 소비할 수 있는지 확인된 것입니다. 그렇지 않으면 일치하지 않는 속성 으로 인해 또는 사용 가능한 예약 리소스 없음으로 인해 VM 만들기가 실패합니다. 테스트 후 다음 중 하나 이상을 수행할 수 있습니다.

예약 사용 확인

VM이 예약을 효과적으로 사용하고 있는지 확인하려면 다음 방법을 사용하여 사용량을 확인할 수 있습니다.

  • 예약 세부정보 보기

    VM을 만들거나 업데이트한 후 예약을 사용하는 VM 수가 1개 증가하면 이 작업으로 인해 VM에서 예약을 사용하기 시작했을 수 있습니다. 이는 예약이 사용 중인지 확인하는 가장 빠른 방법입니다. 그러나 예약을 사용하는 정확한 VM을 확인하는 데는 효과적이지 않을 수 있습니다.

  • 특정 예약을 타겟팅하도록 VM을 만듭니다

    특정 예약을 타겟팅하는 VM을 성공적으로 만들 수 있다면 해당 VM에서 예약을 사용합니다. 특정 VM이 예약을 사용하고 있는지, VM 속성이 예약 속성과 일치하는지 확인하는 가장 안정적인 방법입니다.

  • 예약 사용 모니터링

    Cloud Monitoring을 사용하면 프로젝트에서 생성된 예약의 사용과 관련된 정보에 액세스하여 확인할 수 있습니다. Monitoring은 최소 30분마다 한 번씩 예약 사용 데이터를 업데이트합니다. 이 메서드는 프로젝트의 하나 이상의 예약에 대한 소비 추세를 확인하고 사용량이 적거나 사용되지 않은 예약에 대한 알림을 받는 데 유용합니다.

  • 예약 사용 내역 보기

    용량 플래너(미리보기)를 사용하면 예약 생성부터 삭제까지 예약의 이전 사용 내역에 액세스하여 볼 수 있습니다. 용량 플래너는 예약 소비 데이터를 24시간마다 업데이트합니다. 이 방법은 프로젝트, 폴더 또는 조직 내에서 예약의 과거 사용량을 확인하고 향후 용량 요구사항을 계획하는 데 유용합니다.

VM의 예약 어피니티가 예약을 사용할 수 있고, 예약이 완전히 사용되지 않았으며, VM과 예약의 속성이 일치하는 것으로 확인되었는데도 VM에서 예약을 사용하지 않는 경우 리소스 가용성을 참고하세요.

예약 사용량 보고서 보기

사용량 내보내기 기능을 사용하여 Compute Engine 사용량의 상세한 보고서를 Cloud Storage 버킷으로 내보냅니다. 자세한 안내는 사용량 보고서 보기를 참조하세요.

사용량 보고서에는 다음이 표시됩니다.

  • 사용 중인 예약 리소스. 이러한 항목은 일반 vCPU, 메모리, GPU, 로컬 SSD 리소스로 표시됩니다.
  • 사용하지 않는 예약 리소스. 이러한 항목에는 일반 SKU 이름과 예약 리소스 URI가 있습니다.
  • 총 예약 리소스. 이러한 항목에는 예약 SKU 이름과 예약 리소스 URI가 있습니다. 이 항목과 관련된 비용은 없습니다. 사용 중인 예약의 양을 계산할 때 이 항목을 사용합니다.
Measurement MeasurementId format Resource URI format
사용 중인 예약 리소스 com.google.cloud/services/compute-engine/SKU_NAME https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/RESOURCE_TYPE/RESOURCE_NAME.

예를 들면 https://compute.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/instances/my-instance입니다.
사용하지 않는 예약 리소스 com.google.cloud/services/compute-engine/SKU_NAME https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/reservations/RESERVATION_NAME.

예를 들면 https://compute.googleapis.com/compute/v1/projects/my-project/zones/europe-west1-b/reservations/my-reservation입니다.
총 예약 리소스 com.google.cloud/services/compute-engine/ReservationSKU_NAME https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/reservations/RESERVATION_NAME.

예를 들면 https://compute.googleapis.com/compute/v1/projects/my-project/zones/europe-west1-b/reservations/my-reservation입니다.

예를 들어 다음 스니펫에서 my-reservation이라는 예약의 사용량 보고서에 포함된 각 항목의 의미는 다음과 같습니다.

  • 행 1은 현재 사용 중인 예약 RAM을 보여줍니다. 행의 ResourceId는 이 RAM이 my-instance라는 VM에서 사용되고 있음을 보여줍니다.
  • 행 2는 사용하지 않는 예약 RAM을 보여줍니다. 행의 ResourceId는 이 예약이 my-reservation에 있음을 보여줍니다. 이 RAM은 어떤 VM에서도 사용되지 않습니다.
  • 행 3은 예약의 총 예약 RAM을 보여줍니다.
Report Date,MeasurementId,Quantity,Unit,Resource URI,ResourceId,Location
2019-06-06,com.google.cloud/services/compute-engine/VmimageN2StandardRam,166970074857472,byte-seconds,https://compute.googleapis.com/compute/v1/projects/my-project/zones/us-central2-a/instances/my-instance,1775485842510981624,us-central2-a
2019-06-06,com.google.cloud/services/compute-engine/VmimageN2StandardRam,166970074857472,byte-seconds,https://compute.googleapis.com/compute/v1/projects/my-project/zones/us-central2-a/reservations/my-reservation,7.58809E+17,us-central2-a
2019-06-06,com.google.cloud/services/compute-engine/ReservationN2StandardRam,333940149714944,byte-seconds,https://compute.googleapis.com/compute/v1/projects/my-project/zones/us-central2-a/reservations/my-reservation,7.58809E+17,us-central2-a
...

문제 해결

예약 사용 관련 문제 해결 방법을 알아보세요.

다음 단계