Duplicar um disco com clones


Este documento fornece informações sobre como funcionam os clones de disco e como criar um clone de disco. A clonagem de disco permite fazer duplicatas utilizáveis ​​instantaneamente de discos existentes. Crie um clone de disco em cenários em que você deseja criar uma cópia idêntica de um disco existente que pode ser anexado instantaneamente a uma VM, como o seguinte:

  • Criação de ambientes de teste duplicando dados de produção para depuração sem perturbar a produção
  • Criando cópias para verificação de backup de banco de dados
  • Movendo dados do disco que não é de inicialização para um novo projeto
  • Duplicar discos enquanto expande suas VMs

Para se proteger contra a recuperação de desastres, faça backup do disco com instantâneos padrão em vez de usar clones de disco. Para capturar o conteúdo do disco em intervalos regulares sem criar novos discos, use instantâneos instantâneos porque eles são mais eficientes em termos de armazenamento do que os clones. Para opções adicionais de proteção de disco, consulte Opções de proteção de dados .

Antes de começar

Como funciona a clonagem de disco

Ao clonar um disco, você cria um novo disco que contém todos os dados do disco de origem. Você pode criar um clone de disco mesmo que o disco existente esteja anexado a uma instância de VM.

O tipo de disco do clone deve ser igual ao do disco de origem. No entanto, você pode modificar as propriedades do clone, como o tamanho do disco. Você também pode excluir o disco de origem sem qualquer risco de excluir o clone.

Tipos de disco suportados

Você pode criar clones de disco somente para os seguintes tipos de disco:

  • Disco permanente : todos os tipos de disco permanente
  • Google Cloud Hyperdisk : Hyperdisk Balanced, Hyperdisk Extreme e Hyperdisk Throughput

Restrições

Dependendo do tipo de disco, os clones de disco têm as seguintes restrições:

Restrições gerais

As seguintes restrições se aplicam a clones de todos os tipos de disco:

  • O tipo de disco do clone deve ser igual ao do disco de origem.
  • Não é possível criar um clone de disco zonal de um disco zonal existente em uma zona diferente.
  • O tamanho do clone deve ser pelo menos igual ao tamanho do disco de origem. Se você criar um clone usando o console do Google Cloud, não será possível especificar um tamanho de disco, e o clone terá o mesmo tamanho do disco de origem.
  • Se você usar uma chave de criptografia fornecida pelo cliente ou uma chave de criptografia gerenciada pelo cliente para criptografar o disco de origem, deverá usar a mesma chave para criptografar o clone. Para obter mais informações, consulte Criando um clone de um disco de origem criptografado .
  • Você não pode excluir o disco de origem enquanto seu clone está sendo criado.
  • A instância de computação à qual o disco de origem está conectado não poderá ser ligada enquanto o clone estiver sendo criado.
  • Se o disco de origem foi marcado para ser excluído junto com a VM à qual está anexado, não será possível excluir a VM enquanto o clone estiver sendo criado.
  • Você pode criar no máximo um clone de um determinado disco de origem ou de seus clones a cada 30 segundos.
  • Você pode ter no máximo 1.000 clones de disco simultâneos de um determinado disco de origem ou de seus clones. Exceder esse limite retorna um internalError . No entanto, se você criar um clone de disco e excluí-lo posteriormente, o clone de disco excluído não será incluído nesse limite.
  • Depois que um disco é clonado, todos os clones subsequentes desse disco ou de seus clones são contados em relação ao limite de 1.000 clones de disco simultâneos para o disco de origem e são contados em relação ao limite de criação de no máximo um clone a cada 30 segundos.
  • Se você criar um disco regional clonando um disco zonal, poderá clonar no máximo 1 TiB de capacidade a cada 15 minutos, com um limite de solicitação de intermitência de 257 TiB.

Restrições para clones de disco permanente

Os clones de disco para disco permanente têm as seguintes restrições:

  • Não é possível criar um clone de disco zonal a partir de um disco regional.
  • Para criar um clone de disco regional a partir de um disco de origem zonal, uma das zonas de réplica do clone de disco regional deve corresponder à zona do disco de origem.
  • Após a criação, um clone de disco regional pode ser usado em média em 3 minutos. No entanto, o disco pode levar dezenas de minutos para ser totalmente replicado e atingir um estado em que o objetivo do ponto de recuperação (RPO) esteja próximo de zero.
  • Se você criou um disco zonal a partir de uma imagem, não poderá usar esse disco zonal para criar um clone de disco regional.

Restrições para clones do Google Cloud Hyperdisk

Você pode criar clones de disco somente para discos Hyperdisk Balanced, Hyperdisk Extreme e Hyperdisk Throughput. Você não pode clonar discos Hyperdisk Balanced High Availability ou Hyperdisk ML.

