Menduplikasi disk dengan clone


Dokumen ini memberikan informasi tentang cara kerja clone disk dan cara membuat clone disk. Cloning disk memungkinkan Anda membuat duplikat disk yang ada yang dapat langsung digunakan. Buat clone disk dalam skenario saat Anda ingin membuat salinan disk yang ada yang identik dan dapat langsung dilampirkan ke VM, seperti berikut:

  • Membuat lingkungan staging dengan menduplikasi data produksi untuk proses debug tanpa mengganggu produksi
  • Membuat salinan untuk verifikasi cadangan database
  • Memindahkan data disk non-boot ke project baru
  • Menduplikasi disk saat menskalakan VM

Untuk melindungi dari pemulihan dari bencana, cadangkan disk Anda dengan snapshot standar, bukan menggunakan clone disk. Untuk merekam konten disk secara berkala tanpa membuat disk baru, gunakan snapshot instan karena lebih hemat penyimpanan daripada clone. Untuk opsi perlindungan disk tambahan, lihat Opsi perlindungan data.

Sebelum memulai

  • Jika Anda belum melakukannya, siapkan autentikasi. Autentikasi adalah proses verifikasi identitas Anda untuk mengakses layanan dan API Google Cloud. Untuk menjalankan kode atau contoh dari lingkungan pengembangan lokal, Anda dapat mengautentikasi ke Compute Engine dengan memilih salah satu opsi berikut:

    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. Terraform

      Untuk menggunakan contoh Terraform di halaman ini dalam lingkungan pengembangan lokal, instal dan lakukan inisialisasi gcloud CLI, lalu siapkan Kredensial Default Aplikasi dengan kredensial pengguna Anda.

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. Buat kredensial autentikasi lokal untuk Akun Google Anda:

        gcloud auth application-default login

      Untuk informasi selengkapnya, lihat Set up authentication for a local development environment.

      Go

      Untuk menggunakan contoh Go di halaman ini dalam lingkungan pengembangan lokal, instal dan lakukan inisialisasi gcloud CLI, lalu siapkan Kredensial Default Aplikasi dengan kredensial pengguna Anda.

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. Buat kredensial autentikasi lokal untuk Akun Google Anda:

        gcloud auth application-default login

      Untuk informasi selengkapnya, lihat Set up authentication for a local development environment.

      Java

      Untuk menggunakan contoh Java di halaman ini dalam lingkungan pengembangan lokal, instal dan lakukan inisialisasi gcloud CLI, lalu siapkan Kredensial Default Aplikasi dengan kredensial pengguna Anda.

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. Buat kredensial autentikasi lokal untuk Akun Google Anda:

        gcloud auth application-default login

      Untuk informasi selengkapnya, lihat Set up authentication for a local development environment.

      Python

      Untuk menggunakan contoh Python di halaman ini dalam lingkungan pengembangan lokal, instal dan lakukan inisialisasi gcloud CLI, lalu siapkan Kredensial Default Aplikasi dengan kredensial pengguna Anda.

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. Buat kredensial autentikasi lokal untuk Akun Google Anda:

        gcloud auth application-default login

      Untuk informasi selengkapnya, lihat Set up authentication for a local development environment.

      REST

      Untuk menggunakan contoh REST API di halaman ini dalam lingkungan pengembangan lokal, gunakan kredensial yang Anda berikan ke gcloud CLI.

        Install the Google Cloud CLI, then initialize it by running the following command:

        gcloud init

      Untuk informasi selengkapnya, lihat Melakukan autentikasi untuk menggunakan REST dalam dokumentasi autentikasi Google Cloud.

Cara kerja cloning disk

Saat meng-clone disk, Anda membuat disk baru yang berisi semua data di disk sumber. Anda dapat membuat clone disk meskipun disk yang ada terpasang ke instance VM.

Jenis disk clone harus sama dengan disk sumber. Namun, Anda dapat mengubah properti pada clone, seperti ukuran disk. Anda juga dapat menghapus disk sumber tanpa berisiko menghapus clone.

Jenis disk yang didukung

Anda dapat membuat clone disk hanya untuk jenis disk berikut:

  • Persistent Disk: Semua jenis Persistent Disk
  • Google Cloud Hyperdisk: Hyperdisk Balanced, Hyperdisk Extreme, dan Hyperdisk Throughput

Pembatasan

Bergantung pada jenis disk, clone disk memiliki batasan berikut:

Batasan umum

Batasan berikut berlaku untuk clone dari semua jenis disk:

  • Jenis disk clone harus sama dengan disk sumber.
  • Anda tidak dapat membuat clone disk zonal dari disk zona yang ada di zona berbeda.
  • Ukuran clone minimal harus sama dengan ukuran disk sumber. Jika membuat clone menggunakan konsol Google Cloud, Anda tidak dapat menentukan ukuran disk, dan clone tersebut akan memiliki ukuran yang sama dengan disk sumber.
  • Jika Anda menggunakan kunci enkripsi yang disediakan pelanggan atau kunci enkripsi yang dikelola pelanggan untuk mengenkripsi disk sumber, Anda harus menggunakan kunci yang sama untuk mengenkripsi clone tersebut. Untuk informasi selengkapnya, lihat Membuat clone disk sumber yang dienkripsi.
  • Anda tidak dapat menghapus disk sumber saat clone-nya sedang dibuat.
  • Instance komputasi tempat disk sumber terpasang tidak akan dapat dinyalakan saat clone sedang dibuat.
  • Jika disk sumber ditandai untuk dihapus bersama dengan VM yang terpasang, Anda tidak dapat menghapus VM saat clone sedang dibuat.
  • Anda dapat membuat maksimal satu clone disk sumber tertentu atau clone-nya setiap 30 detik.
  • Anda dapat memiliki maksimal 1.000 clone disk secara bersamaan dari disk sumber tertentu atau clone-nya. Jika batas ini terlampaui, internalError akan muncul. Namun, jika Anda membuat clone disk dan menghapusnya nanti, clone disk yang telah dihapus tersebut tidak akan disertakan dalam batasan ini.
  • Setelah disk di-clone, setiap clone berikutnya dari disk tersebut atau clone-nya akan dihitung dalam batas 1.000 clone disk simultan untuk disk sumber asli, dan dihitung dalam batas pembuatan maksimal satu clone setiap 30 detik.
  • Jika membuat disk regional dengan meng-clone disk zona, Anda dapat meng-clone maksimal 1 TiB kapasitas setiap 15 menit, dengan batas permintaan burst sebesar 257 TiB.

