Duplicar um disco com clones

Neste documento, você encontra informações sobre como os clones de disco funcionam e como criar um clone de disco. Com a clonagem de discos, é possível criar cópias instantaneamente utilizáveis de dados em discos permanentes no mesmo local (zona ou região). Crie um clone de disco em cenários em que você quer uma cópia de um disco que pode ser anexado instantaneamente a uma VM, como o seguinte:

  • Criar ambientes de preparo duplicando dados de produção para depurar sem perturbando a produção
  • Realizar verificações de malware não destrutivas em um disco sem afetar o desempenho de uma carga de trabalho de produção
  • Como criar cópias para a verificação de backup do banco de dados
  • Como mover dados de discos que não são de inicialização para um novo projeto
  • Duplicação de discos durante o escalonamento horizontal de VMs

Para ativar a recuperação de desastres dos seus dados, faça backup do disco com snapshots padrão em vez de usar clones de disco. Para capturar o conteúdo do disco em intervalos regulares sem criar novos use snapshots instantâneos porque são mais eficientes em armazenamento do que os clones. Para aumentar a proteção do disco consulte Opções de proteção de dados.

Antes de começar

Resumo dos casos de uso

Além de duplicar um disco para testes e depuração rápidos, é possível ativar a alta disponibilidade para um disco zonal criando um clone regional do disco zonal. Quando você cria um disco regional de um disco zonal, o disco regional tem uma réplica do disco em duas zonas na mesma região. Depois de criar o disco regional, use-o em vez do disco zonal. Em caso de interrupção em uma zona, ainda é possível acessar os dados da réplica na outra zona.

Esta tabela resume os diferentes tipos de clones compatíveis com o Compute Engine.

Tipo de clonagem Quando usar Tipos de disco compatíveis
Clone zonal de um disco zonal Crie uma cópia idêntica de um disco na mesma zona para qualquer uma das seguintes tarefas:
  • Escalonar horizontalmente as cargas de trabalho duplicando os discos atuais para novas VMs.
  • Ambientes de preparo, depuração ou teste com dados de produção.
  • Verificar um disco em produção em busca de malware.
  • Mover um disco para um novo projeto.
  • Persistent Disk: disco permanente padrão, equilibrado e SSD
  • Hyperdisk: todos os tipos de Hyperdisk, exceto Hyperdisk Balanced High Availability
Clone regional de um disco zonal
  • Tornar uma carga de trabalho zonal altamente disponível adicionando uma réplica dos dados em outra zona.
  • Verificar um disco em produção em busca de malware.
  • Persistent Disk: disco permanente padrão, equilibrado e SSD
  • Hyperdisk: Hyperdisk Extreme e Hyperdisk Balanced
Clone regional de um disco regional Crie uma cópia idêntica de um disco regional na mesma região para:
  • Testar ou escalonar horizontalmente cargas de trabalho regionais de alta disponibilidade (HA).
  • Manter a redundância de dados em duas zonas ao realizar tarefas administrativas ou testes.
  • Criando cópias de volumes de banco de dados de alta disponibilidade para verificação.
  • Persistent Disk: disco permanente regional equilibrado, SSD e disco permanente padrão
  • Hyperdisk: Hyperdisk Balanced High Availability

Como funciona a clonagem de disco

Quando você clona um disco, você cria um novo disco que contém todos os dados no disco de origem. É possível criar um clone de disco mesmo que o disco atual esteja anexado a uma instância de VM. Depois de clonar um disco, é possível excluir o disco de origem sem o risco de excluir o clone.

Por padrão, os clones de um disco herdam o tamanho, os limites de desempenho, o tipo e a zona ou região exata. É possível mudar algumas dessas propriedades da seguinte forma:

  • Tamanho: é possível criar um clone com um tamanho maior do que o disco de origem, mas não menor.

  • Performance: para volumes do Hyperdisk, é possível especificar um limite de desempenho diferente para o clone. Os clones regionais de volumes zonais do Hyperdisk são volumes do Hyperdisk Balanced High Availability e podem ter limites de desempenho diferentes.

  • Local: por padrão, o clone de um disco é criado na mesma zona para discos zonais e na mesma região para discos regionais. No entanto, para criar um clone regional de um disco zonal, especifique uma segunda zona na mesma região do disco zonal. O novo clone também é chamado de clone regional e tem uma réplica em cada na zona do disco de origem e na segunda zona especificada.

  • Tipo: clones regionais de volumes zonais do Hyperdisk Balanced ou do Hyperdisk Extreme são volumes do Hyperdisk Balanced High Availability.

