커스텀 이미지 만들기


소스 디스크, 이미지, 스냅샷 또는 Cloud Storage에 저장된 이미지에서 커스텀 이미지를 만들고 이 이미지를 사용하여 가상 머신(VM) 인스턴스를 만들 수 있습니다. 커스텀 이미지는 영구 부팅 디스크 또는 구체적인 이미지를 만들어 특정 상태로 수정하고 VM을 만들기 위해 이 상태를 저장해야 하는 상황에 적합합니다.

또는 가상 디스크 가져오기 도구를 사용하여 부팅 디스크 이미지를 기존 시스템에서 Compute Engine으로 가져와 커스텀 이미지 목록에 추가할 수 있습니다.

시작하기 전에

  • 이미지 문서를 읽습니다.
  • 아직 인증을 설정하지 않았다면 설정합니다. 인증은 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 사용을 위한 인증을 참고하세요.

커스텀 이미지 만들기

이 섹션에서는 Linux VM에서 커스텀 이미지를 만드는 방법을 설명합니다. Windows 이미지를 만드는 방법에 대한 상세 설명은 Windows 이미지 만들기를 참조하세요.

이미지 저장 위치 선택

커스텀 이미지를 만들 때 이중 리전 위치를 제외하고 이미지의 Cloud Storage 위치를 지정할 수 있습니다. 이미지 스토리지 위치를 지정하면 데이터 위치에 대한 규제 및 규정 준수 요구사항뿐 아니라 여러 리전 간에 데이터 중복성을 보장함으로써 고가용성 요건을 충족할 수 있습니다. Cloud Storage에 저장된 이미지를 생성, 수정, 삭제하려면 roles/compute.storageAdmin이 있어야 합니다.

스토리지 위치 기능은 선택사항입니다. 위치를 선택하지 않으면 Compute Engine은 이미지 소스와 가장 가까운 멀티 리전에 이미지를 저장합니다. 예를 들어 us-central1에 있는 소스 디스크에서 이미지를 만들 때 커스텀 이미지의 위치를 지정하지 않으면 Compute Engine은 us 멀티 리전에 이미지는 저장합니다.

VM을 만드는 리전에서 이미지를 사용할 수 없는 경우 Compute Engine은 VM을 처음 만들 때 해당 리전에 이미지를 캐시합니다.

이미지가 저장된 위치를 확인하려면 gcloud compute에서 images describe 명령어를 사용하세요.

gcloud compute images describe IMAGE_NAME \
    --project=PROJECT_ID

다음을 바꿉니다.

  • IMAGE_NAME: 이미지의 이름입니다.

  • PROJECT_ID: 이미지가 속한 프로젝트 ID입니다.

이 기능이 출시되기 이전의 모든 기존 이미지는 현재 위치에 그대로 남아 있으며, 변경 사항은 다른 모든 이미지의 이미지 위치를 볼 수 있다는 점뿐입니다. 기존 이미지를 옮기려면 새 위치에서 이 이미지를 다시 만들어야 합니다.

이미지를 위한 VM 준비

실행 중인 VM에 연결되어 있는 경우에도 디스크에서 이미지를 만들 수 있습니다. 그러나 이미지의 안정성을 높이려면 이미지를 쉽게 캡처할 수 있는 상태로 VM을 전환해야 합니다. 이 섹션에서는 이미지의 부팅 디스크를 준비하는 방법을 설명합니다.

영구 디스크에 데이터 쓰기 최소화

디스크 쓰기를 줄이려면 다음 프로세스 중 하나를 사용합니다.

  • 인스턴스가 영구 디스크에 데이터를 쓰지 않고 종료될 수 있도록 VM을 중지합니다.

  • 이미지를 만들기 전에 VM을 중지할 수 없는 경우 디스크에 쓰는 양을 최소화하고 파일 시스템을 동기화합니다. 영구 디스크에 쓰기를 최소화하려면 다음 단계를 따르세요.

    1. 영구 디스크에 데이터를 쓰는 앱 또는 운영체제 프로세스를 일시중지합니다.
    2. 필요한 경우 디스크에 앱 플러시를 실행합니다. 예를 들어 MySQL에는 FLUSH 문이 있습니다. 다른 앱에도 비슷한 프로세스가 있을 수 있습니다.
    3. 앱에서 영구 디스크에 쓰지 못하도록 합니다.
    4. sudo sync를 실행합니다.

디스크의 자동 삭제 옵션 중지

기본적으로 자동 삭제 옵션은 부팅 디스크에 사용 설정되어 있습니다. 디스크에서 이미지를 만들기 전에 자동 삭제를 중지하여 VM이 삭제될 때 디스크가 자동으로 삭제되지 않도록 합니다.

다음 방법 중 하나를 사용하여 디스크의 자동 삭제를 사용 중지합니다.

콘솔

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

    VM 인스턴스 페이지로 이동

  2. 이미지를 만들 수 있는 소스로 사용하고 있는 VM의 이름을 클릭합니다.

    VM 인스턴스 세부정보 페이지가 표시됩니다.

  3. 수정을 클릭합니다.

  4. 부팅 디스크 섹션의 삭제 규칙에서 디스크 유지 옵션이 선택되어 있는지 확인합니다.

  5. 저장을 클릭합니다.

gcloud