Batasan untuk clone Persistent Disk

Clone disk untuk Persistent Disk memiliki batasan berikut:

  • Anda tidak dapat membuat clone disk zonal dari disk regional.
  • Untuk membuat clone disk regional dari disk sumber zona, salah satu zona replika clone disk regional harus cocok dengan zona disk sumber.
  • Setelah pembuatan, clone disk regional rata-rata dapat digunakan dalam waktu 3 menit. Namun, disk mungkin memerlukan waktu puluhan menit untuk direplikasi sepenuhnya dan mencapai status dengan tujuan titik pemulihan (RPO) mendekati nol.
  • Jika membuat disk zona dari image, Anda tidak dapat menggunakan disk zona tersebut untuk membuat clone disk regional.

Batasan untuk clone Google Cloud Hyperdisk

Anda dapat membuat clone disk hanya untuk volume Hyperdisk Balanced, Hyperdisk Extreme, dan Hyperdisk Throughput.

Pesan error

Jika Anda melebihi batas frekuensi clone, permintaan akan gagal dengan error berikut:

RATE LIMIT: ERROR: (gcloud.compute.disks.create) Could not fetch resource:
 - Operation rate exceeded for resource RESOURCE. Too frequent operations from the source resource.

Membuat clone disk

Bagian ini menjelaskan cara menduplikasi disk yang ada dan membuat clone disk.

Untuk mengetahui langkah-langkah mendetail, bergantung pada jenis pembuatan clone disk, lihat salah satu bagian berikut dalam dokumen ini:

Membuat clone disk zonal

Anda dapat membuat clone disk zonal dari disk yang ada di zona yang sama dengan disk sumber menggunakan Konsol Google Cloud, Google Cloud CLI, atau REST.

Konsol

  1. Di konsol Google Cloud, buka halaman Disks.

    Buka Disk

  2. Dalam daftar disk, buka disk yang ingin Anda clone.

  3. Di kolom Actions, klik tombol menu dan pilih Clone disk.

    Membuat clone.

    Di panel Clone disk yang muncul, lakukan hal berikut:

    1. Di kolom Name, tentukan nama untuk disk yang di-clone.
    2. Untuk Location, pastikan Single zone dipilih.
    3. Di bagian Properties, tinjau detail lain untuk disk yang di-clone.
    4. Untuk menyelesaikan pembuatan disk yang di-clone, klik Buat.

gcloud

Untuk meng-clone disk sumber zonal dan membuat disk zonal baru, jalankan perintah disks create dan tentukan flag --source-disk:

gcloud compute disks create TARGET_DISK_NAME \
    --description="cloned disk" \
    --source-disk=projects/PROJECT_ID/zones/ZONE/disks/SOURCE_DISK_NAME

Ganti kode berikut:

  • TARGET_DISK_NAME: nama untuk disk baru.
  • PROJECT_ID: project ID tempat Anda ingin meng-clone disk.
  • ZONE: zona sumber dan disk baru.
  • SOURCE_DISK_NAME: nama disk sumber.

Terraform

Untuk membuat clone disk, gunakan resource google_compute_disk.

resource "google_compute_disk" "default" {
  name  = "disk-name1"
  type  = "pd-ssd"
  zone  = "us-central1-a"
  image = "debian-11-bullseye-v20220719"
  labels = {
    environment = "dev"
  }
  physical_block_size_bytes = 4096
}

Untuk mempelajari cara menerapkan atau menghapus konfigurasi Terraform, lihat Perintah dasar Terraform.

Go

Go

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Go di panduan memulai Compute Engine menggunakan library klien. Untuk informasi selengkapnya, lihat dokumentasi referensi API Go Compute Engine.

Untuk melakukan autentikasi ke Compute Engine, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

import (
	"context"
	"fmt"
	"io"

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

// createDiskFromDisk creates a new disk with the contents of
// an already existitng disk. Type, and size and zone may differ.
func createDiskFromDisk(
	w io.Writer,
	projectID, zone, diskName, diskType, sourceDiskLink string,
	diskSizeGb int64,
) error {
	// projectID := "your_project_id"
	// zone := "us-west3-b" // should match diskType below
	// diskName := "your_disk_name"
	// diskType := "zones/us-west3-b/diskTypes/pd-ssd"
	// sourceDiskLink := "projects/your_project_id/global/disks/disk_name"
	// diskSizeGb := 120

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

	req := &computepb.InsertDiskRequest{
		Project: projectID,
		Zone:    zone,
		DiskResource: &computepb.Disk{
			Name:       proto.String(diskName),
			Zone:       proto.String(zone),
			Type:       proto.String(diskType),
			SourceDisk: proto.String(sourceDiskLink),
			SizeGb:     proto.Int64(diskSizeGb),
		},
	}

	op, err := disksClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create disk: %w", err)
	}

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

	fmt.Fprintf(w, "Disk created\n")

	return nil
}

Java

Java

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Java di panduan memulai Compute Engine menggunakan library klien. Untuk informasi selengkapnya, lihat dokumentasi referensi API Java Compute Engine.