Volumes regionais do Hyperdisk clonados de volumes zonais do Hyperdisk

Um clone regional de um volume zonal do Hyperdisk é sempre um novo volume do Hyperdisk Balanced High Availability. Isso porque o Hyperdisk Balanced High Availability é o único hiperdisco regional compatível. A maneira de criar um hiperdisco regional com base em um hiperdisco zonal depende do tipo dele.

Performance de volumes do Hyperdisk Balanced High Availability clonados de discos zonais

Quando você cria um volume do Hyperdisk Balanced High Availability com base em um volume do Hyperdisk Balanced ou Hyperdisk Extreme, o novo disco herda o tamanho do disco de origem, mas é possível especificar um tamanho diferente.

O desempenho provisionado máximo do novo disco pode ser menor do que o do disco de origem, porque o Hyperdisk Extreme e o Hyperdisk Balanced têm limites de desempenho mais altos do que o Hyperdisk Balanced High Availability, conforme listado na tabela a seguir.

Tipo de Hyperdisk Máximo de operações de E/S por segundo (IOPS) Capacidade máxima ( MiB/s)
Alta disponibilidade do hiperdisco equilibrada 100.000 2.400
Hiperdisco equilibrado 160.000 2.400
Hiperdisco extremo 350.000 5.000

É possível especificar limites para o novo disco regional, mas eles não podem exceder os limites máximos de desempenho oferecidos pelo Hyperdisk Balanced High Availability: 100.000 IOPS e 2.400 MiB/s.

Se você não especificar um limite de desempenho para o novo disco, o Compute Engine vai provisionar o disco com as IOPS e a capacidade de processamento padrão que dependem do tamanho do volume do Hyperdisk Balanced High Availability. Para conferir os limites padrão, consulte Limites padrão de tamanho e desempenho do Hyperdisk Balanced High Availability.

Para atingir 100.000 IOPS, o tamanho de um volume do Hyperdisk Balanced High Availability precisa ser de pelo menos 200 GiB. Portanto, talvez seja necessário aumentar o tamanho provisionado do clone regional.

Exemplo

Considere um volume de 150 GiB do Hyperdisk Extreme, hdx-1, provisionado com 180.000 IOPS.

Se você criar um clone regional de hdx-1 e não especificar um novo tamanho ou limite de desempenho, o Compute Engine vai criar um volume do Hyperdisk Balanced High Availability de 150 GiB com o limite de IOPS padrão para esse tamanho: 3.900 IOPS.

Se você não aumentar o tamanho, poderá especificar até 75.000 IOPS para o clone regional.

Volumes regionais de disco permanente clonados de volumes zonais de Persistent Disk

Um volume de Persistent Disk regional clonado de um Persistent Disk zonal tem o mesmo tipo do clone. Por exemplo, se você clonar um disco permanente padrão zonal, vai criar um volume de disco permanente padrão regional.

No entanto, os clones regionais de volumes de Persistent Disk podem ter limites de tamanho e desempenho diferentes do disco de origem zonal, conforme a seguir.

  • Limites de desempenho mais baixos: os clones regionais do Persistent Disk podem ter um limite de desempenho de IOPS e capacidade de processamento menor do que o disco de origem. Isso acontece porque Persistent Disk zonal oferece limites máximos de desempenho de instância mais altos. Por exemplo, o disco permanente equilibrado zonal tem um limite máximo de instância de 80.000 IOPS de gravação, mas o disco permanente equilibrado regional tem um limite de 60.000 IOPS de gravação.

    Para limites de desempenho detalhados, compare os limites de desempenho para discos permanentes zonais e os limites de desempenho para discos permanentes regionais.

  • Para disco permanente padrão regional, um tamanho mínimo de 200 GiB: o disco permanente padrão regional tem um tamanho mínimo de 200 GiB. Portanto, para criar um clone regional de um volume de disco permanente padrão zonal de 10 a 199 GiB, especifique um tamanho de pelo menos 200 GiB para o disco regional.

Tipos de disco compatíveis

É possível clonar todos os tipos de Persistent Disk e Hyperdisk se o clone estiver no mesmo local (zona ou região) do disco de origem.

