永続ディスクを変更する


永続ディスクは、仮想マシン(VM)インスタンスのブートディスクとして使用するか、VM にアタッチするデータディスクとして使用できます。このドキュメントでは、次の目的で既存の永続ディスクを変更する方法について説明します。

  • 別のディスクタイプに切り替える。
  • 接続された VM が削除されたときにディスクを自動削除する。

永続ディスクに関する一般的な情報と使用可能なディスクタイプについては、永続ディスクの概要をご覧ください。

Persistent Disk ボリュームのタイプを変更する

パフォーマンスや料金の要件を満たすために、特定の Persistent Disk ボリュームのタイプを変更する必要が生じる場合があります。たとえば、ワークロードのデータディスクを標準 Persistent Disk からバランス Persistent Disk に変更する場合があります。

既存の Persistent Disk ボリュームのタイプを直接変更することはできません。既存のディスクのスナップショットを作成してから、そのスナップショットを使用して新しいタイプのディスクを作成する必要があります。

たとえば、標準 Persistent Disk を SSD Persistent Disk に変更するには、次の手順を行います。

コンソール

  1. 標準永続ディスクのスナップショットを作成します。
  2. スナップショットに基づく新しい永続ディスクを作成します。[タイプ] プルダウン リストから [SSD 永続ディスク] を選択します。

gcloud

  1. 標準永続ディスクのスナップショットを作成します。
  2. スナップショットに基づく新しい永続ディスクを作成します。--type フラグを追加し、pd-ssd を指定します。

REST

  1. 標準永続ディスクのスナップショットを作成します。
  2. スナップショットに基づく新しい永続ディスクを作成します。type フィールドに "zones/ZONE/diskTypes/pd-ssd" を指定します。ZONE は、インスタンスと新しいディスクが配置されるゾーンに置き換えます。

新しいディスクを作成してテストしたら、スナップショットを削除し、元のディスクを削除できます。

Persistent Disk ボリュームの自動削除状態を設定する

読み取り / 書き込みの Persistent Disk ボリュームは、関連する VM インスタンスが削除されるときに自動的に削除できます。この動作は、アタッチされているディスクの VM インスタンスの autoDelete プロパティで制御され、いつでも更新できます。同様に、autoDelete 値を false に設定すると、Persistent Disk ボリュームが削除されなくなります。

コンソール

  1. Google Cloud コンソールの [VM インスタンス] ページに移動します。

    [VM インスタンス] に移動

  2. ディスクが関連付けられているインスタンスを選択します。

  3. インスタンス名をクリックします。[VM インスタンスの詳細] ページが表示されます。

  4. [編集] をクリックします。

  5. [ストレージ] セクションの [追加ディスク] で鉛筆アイコン をクリックし、ディスクの削除ルールを変更します。

  6. [保存] をクリックしてインスタンスを更新します。

gcloud

gcloud compute instances set-disk-auto-delete コマンドを使用して、Persistent Disk の自動削除状態を設定します。ディスクを保持するには、--no-auto-delete フラグを使用します。ディスクを削除するには、--auto-delete フラグを使用します。

gcloud compute instances set-disk-auto-delete VM_NAME \
  AUTO_DELETE_SETTING \
  --disk DISK_NAME

次のように置き換えます。

  • VM_NAME: インスタンスの名前
  • AUTO_DELETE_SETTING: ディスクを自動的に削除するかどうか。VM を削除した後もディスクを保持するには --no-auto-delete を指定します。VM と同時にディスクを削除するには --auto-delete を指定します。
  • DISK_NAME: ディスクの名前

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

このサンプルを試す前に、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

このサンプルを試す前に、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

API を使用して自動削除状態を設定するには、instances.setDiskAutoDelete メソッドに POST リクエストを送信します。

autoDelete パラメータを使用して、ディスクを削除するかどうかを指定します。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/setDiskAutoDelete?deviceName=DISK_NAME,autoDelete=AUTO_DELETE_OPTION

次のように置き換えます。

  • PROJECT_ID: プロジェクト ID
  • ZONE: インスタンスとディスクが配置されているゾーン
  • VM_NAME: インスタンスの名前
  • DISK_NAME: インスタンスにアタッチされたディスクの名前。
  • AUTO_DELETE_OPTION: VM の削除時にディスクを自動的に削除するかどうかを指定します。ディスクを削除するには、true に設定します。VM の削除後もディスクを保持するには、false に設定します。

トラブルシューティング

完全なディスクとディスクサイズ変更に関連する問題の診断と解決方法については、完全なディスクとディスクサイズ変更のトラブルシューティングをご覧ください。

次のステップ