Untuk melakukan autentikasi ke Compute Engine, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.


import com.google.cloud.compute.v1.Disk;
import com.google.cloud.compute.v1.DisksClient;
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 CreateFromSource {

  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 project = "YOUR_PROJECT_ID";

    // Name of the zone in which you want to create the disk.
    String zone = "europe-central2-b";

    // Name of the disk you want to create.
    String diskName = "YOUR_DISK_NAME";

    // 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"
    String diskType = String.format("zones/%s/diskTypes/pd-ssd", zone);

    // Size of the new disk in gigabytes.
    int diskSizeGb = 10;

    // A link to the disk you want to use as a source for the new disk.
    // This value uses the following format:
    // "projects/{project_name}/zones/{zone}/disks/{disk_name}"
    String diskLink = String.format("projects/%s/zones/%s/disks/%s", "PROJECT_NAME", "ZONE",
        "DISK_NAME");

    createDiskFromDisk(project, zone, diskName, diskType, diskSizeGb, diskLink);
  }

  // Creates a disk in a project in a given zone.
  public static void createDiskFromDisk(String project, String zone, String diskName,
      String diskType, int diskSizeGb, String diskLink)
      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 `disksClient.close()` method on the client to safely
    // clean up any remaining background resources.
    try (DisksClient disksClient = DisksClient.create()) {

      // Create the disk.
      Disk disk = Disk.newBuilder()
          .setZone(zone)
          .setSizeGb(diskSizeGb)
          .setSourceDisk(diskLink)
          .setType(diskType)
          .setName(diskName)
          .build();

      // Wait for the insert instance operation to complete.
      Operation operation = disksClient.insertAsync(project, zone, disk)
          .get(3, TimeUnit.MINUTES);

      if (operation.hasError()) {
        System.out.println("Disk creation failed!");
        throw new Error(operation.getError().toString());
      }
      System.out.println(
          "Disk created from source. Operation Status: " + operation.getStatus());
    }
  }
}

Python

Python

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Python di panduan memulai Compute Engine menggunakan library klien. Untuk informasi selengkapnya, lihat dokumentasi referensi API Python Compute Engine.

Untuk melakukan autentikasi ke Compute Engine, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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 create_disk_from_disk(
    project_id: str,
    zone: str,
    disk_name: str,
    disk_type: str,
    disk_size_gb: int,
    disk_link: str,
) -> compute_v1.Disk:
    """
    Creates a disk in a project in a given zone.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone in which you want to create the disk.
        disk_name: name of the disk you want to create.
        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
        disk_link: a link to the disk you want to use as a source for the new disk.
            This value uses the following format: "projects/{project_name}/zones/{zone}/disks/{disk_name}"

    Returns:
        An attachable disk.
    """
    disk_client = compute_v1.DisksClient()
    disk = compute_v1.Disk()
    disk.zone = zone
    disk.size_gb = disk_size_gb
    disk.source_disk = disk_link
    disk.type_ = disk_type
    disk.name = disk_name
    operation = disk_client.insert(project=project_id, zone=zone, disk_resource=disk)

    wait_for_extended_operation(operation, "disk creation")

    return disk_client.get(project=project_id, zone=zone, disk=disk_name)

REST

Untuk meng-clone disk sumber zonal dan membuat disk zonal baru, buat permintaan POST ke metode compute.disks.insert. Dalam isi permintaan, tentukan parameter name dan sourceDisk. Clone disk mewarisi semua properti yang dihilangkan dari disk sumber.

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

{
  "name": "TARGET_DISK_NAME"
  "sourceDisk": "projects/PROJECT_ID/zones/ZONE/disks/SOURCE_DISK_NAME"
}

Ganti kode berikut:

  • PROJECT_ID: project ID tempat Anda ingin meng-clone disk.
  • ZONE: zona sumber dan disk baru.
  • TARGET_DISK_NAME: nama untuk disk baru.
  • SOURCE_DISK_NAME: nama disk sumber

Membuat clone disk regional dari disk zona

Anda dapat membuat disk Persistent Disk regional baru dengan meng-clone volume Persistent Disk zona yang ada. Untuk memigrasikan disk zona ke disk regional, Google merekomendasikan opsi ini, bukan membuat snapshot disk zona dan memulihkan snapshot ke disk regional baru.

Konsol

  1. Di konsol Google Cloud, buka halaman Disks.

    Buka Disk

  2. Dalam daftar disk, buka volume Persistent Disk zona yang ingin Anda clone.

  3. Di kolom Actions, klik tombol menu dan pilih Clone disk.

    Membuat clone.

    Di panel Clone disk yang muncul, lakukan hal berikut:

    1. Di kolom Name, tentukan nama untuk disk yang di-clone.
    2. Untuk Location, pilih Regional, lalu pilih zona replika sekunder untuk disk regional baru yang di-clone.
    3. Di bagian Properties, tinjau detail lain untuk disk yang di-clone.
    4. Untuk menyelesaikan pembuatan disk yang di-clone, klik Buat.

gcloud

Untuk membuat clone disk regional dari disk zona, jalankan perintah gcloud compute disks create dan tentukan parameter --region dan --replica-zones.

gcloud compute disks create TARGET_DISK_NAME \
  --description="zonal to regional cloned disk" \
  --region=CLONED_REGION \
  --source-disk=SOURCE_DISK_NAME \
  --source-disk-zone=SOURCE_DISK_ZONE \
  --replica-zones=SOURCE_DISK_ZONE,REPLICA_ZONE_2 \
  --project=PROJECT_ID

Ganti kode berikut:

  • TARGET_DISK_NAME: nama untuk clone disk regional baru.
  • CLONED_REGION: region disk sumber dan disk yang di-clone.
  • SOURCE_DISK_NAME: nama disk zona yang akan di-clone.
  • SOURCE_DISK_ZONE: zona untuk disk sumber. Ini juga akan menjadi zona replika pertama untuk clone disk regional.
  • REPLICA_ZONE_2: zona replika kedua untuk clone disk regional baru.
  • PROJECT_ID: project ID tempat Anda ingin meng-clone disk.