Google Cloud CLI에서 gcloud compute instances set-disk-auto-delete 명령어를 사용하여 디스크의 자동 삭제 옵션을 중지합니다.

gcloud compute instances set-disk-auto-delete VM_NAME \
    --no-auto-delete \
    --disk=SOURCE_DISK

다음을 바꿉니다.

  • VM_NAME: VM 인스턴스의 이름입니다.
  • SOURCE_DISK: 이미지를 만들 디스크의 이름입니다.

Go

Go

이 샘플을 사용해 보기 전에 Compute Engine 빠른 시작: 클라이언트 라이브러리 사용Go 설정 안내를 따르세요. 자세한 내용은 Compute Engine Go API 참고 문서를 확인하세요.

Compute Engine에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
)

// setDiskAutodelete sets the autodelete flag of a disk to given value.
func setDiskAutoDelete(
	w io.Writer,
	projectID, zone, instanceName, diskName string, autoDelete bool,
) error {
	// projectID := "your_project_id"
	// zone := "us-west3-b"
	// instanceName := "your_instance_name"
	// diskName := "your_disk_name"
	// autoDelete := true

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

	getInstanceReq := &computepb.GetInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
	}

	instance, err := instancesClient.Get(ctx, getInstanceReq)
	if err != nil {
		return fmt.Errorf("unable to get instance: %w", err)
	}

	diskExists := false

	for _, disk := range instance.GetDisks() {
		if disk.GetDeviceName() == diskName {
			diskExists = true
			break
		}
	}

	if !diskExists {
		return fmt.Errorf(
			"instance %s doesn't have a disk named %s attached",
			instanceName,
			diskName,
		)
	}

	req := &computepb.SetDiskAutoDeleteInstanceRequest{
		Project:    projectID,
		Zone:       zone,
		Instance:   instanceName,
		DeviceName: diskName,
		AutoDelete: autoDelete,
	}

	op, err := instancesClient.SetDiskAutoDelete(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to set disk autodelete field: %w", err)
	}

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

	fmt.Fprintf(w, "disk autoDelete field updated.\n")

	return nil
}

자바

Java

이 샘플을 사용해 보기 전에 Compute Engine 빠른 시작: 클라이언트 라이브러리 사용Java 설정 안내를 따르세요. 자세한 내용은 Compute Engine Java API 참고 문서를 확인하세요.

Compute Engine에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


import com.google.cloud.compute.v1.Instance;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.SetDiskAutoDeleteInstanceRequest;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class SetDiskAutodelete {

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

    // The zone of the disk that you want to modify.
    String zone = "europe-central2-b";

    // Name of the instance the disk is attached to.
    String instanceName = "YOUR_INSTANCE_NAME";

    // The name of the disk for which you want to modify the autodelete flag.
    String diskName = "YOUR_DISK_NAME";

    // The new value of the autodelete flag.
    boolean autoDelete = true;

    setDiskAutodelete(projectId, zone, instanceName, diskName, autoDelete);
  }

  // Sets the autodelete flag of a disk to given value.
  public static void setDiskAutodelete(String projectId, String zone, String instanceName,
      String diskName, boolean autoDelete)
      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. After completing all of your requests, call
    // the `instancesClient.close()` method on the client to safely
    // clean up any remaining background resources.
    try (InstancesClient instancesClient = InstancesClient.create()) {

      // Retrieve the instance given by the instanceName.
      Instance instance = instancesClient.get(projectId, zone, instanceName);

      // Check if the instance contains a disk that matches the given diskName.
      boolean diskNameMatch = instance.getDisksList()
          .stream()
          .anyMatch(disk -> disk.getDeviceName().equals(diskName));

      if (!diskNameMatch) {
        throw new Error(
            String.format("Instance %s doesn't have a disk named %s attached", instanceName,
                diskName));
      }

      // Create the request object.
      SetDiskAutoDeleteInstanceRequest request = SetDiskAutoDeleteInstanceRequest.newBuilder()
          .setProject(projectId)
          .setZone(zone)
          .setInstance(instanceName)
          .setDeviceName(diskName)
          // Update the autodelete property.
          .setAutoDelete(autoDelete)
          .build();

      // Wait for the update instance operation to complete.
      Operation response = instancesClient.setDiskAutoDeleteAsync(request)
          .get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        System.out.println("Failed to update Disk autodelete field!" + response);
        return;
      }
      System.out.println(
          "Disk autodelete field updated. Operation Status: " + response.getStatus());
    }
  }
}

Node.js

Node.js

이 샘플을 사용해 보기 전에 Compute Engine 빠른 시작: 클라이언트 라이브러리 사용Node.js 설정 안내를 따르세요. 자세한 내용은 Compute Engine Node.js API 참고 문서를 확인하세요.

Compute Engine에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const zone = 'europe-central2-b';
// const instanceName = 'YOUR_INSTANCE_NAME';
// const diskName = 'YOUR_DISK_NAME';
// const autoDelete = true;

const compute = require('@google-cloud/compute');

