M3, 1세대 및 2세대 머신 계열의 경우 연결된 로컬 SSD 디스크가 있는 VM을 만들려면 다음 인스턴스 만들기 안내를 따르되 --local-ssd 플래그를 사용하여 로컬 SSD 디스크를 만들고 연결합니다. 여러 개의 로컬 SSD 디스크를 만들려면 --local-ssd 플래그를 더 추가합니다.
원하는 경우 --local-ssd 플래그마다 인터페이스 값과 기기 이름을 설정할 수도 있습니다.
예를 들어 4개의 로컬 SSD 디스크가 있는 M3 VM을 만들고 다음과 같이 디스크 인터페이스 유형을 지정할 수 있습니다.
# Create a VM with a local SSD for temporary storage use cases
resource "google_compute_instance" "default" {
name = "my-vm-instance-with-scratch"
machine_type = "n2-standard-8"
zone = "us-central1-a"
boot_disk {
initialize_params {
image = "debian-cloud/debian-11"
}
}
# Local SSD interface type; NVME for image with optimized NVMe drivers or SCSI
# Local SSD are 375 GiB in size
scratch_disk {
interface = "SCSI"
}
network_interface {
network = "default"
access_config {}
}
}
import com.google.cloud.compute.v1.AttachedDisk;
import com.google.cloud.compute.v1.AttachedDiskInitializeParams;
import com.google.cloud.compute.v1.Image;
import com.google.cloud.compute.v1.ImagesClient;
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.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class CreateWithLocalSsd {
public static void main(String[] args)
throws IOException, ExecutionException, InterruptedException, TimeoutException {
// TODO(developer): Replace these variables before running the sample.
// projectId: project ID or project number of the Cloud project you want to use.
String projectId = "your-project-id";
// zone: name of the zone to create the instance in. For example: "us-west3-b"
String zone = "zone-name";
// instanceName: name of the new virtual machine (VM) instance.
String instanceName = "instance-name";
createWithLocalSsd(projectId, zone, instanceName);
}
// Create a new VM instance with Debian 10 operating system and SSD local disk.
public static void createWithLocalSsd(String projectId, String zone, String instanceName)
throws IOException, ExecutionException, InterruptedException, TimeoutException {
int diskSizeGb = 10;
boolean boot = true;
boolean autoDelete = true;
String diskType = String.format("zones/%s/diskTypes/pd-standard", zone);
// Get the latest debian image.
Image newestDebian = getImageFromFamily("debian-cloud", "debian-10");
List<AttachedDisk> disks = new ArrayList<>();
// Create the disks to be included in the instance.
disks.add(
createDiskFromImage(diskType, diskSizeGb, boot, newestDebian.getSelfLink(), autoDelete));
disks.add(createLocalSsdDisk(zone));
// Create the instance.
Instance instance = createInstance(projectId, zone, instanceName, disks);
if (instance != null) {
System.out.printf("Instance created with local SSD: %s", instance.getName());
}
}
// Retrieve the newest image that is part of a given family in a project.
// Args:
// projectId: 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.
private static Image getImageFromFamily(String projectId, String family) throws IOException {
// 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 `imagesClient.close()` method on the client to safely
// clean up any remaining background resources.
try (ImagesClient imagesClient = ImagesClient.create()) {
// List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
return imagesClient.getFromFamily(projectId, family);
}
}
// Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
// source for the new disk.
//
// Args:
// diskType: 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"
//
// diskSizeGb: size of the new disk in gigabytes.
//
// boot: boolean flag indicating whether this disk should be used as a
// boot disk of an instance.
//
// sourceImage: 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}"
//
// autoDelete: boolean flag indicating whether this disk should be deleted
// with the VM that uses it.
private static AttachedDisk createDiskFromImage(String diskType, int diskSizeGb, boolean boot,
String sourceImage, boolean autoDelete) {
AttachedDiskInitializeParams attachedDiskInitializeParams =
AttachedDiskInitializeParams.newBuilder()
.setSourceImage(sourceImage)
.setDiskSizeGb(diskSizeGb)
.setDiskType(diskType)
.build();
AttachedDisk bootDisk = AttachedDisk.newBuilder()
.setInitializeParams(attachedDiskInitializeParams)
// Remember to set auto_delete to True if you want the disk to be deleted when you delete
// your VM instance.
.setAutoDelete(autoDelete)
.setBoot(boot)
.build();
return bootDisk;
}
// Create an AttachedDisk object to be used in VM instance creation. The created disk contains
// no data and requires formatting before it can be used.
// Args:
// zone: The zone in which the local SSD drive will be attached.
private static AttachedDisk createLocalSsdDisk(String zone) {
AttachedDiskInitializeParams attachedDiskInitializeParams =
AttachedDiskInitializeParams.newBuilder()
.setDiskType(String.format("zones/%s/diskTypes/local-ssd", zone))
.build();
AttachedDisk disk = AttachedDisk.newBuilder()
.setType(AttachedDisk.Type.SCRATCH.name())
.setInitializeParams(attachedDiskInitializeParams)
.setAutoDelete(true)
.build();
return disk;
}
// Send an instance creation request to the Compute Engine API and wait for it to complete.
// Args:
// projectId: 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"
// instanceName: 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.
private static Instance createInstance(String projectId, String zone, String instanceName,
List<AttachedDisk> disks)
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()) {
// machineType: 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"
String typeName = "n1-standard-1";
String machineType = String.format("zones/%s/machineTypes/%s", zone, typeName);
// networkLink: 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.
String networkLink = "global/networks/default";
// Collect information into the Instance object.
Instance instance = Instance.newBuilder()
.setName(instanceName)
.setMachineType(machineType)
.addNetworkInterfaces(NetworkInterface.newBuilder().setName(networkLink).build())
.addAllDisks(disks)
.build();
Operation response = instancesClient.insertAsync(projectId, zone, instance)
.get(3, TimeUnit.MINUTES);
if (response.hasError()) {
throw new Error("Instance creation failed ! ! " + response);
}
System.out.println("Operation Status: " + response.getStatus());
return instancesClient.get(projectId, zone, instanceName);
}
}
}
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 local_ssd_disk(zone: str) -> compute_v1.AttachedDisk():
"""
Create an AttachedDisk object to be used in VM instance creation. The created disk contains
no data and requires formatting before it can be used.
Args:
zone: The zone in which the local SSD drive will be attached.
Returns:
AttachedDisk object configured as a local SSD disk.
"""
disk = compute_v1.AttachedDisk()
disk.type_ = compute_v1.AttachedDisk.Type.SCRATCH.name
initialize_params = compute_v1.AttachedDiskInitializeParams()
initialize_params.disk_type = f"zones/{zone}/diskTypes/local-ssd"
disk.initialize_params = initialize_params
disk.auto_delete = True
return 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_with_ssd(
project_id: str, zone: str, instance_name: str
) -> compute_v1.Instance:
"""
Create a new VM instance with Debian 10 operating system and SSD local disk.
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.
Returns:
Instance object.
"""
newest_debian = get_image_from_family(project="debian-cloud", family="debian-10")
disk_type = f"zones/{zone}/diskTypes/pd-standard"
disks = [
disk_from_image(disk_type, 10, True, newest_debian.self_link, True),
local_ssd_disk(zone),
]
instance = create_instance(project_id, zone, instance_name, disks)
return instance
ext4 파일 시스템으로 로컬 SSD를 포맷합니다. 이 명령어는 로컬 SSD에서 기존 데이터를 모두 삭제합니다.
$ sudo mkfs.ext4 -F /dev/disk/by-id/[SSD_NAME]
[SSD_NAME]을 포맷할 로컬 SSD의 ID로 바꿉니다. 예를 들어 인스턴스의 첫 번째 NVMe 로컬 SSD를 포맷하려면 google-local-nvme-ssd-0을 지정합니다.
mkdir 명령어를 사용하여 기기를 마운트할 수 있는 디렉터리를 만듭니다.
$ sudo mkdir -p /mnt/disks/[MNT_DIR]
[MNT_DIR]을 로컬 SSD 디스크를 마운트하려는 디렉터리 경로로 바꿉니다.
로컬 SSD를 VM에 마운트합니다.
$ sudo mount /dev/[SSD_NAME] /mnt/disks/[MNT_DIR]
다음을 바꿉니다.
[SSD_NAME]: 마운트하려는 로컬 SSD의 ID입니다.
[MNT_DIR]: 로컬 SSD를 마운트하려는 디렉터리입니다.
기기의 읽기 및 쓰기 액세스 권한을 구성합니다. 이 예시에서는 모든 사용자에게 기기에 대한 쓰기 액세스 권한을 부여합니다.
$ sudo chmod a+w /mnt/disks/[MNT_DIR]
[MNT_DIR]을 로컬 SSD를 마운트한 디렉터리로 바꿉니다.
원하는 경우 인스턴스가 다시 시작될 때 기기가 자동으로 다시 마운트되도록 로컬 SSD를 /etc/fstab 파일에 추가할 수 있습니다. 이 항목은 인스턴스가 중지되는 경우 로컬 SSD의 데이터를 보존하지 않습니다. 자세한 내용은 로컬 SSD 데이터 지속성을 참조하세요.
항목 /etc/fstab 파일을 지정할 때는 로컬 SSD가 없더라도 인스턴스가 계속 부팅할 수 있도록 nofail 옵션을 포함해야 합니다. 예를 들어 부팅 디스크의 스냅샷을 만들고 로컬 SSD 디스크가 연결되지 않은 상태에서 새 인스턴스를 만들 경우 인스턴스가 시작 프로세스를 계속 수행할 수 있으며 무기한 중지되지 않습니다.
/etc/fstab 항목을 만듭니다. blkid 명령어를 사용하여 기기의 파일 시스템에 해당하는 UUID를 찾고 이 UUID가 마운트 옵션에 포함되도록 /etc/fstab 파일을 수정합니다. 명령어 하나로 이 단계를 완료할 수 있습니다.
예를 들어 NVMe 모드의 로컬 SSD의 경우 다음 명령어를 사용하세요.
$ echo UUID=`sudo blkid -s UUID -o value /dev/disk/by-id/google-local-nvme-ssd-0` /mnt/disks/[MNT_DIR] ext4 discard,defaults,nofail 0 2 | sudo tee -a /etc/fstab
SCSI와 같은 비NVMe 모드의 로컬 SSD의 경우 다음 명령어를 사용합니다.
$ echo UUID=`sudo blkid -s UUID -o value /dev/disk/by-id/google-local-ssd-0` /mnt/disks/[MNT_DIR] ext4 discard,defaults,nofail 0 2 | sudo tee -a /etc/fstab
[MNT_DIR]을 로컬 SSD를 마운트한 디렉터리로 바꿉니다.
cat 명령어를 사용하여 /etc/fstab 항목이 올바른지 확인합니다.
$ cat /etc/fstab
이 인스턴스의 부팅 디스크에서 스냅샷을 만들고 사용하여 로컬 SSD가 없는 별도의 인스턴스를 만들 경우, /etc/fstab 파일을 수정하고 이 로컬 SSD의 항목을 삭제합니다. nofail 옵션이 있더라도 /etc/fstab 파일을 인스턴스에 연결된 파티션과 동기화된 상태로 유지하고 부팅 디스크의 스냅샷을 만들기 전에 이러한 항목을 삭제합니다.
Windows 인스턴스
Windows 디스크 관리 도구를 사용해 Windows 인스턴스에서 로컬 SSD를 포맷하고 마운트합니다.
RDP를 통해 인스턴스에 연결합니다. 이 예시에서는 VM 인스턴스 페이지로 이동하여 로컬 SSD가 연결된 인스턴스 옆에 있는 RDP 버튼을 클릭합니다. 사용자 이름과 비밀번호를 입력하면 서버의 데스크톱 인터페이스가 포함된 창이 열립니다.
Windows 시작 버튼을 마우스 오른쪽 버튼으로 클릭하고 디스크 관리를 선택합니다.
로컬 SSD를 아직 초기화하지 않았으면 새 파티션의 파티션 나누기 스키마를 선택하라는 메시지가 표시됩니다. GPT를 선택하고 확인을 클릭합니다.
로컬 SSD가 초기화된 후 할당되지 않은 디스크 공간을 마우스 오른쪽 버튼으로 클릭하고 새 단순 볼륨을 선택합니다.
단순 볼륨 만들기 마법사의 안내에 따라 새 볼륨을 구성합니다. 파티션 형식은 원하는 것을 사용하면 되지만 이 예시에서는 NTFS를 선택합니다. 또한 빠른 포맷 실행을 선택해 포맷 프로세스 속도를 높입니다.
마법사를 완료하고 볼륨 포맷을 마친 후에 새 로컬 SSD가 Healthy 상태인지 확인합니다.
작업이 끝났습니다. 이제 로컬 SSD에 파일을 쓸 수 있습니다.
로컬 SSD 파티션 여러 개를 포맷하고 단일 논리 볼륨에 마운트
영구 SSD와 달리 로컬 SSD는 인스턴스에 연결하는 기기마다 용량이 375GB로 고정되어 있습니다. 로컬 SSD 파티션 여러 개를 단일 논리 볼륨에 결합하려면 이러한 파티션에 볼륨 관리를 직접 정의해야 합니다.
Linux 인스턴스
mdadm을 사용하여 RAID 0 배열을 만듭니다. 이 예시에서는 단일 ext4 파일 시스템으로 배열을 포맷하지만 원하는 파일 시스템을 적용할 수 있습니다.
find는 순서를 보장하지 않습니다. 출력 라인 수가 예상 SSD 파티션 수와 일치하기만 하면 기기가 다른 순서로 나열되더라도 문제가 없습니다.
SCSI 모드의 로컬 SSD에는 google-local-ssd와 같은 표준 이름이 사용되며 NVMe 모드의 로컬 SSD에는 google-local-nvme-ssd과 같은 이름이 사용됩니다.
mdadm을 사용하여 여러 로컬 SSD 기기를 /dev/md0이라는 이름의 단일 배열로 결합합니다. 이 예시에서는 NVMe 모드의 로컬 SSD 기기 8개를 병합합니다. SCSI 모드의 로컬 SSD 기기인 경우 find 명령어로 얻은 이름을 지정합니다.
mdadm --detail을 사용하여 배열의 세부정보를 확인할 수 있습니다. --prefer=by-id 플래그를 추가하면 /dev/disk/by-id 경로를 사용하는 기기가 나열됩니다.
sudo mdadm --detail --prefer=by-id /dev/md0
배열의 각 기기에서 다음과 같이 출력되어야 합니다.
...
Number Major Minor RaidDevice State
0 259 0 0 active sync /dev/disk/by-id/google-local-nvme-ssd-0
...
ext4 파일 시스템으로 전체 /dev/md0 배열을 포맷합니다.
$ sudo mkfs.ext4 -F /dev/md0
/dev/md0을 마운트할 수 있는 디렉터리를 만듭니다. 이 예시에서는 /mnt/disks/ssd-array 디렉터리를 만듭니다.
$ sudo mkdir -p /mnt/disks/[MNT_DIR]
[MNT_DIR]을 로컬 SSD 배열을 마운트하려는 디렉터리로 바꿉니다.
/dev/md0 배열을 /mnt/disks/ssd-array 디렉터리에 마운트합니다.
$ sudo mount /dev/md0 /mnt/disks/[MNT_DIR]
[MNT_DIR]을 로컬 SSD 배열을 마운트하려는 디렉터리로 바꿉니다.
기기의 읽기 및 쓰기 액세스 권한을 구성합니다. 이 예시에서는 모든 사용자에게 기기에 대한 쓰기 액세스 권한을 부여합니다.
$ sudo chmod a+w /mnt/disks/[MNT_DIR]
[MNT_DIR]을 로컬 SSD 배열을 마운트한 디렉터리로 바꿉니다.
원하는 경우 인스턴스가 다시 시작될 때 기기가 자동으로 다시 마운트되도록 로컬 SSD를 /etc/fstab 파일에 추가할 수 있습니다. 이 항목은 인스턴스가 중지되는 경우 로컬 SSD의 데이터를 보존하지 않습니다.
자세한 내용은 로컬 SSD 데이터 지속성을 참조하세요.
항목 /etc/fstab 파일을 지정할 때는 로컬 SSD가 없더라도 인스턴스가 계속 부팅할 수 있도록 nofail 옵션을 포함해야 합니다. 예를 들어 부팅 디스크의 스냅샷을 만들고 로컬 SSD가 연결되지 않은 상태에서 새 인스턴스를 만들 경우 인스턴스가 시작 프로세스를 계속 수행할 수 있으며 무기한 중지되지 않습니다.
/etc/fstab 항목을 만듭니다. blkid 명령어를 사용하여 기기의 파일 시스템에 해당하는 UUID를 찾고 이 UUID가 마운트 옵션에 포함되도록 /etc/fstab 파일을 수정합니다. 로컬 SSD를 사용할 수 없는 경우에도 시스템이 부팅되도록 nofail 옵션을 지정합니다. 이 단계는 단일 명령어로 완료할 수 있습니다. 예를 들면 다음과 같습니다.
$ echo UUID=`sudo blkid -s UUID -o value /dev/md0` /mnt/disks/[MNT_DIR] ext4 discard,defaults,nofail 0 2 | sudo tee -a /etc/fstab
[MNT_DIR]을 로컬 SSD 배열을 마운트한 디렉터리로 바꿉니다.
UUID 대신 /etc/fstab 파일에 /dev/md0과 같은 기기 이름을 사용하는 경우 부팅 시 배열이 자동으로 재조합되도록 /etc/mdadm/mdadm.conf 파일을 수정해야 합니다. 이렇게 하려면 다음 두 단계를 완료해야 합니다.
부팅 시 디스크 배열이 자동으로 스캔되고 재조합되는지 확인합니다.
$ sudo mdadm --detail --scan | sudo tee -a /etc/mdadm/mdadm.conf
초기 부팅 프로세스 중에 배열을 사용할 수 있도록 initramfs를 업데이트합니다.
$ sudo update-initramfs -u
cat 명령어를 사용하여 /etc/fstab 항목이 올바른지 확인합니다.
$ cat /etc/fstab
이 인스턴스의 부팅 디스크에서 스냅샷을 만들고 사용하여 로컬 SSD가 없는 별도의 인스턴스를 만들 경우, /etc/fstab 파일을 수정하고 이 로컬 SSD 배열의 항목을 삭제합니다. nofail 옵션이 있더라도 /etc/fstab 파일을 인스턴스에 연결된 파티션과 동기화된 상태로 유지하고 부팅 디스크의 스냅샷을 만들기 전에 이러한 항목을 삭제합니다.
Windows 인스턴스
Windows 디스크 관리 도구를 사용해 Windows 인스턴스에서 로컬 SSD 배열을 포맷하고 마운트합니다.
RDP를 통해 인스턴스에 연결합니다. 이 예시에서는 VM 인스턴스 페이지로 이동하여 로컬 SSD가 연결된 인스턴스 옆에 있는 RDP 버튼을 클릭합니다. 사용자 이름과 비밀번호를 입력하면 서버의 데스크톱 인터페이스가 포함된 창이 열립니다.
Windows 시작 버튼을 마우스 오른쪽 버튼으로 클릭하고 디스크 관리를 선택합니다.
로컬 SSD를 아직 초기화하지 않았으면 새 파티션의 파티션 나누기 스키마를 선택하라는 메시지가 표시됩니다. GPT를 선택하고 확인을 클릭합니다.
로컬 SSD가 초기화된 후 할당되지 않은 디스크 공간을 마우스 오른쪽 버튼으로 클릭하고 새 스트라이프 볼륨을 선택합니다.
스트라이프 배열에 포함할 로컬 SSD 파티션을 선택합니다. 이 예시에서는 모든 파티션을 선택하여 단일 로컬 SSD 기기로 결합합니다.
새 스트라이프 볼륨 마법사의 안내에 따라 새 볼륨을 구성합니다. 파티션 형식은 원하는 것을 사용하면 되지만 이 예시에서는 NTFS를 선택합니다. 또한 빠른 포맷 실행을 선택해 포맷 프로세스 속도를 높입니다.
마법사를 완료하고 볼륨 포맷을 마친 후에 새 로컬 SSD가 Healthy 상태인지 확인합니다.