Terraform

Untuk membuat clone disk regional dari disk zona, secara opsional Anda dapat membuat snapshot disk zona, lalu meng-clone snapshot tersebut. Untuk melakukannya, gunakan referensi berikut:

resource "google_compute_region_disk" "regiondisk" {
  name                      = "region-disk-name"
  snapshot                  = google_compute_snapshot.snapdisk.id
  type                      = "pd-ssd"
  region                    = "us-central1"
  physical_block_size_bytes = 4096
  size                      = 11

  replica_zones = ["us-central1-a", "us-central1-f"]
}

Untuk mempelajari cara menerapkan atau menghapus konfigurasi Terraform, lihat Perintah dasar Terraform.

Go

Go

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Go di panduan memulai Compute Engine menggunakan library klien. Untuk informasi selengkapnya, lihat dokumentasi referensi API Go Compute Engine.

Untuk melakukan autentikasi ke Compute Engine, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

import (
	"context"
	"fmt"
	"io"

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

// createRegionalDiskFromDisk creates a new regional disk with the contents of
// an already existitng zonal disk. Disk type and size may differ.
func createRegionalDiskFromDisk(
	w io.Writer,
	projectID, region string, replicaZones []string,
	diskName, diskType, sourceDiskLink string,
	diskSizeGb int64,
) error {
	// projectID := "your_project_id"
	// region := "us-west3" // should match diskType below
	// diskName := "your_disk_name"
	// diskType := "regions/us-west3/diskTypes/pd-ssd"
	// sourceDiskLink := "projects/your_project_id/global/disks/disk_name"
	// diskSizeGb := 120

	// Exactly two replica zones must be specified
	replicaZoneURLs := []string{
		fmt.Sprintf("projects/%s/zones/%s", projectID, replicaZones[0]),
		fmt.Sprintf("projects/%s/zones/%s", projectID, replicaZones[1]),
	}

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

	req := &computepb.InsertRegionDiskRequest{
		Project: projectID,
		Region:  region,
		DiskResource: &computepb.Disk{
			Name:         proto.String(diskName),
			Region:       proto.String(region),
			Type:         proto.String(diskType),
			SourceDisk:   proto.String(sourceDiskLink),
			SizeGb:       proto.Int64(diskSizeGb),
			ReplicaZones: replicaZoneURLs,
		},
	}

	op, err := disksClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create disk: %w", err)
	}

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

	fmt.Fprintf(w, "Disk created\n")

	return nil
}

Java

Java

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Java di panduan memulai Compute Engine menggunakan library klien. Untuk informasi selengkapnya, lihat dokumentasi referensi API Java Compute Engine.

Untuk melakukan autentikasi ke Compute Engine, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.


import com.google.cloud.compute.v1.Disk;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.RegionDisksClient;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class RegionalCreateFromSource {

  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 project = "YOUR_PROJECT_ID";

    // Name of the zone in which you want to create the disk.
    String region = "europe-central2";

    // An iterable collection of zone names in which you want to keep
    // the new disks' replicas. One of the replica zones of the clone must match
    // the zone of the source disk.
    List<String> replicaZones = new ArrayList<>();

    // Name of the disk you want to create.
    String diskName = "YOUR_DISK_NAME";

    // 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"
    String diskType = String.format("zones/%s/diskTypes/pd-ssd", "ZONE_NAME");

    // Size of the new disk in gigabytes.
    int diskSizeGb = 10;

    // A link to the disk you want to use as a source for the new disk.
    // This value uses the following format:
    // "projects/{project_name}/zones/{zone}/disks/{disk_name}"
    String diskLink = String.format("projects/%s/zones/%s/disks/%s", "PROJECT_NAME", "ZONE",
        "DISK_NAME");

    // A link to the snapshot you want to use as a source for the new disk.
    // This value uses the following format:
    // "projects/{project_name}/global/snapshots/{snapshot_name}"
    String snapshotLink = String.format("projects/%s/global/snapshots/%s", "PROJECT_NAME",
        "SNAPSHOT_NAME");

    createRegionalDisk(project, region, replicaZones, diskName, diskType, diskSizeGb,
        Optional.ofNullable(diskLink), Optional.ofNullable(snapshotLink));
  }

  // Creates a regional disk from an existing zonal disk in a given project.
  public static void createRegionalDisk(
      String project, String region, List<String> replicaZones, String diskName, String diskType,
      int diskSizeGb, Optional<String> diskLink, Optional<String> snapshotLink)
      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 `regionDisksClient.close()` method on the client to safely
    // clean up any remaining background resources.
    try (RegionDisksClient regionDisksClient = RegionDisksClient.create()) {

      Disk.Builder diskBuilder = Disk.newBuilder()
          .addAllReplicaZones(replicaZones)
          .setName(diskName)
          .setType(diskType)
          .setSizeGb(diskSizeGb)
          .setRegion(region);

      // Set source disk if diskLink is not empty.
      diskLink.ifPresent(diskBuilder::setSourceDisk);

      // Set source snapshot if the snapshot link is not empty.
      snapshotLink.ifPresent(diskBuilder::setSourceSnapshot);

      // Wait for the operation to complete.
      Operation operation = regionDisksClient.insertAsync(project, region, diskBuilder.build())
          .get(3, TimeUnit.MINUTES);

      if (operation.hasError()) {
        System.out.println("Disk creation failed!");
        throw new Error(operation.getError().toString());
      }
      System.out.println(
          "Regional disk created. Operation Status: " + operation.getStatus());
    }
  }
}

Python