async function setDiskAutodelete() {
  const instancesClient = new compute.InstancesClient();

  const [instance] = await instancesClient.get({
    project: projectId,
    zone,
    instance: instanceName,
  });

  if (!instance.disks.some(disk => disk.deviceName === diskName)) {
    throw new Error(
      `Instance ${instanceName} doesn't have a disk named ${diskName} attached.`
    );
  }

  const [response] = await instancesClient.setDiskAutoDelete({
    project: projectId,
    zone,
    instance: instanceName,
    deviceName: diskName,
    autoDelete,
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.ZoneOperationsClient();

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

  console.log('Disk autoDelete field updated.');
}

setDiskAutodelete();

Python

Python

이 샘플을 사용해 보기 전에 Compute Engine 빠른 시작: 클라이언트 라이브러리 사용Python 설정 안내를 따르세요. 자세한 내용은 Compute Engine Python API 참고 문서를 확인하세요.

Compute Engine에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

from __future__ import annotations

import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    Waits for the extended (long-running) operation to complete.

    If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result


def set_disk_autodelete(
    project_id: str, zone: str, instance_name: str, disk_name: str, autodelete: bool
) -> None:
    """
    Set the autodelete flag of a disk to given value.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone in which is the disk you want to modify.
        instance_name: name of the instance the disk is attached to.
        disk_name: the name of the disk which flag you want to modify.
        autodelete: the new value of the autodelete flag.
    """
    instance_client = compute_v1.InstancesClient()
    instance = instance_client.get(
        project=project_id, zone=zone, instance=instance_name
    )

    for disk in instance.disks:
        if disk.device_name == disk_name:
            break
    else:
        raise RuntimeError(
            f"Instance {instance_name} doesn't have a disk named {disk_name} attached."
        )

    disk.auto_delete = autodelete

    operation = instance_client.update(
        project=project_id,
        zone=zone,
        instance=instance_name,
        instance_resource=instance,
    )

    wait_for_extended_operation(operation, "disk update")

REST

디스크의 자동 삭제 옵션을 설정하려면 instances.setDiskAutoDelete 메서드에 대한 POST 요청을 실행합니다.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/setDiskAutoDelete?autoDelete=false&deviceName=SOURCE_DISK

다음을 바꿉니다.

  • PROJECT_ID: 소스 VM이 속한 프로젝트 ID입니다.
  • ZONE: 소스 VM이 있는 영역입니다.
  • VM_NAME: 소스 VM 이름입니다.
  • SOURCE_DISK: 이미지를 만들 디스크의 기기 이름입니다.

VM을 준비한 후 이미지를 만듭니다.

이미지 만들기

다음 소스에서 디스크 이미지를 만들 수 있습니다.

  • 영구 디스크(디스크가 VM에 연결된 경우에도 가능)
  • 영구 디스크의 스냅샷
  • 프로젝트의 다른 이미지
  • 다른 프로젝트에서 공유된 이미지
  • Cloud Storage의 압축 RAW 이미지

10분마다 한 번씩 디스크 이미지를 만들 수 있습니다. 디스크 이미지 만들기 요청 버스트를 실행하려면 60분 동안 최대 6개의 요청을 실행할 수 있습니다. 자세한 내용은 스냅샷 빈도 제한을 참조하세요.

Console

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

    이미지 만들기로 이동

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

  3. 이미지를 만들 소스를 지정합니다. 소스는 영구 디스크, 스냅샷, 다른 이미지, Cloud Storage의 disk.raw 파일일 수 있습니다.

  4. 실행 중인 VM에 연결된 디스크에서 이미지를 만드는 경우 인스턴스 계속 실행을 선택하여 VM이 실행되는 동안 이미지를 만들 것임을 확인합니다. 이미지를 만들기 전에 VM을 준비할 수 있습니다.

  5. 소스 디스크 위치 기준(기본값) 드롭다운 목록에서 이미지를 저장할 위치를 지정합니다. 예를 들어 us를 지정하여 us 멀티 리전에 이미지를 저장하거나 us-central1을 지정하여 us-central1 리전에 저장합니다. 선택하지 않으면 Compute Engine은 이미지의 소스 위치와 가장 가까운 멀티 리전에 이미지를 저장합니다.

  6. 선택사항: 이미지 속성을 지정합니다.

    • 계열: 새 이미지가 속할 이미지 계열입니다.
    • 설명: 커스텀 이미지에 대한 설명입니다.
    • 라벨: 리소스를 그룹화하는 라벨입니다.
  7. 암호화 키를 지정합니다. Google 소유 및 Google 관리 키인 Cloud Key Management Service (Cloud KMS) 또는 고객 제공 암호화 키 (CSEK) 사이에서 선택할 수 있습니다. 암호화 키가 지정되지 않은 경우 이미지는 Google 소유 및 Google 관리 키를 사용하여 암호화됩니다.

  8. 만들기를 클릭하여 이미지를 만듭니다.

gcloud

Google Cloud CLI에서 gcloud compute images create 명령어를 사용하여 커스텀 이미지를 만듭니다.

소스 디스크에서 이미지 만들기:

--force 플래그는 실행 중인 인스턴스에서 이미지를 만들 수 있는 선택적 플래그입니다. 기본적으로는 실행 중인 인스턴스에서 이미지를 만들 수 없습니다. 인스턴스가 실행되는 동안 이미지를 만들려고 하는 경우에만 이 플래그를 지정하세요.

gcloud compute images create IMAGE_NAME \
    --source-disk=SOURCE_DISK \
    --source-disk-zone=ZONE \
    [--family=IMAGE_FAMILY] \
    [--storage-location=LOCATION] \
    [--force]

다음을 바꿉니다.

  • IMAGE_NAME: 새 이미지의 이름입니다.
  • SOURCE_DISK: 이미지를 만들 소스 디스크입니다.
  • ZONE: 디스크가 있는 영역입니다.
  • IMAGE_FAMILY: (선택 사항) 이 이미지가 속한 이미지 계열을 지정하는 플래그입니다.
  • LOCATION: (선택 사항) 이미지가 저장되는 리전 또는 멀티 리전을 지정할 수 있는 플래그입니다. 예를 들어 us를 지정하여 us 멀티 리전에 이미지를 저장하거나 us-central1을 지정하여 us-central1 리전에 저장합니다. 선택하지 않으면 Compute Engine은 이미지의 소스 위치와 가장 가까운 멀티 리전에 이미지를 저장합니다.

소스 이미지에서 이미지 만들기:

gcloud compute images create IMAGE_NAME \
  --source-image=SOURCE_IMAGE \
  [--source-image-project=IMAGE_PROJECT] \
  [--family=IMAGE_FAMILY] \
  [--storage-location=LOCATION]

다음을 바꿉니다.

  • IMAGE_NAME: 새 이미지의 이름입니다.
  • SOURCE_IMAGE: 새 이미지를 만들 소스 이미지입니다.
  • IMAGE_PROJECT: (선택 사항) 소스 이미지가 있는 프로젝트입니다. 다른 프로젝트에서 이미지를 복사하려는 경우 이 매개변수를 사용합니다.
  • IMAGE_FAMILY: (선택 사항) 새 이미지가 속할 이미지 계열
  • LOCATION: (선택 사항) 이미지가 저장되는 리전 또는 멀티 리전을 지정할 수 있습니다. 예를 들어 us를 지정하여 us 멀티 리전에 이미지를 저장하거나 us-central1을 지정하여 us-central1 리전에 저장합니다. 선택하지 않으면 Compute Engine은 이미지의 소스 위치와 가장 가까운 멀티 리전에 이미지를 저장합니다.

스냅샷에서 이미지 만들기:

gcloud compute images create IMAGE_NAME \
    --source-snapshot=SOURCE_SNAPSHOT \
    [--storage-location=LOCATION]

다음을 바꿉니다.

  • IMAGE_NAME: 새 이미지의 이름입니다.
  • SOURCE_SNAPSHOT: 이미지를 만들 스냅샷입니다.
  • LOCATION: (선택 사항) 이미지가 저장되는 리전 또는 멀티 리전을 지정할 수 있는 플래그입니다. 예를 들어 us를 지정하여 us 멀티 리전에 이미지를 저장하거나 us-central1을 지정하여 us-central1 리전에 저장합니다. 선택하지 않으면 Compute Engine은 이미지의 소스 위치와 가장 가까운 멀티 리전에 이미지를 저장합니다.

이미지 위치 보기:

gcloud compute images describe 명령어를 사용하여 이미지 위치를 봅니다.

gcloud compute images describe IMAGE_NAME

IMAGE_NAME을 검토할 이미지의 이름으로 바꿉니다.

Go

Go

이 샘플을 사용해 보기 전에 Compute Engine 빠른 시작: 클라이언트 라이브러리 사용Go 설정 안내를 따르세요. 자세한 내용은 Compute Engine Go API 참고 문서를 확인하세요.

Compute Engine에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
)

// Creates a disk image from an existing disk
func createImageFromDisk(
	w io.Writer,
	projectID, zone, sourceDiskName, imageName string,
	storageLocations []string,
	forceCreate bool,
) error {
	// projectID := "your_project_id"
	// zone := "us-central1-a"
	// sourceDiskName := "your_disk_name"
	// imageName := "my_image"
	// // If storageLocations empty, automatically selects the closest one to the source
	// storageLocations = []string{}
	// // If forceCreate is set to `true`, proceeds even if the disk is attached to
	// // a running instance. This may compromise integrity of the image!
	// forceCreate = false

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

	// Get the source disk
	source_req := &computepb.GetDiskRequest{
		Disk:    sourceDiskName,
		Project: projectID,
		Zone:    zone,
	}

	disk, err := disksClient.Get(ctx, source_req)
	if err != nil {
		return fmt.Errorf("unable to get source disk: %w", err)
	}

	// Create the image
	req := computepb.InsertImageRequest{
		ForceCreate: &forceCreate,
		ImageResource: &computepb.Image{
			Name:             &imageName,
			SourceDisk:       disk.SelfLink,
			StorageLocations: storageLocations,
		},
		Project: projectID,
	}

	op, err := imagesClient.Insert(ctx, &req)

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

	fmt.Fprintf(w, "Disk image %s created\n", imageName)

	return nil
}

자바

Java

이 샘플을 사용해 보기 전에 Compute Engine 빠른 시작: 클라이언트 라이브러리 사용Java 설정 안내를 따르세요. 자세한 내용은 Compute Engine Java API 참고 문서를 확인하세요.

Compute Engine에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


import com.google.cloud.compute.v1.Disk;
import com.google.cloud.compute.v1.DisksClient;
import com.google.cloud.compute.v1.Image;
import com.google.cloud.compute.v1.ImagesClient;
import com.google.cloud.compute.v1.InsertImageRequest;
import com.google.cloud.compute.v1.Instance;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.Operation;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateImage {

  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 use.
    String project = "your-project-id";
    // Zone of the disk you copy from.
    String zone = "europe-central2-b";
    // Name of the source disk you copy from.
    String sourceDiskName = "source-disk-name";
    // Name of the image you want to create.
    String imageName = "your-image-name";
    // Storage location for the image. If the value is undefined,
    // function will store the image in the multi-region closest to your image's source location.
    String storageLocation = "eu";
    // Create the image even if the source disk is attached to a running instance.
    boolean forceCreate = false;

    createImage(project, zone, sourceDiskName, imageName, storageLocation, forceCreate);
  }

  // Creates a new disk image from the specified source disk.
  public static void createImage(String project, String zone, String sourceDiskName,
      String imageName, String storageLocation, boolean forceCreate)
      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. After completing all of your requests, call
    // the `client.close()` method on the client to safely
    // clean up any remaining background resources.
    try (ImagesClient imagesClient = ImagesClient.create();
        InstancesClient instancesClient = InstancesClient.create();
        DisksClient disksClient = DisksClient.create()) {

      Disk disk = disksClient.get(project, zone, sourceDiskName);

      // Getting instances where source disk is attached.
      for (String fullInstanceName : disk.getUsersList()) {
        Map<String, String> instanceInfo = parseInstanceName(fullInstanceName);
        Instance instance = instancesClient.get(instanceInfo.get("instanceProjectId"),
            instanceInfo.get("instanceZone"), instanceInfo.get("instanceName"));

        // Сheck whether the instances are stopped.
        if (!Arrays.asList("TERMINATED", "STOPPED").contains(instance.getStatus())
            && !forceCreate) {
          throw new IllegalStateException(
              String.format(
                  "Instance %s should be stopped. For Windows instances please stop the instance "
                      + "using GCESysprep command. For Linux instances just shut it down normally."
                      + " You can suppress this error and create an image of the disk by setting "
                      + "'forceCreate' parameter to true (not recommended). "
                      + "More information here: "
                      + "* https://cloud.google.com/compute/docs/instances/windows/creating-windows-os-image#api"
                      + "* https://cloud.google.com/compute/docs/images/create-delete-deprecate-private-images#prepare_instance_for_image",
                  instanceInfo.get("instanceName")));
        }
      }

      if (forceCreate) {
        System.out.println(
            "Warning: forceCreate option compromise the integrity of your image. "
                + "Stop the instance before you create the image if possible.");
      }

      // Create Image.
      Image image = Image.newBuilder()
          .setName(imageName)
          .setSourceDisk(String.format("/zones/%s/disks/%s", zone, sourceDiskName))
          .addStorageLocations(storageLocation.isEmpty() ? "" : storageLocation)
          .build();

      InsertImageRequest insertImageRequest = InsertImageRequest.newBuilder()
          .setProject(project)
          .setForceCreate(forceCreate)
          .setImageResource(image)
          .build();

      Operation response = imagesClient.insertAsync(insertImageRequest).get(5, TimeUnit.MINUTES);

      if (response.hasError()) {
        System.out.println("Image creation failed ! ! " + response);
        return;
      }

      System.out.println("Image created.");
    }
  }


  public static Map<String, String> parseInstanceName(String name) {
    String[] parsedName = name.split("/");
    int splitLength = parsedName.length;

    if (splitLength < 5) {
      throw new IllegalArgumentException(
          "Provide correct instance name in the following format: "
              + "https://www.googleapis.com/compute/v1/projects/PROJECT/zones/ZONE/instances/INSTANCE_NAME");
    }

    return new HashMap<>() {
      {
        put("instanceName", parsedName[splitLength - 1]);
        put("instanceZone", parsedName[splitLength - 3]);
        put("instanceProjectId", parsedName[splitLength - 5]);
      }
    };
  }

}