Mensagens de erro

Se você exceder os limites de frequência de clonagem, a solicitação falhará com o seguinte erro:

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

Crie clones de disco

Esta seção explica como você pode duplicar um disco existente e criar um clone de disco.

Para etapas detalhadas, dependendo do tipo de criação do clone de disco, consulte uma das seções a seguir neste documento:

Crie um clone de disco zonal

Você pode criar clones de disco zonais de um disco existente na mesma zona do disco de origem usando o console do Google Cloud, a CLI do Google Cloud ou REST.

Console

  1. No console do Google Cloud, acesse a página Discos .

    Vá para discos

  2. Na lista de discos, navegue até o disco que deseja clonar.

  3. Na coluna Ações , clique no botão de menu e selecione Clonar disco .

    Crie um clone.

    No painel Clonar disco que aparece, faça o seguinte:

    1. No campo Nome , especifique um nome para o disco clonado.
    2. Para Localização , verifique se Zona única está selecionada.
    3. Em Propriedades , revise outros detalhes do disco clonado.
    4. Para finalizar a criação do disco clonado, clique em Criar .

gcloud

Para clonar um disco de origem zonal e criar um novo disco zonal, execute o comando disks create e especifique o sinalizador --source-disk :

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

Substitua o seguinte:

  • TARGET_DISK_NAME : o nome do novo disco.
  • PROJECT_ID : o ID do projeto onde você deseja clonar o disco.
  • ZONE : a zona da origem e do novo disco.
  • SOURCE_DISK_NAME : o nome do disco de origem.

Terraforma

Para criar um clone de disco, use o recurso 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
}

Para saber como aplicar ou remover uma configuração do Terraform, consulte Comandos básicos do Terraform .

Ir

Go

Antes de testar este exemplo, siga as instruções de configuração Go no guia de início rápido do Compute Engine usando bibliotecas de cliente . Para mais informações, consulte a documentação de referência da API Compute Engine Go .

Para autenticar no Compute Engine, configure as credenciais padrão do aplicativo. Para obter mais informações, consulte Configurar autenticação para um ambiente de desenvolvimento local .

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

Antes de testar este exemplo, siga as instruções de configuração Java no guia de início rápido do Compute Engine usando bibliotecas de cliente . Para mais informações, consulte a documentação de referência da API Java do Compute Engine .

Para autenticar no Compute Engine, configure as credenciais padrão do aplicativo. Para obter mais informações, consulte Configurar autenticação para um ambiente de desenvolvimento local .


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());
    }
  }
}

Pitão

Python

Antes de testar este exemplo, siga as instruções de configuração Python no guia de início rápido do Compute Engine usando bibliotecas de cliente . Para mais informações, consulte a documentação de referência da API Python do Compute Engine .

Para autenticar no Compute Engine, configure as credenciais padrão do aplicativo. Para obter mais informações, consulte Configurar autenticação para um ambiente de desenvolvimento local .

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)

DESCANSAR

Para clonar um disco de origem zonal e criar um novo disco zonal, faça uma solicitação POST para o método compute.disks.insert . No corpo da solicitação, especifique os parâmetros name e sourceDisk . O clone do disco herda todas as propriedades omitidas do disco de origem.

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"
}

Substitua o seguinte:

  • PROJECT_ID : o ID do projeto onde você deseja clonar o disco.
  • ZONE : a zona da origem e do novo disco.
  • TARGET_DISK_NAME : o nome do novo disco.
  • SOURCE_DISK_NAME : o nome do disco de origem

Crie um clone de disco regional a partir de um disco zonal

Você pode criar um novo disco regional de disco permanente clonando um volume zonal de disco permanente existente. Para migrar um disco zonal para um disco regional, o Google recomenda esta opção em vez de criar um snapshot do disco zonal e restaurar o snapshot para um novo disco regional.

Console

  1. No console do Google Cloud, acesse a página Discos .

    Vá para discos

  2. Na lista de discos, navegue até o volume zonal do disco permanente que você deseja clonar.

  3. Na coluna Ações , clique no botão de menu e selecione Clonar disco .

    Crie um clone.

    No painel Clonar disco que aparece, faça o seguinte:

    1. No campo Nome , especifique um nome para o disco clonado.
    2. Para Localização , selecione Regional e selecione a zona de réplica secundária para o novo disco clonado regional.
    3. Em Propriedades , revise outros detalhes do disco clonado.
    4. Para finalizar a criação do disco clonado, clique em Criar .

gcloud

Para criar um clone de disco regional a partir de um disco zonal, execute o comando gcloud compute disks create e especifique os parâmetros --region e --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