Python

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Python di panduan memulai Compute Engine menggunakan library klien. Untuk informasi selengkapnya, lihat dokumentasi referensi API Python Compute Engine.

Untuk melakukan autentikasi ke Compute Engine, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

from __future__ import annotations

from collections.abc import Iterable
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 create_regional_disk(
    project_id: str,
    region: str,
    replica_zones: Iterable[str],
    disk_name: str,
    disk_type: str,
    disk_size_gb: int,
    disk_link: str | None = None,
    snapshot_link: str | None = None,
) -> compute_v1.Disk:
    """
    Creates a regional disk from an existing zonal disk in a given project.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        region: name of the region in which you want to create the disk.
        replica_zones: an iterable collection of zone names in which you want to keep
            the new disks' replicas. One of the replica zones of the clone must match
            the zone of the source disk.
        disk_name: name of the disk you want to create.
        disk_type: the type of disk you want to create. This value uses the following format:
            "regions/{region}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
            For example: "regions/us-west3/diskTypes/pd-ssd"
        disk_size_gb: size of the new disk in gigabytes
        disk_link: a link to the disk you want to use as a source for the new disk.
            This value uses the following format: "projects/{project_name}/zones/{zone}/disks/{disk_name}"
        snapshot_link: a link to the snapshot you want to use as a source for the new disk.
            This value uses the following format: "projects/{project_name}/global/snapshots/{snapshot_name}"

    Returns:
        An attachable regional disk.
    """
    disk_client = compute_v1.RegionDisksClient()
    disk = compute_v1.Disk()
    disk.replica_zones = replica_zones
    disk.size_gb = disk_size_gb
    if disk_link:
        disk.source_disk = disk_link
    if snapshot_link:
        disk.source_snapshot = snapshot_link
    disk.type_ = disk_type
    disk.region = region
    disk.name = disk_name
    operation = disk_client.insert(
        project=project_id, region=region, disk_resource=disk
    )

    wait_for_extended_operation(operation, "disk creation")

    return disk_client.get(project=project_id, region=region, disk=disk_name)

REST

Untuk membuat clone disk regional dari disk zona, buat permintaan POST ke metode compute.disks.insert dan tentukan parameter sourceDisk dan replicaZone.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/CLONED_REGION/disks

{
  "name": "TARGET_DISK_NAME"
  "sourceDisk": "projects/PROJECT_ID/zones/SOURCE_DISK_ZONE/disks/SOURCE_DISK_NAME"
  "replicaZone": "SOURCE_DISK_ZONE,REPLICA_ZONE_2"
}

Ganti kode berikut:

  • PROJECT_ID: project ID tempat Anda ingin meng-clone disk.
  • TARGET_DISK_NAME: nama untuk clone disk regional baru.
  • CLONED_REGION: region disk sumber dan disk yang di-clone.
  • SOURCE_DISK_NAME: nama disk zona yang akan di-clone.
  • SOURCE_DISK_ZONE: zona untuk disk sumber. Ini juga akan menjadi zona replika pertama untuk clone disk regional.
  • REPLICA_ZONE_2: zona replika kedua untuk clone disk regional baru.

Membuat clone disk dari disk sumber terenkripsi

Anda dapat menggunakan kunci enkripsi yang disediakan pelanggan (CSEK) atau kunci enkripsi yang dikelola pelanggan untuk mengenkripsi disk.

Membuat clone disk untuk disk terenkripsi CSEK

Jika menggunakan CSEK untuk mengenkripsi disk sumber, Anda juga harus menggunakan kunci yang sama untuk mengenkripsi clone tersebut.

Konsol

  1. Di konsol Google Cloud, buka halaman Disks.

    Buka Disk

  2. Dalam daftar persistent disk zona, temukan disk yang ingin di-clone.

  3. Di kolom Actions, klik tombol menu dan pilih Clone disk.

    Membuat clone.

    Di panel Clone disk yang muncul, lakukan hal berikut:

    1. Di kolom Name, tentukan nama untuk disk yang di-clone.
    2. Di kolom Decryption and encryption, berikan kunci enkripsi disk sumber.
    3. Di bagian Properties, tinjau detail lain untuk disk yang di-clone.
    4. Untuk menyelesaikan pembuatan disk yang di-clone, klik Buat.

gcloud

Untuk membuat clone disk untuk disk sumber terenkripsi CSEK, jalankan perintah gcloud compute disks create dan berikan kunci enkripsi disk sumber menggunakan flag --csek-key-file. Jika Anda menggunakan kunci yang digabungkan RSA, gunakan perintah gcloud beta compute disks create.

gcloud compute disks create TARGET_DISK_NAME \
  --description="cloned disk" \
  --source-disk=projects/PROJECT_ID/zones/ZONE/disks/SOURCE_DISK_NAME \
  --csek-key-file example-key-file.json

Ganti kode berikut:

  • TARGET_DISK_NAME: nama untuk disk baru.
  • PROJECT_ID: project ID tempat Anda ingin meng-clone disk.
  • ZONE: zona sumber dan disk baru.
  • SOURCE_DISK_NAME: nama disk sumber

Go

Go

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Go di panduan memulai Compute Engine menggunakan library klien. Untuk informasi selengkapnya, lihat dokumentasi referensi API Go Compute Engine.

Untuk melakukan autentikasi ke Compute Engine, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

