커스텀 호스트 이름으로 VM 인스턴스 만들기


가상 머신 (VM) 인스턴스를 만들 때 Google Cloud는 VM 이름으로부터 내부 DNS 이름을 만듭니다. 커스텀 호스트 이름을 지정하지 않으면 Google Cloud는 자동으로 생성된 내부 DNS 이름을 VM에 제공하는 호스트 이름으로 사용합니다.

정규화된 DNS 이름을 지정하여 커스텀 호스트 이름으로 VM을 만들 수 있습니다. 커스텀 호스트 이름은 규칙을 유지하거나 특정 호스트 이름이 필요한 애플리케이션의 요구사항을 지원하는 데 유용합니다.

커스텀 호스트 이름을 지정해도 Google Cloud는 Compute Engine 내부 DNS 이름을 만듭니다. 자동으로 생성된 이 내부 DNS 레코드를 사용하여 VM에 연결할 수 있습니다. 내부 DNS 레코드는 커스텀 호스트 이름이 아니라 내부 DNS 이름으로 확인됩니다. 커스텀 호스트 이름이 있더라도 적절한 영역에 해당 DNS 레코드를 만들어야 합니다. 예를 들어, Cloud DNS를 사용할 수 있습니다.

시작하기 전에

  • 아직 인증을 설정하지 않았다면 설정합니다. 인증은 Google Cloud 서비스 및 API에 액세스하기 위해 ID를 확인하는 프로세스입니다. 로컬 개발 환경에서 코드 또는 샘플을 실행하려면 다음과 같이 Compute Engine에 인증하면 됩니다.

    이 페이지의 샘플 사용 방법에 대한 탭을 선택하세요.

    콘솔

    Google Cloud 콘솔을 사용하여 Google Cloud 서비스 및 API에 액세스할 때는 인증을 설정할 필요가 없습니다.

    gcloud

    1. Google Cloud CLI를 설치한 후 다음 명령어를 실행하여 초기화합니다.

      gcloud init
    2. 기본 리전 및 영역을 설정합니다.

    Terraform

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

    1. Google Cloud CLI를 설치합니다.
    2. gcloud CLI를 초기화하려면 다음 명령어를 실행합니다.

      gcloud init
    3. Google 계정의 로컬 인증 사용자 인증 정보를 만듭니다.

      gcloud auth application-default login

    자세한 내용은 로컬 개발 환경의 인증 설정를 참조하세요.

    Go

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

    1. Google Cloud CLI를 설치합니다.
    2. gcloud CLI를 초기화하려면 다음 명령어를 실행합니다.

      gcloud init
    3. Google 계정의 로컬 인증 사용자 인증 정보를 만듭니다.

      gcloud auth application-default login

    자세한 내용은 로컬 개발 환경의 인증 설정를 참조하세요.

    Java

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

    1. Google Cloud CLI를 설치합니다.
    2. gcloud CLI를 초기화하려면 다음 명령어를 실행합니다.

      gcloud init
    3. Google 계정의 로컬 인증 사용자 인증 정보를 만듭니다.

      gcloud auth application-default login

    자세한 내용은 로컬 개발 환경의 인증 설정를 참조하세요.

    Node.js

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

    1. Google Cloud CLI를 설치합니다.
    2. gcloud CLI를 초기화하려면 다음 명령어를 실행합니다.

      gcloud init
    3. Google 계정의 로컬 인증 사용자 인증 정보를 만듭니다.

      gcloud auth application-default login

    자세한 내용은 로컬 개발 환경의 인증 설정를 참조하세요.

    Python

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

    1. Google Cloud CLI를 설치합니다.
    2. gcloud CLI를 초기화하려면 다음 명령어를 실행합니다.

      gcloud init
    3. Google 계정의 로컬 인증 사용자 인증 정보를 만듭니다.

      gcloud auth application-default login

    자세한 내용은 로컬 개발 환경의 인증 설정를 참조하세요.

    REST

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

      Google Cloud CLI를 설치한 후 다음 명령어를 실행하여 초기화합니다.

      gcloud init