Substitua o seguinte:

  • TARGET_DISK_NAME : o nome do novo clone de disco regional.
  • CLONED_REGION : a região dos discos de origem e clonados.
  • SOURCE_DISK_NAME : o nome do disco zonal a ser clonado.
  • SOURCE_DISK_ZONE : a zona do disco de origem. Esta também será a primeira zona de réplica para o clone do disco regional.
  • REPLICA_ZONE_2 : a segunda zona de réplica para o novo clone de disco regional.
  • PROJECT_ID : o ID do projeto onde você deseja clonar o disco.

Terraforma

Para criar um clone de disco regional a partir de um disco zonal, você pode, opcionalmente, criar um instantâneo do disco zonal e, em seguida, clonar o instantâneo. Para fazer isso, use os seguintes recursos:

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"]
}

Para saber como aplicar ou remover uma configuração do Terraform, consulte Comandos básicos do Terraform .

Ir

Go

Antes de testar este exemplo, siga as instruções de configuração Go no guia de início rápido do Compute Engine usando bibliotecas de cliente . Para mais informações, consulte a documentação de referência da API Compute Engine Go .

Para autenticar no Compute Engine, configure as credenciais padrão do aplicativo. Para obter mais informações, consulte Configurar autenticação para um ambiente de desenvolvimento local .

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

Antes de testar este exemplo, siga as instruções de configuração Java no guia de início rápido do Compute Engine usando bibliotecas de cliente . Para mais informações, consulte a documentação de referência da API Java do Compute Engine .

Para autenticar no Compute Engine, configure as credenciais padrão do aplicativo. Para obter mais informações, consulte Configurar autenticação para um ambiente de desenvolvimento local .


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());
    }
  }
}

Pitão

Python

Antes de testar este exemplo, siga as instruções de configuração Python no guia de início rápido do Compute Engine usando bibliotecas de cliente . Para mais informações, consulte a documentação de referência da API Python do Compute Engine .

Para autenticar no Compute Engine, configure as credenciais padrão do aplicativo. Para obter mais informações, consulte Configurar autenticação para um ambiente de desenvolvimento local .

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)

DESCANSAR

Para criar um clone de disco regional a partir de um disco zonal, faça uma solicitação POST para o método compute.disks.insert e especifique os parâmetros sourceDisk e 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"
}

Substitua o seguinte:

  • PROJECT_ID : o ID do projeto onde você deseja clonar o disco.
  • TARGET_DISK_NAME : o nome do novo clone de disco regional.
  • CLONED_REGION : a região dos discos de origem e clonados.
  • SOURCE_DISK_NAME : o nome do disco zonal a ser clonado.
  • SOURCE_DISK_ZONE : a zona do disco de origem. Esta também será a primeira zona de réplica para o clone do disco regional.
  • REPLICA_ZONE_2 : a segunda zona de réplica para o novo clone de disco regional.

Crie um clone de disco de um disco de origem criptografado

Você pode usar uma chave de criptografia fornecida pelo cliente (CSEK) ou uma chave de criptografia gerenciada pelo cliente para criptografar seus discos.

Crie clones de disco para discos criptografados por CSEK

Se você usar uma CSEK para criptografar o disco de origem, também deverá usar a mesma chave para criptografar o clone.

Console

  1. No console do Google Cloud, acesse a página Discos .

    Vá para discos

  2. Na lista de discos permanentes zonais, encontre o disco que você deseja clonar.

  3. Na coluna Ações , clique no botão de menu e selecione Clonar disco .

    Crie um clone.

    No painel Clonar disco que aparece, faça o seguinte:

    1. No campo Nome , especifique um nome para o disco clonado.
    2. No campo Descriptografia e criptografia , forneça a chave de criptografia do disco de origem.
    3. Em Propriedades , revise outros detalhes do disco clonado.
    4. Para finalizar a criação do disco clonado, clique em Criar .

gcloud

Para criar um clone de disco para um disco de origem criptografado por CSEK, execute o comando gcloud compute disks create e forneça a chave de criptografia do disco de origem usando o sinalizador --csek-key-file . Se você estiver usando uma chave encapsulada em RSA, use o comando 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

Substitua o seguinte:

  • TARGET_DISK_NAME : o nome do novo disco.
  • PROJECT_ID : o ID do projeto onde você deseja clonar o disco.
  • ZONE : a zona da origem e do novo disco.
  • SOURCE_DISK_NAME : o nome do disco de origem

Ir

Go

Antes de testar este exemplo, siga as instruções de configuração Go no guia de início rápido do Compute Engine usando bibliotecas de cliente . Para mais informações, consulte a documentação de referência da API Compute Engine Go .