import (
	"context"
	"fmt"
	"io"

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

// Creates a zonal non-boot persistent disk in a project with the copy of data from an existing disk.
// The encryption key must be the same for the source disk and the new disk.
// The disk type and size may differ.
func createDiskFromCustomerEncryptedDisk(
	w io.Writer,
	projectID, zone, diskName, diskType string,
	diskSizeGb int64,
	diskLink, encryptionKey string,
) error {
	// projectID := "your_project_id"
	// zone := "us-west3-b" // should match diskType below
	// diskName := "your_disk_name"
	// diskType := "zones/us-west3/diskTypes/pd-ssd"
	// diskSizeGb := 120
	// diskLink := "projects/your_project_id/global/disks/disk_name"
	// encryptionKey := "SGVsbG8gZnJvbSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0=" // in base64

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

	req := &computepb.InsertDiskRequest{
		Project: projectID,
		Zone:    zone,
		DiskResource: &computepb.Disk{
			Name:       proto.String(diskName),
			Zone:       proto.String(zone),
			Type:       proto.String(diskType),
			SizeGb:     proto.Int64(diskSizeGb),
			SourceDisk: proto.String(diskLink),
			DiskEncryptionKey: &computepb.CustomerEncryptionKey{
				RawKey: &encryptionKey,
			},
		},
	}

	op, err := disksClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create disk: %w", err)
	}

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

	fmt.Fprintf(w, "Disk created\n")

	return nil
}

Java

Java

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Java di panduan memulai Compute Engine menggunakan library klien. Untuk informasi selengkapnya, lihat dokumentasi referensi API Java Compute Engine.

Untuk melakukan autentikasi ke Compute Engine, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.


import com.google.cloud.compute.v1.CustomerEncryptionKey;
import com.google.cloud.compute.v1.Disk;
import com.google.cloud.compute.v1.DisksClient;
import com.google.cloud.compute.v1.InsertDiskRequest;
import com.google.cloud.compute.v1.Operation;
import com.google.protobuf.ByteString;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CloneEncryptedDisk {

  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 project = "YOUR_PROJECT_ID";

    // Name of the zone in which you want to create the disk.
    String zone = "europe-central2-b";

    // Name of the disk you want to create.
    String diskName = "YOUR_DISK_NAME";

    // 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"
    String diskType = String.format("zones/%s/diskTypes/pd-ssd", zone);

    // Size of the new disk in gigabytes.
    int diskSizeGb = 10;

    // A link to the disk you want to use as a source for the new disk.
    // This value uses the following format:
    // "projects/{project_name}/zones/{zone}/disks/{disk_name}"
    String diskLink = String.format("projects/%s/zones/%s/disks/%s", "PROJECT_NAME", "ZONE",
        "DISK_NAME");

    // Customer-supplied encryption key used for encrypting data in the source disk.
    // The data will be encrypted with the same key in the new disk.
    byte[] encryptionKey = null;

    createDiskFromCustomerEncryptedKey(project, zone, diskName, diskType, diskSizeGb, diskLink,
        encryptionKey);
  }

  // Creates a zonal non-boot persistent disk in a project with the copy of data
  // from an existing disk.
  // The encryption key must be the same for the source disk and the new disk.
  public static void createDiskFromCustomerEncryptedKey(String project, String zone,
      String diskName, String diskType, int diskSizeGb, String diskLink, byte[] encryptionKey)
      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 `disksClient.close()` method on the client to safely
    // clean up any remaining background resources.
    try (DisksClient disksClient = DisksClient.create()) {

      // Create a disk and set the encryption key.
      Disk disk = Disk.newBuilder()
          .setZone(zone)
          .setName(diskName)
          .setType(diskType)
          .setSizeGb(diskSizeGb)
          .setSourceDisk(diskLink)
          .setDiskEncryptionKey(CustomerEncryptionKey
              .newBuilder()
              .setRawKeyBytes(ByteString.copyFrom(encryptionKey))
              .build())
          .build();

      // Wait for the insert disk operation to complete.
      Operation operation = disksClient.insertAsync(
          InsertDiskRequest.newBuilder()
              .setProject(project)
              .setZone(zone)
              .setDiskResource(disk)
              .build()).get(3, TimeUnit.MINUTES);

      if (operation.hasError()) {
        System.out.println("Disk creation failed!");
        throw new Error(operation.getError().toString());
      }
      System.out.println(
          "Disk cloned with customer encryption key. Operation Status: " + operation.getStatus());
    }
  }
}

Python

Python

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Python di panduan memulai Compute Engine menggunakan library klien. Untuk informasi selengkapnya, lihat dokumentasi referensi API Python Compute Engine.

Untuk melakukan autentikasi ke Compute Engine, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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 create_disk_from_customer_encrypted_disk(
    project_id: str,
    zone: str,
    disk_name: str,
    disk_type: str,
    disk_size_gb: int,
    disk_link: str,
    encryption_key: bytes,
) -> compute_v1.Disk:
    """
    Creates a zonal non-boot persistent disk in a project with the copy of data from an existing disk.

    The encryption key must be the same for the source disk and the new disk.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone in which you want to create the disk.
        disk_name: name of the disk you want to create.
        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
        disk_link: a link to the disk you want to use as a source for the new disk.
            This value uses the following format: "projects/{project_name}/zones/{zone}/disks/{disk_name}"
        encryption_key: customer-supplied encryption key used for encrypting
            data in the source disk. The data will be encrypted with the same key
            in the new disk.

    Returns:
        An attachable copy of an existing disk.
    """
    disk_client = compute_v1.DisksClient()
    disk = compute_v1.Disk()
    disk.zone = zone
    disk.size_gb = disk_size_gb
    disk.source_disk = disk_link
    disk.type_ = disk_type
    disk.name = disk_name
    disk.disk_encryption_key = compute_v1.CustomerEncryptionKey()
    disk.disk_encryption_key.raw_key = encryption_key
    operation = disk_client.insert(project=project_id, zone=zone, disk_resource=disk)

    wait_for_extended_operation(operation, "disk creation")

    return disk_client.get(project=project_id, zone=zone, disk=disk_name)

REST

Untuk membuat clone disk untuk disk sumber terenkripsi CSEK, buat permintaan POST ke metode compute.disks.insert dan berikan kunci enkripsi disk sumber menggunakan properti diskEncryptionKey. Jika Anda menggunakan kunci yang digabungkan RSA, gunakan metode versi beta.

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