필요한 역할

커스텀 호스트 이름으로 VM을 만드는 데 필요한 권한을 얻으려면 관리자에게 프로젝트에 대한 Compute 인스턴스 관리자(v1)(roles/compute.instanceAdmin.v1) IAM 역할을 부여해 달라고 요청하세요. 역할 부여에 대한 자세한 내용은 액세스 관리를 참조하세요.

이 사전 정의된 역할에는 커스텀 호스트 이름으로 VM을 만드는 데 필요한 권한이 포함되어 있습니다. 필요한 정확한 권한을 보려면 필수 권한 섹션을 펼치세요.

필수 권한

커스텀 호스트 이름으로 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 권한

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

제한사항

  • 커스텀 호스트 이름에 대한 DNS 레코드를 수동으로 구성해야 합니다. 커스텀 호스트 이름은 Compute Engine 내부 DNS에서 제공하는 자동으로 생성된 레코드로 확인되지 않습니다. 다음 중 하나를 사용하여 커스텀 호스트 이름에 대한 DNS 레코드를 호스팅할 수 있습니다.

  • VM을 만든 후에는 커스텀 호스트 이름을 변경할 수 없습니다.

이름 지정 규칙

커스텀 호스트 이름은 유효한 호스트 이름에 대한 RFC 1035 요구사항을 준수해야 합니다. 이러한 요구사항을 충족하려면 커스텀 호스트 이름이 다음 형식 사양을 충족해야 합니다.

  • 호스트 이름에는 다음과 같이 2개 이상의 라벨이 포함됩니다.
    • 각 라벨에는 [a-z]([-a-z0-9]*[a-z0-9])? 문자만 포함하는 정규 표현식이 포함됩니다.
    • 라벨은 점으로 연결됩니다.
    • 각 라벨의 허용 길이는 1~63자(영문 기준)입니다.
  • 호스트 이름은 253자(영문 기준) 이하여야 합니다.

유효하지 않음: 단일 라벨이 포함되어 있습니다.

my-host1234

유효: 점으로 연결된 라벨 3개가 포함됩니다.

my-host1234.example.com

커스텀 호스트 이름으로 VM 만들기

Console

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

    인스턴스 만들기로 이동

  2. VM의 이름을 지정합니다. 자세한 내용은 리소스 이름 지정 규칙을 참조하세요.

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

    1. 네트워킹 섹션을 펼칩니다.
    2. 호스트 이름 필드에 커스텀 호스트 이름을 지정합니다.
  4. 필요에 따라 VM을 추가로 맞춤설정합니다.

  5. 만들기를 클릭하여 VM을 만들고 시작합니다.

다음 단계: DNS 레코드를 구성합니다. 자세한 내용은 레코드 관리를 참조하세요.

gcloud

Google Cloud CLI를 사용하여 안내에 따라 이미지에서 인스턴스 만들기 또는 스냅샷 생성 과정을 진행하고, --hostname 플래그를 추가하고, 다음과 같이 gcloud compute instances create 명령어를 사용합니다.

gcloud compute instances create VM_NAME \
    --hostname=HOST_NAME

다음을 바꿉니다.

  • VM_NAME: VM의 이름입니다.
  • HOST_NAME: 할당하려는 정규화된 도메인 호스트 이름입니다.

예를 들어 커스텀 호스트 이름 test.example.com으로 VM myinstance를 만들려면 다음 명령어를 실행합니다.

gcloud compute instances create myinstance \
    --hostname=test.example.com

다음 단계: DNS 레코드를 구성합니다. 자세한 내용은 레코드 관리를 참조하세요.

Terraform

Terraform 리소스를 사용하여 hostname 인수를 사용하여 커스텀 호스트 이름으로 인스턴스를 만들 수 있습니다.