A clonagem de um disco zonal para um regional é compatível apenas com os seguintes tipos de disco:

  • Google Cloud Hyperdisk:

    • Hiperdisco equilibrado
    • Hiperdisco extremo

    Para criar um disco regional com base em um volume do Hyperdisk ML ou do Hyperdisk Throughput, crie um snapshot e, em seguida, crie um volume do Hyperdisk Balanced High Availability com base no snapshot.

  • Persistent Disk:

    • Disco permanente equilibrado
    • Disco permanente SSD
    • Disco permanente padrão

Restrições

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

  • Não é possível criar um volume do Hyperdisk Balanced High Availability clonando um volume zonal do Hyperdisk ML ou do Hyperdisk Throughput. Para criar um volume do Hyperdisk Balanced High Availability para esses tipos de Hyperdisk, siga as etapas em Mudar um disco zonal para um volume regional do Hyperdisk Balanced High Availability.
  • Não é possível clonar um disco em um pool de armazenamento.
  • Não é possível criar um clone de disco zonal de um disco zonal existente em uma zona diferente.
  • O tamanho do clone precisa ser pelo menos do tamanho do disco de origem. Se você criar um clone usando o Google Cloud console, não será possível especificar um tamanho de disco e o clone terá o mesmo tamanho do disco de origem.
  • Se você clonar um volume do Hyperdisk ou do Persistent Disk no console do Google Cloud , não será possível especificar o desempenho provisionado para o disco clonado.
  • Se você usar uma chave de criptografia fornecida pelo cliente (CSEK) ou uma chave de criptografia gerenciada pelo cliente (CMEK) para criptografar o disco de origem, será necessário usar a mesma chave para criptografar o clone. Para obter mais informações, consulte Como criar um clone de um disco de origem criptografado.
  • Não é possível excluir o disco de origem enquanto o clone está sendo criado.
  • A instância do Compute a que o disco de origem está anexado não vai conseguir ligado enquanto o clone é criado.
  • Se o disco de origem foi marcado para ser excluído com a VM em que ele está não será possível excluir a VM enquanto o clone estiver sendo criado.
  • É possível criar no máximo um clone de um determinado disco de origem ou os clones dele a cada 30 segundos.
  • É possível ter no máximo 1.000 clones de disco simultâneos de um determinado disco de origem ou os clones dele. Exceder esse limite retorna um internalError. No entanto, se você criar um clone de disco e excluí-lo mais tarde, o clone de disco excluído não será incluído nesse limite.
  • Depois que um disco é clonado, qualquer clone subsequente desse disco ou dos respectivos clones é contabilizado no limite de 1.000 clones de disco simultâneos no disco de origem original e contabilizados no limite da criação de no máximo um clone a cada 30 segundos.
  • Se você criar um disco regional clonando um disco zonal, será possível clonar no máximo 1 TiB de capacidade a cada 15 minutos, com um limite de solicitação de burst de 257 TiB.
  • 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, um dos zonas de réplica do clone do disco regional precisa corresponder à zona do disco de origem.
  • Após a criação, o clone do disco regional pode ser usado em três minutos, em média. No entanto, o disco pode levar dezenas de minutos para se tornar totalmente replicado e chegar a um estado em que o objetivo do ponto de recuperação (RPO, na sigla em inglês) está perto de zero.
  • Se você criou um disco zonal com base em uma imagem, não é possível usar esse disco para criar um clone de disco regional.

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.

Criar clones de disco

Nesta seção, explicamos como duplicar e criar um disco clone.

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

Criar um clone de disco no mesmo local da origem

É possível criar um clone de um disco zonal ou regional na mesma zona ou região, respectivamente, do disco de origem usando o consoleGoogle Cloud , a Google Cloud CLI, REST ou as bibliotecas de cliente do Cloud.

Console do Google Cloud

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

    Acessar "Discos"

  2. Na lista de discos, navegue até o disco que você quer clonar.

  3. Na coluna Ações, clique em Botão de menu e Selecione Clonar disco.

    Crie o clone.

    No painel Clonar disco exibido, faça o seguinte:

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

CLI do Google Cloud

Para clonar um disco de origem zonal e criar outro, execute o Comando disks create e especifique a sinalização --source-disk:

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

Substitua:

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

Terraform

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.

Go

Go

Antes de testar esta amostra, siga as instruções de configuração do Go no Guia de início rápido do Compute Engine: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Go do Compute Engine.

Para autenticar-se no Compute Engine, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

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 esta amostra, siga as instruções de configuração do Java no Guia de início rápido do Compute Engine: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Java do Compute Engine.