{
  "name": "TARGET_DISK_NAME"
  "sourceDisk": "projects/PROJECT_ID/zones/ZONE/disks/SOURCE_DISK_NAME"
  "diskEncryptionKey": {
    "rsaEncryptedKey": "ieCx/NcW06PcT7Ep1X6LUTc/hLvUDYyzSZPPVCVPTVEohpeHASqC8uw5TzyO9U+Fka9JFHz0mBibXUInrC/jEk014kCK/NPjYgEMOyssZ4ZINPKxlUh2zn1bV+MCaTICrdmuSBTWlUUiFoDD6PYznLwh8ZNdaheCeZ8ewEXgFQ8V+sDroLaN3Xs3MDTXQEMMoNUXMCZEIpg9Vtp9x2oeQ5lAbtt7bYAAHf5l+gJWw3sUfs0/Glw5fpdjT8Uggrr+RMZezGrltJEF293rvTIjWOEB3z5OHyHwQkvdrPDFcTqsLfh+8Hr8g+mf+7zVPEC8nEbqpdl3GPv3A7AwpFp7MA=="
  },
}

Ganti kode berikut:

  • PROJECT_ID: project ID tempat Anda ingin meng-clone disk.
  • ZONE: zona sumber dan disk baru.
  • TARGET_DISK_NAME: nama untuk disk baru.
  • SOURCE_DISK_NAME: nama disk sumber

Membuat clone disk untuk disk yang dienkripsi CMEK

Jika menggunakan CMEK untuk mengenkripsi disk sumber, Anda juga harus menggunakan kunci yang sama untuk mengenkripsi clone tersebut.

Konsol

Compute Engine otomatis mengenkripsi clone menggunakan kunci enkripsi disk sumber.

gcloud

Untuk membuat clone disk untuk disk sumber terenkripsi CMEK, jalankan perintah gcloud compute disks create dan berikan kunci enkripsi disk sumber menggunakan flag --kms-key. Jika Anda menggunakan kunci yang digabungkan RSA, gunakan perintah gcloud beta compute disks create.

gcloud compute disks create TARGET_DISK_NAME \
  --description="cloned disk" \
  --source-disk=projects/PROJECT_ID/zones/ZONE/disks/SOURCE_DISK_NAME \
  --kms-key projects/KMS_PROJECT_ID/locations/REGION/keyRings/KEY_RING/cryptoKeys/KEY

Ganti kode berikut:

  • TARGET_DISK_NAME: nama untuk disk baru.
  • PROJECT_ID: project ID tempat Anda ingin meng-clone disk.
  • ZONE: zona sumber dan disk baru.
  • SOURCE_DISK_NAME: nama disk sumber.
  • KMS_PROJECT_ID: project ID untuk kunci enkripsi.
  • REGION: region kunci enkripsi.
  • KEY_RING: key ring kunci enkripsi.
  • KEY: nama kunci enkripsi.

Go

Go

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Go di panduan memulai Compute Engine menggunakan library klien. Untuk informasi selengkapnya, lihat dokumentasi referensi API Go Compute Engine.

Untuk melakukan autentikasi ke Compute Engine, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

import (
	"context"
	"fmt"
	"io"

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

// Creates a zonal non-boot persistent disk in a project with the copy of data from an existing disk.
// The encryption key must be the same for the source disk and the new disk.
// The disk type and size may differ.
func createDiskFromKmsEncryptedDisk(
	w io.Writer,
	projectID, zone, diskName, diskType string,
	diskSizeGb int64,
	diskLink, kmsKeyLink string,
) error {
	// projectID := "your_project_id"
	// zone := "us-west3-b" // should match diskType below
	// diskName := "your_disk_name"
	// diskType := "zones/us-west3/diskTypes/pd-ssd"
	// diskSizeGb := 120
	// diskLink := "projects/your_project_id/global/disks/disk_name"
	// kmsKeyLink := "projects/your_kms_project_id/locations/us-central1/keyRings/your_key_ring/cryptoKeys/your_key"

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

	req := &computepb.InsertDiskRequest{
		Project: projectID,
		Zone:    zone,
		DiskResource: &computepb.Disk{
			Name:       proto.String(diskName),
			Zone:       proto.String(zone),
			Type:       proto.String(diskType),
			SizeGb:     proto.Int64(diskSizeGb),
			SourceDisk: proto.String(diskLink),
			DiskEncryptionKey: &computepb.CustomerEncryptionKey{
				KmsKeyName: &kmsKeyLink,
			},
		},
	}

	op, err := disksClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create disk: %w", err)
	}

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

	fmt.Fprintf(w, "Disk created\n")

	return nil
}

Java

Java

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Java di panduan memulai Compute Engine menggunakan library klien. Untuk informasi selengkapnya, lihat dokumentasi referensi API Java Compute Engine.

Untuk melakukan autentikasi ke Compute Engine, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.