Python

Python

이 샘플을 사용해 보기 전에 Compute Engine 빠른 시작: 클라이언트 라이브러리 사용Python 설정 안내를 따르세요. 자세한 내용은 Compute Engine Python API 참고 문서를 확인하세요.

Compute Engine에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

from __future__ import annotations

import sys
from typing import Any
import warnings

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


STOPPED_MACHINE_STATUS = (
    compute_v1.Instance.Status.TERMINATED.name,
    compute_v1.Instance.Status.STOPPED.name,
)


def create_image_from_disk(
    project_id: str,
    zone: str,
    source_disk_name: str,
    image_name: str,
    storage_location: str | None = None,
    force_create: bool = False,
) -> compute_v1.Image:
    """
    Creates a new disk image.

    Args:
        project_id: project ID or project number of the Cloud project you use.
        zone: zone of the disk you copy from.
        source_disk_name: name of the source disk you copy from.
        image_name: name of the image you want to create.
        storage_location: storage location for the image. If the value is undefined,
            function will store the image in the multi-region closest to your image's
            source location.
        force_create: create the image even if the source disk is attached to a
            running instance.

    Returns:
        An Image object.
    """
    image_client = compute_v1.ImagesClient()
    disk_client = compute_v1.DisksClient()
    instance_client = compute_v1.InstancesClient()

    # Get source disk
    disk = disk_client.get(project=project_id, zone=zone, disk=source_disk_name)

    for disk_user in disk.users:
        instance_name = disk_user.split("/")[-1]
        instance = instance_client.get(
            project=project_id, zone=zone, instance=instance_name
        )
        if instance.status in STOPPED_MACHINE_STATUS:
            continue
        if not force_create:
            raise RuntimeError(
                f"Instance {disk_user} should be stopped. For Windows instances please "
                f"stop the instance using `GCESysprep` command. For Linux instances just "
                f"shut it down normally. You can supress this error and create an image of"
                f"the disk by setting `force_create` parameter to true (not recommended). \n"
                f"More information here: \n"
                f" * https://cloud.google.com/compute/docs/instances/windows/creating-windows-os-image#api \n"
                f" * https://cloud.google.com/compute/docs/images/create-delete-deprecate-private-images#prepare_instance_for_image"
            )
        else:
            warnings.warn(
                f"Warning: The `force_create` option may compromise the integrity of your image. "
                f"Stop the {disk_user} instance before you create the image if possible."
            )

    # Create image
    image = compute_v1.Image()
    image.source_disk = disk.self_link
    image.name = image_name
    if storage_location:
        image.storage_locations = [storage_location]

    operation = image_client.insert(project=project_id, image_resource=image)

    wait_for_extended_operation(operation, "image creation from disk")

    return image_client.get(project=project_id, image=image_name)