Para autenticar-se no Compute Engine, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.


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

Antes de testar esta amostra, siga as instruções de configuração do Python no Guia de início rápido do Compute Engine: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Python do Compute Engine.

Para autenticar-se no Compute Engine, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

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

Para clonar um disco de origem zonal e criar um novo, crie um POST. solicitação ao método compute.disks.insert. No corpo da solicitação, especifique os parâmetros name e sourceDisk. O disco clonado 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:

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

Como criar um clone de disco regional a partir de um disco zonal

É possível clonar um disco zonal existente para criar um novo disco regional de qualquer um dos seguintes tipos:

  • Hiperdisco equilibrado
  • Hiperdisco extremo
  • Disco permanente padrão, equilibrado e SSD

Se o disco de origem for um volume do Hyperdisk Balanced ou do Hyperdisk Extreme, o disco regional será sempre um volume do Hyperdisk Balanced High Availability e não vai herdar o mesmo desempenho provisionado do disco zonal. Para definir o desempenho provisionado do disco regional, clone o disco com a Google Cloud CLI ou a REST. Se você clonar o disco com o console Google Cloud , não será possível especificar um limite de desempenho, e o disco será provisionado com os limites padrão para o tamanho dele.

Console

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

    Acessar "Discos"

  2. Na lista de discos, acesse o volume de disco permanente zonal que você que você quer clonar.

  3. Na coluna Ações, clique em Botão de menu e Selecione Clonar disco.

    Crie o clone.

    No painel Clonar disco exibido, faça o seguinte:

    1. No campo Nome, especifique um nome para o disco clonado.
    2. Em Local, selecione Regional e, depois, a opção secundária zona de réplica para o novo disco clonado regional.
    3. Em Propriedades, revise outros detalhes do disco clonado.
    4. Para concluir 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.

Se o disco zonal for um volume do Hyperdisk Balanced ou do Hyperdisk Extreme, especifique a flag --disk-type=hyperdisk-balanced-high-availability, já que o disco regional precisa ser um volume do Hyperdisk Balanced High Availability.

Para clonar um volume do Persistent Disk, omita a flag --disk-type.

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 \
  [ --disk-type=hyperdisk-balanced-high-availability ] \
  [ --provisioned-iops=IOPS_LIMIT ] \
  [ --provisioned-throughput=THROUGHPUT_LIMIT ]

Substitua:

  • TARGET_DISK_NAME: o nome do novo disco clonado.
  • CLONED_REGION: a região da origem e clonada. em discos permanentes.
  • SOURCE_DISK_NAME: o nome do disco zonal que 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 em que você quer clonar o disco.
  • IOPS_LIMIT: opcional: para criar um disco regional do Hyperdisk Balanced High Availability, especifique um número de IOPS que o disco pode processar, até 100.000 IOPS.
  • THROUGHPUT_LIMIT: opcional: para criar um disco regional do Hyperdisk Balanced High Availability disco, especifique a capacidade máxima de processamento em MiB/s que o disco pode fornecer, até 2.400 MiB/s.

Terraform

Para criar um clone de disco regional a partir de um disco zonal, use o recurso a seguir. Se o disco de origem for um volume do Hyperdisk Balanced ou Hyperdisk Extreme, defina o argumento type como hyperdisk-balanced-high-availability.

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.

Go

Go

Antes de testar esta amostra, siga as instruções de configuração do Go no Guia de início rápido do Compute Engine: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Go do Compute Engine.

Para autenticar-se no Compute Engine, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

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 esta amostra, siga as instruções de configuração do Java no Guia de início rápido do Compute Engine: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Java do Compute Engine.

Para autenticar-se no Compute Engine, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.


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

Antes de testar esta amostra, siga as instruções de configuração do Python no Guia de início rápido do Compute Engine: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Python do Compute Engine.

Para autenticar-se no Compute Engine, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

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

Para criar um clone de disco regional com base em um disco zonal, faça uma solicitação POST para o método compute.disks.insert e especifique os parâmetros sourceDisk e replicaZone.

Se o disco zonal for um volume do Hyperdisk Balanced ou do Hyperdisk Extreme, inclua o campo type para criar um volume do Hyperdisk Balanced High Availability.

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",
  "type": "projects/PROJECT_ID/regions/CLONED_REGION/diskTypes/hyperdisk-balanced-high-availability",
  "provisionedIops": "IOPS_LIMIT",
  "provisionedThroughput": "THROUGHPUT_LIMIT"
}