resource "google_compute_instance" "custom_hostname_instance" {
  name         = "custom-hostname-instance-name"
  machine_type = "f1-micro"
  zone         = "us-central1-c"

  # Set a custom hostname below
  hostname = "hashicorptest.com"

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-11"
    }
  }
  network_interface {
    # A default network is created for all GCP projects
    network = "default"
    access_config {
    }
  }
}
Terraform 코드를 생성하려면 Google Cloud 콘솔에서 상응하는 코드 구성요소를 사용하면 됩니다.
  1. Google Cloud 콘솔에서 VM 인스턴스 페이지로 이동합니다.

    VM 인스턴스로 이동

  2. 인스턴스 만들기를 클릭합니다.
  3. 원하는 매개변수를 지정합니다.
  4. 페이지 상단 또는 하단에서 상응하는 코드를 클릭한 후 Terraform 탭을 클릭하여 Terraform 코드를 확인합니다.

다음 단계: DNS 레코드를 구성합니다. 자세한 내용은 레코드 관리를 참조하세요.

Go

import (
	"context"
	"fmt"
	"io"

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

// createInstanceWithCustomHostname creates an instance with custom hostname.
func createInstanceWithCustomHostname(w io.Writer, projectID, zone, instanceName, hostname, machineType, sourceImage, networkName string) error {
	// projectID := "your_project_id"
	// zone := "europe-central2-b"
	// instanceName := "your_instance_name"
	// hostname := "host.example.com" // Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
	// machineType := "n1-standard-1"
	// sourceImage := "projects/debian-cloud/global/images/family/debian-10"
	// networkName := "global/networks/default"

	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,
		InstanceResource: &computepb.Instance{
			Name: proto.String(instanceName),
			// Custom hostnames are not resolved by the automatically created records
			// provided by Compute Engine internal DNS.
			// You must manually configure the DNS record for your custom hostname.
			Hostname: proto.String(hostname),
			Disks: []*computepb.AttachedDisk{
				{
					// Describe the size and source image of the boot disk to attach to the instance.
					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(fmt.Sprintf("zones/%s/machineTypes/%s", zone, machineType)),
			NetworkInterfaces: []*computepb.NetworkInterface{
				{
					// Use the network interface provided in the networkName argument.
					Name: proto.String(networkName),
				},
			},
		},
	}

	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 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 java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateInstanceWithCustomHostname {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // hostName: Custom hostname of the new VM instance.
    // *    Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
    String project = "your-project-id";
    String zone = "zone-name"; // eg: "us-central1-a"
    String instanceName = "instance-name";
    String hostName = "host.example.com";
    createInstanceWithCustomHostname(project, zone, instanceName, hostName);
  }

  // Creates an instance with custom hostname.
  public static void createInstanceWithCustomHostname(String projectId, String zone,
      String instanceName, String hostName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    //  machineType - Machine type for the VM instance specified in the following format:
    //  *    "zones/{zone}/machineTypes/{type_name}". For example:
    //  *    "zones/europe-west3-c/machineTypes/f1-micro"
    //  *    You can find the list of available machine types by using this gcloud command:
    //  *    $ gcloud compute machine-types list
    //  sourceImage - Path of the disk image you want to use for your boot
    //  *    disk. This image can be one of the public images
    //  *    eg: "projects/...
    //  *    or a private image you have access to.
    //  *    You can check the list of available public images using:
    //  *    $ gcloud compute images list
    //  networkName - Name of the network you want the new instance to use.
    //  *    For example: global/networks/default - if you want to use the default network.
    String machineType = "n1-standard-1";
    String sourceImage = String.format("projects/%s/global/images/family/%s", "debian-cloud",
        "debian-11");
    String networkName = "global/networks/default";

    try (InstancesClient instancesClient = InstancesClient.create()) {
      System.out.printf("Creating the %s instance in %s with hostname %s...", instanceName, zone,
          hostName);

      AttachedDisk disk =
          AttachedDisk.newBuilder()
              .setBoot(true)
              .setAutoDelete(true)
              .setType(AttachedDisk.Type.PERSISTENT.toString())
              .setInitializeParams(
                  // Describe the size and source image of the boot disk to attach to the instance.
                  AttachedDiskInitializeParams.newBuilder()
                      .setSourceImage(sourceImage)
                      .setDiskSizeGb(10).build())
              .build();

      // Use the network interface provided in the networkName argument.
      NetworkInterface networkInterface = NetworkInterface.newBuilder()
          .setName(networkName)
          .build();

      Instance instanceResource = Instance.newBuilder()
          // Custom hostnames are not resolved by the automatically created records
          // provided by Compute Engine internal DNS.
          // You must manually configure the DNS record for your custom hostname.
          .setName(instanceName)
          .setHostname(hostName)
          .addDisks(disk)
          .setMachineType(String.format("zones/%s/machineTypes/%s", zone, machineType))
          .addNetworkInterfaces(networkInterface).build();

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

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

      if (response.hasError()) {
        System.out.printf("Instance creation failed for instance: %s ; Response: %s ! ! ",
            instanceName, response);
        return;
      }
      System.out.printf("Instance created : %s", instanceName);
      System.out.printf("Operation Status for instance %s is %s: ", instanceName,
          response.getStatus());
    }

  }

}

Node.js

/**
 * 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 hostname = 'host.example.com'
// const machineType = 'n1-standard-1';
// const sourceImage = 'projects/debian-cloud/global/images/family/debian-10';
// const networkName = 'global/networks/default';

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

// Create a new instance with the values provided above in the specified project and zone.
async function createInstanceWithCustomHostname() {
  const instancesClient = new compute.InstancesClient();

  console.log(
    `Creating the ${instanceName} instance in ${zone} with hostname ${hostname}...`
  );

  const [response] = await instancesClient.insert({
    instanceResource: {
      name: instanceName,
      // Custom hostnames are not resolved by the automatically created records
      // provided by Compute Engine internal DNS.
      // You must manually configure the DNS record for your custom hostname.
      hostname,
      disks: [
        {
          // Describe the size and source image of the boot disk to attach to the instance.
          initializeParams: {
            diskSizeGb: '10',
            sourceImage,
          },
          autoDelete: true,
          boot: true,
          type: 'PERSISTENT',
        },
      ],
      machineType: `zones/${zone}/machineTypes/${machineType}`,
      networkInterfaces: [
        {
          // Use the network interface provided in the networkName argument.
          name: networkName,
        },
      ],
    },
    project: projectId,
    zone,
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.ZoneOperationsClient();

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

  console.log('Instance created.');
}

createInstanceWithCustomHostname();

Python

from __future__ import annotations

import re
import sys
from typing import Any
import warnings

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

def get_image_from_family(project: str, family: str) -> compute_v1.Image:
    """
    Retrieve the newest image that is part of a given family in a project.

    Args:
        project: project ID or project number of the Cloud project you want to get image from.
        family: name of the image family you want to get image from.

    Returns:
        An Image object.
    """
    image_client = compute_v1.ImagesClient()
    # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
    newest_image = image_client.get_from_family(project=project, family=family)
    return newest_image

def disk_from_image(
    disk_type: str,
    disk_size_gb: int,
    boot: bool,
    source_image: str,
    auto_delete: bool = True,
) -> compute_v1.AttachedDisk:
    """
    Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
    source for the new disk.

    Args:
         disk_type: the type of disk you want to create. This value uses the following format:
            "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
            For example: "zones/us-west3-b/diskTypes/pd-ssd"
        disk_size_gb: size of the new disk in gigabytes
        boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
        source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
            of the publicly available images or an image from one of your projects.
            This value uses the following format: "projects/{project_name}/global/images/{image_name}"
        auto_delete: boolean flag indicating whether this disk should be deleted with the VM that uses it

    Returns:
        AttachedDisk object configured to be created using the specified image.
    """
    boot_disk = compute_v1.AttachedDisk()
    initialize_params = compute_v1.AttachedDiskInitializeParams()
    initialize_params.source_image = source_image
    initialize_params.disk_size_gb = disk_size_gb
    initialize_params.disk_type = disk_type
    boot_disk.initialize_params = initialize_params
    # Remember to set auto_delete to True if you want the disk to be deleted when you delete
    # your VM instance.
    boot_disk.auto_delete = auto_delete
    boot_disk.boot = boot
    return boot_disk

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

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

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

    Returns:
        Whatever the operation.result() returns.

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

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

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

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

    return result

def create_instance(
    project_id: str,
    zone: str,
    instance_name: str,
    disks: list[compute_v1.AttachedDisk],
    machine_type: str = "n1-standard-1",
    network_link: str = "global/networks/default",
    subnetwork_link: str = None,
    internal_ip: str = None,
    external_access: bool = False,
    external_ipv4: str = None,
    accelerators: list[compute_v1.AcceleratorConfig] = None,
    preemptible: bool = False,
    spot: bool = False,
    instance_termination_action: str = "STOP",
    custom_hostname: str = None,
    delete_protection: bool = False,
) -> compute_v1.Instance:
    """
    Send an instance creation request to the Compute Engine API and wait for it to complete.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone to create the instance in. For example: "us-west3-b"
        instance_name: name of the new virtual machine (VM) instance.
        disks: a list of compute_v1.AttachedDisk objects describing the disks
            you want to attach to your new instance.
        machine_type: machine type of the VM being created. This value uses the
            following format: "zones/{zone}/machineTypes/{type_name}".
            For example: "zones/europe-west3-c/machineTypes/f1-micro"
        network_link: name of the network you want the new instance to use.
            For example: "global/networks/default" represents the network
            named "default", which is created automatically for each project.
        subnetwork_link: name of the subnetwork you want the new instance to use.
            This value uses the following format:
            "regions/{region}/subnetworks/{subnetwork_name}"
        internal_ip: internal IP address you want to assign to the new instance.
            By default, a free address from the pool of available internal IP addresses of
            used subnet will be used.
        external_access: boolean flag indicating if the instance should have an external IPv4
            address assigned.
        external_ipv4: external IPv4 address to be assigned to this instance. If you specify
            an external IP address, it must live in the same region as the zone of the instance.
            This setting requires `external_access` to be set to True to work.
        accelerators: a list of AcceleratorConfig objects describing the accelerators that will
            be attached to the new instance.
        preemptible: boolean value indicating if the new instance should be preemptible
            or not. Preemptible VMs have been deprecated and you should now use Spot VMs.
        spot: boolean value indicating if the new instance should be a Spot VM or not.
        instance_termination_action: What action should be taken once a Spot VM is terminated.
            Possible values: "STOP", "DELETE"
        custom_hostname: Custom hostname of the new VM instance.
            Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
        delete_protection: boolean value indicating if the new virtual machine should be
            protected against deletion or not.
    Returns:
        Instance object.
    """
    instance_client = compute_v1.InstancesClient()

    # Use the network interface provided in the network_link argument.
    network_interface = compute_v1.NetworkInterface()
    network_interface.network = network_link
    if subnetwork_link:
        network_interface.subnetwork = subnetwork_link

    if internal_ip:
        network_interface.network_i_p = internal_ip

    if external_access:
        access = compute_v1.AccessConfig()
        access.type_ = compute_v1.AccessConfig.Type.ONE_TO_ONE_NAT.name
        access.name = "External NAT"
        access.network_tier = access.NetworkTier.PREMIUM.name
        if external_ipv4:
            access.nat_i_p = external_ipv4
        network_interface.access_configs = [access]

    # Collect information into the Instance object.
    instance = compute_v1.Instance()
    instance.network_interfaces = [network_interface]
    instance.name = instance_name
    instance.disks = disks
    if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
        instance.machine_type = machine_type
    else:
        instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"

    instance.scheduling = compute_v1.Scheduling()
    if accelerators:
        instance.guest_accelerators = accelerators
        instance.scheduling.on_host_maintenance = (
            compute_v1.Scheduling.OnHostMaintenance.TERMINATE.name
        )

    if preemptible:
        # Set the preemptible setting
        warnings.warn(
            "Preemptible VMs are being replaced by Spot VMs.", DeprecationWarning
        )
        instance.scheduling = compute_v1.Scheduling()
        instance.scheduling.preemptible = True

    if spot:
        # Set the Spot VM setting
        instance.scheduling.provisioning_model = (
            compute_v1.Scheduling.ProvisioningModel.SPOT.name
        )
        instance.scheduling.instance_termination_action = instance_termination_action

    if custom_hostname is not None:
        # Set the custom hostname for the instance
        instance.hostname = custom_hostname

    if delete_protection:
        # Set the delete protection bit
        instance.deletion_protection = True

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

    # Wait for the create operation to complete.
    print(f"Creating the {instance_name} instance in {zone}...")

    operation = instance_client.insert(request=request)

    wait_for_extended_operation(operation, "instance creation")

    print(f"Instance {instance_name} created.")
    return instance_client.get(project=project_id, zone=zone, instance=instance_name)

def create_instance_custom_hostname(
    project_id: str, zone: str, instance_name: str, hostname: str
) -> compute_v1.Instance:
    """
    Create a new VM instance with Debian 10 operating system and a custom hostname.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone to create the instance in. For example: "us-west3-b"
        instance_name: name of the new virtual machine (VM) instance.
        hostname: the hostname you want to use for the new instance.

    Returns:
        Instance object.
    """
    newest_debian = get_image_from_family(project="debian-cloud", family="debian-11")
    disk_type = f"zones/{zone}/diskTypes/pd-standard"
    disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
    instance = create_instance(
        project_id, zone, instance_name, disks, custom_hostname=hostname
    )
    return instance

REST

API 안내에 따라 스냅샷 또는 이미지에서 인스턴스를 만들고 요청 본문에 hostname 필드를 지정합니다.

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

{
 "name": "VM_NAME",
 "hostname": "HOST_NAME",
 ...
}

다음을 바꿉니다.

  • PROJECT_ID: 프로젝트 ID입니다.
  • ZONE: VM을 만들 영역입니다.
  • VM_NAME: VM의 이름입니다.
  • HOST_NAME: 할당하려는 정규화된 도메인 호스트 이름입니다.

커스텀 호스트 이름 확인

Linux VM의 경우 VM에서 hostname -f 명령어를 실행하여 호스트 이름을 확인할 수 있습니다.

Google Cloud Console 또는 Google Cloud CLI를 사용하여 커스텀 호스트 이름을 확인할 수도 있습니다.

Console

  1. VM의 커스텀 호스트 이름을 보려면 VM 인스턴스 페이지로 이동합니다.

    VM 인스턴스로 이동

  2. 인스턴스 이름을 클릭하여 VM 인스턴스 세부정보 페이지를 엽니다.

  3. 호스트 이름 섹션을 검토합니다. 호스트 이름 필드는 커스텀 호스트 이름이 설정된 경우에만 표시됩니다.

    호스트 이름을 보여주는 VM 인스턴스 페이지

gcloud

gcloud compute를 사용하여 VM의 커스텀 호스트 이름을 보려면 --format 플래그가 지정된 instances describe 하위 명령어를 사용하여 출력을 필터링합니다. VM_NAME을 VM의 이름으로 바꿉니다.

gcloud compute instances describe VM_NAME \
    --format='get(hostname)'

예를 들어 myinstance라는 VM의 커스텀 호스트 이름을 보려면 다음 명령어를 실행합니다.

gcloud compute instances describe myinstance \
    --format='get(hostname)'

다음과 유사한 출력이 표시됩니다.

test.example.com

커스텀 호스트 이름이 설정되지 않은 경우 이 명령어의 출력이 비어 있습니다.

다음 단계