REST

images().insert 메서드에 대해 POST 요청을 실행합니다. 이때 요청 본문의 URL은 이미지를 만들 소스 객체를 가리킵니다. 자체 프로젝트 ID와 리소스 이름을 사용하여 리소스에 URL을 지정합니다.

영구 디스크에서 이미지 만들기:

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

{
  "name": "IMAGE_NAME",
  "sourceDisk": "/zones/ZONE/disks/SOURCE_DISK",
  ("storageLocations": "LOCATION",)
  ("forceCreate": "TRUE")
}

다음을 바꿉니다.

  • PROJECT_ID: 이미지가 속한 프로젝트 ID입니다.
  • IMAGE_NAME: 만들려는 새 이미지의 이름입니다.
  • ZONE: 소스 디스크가 있는 영역입니다.
  • SOURCE_DISK: 이미지를 만들 소스 디스크입니다.
  • LOCATION: (선택 사항) 이미지의 스토리지 위치입니다. 예를 들어 us를 지정하여 us 멀티 리전에 이미지를 저장하거나 us-central1을 지정하여 us-central1 리전에 저장합니다. 선택하지 않으면 Compute Engine은 이미지의 소스 위치와 가장 가까운 멀티 리전에 이미지를 저장합니다.

선택사항인 forceCreate 매개변수를 사용하면 실행 중인 VM에서 이미지를 만들 수 있습니다. 실행 중인 VM에서 이미지를 만들려고 하는 경우에만 TRUE로 지정하세요. forceCreate 기본 설정은 FALSE입니다.