Substitua:

  • PROJECT_ID: o ID do projeto em que você quer clonar o disco.
  • TARGET_DISK_NAME: o nome do novo disco clonado.
  • CLONED_REGION: a região da origem e clonada. em discos permanentes.
  • SOURCE_DISK_NAME: o nome do disco zonal que 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.
  • IOPS_LIMIT: opcional: para criar um disco regional do Hyperdisk Balanced High Availability, especifique um número de IOPS que o disco pode processar, até 100.000 IOPS.
  • THROUGHPUT_LIMIT: opcional: para criar um disco regional do Hyperdisk Balanced High Availability disco, especifique a capacidade máxima de processamento em MiB/s que o disco pode fornecer, até 2.400 MiB/s.

Criar um clone de disco de um disco de origem criptografado por CMEK ou CSEK

Para criar um clone zonal ou regional de um disco criptografado com CSEK ou CMEK, siga os procedimentos descritos nas seções anteriores. No entanto, também é necessário fornecer a chave usada para criptografar o disco de origem.

Criar clones de discos para discos criptografados por CSEK

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

Console

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

    Acessar "Discos"

  2. Na lista de discos permanentes zonais, localize o disco que você quer clonar.

  3. Na coluna Ações, clique em Botão de menu e Selecione Clonar disco.

    Crie o clone.

    No painel Clonar disco exibido, faça o seguinte:

    1. No campo Nome, especifique um nome para o disco clonado.
    2. No campo Descriptografia e criptografia, forneça o disco de origem. de criptografia de dados.
    3. Em Propriedades, revise outros detalhes do disco clonado.
    4. Para concluir 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 método --csek-key-file flag. Se você estiver usando uma chave incorporada por RSA, utilize 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:

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

Go

Go

Antes de testar esta amostra, siga as instruções de configuração do Go no Guia de início rápido do Compute Engine: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Go do Compute Engine.

Para autenticar-se no Compute Engine, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

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 esta amostra, siga as instruções de configuração do Java no Guia de início rápido do Compute Engine: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Java do Compute Engine.

Para autenticar-se no Compute Engine, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.


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

Antes de testar esta amostra, siga as instruções de configuração do Python no Guia de início rápido do Compute Engine: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Python do Compute Engine.

Para autenticar-se no Compute Engine, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

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

Para criar um clone de disco para um disco de origem criptografado por CSEK, faça uma solicitação POST ao método compute.disks.insert e informe a chave de criptografia do disco de origem usando diskEncryptionKey do anúncio. Se você estiver usando uma chave incorporada por 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:

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

Criar clones de discos para discos criptografados por CMEKs

Se você usar uma CMEK para criptografar seu disco de origem, use também 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 flag --kms-key. Se você estiver usando uma chave incorporada por RSA, utilize 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:

  • TARGET_DISK_NAME: o nome do novo disco.
  • PROJECT_ID: o ID do projeto em que você quer clonar o disco.
  • ZONE: a zona da origem e o novo disco.
  • SOURCE_DISK_NAME: o nome do disco de origem.
  • KMS_PROJECT_ID: o ID do projeto da chave de criptografia.
  • REGION: a região da chave de criptografia.
  • KEY_RING: o keyring da chave de criptografia.
  • KEY: o nome da chave de criptografia.

Go

Go

Antes de testar esta amostra, siga as instruções de configuração do Go no Guia de início rápido do Compute Engine: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Go do Compute Engine.

Para autenticar-se no Compute Engine, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

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 esta amostra, siga as instruções de configuração do Java no Guia de início rápido do Compute Engine: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Java do Compute Engine.

Para autenticar-se no Compute Engine, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.


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

Antes de testar esta amostra, siga as instruções de configuração do Python no Guia de início rápido do Compute Engine: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Python do Compute Engine.

Para autenticar-se no Compute Engine, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

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

Para criar um clone de disco para um disco de origem criptografado por CMEK, faça uma solicitação POST ao 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 incorporada por 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:

  • PROJECT_ID: o ID do projeto em que você quer clonar o disco.
  • ZONE: a zona da origem e o 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 da chave de criptografia.
  • REGION: a região da chave de criptografia.
  • KEY_RING: o keyring da chave de criptografia.
  • KEY: o nome da chave de criptografia.

A seguir