Linux
Windows
가상 머신 (VM) 인스턴스를 만들 때 Google Cloud는 VM 이름으로부터 내부 DNS 이름을 만듭니다.
커스텀 호스트 이름을 지정하지 않으면 Google Cloud는 자동으로 생성된 내부 DNS 이름을 VM에 제공하는 호스트 이름으로 사용합니다.
정규화된 DNS 이름을 지정하여 커스텀 호스트 이름으로 VM을 만들 수 있습니다. 커스텀 호스트 이름은 규칙을 유지하거나 특정 호스트 이름이 필요한 애플리케이션의 요구사항을 지원하는 데 유용합니다.
커스텀 호스트 이름을 지정해도 Google Cloud는 Compute Engine 내부 DNS 이름을 만듭니다. 자동으로 생성된 이 내부 DNS 레코드를 사용하여 VM에 연결할 수 있습니다. 내부 DNS 레코드는 커스텀 호스트 이름이 아니라 내부 DNS 이름으로 확인됩니다. 커스텀 호스트 이름이 있더라도 적절한 영역에 해당 DNS 레코드를 만들어야 합니다. 예를 들어, Cloud DNS를 사용할 수 있습니다.
시작하기 전에
필요한 역할
커스텀 호스트 이름으로 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
권한
커스텀 역할이나 다른 사전 정의된 역할을 사용하여 이 권한을 부여받을 수도 있습니다.
제한사항
이름 지정 규칙
커스텀 호스트 이름은 유효한 호스트 이름에 대한 RFC 1035 요구사항을 준수해야 합니다. 이러한 요구사항을 충족하려면 커스텀 호스트 이름이 다음 형식 사양을 충족해야 합니다.
- 호스트 이름에는 다음과 같이 2개 이상의 라벨이 포함됩니다.
- 각 라벨에는
[a-z]([-a-z0-9]*[a-z0-9])?
문자만 포함하는 정규 표현식이 포함됩니다.
- 라벨은 점으로 연결됩니다.
- 각 라벨의 허용 길이는 1~63자(영문 기준)입니다.
- 호스트 이름은 253자(영문 기준) 이하여야 합니다.
유효하지 않음: 단일 라벨이 포함되어 있습니다.
my-host1234
유효: 점으로 연결된 라벨 3개가 포함됩니다.
my-host1234.example.com
커스텀 호스트 이름으로 VM 만들기
Console
Google Cloud 콘솔에서 인스턴스 만들기 페이지로 이동합니다.
인스턴스 만들기로 이동
VM의 이름을 지정합니다. 자세한 내용은 리소스 이름 지정 규칙을 참조하세요.
고급 옵션 섹션을 펼친 후 다음을 수행합니다.
- 네트워킹 섹션을 펼칩니다.
- 호스트 이름 필드에 커스텀 호스트 이름을 지정합니다.
필요에 따라 VM을 추가로 맞춤설정합니다.
만들기를 클릭하여 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 리소스를 사용하여 hostname
인수를 사용하여 커스텀 호스트 이름으로 인스턴스를 만들 수 있습니다.
Terraform 코드를 생성하려면 Google Cloud 콘솔에서 상응하는 코드 구성요소를 사용하면 됩니다.
- Google Cloud 콘솔에서 VM 인스턴스 페이지로 이동합니다.
VM 인스턴스로 이동
- 인스턴스 만들기를 클릭합니다.
- 원하는 매개변수를 지정합니다.
- 페이지 상단 또는 하단에서 상응하는 코드를 클릭한 후 Terraform 탭을 클릭하여 Terraform 코드를 확인합니다.
다음 단계: DNS 레코드를 구성합니다. 자세한 내용은 레코드 관리를 참조하세요.
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
VM의 커스텀 호스트 이름을 보려면 VM 인스턴스 페이지로 이동합니다.
VM 인스턴스로 이동
인스턴스 이름을 클릭하여 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
커스텀 호스트 이름이 설정되지 않은 경우 이 명령어의 출력이 비어 있습니다.
다음 단계