다른 이미지에서 이미지 만들기:

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

{
  "name": "IMAGE_NAME",
  "sourceImage": "/global/images/SOURCE_IMAGE",
  ("storageLocations": "LOCATION")
}

다음을 바꿉니다.

  • PROJECT_ID: 이미지가 속한 프로젝트입니다.
  • IMAGE_NAME: 만들려는 새 이미지의 이름입니다.
  • SOURCE_IMAGE: 이미지를 만들려는 소스 이미지입니다.
  • LOCATION: (선택 사항) 이미지의 스토리지 위치입니다. 예를 들어 us를 지정하여 us 멀티 리전에 이미지를 저장하거나 us-central1을 지정하여 us-central1 리전에 저장합니다. 선택하지 않으면 Compute Engine은 이미지의 소스 위치와 가장 가까운 멀티 리전에 이미지를 저장합니다.

스냅샷에서 이미지 만들기:

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/images
{
  "name": "IMAGE_NAME",
  "sourceSnapshot": "(/SOURCE_PROJECT_ID)/global/snapshots/SOURCE_SNAPSHOT",
  ("storageLocations": "LOCATION")
}

다음을 바꿉니다.

  • PROJECT_ID: 이미지가 속한 프로젝트입니다.
  • IMAGE_NAME: 만들려는 새 이미지의 이름입니다.
  • SOURCE_PROJECT_ID: (선택 사항) 스냅샷이 있는 프로젝트입니다. 해당 프로젝트의 스냅샷 리소스에 액세스할 수 있는 권한이 있어야 합니다.
  • SOURCE_SNAPSHOT: 이미지를 만들 소스 스냅샷입니다.
  • LOCATION: (선택 사항) 이미지의 스토리지 위치입니다. 예를 들어 us를 지정하여 us 멀티 리전에 이미지를 저장하거나 us-central1을 지정하여 us-central1 리전에 저장합니다. 선택하지 않으면 Compute Engine은 이미지의 소스 위치와 가장 가까운 멀티 리전에 이미지를 저장합니다.

이미지 추가에 대한 자세한 내용은 이미지 참조를 참조하세요.

이미지 공유

커스텀 이미지를 만든 후에는 프로젝트 간에 공유할 수 있습니다. 다른 프로젝트의 사용자가 커스텀 이미지를 사용하도록 허용하면 해당 사용자는 요청에 이미지 프로젝트를 지정하여 이러한 이미지에 액세스할 수 있습니다.

게스트 운영체제 기능 사용 설정