import com.google.cloud.compute.v1.CustomerEncryptionKey;
import com.google.cloud.compute.v1.Disk;
import com.google.cloud.compute.v1.DisksClient;
import com.google.cloud.compute.v1.InsertDiskRequest;
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 CloneEncryptedDiskManagedKey {

  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 project = "YOUR_PROJECT_ID";

    // Name of the zone in which you want to create the disk.
    String zone = "europe-central2-b";

    // Name of the disk you want to create.
    String diskName = "YOUR_DISK_NAME";

    // 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"
    String diskType = String.format("zones/%s/diskTypes/pd-ssd", zone);

    // Size of the new disk in gigabytes.
    int diskSizeGb = 10;

    // A link to the disk you want to use as a source for the new disk.
    // This value uses the following format:
    // "projects/{project_name}/zones/{zone}/disks/{disk_name}"
    String diskLink = String.format("projects/%s/zones/%s/disks/%s", "PROJECT_NAME", "ZONE",
        "DISK_NAME");

    // URL of the key from KMS. The key might be from another project, as
    // long as you have access to it. The data will be encrypted with the same key
    // in the new disk. This value uses following format:
    // "projects/{kms_project_id}/locations/{region}/keyRings/{key_ring}/cryptoKeys/{key}"
    String kmsKeyName = "kms-key-name";

    createDiskFromKmsEncryptedDisk(project, zone, diskName, diskType, diskSizeGb, diskLink,
        kmsKeyName);
  }

  // Creates a zonal non-boot disk in a project with the copy of data from an existing disk.
  // The encryption key must be the same for the source disk and the new disk.
  public static void createDiskFromKmsEncryptedDisk(String project, String zone, String diskName,
      String diskType, int diskSizeGb, String diskLink, String kmsKeyName)
      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 `disksClient.close()` method on the client to safely
    // clean up any remaining background resources.
    try (DisksClient disksClient = DisksClient.create()) {

      // Create a disk and set the KMS encryption key name.
      Disk disk = Disk.newBuilder()
          .setZone(zone)
          .setName(diskName)
          .setType(diskType)
          .setSizeGb(diskSizeGb)
          .setSourceDisk(diskLink)
          .setDiskEncryptionKey(CustomerEncryptionKey.newBuilder()
              .setKmsKeyName(kmsKeyName)
              .build())
          .build();

      // Wait for the insert disk operation to complete.
      Operation operation = disksClient.insertAsync(
          InsertDiskRequest.newBuilder()
              .setProject(project)
              .setZone(zone)
              .setDiskResource(disk)
              .build()).get(3, TimeUnit.MINUTES);

      if (operation.hasError()) {
        System.out.println("Disk creation failed!");
        throw new Error(operation.getError().toString());
      }
      System.out.println(
          "Disk cloned with KMS encryption key. Operation Status: " + operation.getStatus());
    }
  }
}

Python

Python

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Python di panduan memulai Compute Engine menggunakan library klien. Untuk informasi selengkapnya, lihat dokumentasi referensi API Python Compute Engine.

Untuk melakukan autentikasi ke Compute Engine, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

from __future__ import annotations

import sys
from typing import Any

from google.api_core.exceptions import BadRequest
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 create_disk_from_kms_encrypted_disk(
    project_id: str,
    zone: str,
    disk_name: str,
    disk_type: str,
    disk_size_gb: int,
    disk_link: str,
    kms_key_name: str,
) -> compute_v1.Disk:
    """
    Creates a zonal non-boot disk in a project with the copy of data from an existing disk.

    The encryption key must be the same for the source disk and the new disk.

    To run this method, the service-<project_id>@compute-system.iam.gserviceaccount.com
    service account needs to have the cloudkms.cryptoKeyEncrypterDecrypter role,
    as described in documentation:
    https://cloud.google.com/compute/docs/disks/customer-managed-encryption#before_you_begin

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone in which you want to create the disk.
        disk_name: name of the disk you want to create.
        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
        disk_link: a link to the disk you want to use as a source for the new disk.
            This value uses the following format: "projects/{project_name}/zones/{zone}/disks/{disk_name}"
        kms_key_name: URL of the key from KMS. The key might be from another project, as
            long as you have access to it. The data will be encrypted with the same key
            in the new disk. This value uses following format:
            "projects/{kms_project_id}/locations/{region}/keyRings/{key_ring}/cryptoKeys/{key}"

    Returns:
        An attachable copy of an existing disk.
    """
    disk_client = compute_v1.DisksClient()
    disk = compute_v1.Disk()
    disk.zone = zone
    disk.size_gb = disk_size_gb
    disk.source_disk = disk_link
    disk.type_ = disk_type
    disk.name = disk_name
    disk.disk_encryption_key = compute_v1.CustomerEncryptionKey()
    disk.disk_encryption_key.kms_key_name = kms_key_name
    try:
        operation = disk_client.insert(
            project=project_id, zone=zone, disk_resource=disk
        )
    except BadRequest as err:
        if "Permission 'cloudkms.cryptoKeyVersions.useToEncrypt' denied" in err.message:
            print(
                f"Please provide the cloudkms.cryptoKeyEncrypterDecrypter role to"
                f"service-{project_id}@compute-system.iam.gserviceaccount.com"
            )
        raise err

    wait_for_extended_operation(operation, "disk creation")

    return disk_client.get(project=project_id, zone=zone, disk=disk_name)

REST

Untuk membuat clone disk untuk disk sumber terenkripsi CMEK, buat permintaan POST ke metode compute.disks.insert dan berikan kunci enkripsi disk sumber menggunakan properti kmsKeyName. Jika Anda menggunakan kunci yang digabungkan RSA, gunakan metode versi beta.

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

{
  "name": "TARGET_DISK_NAME"
  "sourceDisk": "projects/PROJECT_ID/zones/ZONE/disks/SOURCE_DISK_NAME"
  "diskEncryptionKey": {
    "kmsKeyName": "projects/KMS_PROJECT_ID/locations/REGION/keyRings/KEY_RING/cryptoKeys/KEY"
  },
}

Ganti kode berikut:

  • PROJECT_ID: project ID tempat Anda ingin meng-clone disk.
  • ZONE: zona sumber dan disk baru.
  • TARGET_DISK_NAME: nama untuk disk baru.
  • SOURCE_DISK_NAME: nama disk sumber.
  • KMS_PROJECT_ID: project ID untuk kunci enkripsi.
  • REGION: region kunci enkripsi.
  • KEY_RING: key ring kunci enkripsi.
  • KEY: nama kunci enkripsi.

Langkah selanjutnya