Para autenticar no Compute Engine, configure as credenciais padrão do aplicativo. Para obter mais informações, consulte Configurar autenticação para um ambiente de desenvolvimento local .

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

Antes de testar este exemplo, siga as instruções de configuração Java no guia de início rápido do Compute Engine usando bibliotecas de cliente . Para mais informações, consulte a documentação de referência da API Java do Compute Engine .

Para autenticar no Compute Engine, configure as credenciais padrão do aplicativo. Para obter mais informações, consulte Configurar autenticação para um ambiente de desenvolvimento local .


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());
    }
  }
}

Pitão

Python

Antes de testar este exemplo, siga as instruções de configuração Python no guia de início rápido do Compute Engine usando bibliotecas de cliente . Para mais informações, consulte a documentação de referência da API Python do Compute Engine .

Para autenticar no Compute Engine, configure as credenciais padrão do aplicativo. Para obter mais informações, consulte Configurar autenticação para um ambiente de desenvolvimento local .

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)

DESCANSAR

Para criar um clone de disco para um disco de origem criptografado por CSEK, faça uma solicitação POST para o método compute.disks.insert e forneça a chave de criptografia do disco de origem usando a propriedade diskEncryptionKey . Se você estiver usando uma chave encapsulada em RSA, use a versão beta do método .

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=="
  },
}

Substitua o seguinte:

  • PROJECT_ID : o ID do projeto onde você deseja clonar o disco.
  • ZONE : a zona da origem e do novo disco.
  • TARGET_DISK_NAME : o nome do novo disco.
  • SOURCE_DISK_NAME : o nome do disco de origem

Criar clones de disco para discos criptografados por CMEK

Se você usar uma CMEK para criptografar o disco de origem, também deverá usar a mesma chave para criptografar o clone.

Console

O Compute Engine criptografa automaticamente o clone usando a chave de criptografia do disco de origem.

gcloud

Para criar um clone de disco para um disco de origem criptografado por CMEK, execute o comando gcloud compute disks create e forneça a chave de criptografia do disco de origem usando a sinalização --kms-key . Se você estiver usando uma chave encapsulada em RSA, use o comando 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

Substitua o seguinte:

  • TARGET_DISK_NAME : o nome do novo disco.
  • PROJECT_ID : o ID do projeto onde você deseja clonar o disco.
  • ZONE : a zona da origem e do novo disco.
  • SOURCE_DISK_NAME : o nome do disco de origem.
  • KMS_PROJECT_ID : o ID do projeto para a chave de criptografia.
  • REGION : a região da chave de criptografia.
  • KEY_RING : o conjunto de chaves da chave de criptografia.
  • KEY : o nome da chave de criptografia.

Ir

Go

Antes de testar este exemplo, siga as instruções de configuração Go no guia de início rápido do Compute Engine usando bibliotecas de cliente . Para mais informações, consulte a documentação de referência da API Compute Engine Go .

Para autenticar no Compute Engine, configure as credenciais padrão do aplicativo. Para obter mais informações, consulte Configurar autenticação para um ambiente de desenvolvimento local .

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

Antes de testar este exemplo, siga as instruções de configuração Java no guia de início rápido do Compute Engine usando bibliotecas de cliente . Para mais informações, consulte a documentação de referência da API Java do Compute Engine .

Para autenticar no Compute Engine, configure as credenciais padrão do aplicativo. Para obter mais informações, consulte Configurar autenticação para um ambiente de desenvolvimento local .


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());
    }
  }
}

Pitão

Python

Antes de testar este exemplo, siga as instruções de configuração Python no guia de início rápido do Compute Engine usando bibliotecas de cliente . Para mais informações, consulte a documentação de referência da API Python do Compute Engine .

Para autenticar no Compute Engine, configure as credenciais padrão do aplicativo. Para obter mais informações, consulte Configurar autenticação para um ambiente de desenvolvimento local .

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)

DESCANSAR

Para criar um clone de disco para um disco de origem criptografado por CMEK, faça uma solicitação POST para o método compute.disks.insert e forneça a chave de criptografia do disco de origem usando a propriedade kmsKeyName . Se você estiver usando uma chave encapsulada em RSA, use a versão beta do método .

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"
  },
}

Substitua o seguinte:

  • PROJECT_ID : o ID do projeto onde você deseja clonar o disco.
  • ZONE : a zona da origem e do novo disco.
  • TARGET_DISK_NAME : o nome do novo disco.
  • SOURCE_DISK_NAME : o nome do disco de origem.
  • KMS_PROJECT_ID : o ID do projeto para a chave de criptografia.
  • REGION : a região da chave de criptografia.
  • KEY_RING : o conjunto de chaves da chave de criptografia.
  • KEY : o nome da chave de criptografia.

O que vem a seguir