게스트 운영체제(OS) 기능을 사용하여 커스텀 이미지에서 다음 네트워킹, 보안, 스토리지, OS 옵션을 구성합니다. 이렇게 기능이 구성된 커스텀 이미지는 부팅 디스크로 사용됩니다.

gcloud

기존 커스텀 이미지에서 새 커스텀 이미지를 만들려면 --guest-os-features 플래그와 함께 gcloud compute images create 명령어를 사용하세요.

gcloud compute images create IMAGE_NAME \
    --source-image=SOURCE_IMAGE \
    [--source-image-project=IMAGE_PROJECT] \
    --guest-os-features="FEATURES,..." \
    [--storage-location=LOCATION]

다음을 바꿉니다.

  • IMAGE_NAME: 새 이미지의 이름입니다.
  • SOURCE_IMAGE: 새 이미지의 기반이 되는 이미지입니다.
  • IMAGE_PROJECT: (선택사항) 소스 이미지가 포함된 프로젝트입니다.

    다른 프로젝트에서 이미지를 복사하려면 이 매개변수를 사용합니다.

  • FEATURES: 이미지에서 만든 VM에 기능을 사용 설정하는 게스트 OS 태그입니다.

    여러 값을 추가하려면 쉼표를 사용하여 값을 구분하세요. 다음 중 하나 이상의 값으로 설정합니다.

    • VIRTIO_SCSI_MULTIQUEUE. NVMe 대신 로컬 SSD 기기에 사용할 수 있습니다. SCSI를 지원하는 이미지에 대한 자세한 내용은 인터페이스 선택을 참고하세요.

      커널 버전이 3.17 이상인 Linux 이미지에서는 로컬 SSD 기기에서 멀티 큐 SCSI를 사용 설정할 수 있습니다. Compute Engine Windows 드라이버 버전이 1.2인 Windows 이미지에서는 로컬 SSD 기기에서 멀티 큐 SCSI를 사용 설정할 수 있습니다.

    • WINDOWS. Windows Server 커스텀 부팅 이미지를 Windows 이미지로 태그 지정합니다.
    • MULTI_IP_SUBNET. /32 이외의 넷마스크를 사용하여 인터페이스를 구성합니다. 다중 네트워크 인터페이스와 그 작동 방식에 대한 자세한 내용은 다중 네트워크 인터페이스 개요 및 예시를 참고하세요.
    • UEFI_COMPATIBLE. UEFI 펌웨어 및 다음 보안 VM 기능으로 부팅합니다.
    • GVNIC. 최대 50Gbps~100Gbps 속도의 더 높은 네트워크 대역폭을 지원합니다. 자세한 내용은 Google Virtual NIC 사용을 참고하세요.
    • IDPF. Intel 인프라 데이터 경로 함수 (IDPF) 네트워크 인터페이스를 지원합니다.
    • SEV_CAPABLE 또는 SEV_SNP_CAPABLE. AMD Secure Encrypted Virtualization (SEV) 또는 AMD Secure Encrypted Virtualization-Secure Nested Paging (SEV-SNP) 지원이 있는 컨피덴셜 VM 인스턴스에서 이미지를 사용하려면 이 태그를 사용하세요. 커널이 AMD SEV 또는 AMD SEV-SNP를 지원하는지 확인하려면 Linux 커널 세부정보를 참고하세요.
    • SEV_LIVE_MIGRATABLE_V2. AMD SEV에서 라이브 마이그레이션을 지원하는 컨피덴셜 VM 인스턴스에서 이미지를 사용하려면 이 태그를 사용하세요. 커널이 라이브 마이그레이션을 지원하는지 확인하려면 Linux 커널 세부정보를 참고하세요.
    • TDX_CAPABLE. Intel Trust Domain Extensions (TDX) 지원이 있는 컨피덴셜 VM 인스턴스에서 이미지를 사용하려면 이 태그를 사용하세요. 커널이 Intel TDX를 지원하는지 확인하려면 Linux 커널 세부정보를 참고하세요.
    • SUSPEND_RESUME_COMPATIBLE. VM에서 일시중지 및 재개를 지원합니다. 자세한 내용은 OS 호환성을 참고하세요.
  • LOCATION: (선택 사항) 이미지를 저장할 리전 또는 멀티 리전입니다.

    예를 들어 us를 지정하여 us 멀티 리전에 이미지를 저장하거나 us-central1을 지정하여 us-central1 리전에 저장합니다. 선택하지 않으면 Compute Engine은 이미지의 소스 위치와 가장 가까운 멀티 리전에 이미지를 저장합니다.

REST

기존 커스텀 이미지에서 새 커스텀 이미지를 만들려면 guestOsFeatures 플래그와 함께 images().insert 메서드를 사용하세요.


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

{
 "name": "IMAGE_NAME",
 "sourceImage": "(projects/IMAGE_PROJECT)/global/images/SOURCE_IMAGE",
 ("storageLocations": "LOCATION",)
 "guestOsFeatures": [
  {
   "type": "FEATURES"
  }
 ]
}

다음을 바꿉니다.

  • PROJECT_ID: 새 이미지를 만들 프로젝트의 ID입니다.
  • IMAGE_NAME: 새 이미지의 이름입니다.
  • IMAGE_PROJECT: (선택사항) 소스 이미지가 포함된 프로젝트입니다.

    다른 프로젝트에서 이미지를 복사하려면 이 매개변수를 사용합니다.

  • SOURCE_IMAGE: 새 이미지의 기반이 되는 이미지입니다.

  • LOCATION: (선택 사항) 이미지를 저장할 리전 또는 멀티 리전입니다.

    예를 들어 us를 지정하여 us 멀티 리전에 이미지를 저장하거나 us-central1을 지정하여 us-central1 리전에 저장합니다. 선택하지 않으면 Compute Engine은 이미지의 소스 위치와 가장 가까운 멀티 리전에 이미지를 저장합니다.

  • FEATURES: 이미지에서 만든 VM에 기능을 사용 설정하는 게스트 OS 태그입니다.

    여러 값을 추가하려면 쉼표를 사용하여 값을 구분하세요. 다음 중 하나 이상의 값으로 설정합니다.

    • VIRTIO_SCSI_MULTIQUEUE. NVMe 대신 로컬 SSD 기기에 사용할 수 있습니다. SCSI를 지원하는 이미지에 대한 자세한 내용은 인터페이스 선택을 참고하세요.

      커널 버전이 3.17 이상인 Linux 이미지에서는 로컬 SSD 기기에서 멀티 큐 SCSI를 사용 설정할 수 있습니다. Compute Engine Windows 드라이버 버전이 1.2인 Windows 이미지에서는 로컬 SSD 기기에서 멀티 큐 SCSI를 사용 설정할 수 있습니다.

    • WINDOWS. Windows Server 커스텀 부팅 이미지를 Windows 이미지로 태그 지정합니다.
    • MULTI_IP_SUBNET. /32 이외의 넷마스크를 사용하여 인터페이스를 구성합니다. 다중 네트워크 인터페이스와 그 작동 방식에 대한 자세한 내용은 다중 네트워크 인터페이스 개요 및 예시를 참고하세요.
    • UEFI_COMPATIBLE. UEFI 펌웨어 및 다음 보안 VM 기능으로 부팅합니다.
    • GVNIC. 최대 50Gbps~100Gbps 속도의 더 높은 네트워크 대역폭을 지원합니다. 자세한 내용은 Google Virtual NIC 사용을 참고하세요.
    • IDPF. Intel 인프라 데이터 경로 함수 (IDPF) 네트워크 인터페이스를 지원합니다.
    • SEV_CAPABLE 또는 SEV_SNP_CAPABLE. AMD Secure Encrypted Virtualization (SEV) 또는 AMD Secure Encrypted Virtualization-Secure Nested Paging (SEV-SNP) 지원이 있는 컨피덴셜 VM 인스턴스에서 이미지를 사용하려면 이 태그를 사용하세요. 커널이 AMD SEV 또는 AMD SEV-SNP를 지원하는지 확인하려면 Linux 커널 세부정보를 참고하세요.
    • SEV_LIVE_MIGRATABLE_V2. AMD SEV에서 라이브 마이그레이션을 지원하는 컨피덴셜 VM 인스턴스에서 이미지를 사용하려면 이 태그를 사용하세요. 커널이 라이브 마이그레이션을 지원하는지 확인하려면 Linux 커널 세부정보를 참고하세요.
    • TDX_CAPABLE. Intel Trust Domain Extensions (TDX) 지원이 있는 컨피덴셜 VM 인스턴스에서 이미지를 사용하려면 이 태그를 사용하세요. 커널이 Intel TDX를 지원하는지 확인하려면 Linux 커널 세부정보를 참고하세요.
    • SUSPEND_RESUME_COMPATIBLE. VM에서 일시중지 및 재개를 지원합니다. 자세한 내용은 OS 호환성을 참고하세요.

UEFI 변수에 민감한 정보 포함하지 않기

통합 확장 가능 펌웨어 인터페이스 (UEFI) 변수는 부팅 시간 동안 UEFI 펌웨어에서 VM의 운영체제를 부팅하는 데 사용하는 키-값 쌍 변수입니다. 변수가 하드웨어 칩에 저장되는 물리적 머신과 달리 Compute Engine은 이러한 변수의 저장소를 가상화합니다. 따라서 많은 운영체제에서 모든 애플리케이션과 사용자가 이러한 변수에 도달하여 이 정보에 액세스할 수 있습니다.

따라서 비밀번호나 비공개 키와 같은 민감한 정보 또는 개인 식별 정보를 UEFI 변수에 쓰거나 저장하지 않는 것이 좋습니다.

Arm 이미지 고려사항

Google은 Arm CPU 플랫폼에서 실행되는 C4A 및 Tau T2A 머신 시리즈를 제공합니다. 이러한 머신 시리즈 중 하나로 VM을 시작한 다음 해당 소스 VM을 사용하여 Arm 이미지를 만들 수 있습니다. 커스텀 Arm 이미지를 만드는 프로세스는 x86 이미지를 만드는 프로세스와 동일합니다.

사용자가 Arm 이미지와 x86 이미지를 구별할 수 있도록 Arm 이미지에는 ARM64로 설정된 architecture 필드가 있습니다. 이 필드에 가능한 값은 다음과 같습니다.

  • ARCHITECTURE_UNSPECIFIED
  • X86_64
  • ARM64

그러면 이미지 사용자는 이 필드를 기준으로 필터링하여 x86 또는 Arm 기반 이미지를 찾을 수 있습니다.

다음 단계