Dupliquer un disque avec des clones

Ce document explique le fonctionnement des clones de disque et comment en créer un. Le clonage de disque vous permet de créer des copies immédiatement utilisables de disques existants au même emplacement (zone ou région). Créez un clone de disque dans les scénarios où vous souhaitez obtenir une copie d'un disque existant que vous pouvez associer instantanément à une VM, par exemple :

  • Créer des environnements de préproduction en répliquant les données de production à déboguer sans perturber la production
  • Effectuer des analyses de logiciels malveillants non perturbatrices sur un disque sans impacter les performances d'une charge de travail de production
  • Créer des copies pour vérifier les sauvegardes de bases de données
  • Déplacer des données de disque non amorçable vers un nouveau projet
  • Répliquer des disques lors du scaling horizontal de vos VM

Pour activer la reprise après sinistre pour vos données, sauvegardez votre disque à l'aide d'instantanés standards au lieu d'utiliser des clones de disque. Pour capturer le contenu d'un disque à intervalles réguliers sans créer de disque, utilisez des instantanés immédiats, car ils sont plus efficaces en termes de stockage que les clones. Pour en savoir plus sur les autres options de protection des disques, consultez Options de protection des données.

Avant de commencer

Résumé des cas d'utilisation

En plus de dupliquer un disque pour effectuer des tests et des opérations de débogage rapides, vous pouvez activer la haute disponibilité pour un disque zonal en créant un clone régional à partir du disque zonal. Lorsque vous créez un disque régional à partir d'un disque zonal, le disque régional comporte une réplique du disque dans deux zones de la même région. Une fois le disque régional créé, vous l'utilisez à la place du disque zonal. En cas d'indisponibilité dans une zone (ce qui est rare), vous pouvez toujours accéder aux données à partir du réplica dans l'autre zone.

Ce tableau récapitule les différents types de clones compatibles avec Compute Engine.

Type de clonage Cas d'utilisation Types de disques compatibles
Clone zonal à partir d'un disque zonal Créez une copie identique d'un disque dans la même zone pour l'une des tâches suivantes :
  • Faire évoluer les charges de travail en répliquant les disques existants pour les nouvelles VM.
  • Environnements de préproduction, de débogage ou de test avec des données de production.
  • Analyse d'un disque en production pour détecter les logiciels malveillants.
  • Déplacer un disque vers un nouveau projet
  • Persistent Disk : disque persistant standard, équilibré et SSD
  • Hyperdisk : tous les types Hyperdisk, à l'exception d'Hyperdisk équilibré à haute disponibilité
Clone régional d'un disque zonal
  • Rendre une charge de travail zonale disponibilité élevée en ajoutant une réplique des données dans une autre zone.
  • Analyse d'un disque en production pour détecter les logiciels malveillants.
  • Persistent Disk : disque persistant standard, équilibré et SSD
  • Hyperdisk : Hyperdisk Extreme et Hyperdisk Balanced
Clone régional d'un disque régional Créez une copie identique d'un disque régional dans la même région pour :
  • Tester ou faire évoluer des charges de travail régionales à disponibilité élevée
  • Maintenir la redondance des données dans deux zones lors de l'exécution de tâches administratives ou de tests.
  • Création de copies des volumes de base de données HA pour vérification.
  • Persistent Disk : disque Persistent Disk régional avec équilibrage, SSD et standard
  • Hyperdisk : Hyperdisk Balanced High Availability

Fonctionnement du clonage de disque

Lorsque vous clonez un disque, vous créez un disque contenant toutes les données du disque source. Vous pouvez créer un clone de disque même si le disque existant est associé à une instance de VM. Après avoir cloné un disque, vous pouvez supprimer le disque source sans risque de suppression du clone.

Par défaut, les clones d'un disque héritent de sa taille, de ses limites de performances, de son type et de la zone ou région exacte. Vous pouvez modifier certaines de ces propriétés, comme suit :

  • Taille : vous pouvez créer un clone dont la taille est supérieure à celle du disque source, mais pas inférieure.

  • Performances : pour les volumes Hyperdisk, vous pouvez spécifier une limite de performances différente pour le clone. Les clones régionaux de volumes Hyperdisk zonaux sont des volumes Hyperdisk équilibrés à haute disponibilité et peuvent avoir des limites de performances différentes.

  • Emplacement : par défaut, le clone d'un disque est créé dans la même zone pour les disques zonaux et dans la même région pour les disques régionaux. Toutefois, pour créer un clone régional d'un disque zonal, vous pouvez spécifier une deuxième zone située dans la même région que le disque zonal. Le nouveau clone est également appelé clone régional et comporte une réplique dans la zone du disque source et une autre dans la deuxième zone que vous avez spécifiée.

  • Type : les clones régionaux de volumes Hyperdisk Balanced ou Hyperdisk Extreme zonaux sont des volumes Hyperdisk Balanced à haute disponibilité.

Volumes Hyperdisk régionaux clonés à partir de volumes Hyperdisk zonaux

Un clone régional d'un volume Hyperdisk zonal existant est toujours un nouveau volume Hyperdisk Balanced High Availability. En effet, Hyperdisk Balanced High Availability est le seul Hyperdisk régional compatible. La façon dont vous créez un Hyperdisk régional à partir d'un Hyperdisk zonal dépend de son type.

Performances des volumes Hyperdisk Balanced High Availability clonés à partir de disques zonaux

Lorsque vous créez un volume Hyperdisk équilibré à haute disponibilité à partir d'un volume Hyperdisk équilibré ou Hyperdisk Extreme, le nouveau disque hérite de la taille du disque source, mais vous pouvez spécifier une taille différente.

Les performances maximales provisionnées du nouveau disque peuvent être inférieures à celles du disque source, car les disques Hyperdisk Extreme et Hyperdisk Balanced ont des limites de performances plus élevées que les disques Hyperdisk Balanced à haute disponibilité, comme indiqué dans le tableau suivant.

Type de volume Hyperdisk Nombre maximal d'opérations d'E/S par seconde (IOPS) Débit maximal ( Mio/s)
Haute disponibilité sur Hyperdisk équilibré 100 000 2 400
Volume Hyperdisk équilibré 160 000 2 400
Hyperdisk Extreme 350 000 5 000

Vous pouvez spécifier des limites pour le nouveau disque régional, mais elles ne peuvent pas dépasser les limites de performances maximales offertes par Hyperdisk équilibré à haute disponibilité (100 000 IOPS et 2 400 Mio/s).

Si vous ne spécifiez pas de limite de performances pour le nouveau disque, Compute Engine provisionne le disque avec les IOPS et le débit par défaut, qui dépendent de la taille du volume Hyperdisk Balanced High Availability. Pour connaître les limites par défaut, consultez Limites de taille et de performances par défaut des volumes Hyperdisk équilibrés à haute disponibilité.

Pour atteindre 100 000 IOPS, la taille d'un volume Hyperdisk Balanced à haute disponibilité doit être d'au moins 200 Gio. Vous devrez peut-être également augmenter la taille provisionnée du clone régional.

Exemple

Prenons l'exemple d'un volume Hyperdisk Extreme de 150 Gio, hdx-1, provisionné avec 180 000 IOPS.

Si vous créez un clone régional de hdx-1 et que vous ne spécifiez pas de nouvelle taille ni de nouvelle limite de performances, Compute Engine crée un volume Hyperdisk Balanced High Availability de 150 Gio avec la limite d'IOPS par défaut pour cette taille : 3 900 IOPS.

Si vous n'augmentez pas la taille, vous pouvez spécifier jusqu'à 75 000 IOPS pour le clone régional.

Volumes Persistent Disk régionaux clonés à partir de volumes Persistent Disk zonaux

Un volume Persistent Disk régional cloné à partir d'un Persistent Disk zonal a le même type que le clone. Par exemple, si vous clonez un disque persistant standard zonal, vous créez un volume de disque persistant standard régional.

Toutefois, les clones régionaux de volumes Persistent Disk peuvent avoir des limites de taille et de performances différentes de celles du disque source zonal, comme suit.

  • Limites de performances inférieures : les clones régionaux de Persistent Disk peuvent avoir des limites de performances d'IOPS et de débit inférieures à celles du disque source. En effet, les disques persistants zonaux offrent des limites de performances maximales plus élevées pour les instances. Par exemple, le disque persistant avec équilibrage zonal a une limite d'instance de 80 000 IOPS en écriture, tandis que le disque persistant avec équilibrage régional a une limite de 60 000 IOPS en écriture.

    Pour connaître les limites de performances détaillées, comparez les limites de performances des disques persistants zonaux et les limites de performances des disques persistants régionaux.

  • Taille minimale de 200 Gio pour les disques persistants standards régionaux : les disques persistants standards régionaux ont une taille minimale de 200 Gio. Ainsi, pour créer un clone régional d'un volume de disque persistant standard zonal de 10 à 199 Gio, vous devez spécifier une taille d'au moins 200 Gio pour le disque régional.

Types de disques compatibles

Vous pouvez cloner tous les types de disques persistants et d'hyperdisques si le clone se trouve au même emplacement (zone ou région) que le disque source.

Le clonage d'un disque zonal vers un disque régional n'est possible que pour les types de disques suivants :

  • Google Cloud Hyperdisk :

    • Volume Hyperdisk équilibré
    • Hyperdisk Extreme

    Pour créer un disque régional à partir d'un volume Hyperdisk ML ou Hyperdisk Throughput, créez un instantané, puis créez un volume Hyperdisk Balanced High Availability à partir de l'instantané.

  • Persistent Disk :

    • Disque persistant avec équilibrage
    • Disque persistant SSD
    • Disque persistant standard

Restrictions

Les clones de disque sont soumis aux restrictions suivantes :

  • Vous ne pouvez pas créer de volume Hyperdisk équilibré à haute disponibilité en clonant un volume Hyperdisk ML ou Hyperdisk Throughput zonal. Pour créer un volume Hyperdisk Balanced High Availability pour ces types d'Hyperdisk, suivez la procédure décrite dans Convertir un disque zonal en disque Hyperdisk Balanced High Availability régional.
  • Vous ne pouvez pas cloner un disque qui se trouve dans un pool de stockage.
  • Vous ne pouvez pas créer de clone de disque zonal d'un disque zonal existant dans une zone différente.
  • La taille du clone doit être au moins égale à la taille du disque source. Si vous créez un clone à l'aide de la console Google Cloud , vous ne pouvez pas spécifier de taille de disque et le clone est de la même taille que le disque source.
  • Si vous clonez un volume Hyperdisk ou Persistent Disk à partir de la console Google Cloud , vous ne pouvez pas spécifier les performances provisionnées pour le disque cloné.
  • Si vous utilisez une clé de chiffrement fournie par le client (CSEK) ou une clé de chiffrement gérée par le client (CMEK) pour chiffrer le disque source, vous devez utiliser la même clé pour chiffrer le clone. Pour en savoir plus, consultez la section Créer un clone de disque source chiffré.
  • Vous ne pouvez pas supprimer le disque source pendant que son clone est en cours de création.
  • L'instance de calcul à laquelle le disque source est associé ne pourra pas être mise sous tension pendant la création du clone.
  • Si le disque source a été marqué pour être supprimé avec la VM à laquelle il est associé, vous ne pouvez pas supprimer la VM pendant la création du clone.
  • Vous pouvez créer au maximum un clone d'un disque source donné ou ses clones toutes les 30 secondes.
  • Vous pouvez disposer de 1 000 clones d'un disque source donné ou de ses clones simultanément. Si vous dépassez cette limite, l'erreur internalError s'affiche. Toutefois, si vous créez un clone de disque et que vous le supprimez ultérieurement, le clone de disque supprimé n'est pas inclus dans cette limite.
  • Une fois un disque cloné, les clones ultérieurs de ce disque ou de ses clones sont comptabilisés dans la limite de 1 000 clones simultanés pour le disque source d'origine et dans la limite de création d'un clone toutes les 30 secondes.
  • Si vous créez un disque régional en clonant un disque zonal, vous pouvez cloner au maximum 1 Tio de capacité toutes les 15 minutes, avec une limite de requête d'utilisation intensive de 257 Tio.
  • Vous ne pouvez pas créer de clone de disque zonal à partir d'un disque régional.
  • Pour créer un clone de disque régional à partir d'un disque source zonal, l'une des zones répliquées du clone de disque régional doit correspondre à la zone du disque source.
  • Le clone de disque régional est utilisable en moyenne dans les trois minutes suivant sa création. Cependant, il faut plusieurs dizaines de minutes au disque pour être entièrement répliqué et atteindre un état dans lequel l'objectif de point de récupération (RPO, Recovery Point Objective) est proche de zéro.
  • Si vous avez créé un disque zonal à partir d'une image, vous ne pouvez pas l'utiliser pour créer un clone de disque régional.

Messages d'erreur

Si vous dépassez les limites de fréquence de clonage, la requête échoue avec l'erreur suivante :

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

Créer des clones de disque

Cette section explique comment répliquer un disque existant et créer un clone de disque.

Pour obtenir la procédure détaillée, en fonction du type de clone de disque à créer, consultez l'une des sections suivantes de ce document :

Créer un clone de disque au même emplacement que la source

Vous pouvez créer un clone d'un disque zonal ou régional existant qui se trouve dans la même zone ou région que le disque source à l'aide de la consoleGoogle Cloud , de la Google Cloud CLI, de REST ou des bibliothèques clientes Cloud.

Console Google Cloud

  1. Dans la console Google Cloud , accédez à la page Disques.

    Accéder à la page Disques

  2. Dans la liste des disques, accédez au disque que vous souhaitez cloner.

  3. Dans la colonne Actions, cliquez sur le bouton de menu , puis sélectionnez Cloner le disque.

    Créer un clone

    Dans le panneau Cloner le disque qui s'affiche, procédez comme suit :

    1. Dans le champ Nom, spécifiez un nom pour le disque cloné.
    2. Facultatif : Pour les disques zonaux, sous Emplacement, vérifiez que Zone unique est sélectionné.
    3. Sous Propriétés, vérifiez les autres détails du disque cloné.
    4. Pour terminer la création du disque cloné, cliquez sur Créer.

Google Cloud CLI

Pour cloner un disque source zonal et créer un disque zonal, exécutez la commande disks create et spécifiez l'option --source-disk :

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

Remplacez les éléments suivants :

  • TARGET_DISK_NAME : nom du nouveau disque.
  • PROJECT_ID : ID de projet dans lequel cloner le disque.
  • ZONE : zone de la source et du nouveau disque.
  • SOURCE_DISK_NAME : nom du disque source.

Terraform

Pour créer un clone de disque, utilisez la ressource 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
}

Pour savoir comment appliquer ou supprimer une configuration Terraform, consultez Commandes Terraform de base.

Go

Go

Avant d'essayer cet exemple, suivez les instructions de configuration pour Go décrites dans le Guide de démarrage rapide de Compute Engine à l'aide des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Go Compute Engine.

Pour vous authentifier auprès de Compute Engine, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour les bibliothèques clientes.

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

Avant d'essayer cet exemple, suivez les instructions de configuration pour Java décrites dans le Guide de démarrage rapide de Compute Engine à l'aide des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Java Compute Engine.

Pour vous authentifier auprès de Compute Engine, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour les bibliothèques clientes.


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

Avant d'essayer cet exemple, suivez les instructions de configuration pour Python décrites dans le Guide de démarrage rapide de Compute Engine à l'aide des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Python Compute Engine.

Pour vous authentifier auprès de Compute Engine, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour les bibliothèques clientes.

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

Pour cloner un disque source zonal et créer un disque zonal, envoyez une requête POST à la méthode compute.disks.insert. Dans le corps de la requête, spécifiez les paramètres name et sourceDisk. Le clone du disque hérite de toutes les autres propriétés du disque source que vous n'avez pas renseignées.

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

Remplacez les éléments suivants :

  • PROJECT_ID : ID de projet dans lequel cloner le disque.
  • ZONE : zone de la source et du nouveau disque.
  • TARGET_DISK_NAME : nom du nouveau disque.
  • SOURCE_DISK_NAME : nom du disque source.

Créer un clone de disque régional à partir d'un disque zonal

Vous pouvez créer un disque régional en clonant un disque zonal existant de l'un des types suivants :

  • Volume Hyperdisk équilibré
  • Hyperdisk Extreme
  • Disque persistant standard, avec équilibrage et SSD

Si le disque source est un volume Hyperdisk Balanced ou Hyperdisk Extreme, le disque régional est toujours un volume Hyperdisk Balanced High Availability et n'hérite pas des mêmes performances provisionnées que le disque zonal. Pour définir les performances provisionnées du disque régional, vous devez le cloner avec la Google Cloud CLI ou REST. Si vous clonez le disque avec la console Google Cloud , vous ne pouvez pas spécifier de limite de performances. Le disque est provisionné avec les limites par défaut pour sa taille.

Console

  1. Dans la console Google Cloud , accédez à la page Disques.

    Accéder à la page Disques

  2. Dans la liste des disques, accédez au volume Persistent Disk zonal que vous souhaitez cloner.

  3. Dans la colonne Actions, cliquez sur le bouton de menu , puis sélectionnez Cloner le disque.

    Créer un clone

    Dans le panneau Cloner le disque qui s'affiche, procédez comme suit :

    1. Dans le champ Nom, spécifiez un nom pour le disque cloné.
    2. Pour Emplacement, sélectionnez Régional, puis sélectionnez la zone d'instances dupliquées secondaire pour le nouveau disque régional cloné.
    3. Sous Propriétés, vérifiez les autres détails du disque cloné.
    4. Pour terminer la création du disque cloné, cliquez sur Créer.

gcloud

Pour créer un clone de disque régional à partir d'un disque zonal, exécutez la commande gcloud compute disks create et spécifiez les paramètres --region et --replica-zones.

Si le disque zonal est un volume Hyperdisk Balanced ou Hyperdisk Extreme, spécifiez l'indicateur --disk-type=hyperdisk-balanced-high-availability, car le disque régional doit être un volume Hyperdisk Balanced High Availability.

Pour cloner un volume Persistent Disk, omettez l'indicateur --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 ]

Remplacez les éléments suivants :

  • TARGET_DISK_NAME : nom du nouveau clone de disque régional.
  • CLONED_REGION : région des disques source et cloné.
  • SOURCE_DISK_NAME : nom du disque zonal à cloner.
  • SOURCE_DISK_ZONE : zone du disque source. Il s'agira également de la première zone d'instance répliquée pour le clone de disque régional.
  • REPLICA_ZONE_2 : deuxième zone d'instance répliquée du nouveau clone de disque régional.
  • PROJECT_ID : ID de projet dans lequel cloner le disque.
  • IOPS_LIMIT : (facultatif) Pour créer un disque Hyperdisk Balanced High Availability régional, vous pouvez spécifier le nombre d'IOPS que le disque peut gérer, jusqu'à 100 000 IOPS.
  • THROUGHPUT_LIMIT : (facultatif) pour créer un disque Hyperdisk Balanced à haute disponibilité régional, vous pouvez spécifier le débit maximal en Mio/s que le disque peut fournir, jusqu'à 2 400 Mio/s.

Terraform

Pour créer un clone de disque régional à partir d'un disque zonal, utilisez la ressource suivante. Si le disque source est un volume Hyperdisk Balanced ou Hyperdisk Extreme, définissez l'argument type sur 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"]
}

Pour savoir comment appliquer ou supprimer une configuration Terraform, consultez Commandes Terraform de base.

Go

Go

Avant d'essayer cet exemple, suivez les instructions de configuration pour Go décrites dans le Guide de démarrage rapide de Compute Engine à l'aide des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Go Compute Engine.

Pour vous authentifier auprès de Compute Engine, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour les bibliothèques clientes.

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

Avant d'essayer cet exemple, suivez les instructions de configuration pour Java décrites dans le Guide de démarrage rapide de Compute Engine à l'aide des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Java Compute Engine.

Pour vous authentifier auprès de Compute Engine, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour les bibliothèques clientes.


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

Avant d'essayer cet exemple, suivez les instructions de configuration pour Python décrites dans le Guide de démarrage rapide de Compute Engine à l'aide des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Python Compute Engine.

Pour vous authentifier auprès de Compute Engine, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour les bibliothèques clientes.

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

Pour créer un clone de disque régional à partir d'un disque zonal, envoyez une requête POST à la méthode compute.disks.insert et spécifiez les paramètres sourceDisk et replicaZone.

Si le disque zonal est un volume Hyperdisk Balanced ou Hyperdisk Extreme, incluez le champ type pour créer un volume Hyperdisk Balanced à haute disponibilité.

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

Remplacez les éléments suivants :

  • PROJECT_ID : ID de projet dans lequel cloner le disque.
  • TARGET_DISK_NAME : nom du nouveau clone de disque régional.
  • CLONED_REGION : région des disques source et cloné.
  • SOURCE_DISK_NAME : nom du disque zonal à cloner.
  • SOURCE_DISK_ZONE : zone du disque source. Il s'agira également de la première zone d'instance répliquée pour le clone de disque régional.
  • REPLICA_ZONE_2 : deuxième zone d'instance répliquée du nouveau clone de disque régional.
  • IOPS_LIMIT : (facultatif) Pour créer un disque Hyperdisk Balanced High Availability régional, vous pouvez spécifier le nombre d'IOPS que le disque peut gérer, jusqu'à 100 000 IOPS.
  • THROUGHPUT_LIMIT : (facultatif) pour créer un disque Hyperdisk Balanced à haute disponibilité régional, vous pouvez spécifier le débit maximal en Mio/s que le disque peut fournir, jusqu'à 2 400 Mio/s.

Créer un clone de disque à partir d'un disque source chiffré par CMEK ou CSEK

Pour créer un clone zonal ou régional d'un disque chiffré avec une clé CSEK ou CMEK, suivez les procédures décrites dans les sections précédentes. Toutefois, vous devez également fournir la clé utilisée pour chiffrer le disque source.

Créer des clones de disques chiffrés par CSEK

Si vous utilisez une clé CSEK pour chiffrer votre disque source, vous devez également utiliser la même clé pour chiffrer le clone.

Console

  1. Dans la console Google Cloud , accédez à la page Disques.

    Accéder à la page Disques

  2. Dans la liste des disques persistants zonaux, identifiez le disque que vous souhaitez cloner.

  3. Dans la colonne Actions, cliquez sur le bouton de menu , puis sélectionnez Cloner le disque.

    Créer un clone

    Dans le panneau Cloner le disque qui s'affiche, procédez comme suit :

    1. Dans le champ Nom, spécifiez un nom pour le disque cloné.
    2. Dans le champ Déchiffrement et chiffrement, indiquez la clé de chiffrement du disque source.
    3. Sous Propriétés, vérifiez les autres détails du disque cloné.
    4. Pour terminer la création du disque cloné, cliquez sur Créer.

gcloud

Pour créer un clone de disque pour un disque source chiffré par CSEK, exécutez la commande gcloud compute disks create et fournissez la clé de chiffrement du disque source à l'aide de l'option --csek-key-file. Si vous utilisez une clé encapsulée en RSA, exécutez la commande 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

Remplacez les éléments suivants :

  • TARGET_DISK_NAME : nom du nouveau disque.
  • PROJECT_ID : ID de projet dans lequel cloner le disque.
  • ZONE : zone de la source et du nouveau disque.
  • SOURCE_DISK_NAME : nom du disque source.

Go

Go

Avant d'essayer cet exemple, suivez les instructions de configuration pour Go décrites dans le Guide de démarrage rapide de Compute Engine à l'aide des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Go Compute Engine.

Pour vous authentifier auprès de Compute Engine, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour les bibliothèques clientes.

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

Avant d'essayer cet exemple, suivez les instructions de configuration pour Java décrites dans le Guide de démarrage rapide de Compute Engine à l'aide des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Java Compute Engine.

Pour vous authentifier auprès de Compute Engine, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour les bibliothèques clientes.


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

Avant d'essayer cet exemple, suivez les instructions de configuration pour Python décrites dans le Guide de démarrage rapide de Compute Engine à l'aide des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Python Compute Engine.

Pour vous authentifier auprès de Compute Engine, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour les bibliothèques clientes.

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

Pour créer un clone de disque pour un disque source chiffré par CSEK, effectuez une requête POST à la méthode compute.disks.insert et fournissez la clé de chiffrement du disque source à l'aide de la propriété diskEncryptionKey. Si vous utilisez une clé encapsulée en RSA, utilisez la version beta de la méthode.

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

Remplacez les éléments suivants :

  • PROJECT_ID : ID de projet dans lequel cloner le disque.
  • ZONE : zone de la source et du nouveau disque.
  • TARGET_DISK_NAME : nom du nouveau disque.
  • SOURCE_DISK_NAME : nom du disque source.

Créer des clones de disques chiffrés par CMEK

Si vous utilisez une clé CMEK pour chiffrer votre disque source, vous devez également utiliser la même clé pour chiffrer le clone.

Console

Compute Engine chiffre automatiquement le clone à l'aide de la clé de chiffrement du disque source.

gcloud

Pour créer un clone de disque pour un disque source chiffré par CMEK, exécutez la commande gcloud compute disks create et fournissez la clé de chiffrement du disque source à l'aide de l'option --kms-key. Si vous utilisez une clé encapsulée en RSA, exécutez la commande 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

Remplacez les éléments suivants :

  • TARGET_DISK_NAME : nom du nouveau disque.
  • PROJECT_ID : ID de projet dans lequel cloner le disque.
  • ZONE : zone de la source et du nouveau disque.
  • SOURCE_DISK_NAME : nom du disque source.
  • KMS_PROJECT_ID : ID du projet pour la clé de chiffrement.
  • REGION : région de la clé de chiffrement.
  • KEY_RING : trousseau de clés de la clé de chiffrement.
  • KEY : nom de la clé de chiffrement.

Go

Go

Avant d'essayer cet exemple, suivez les instructions de configuration pour Go décrites dans le Guide de démarrage rapide de Compute Engine à l'aide des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Go Compute Engine.

Pour vous authentifier auprès de Compute Engine, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour les bibliothèques clientes.

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

Avant d'essayer cet exemple, suivez les instructions de configuration pour Java décrites dans le Guide de démarrage rapide de Compute Engine à l'aide des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Java Compute Engine.

Pour vous authentifier auprès de Compute Engine, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour les bibliothèques clientes.


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

Avant d'essayer cet exemple, suivez les instructions de configuration pour Python décrites dans le Guide de démarrage rapide de Compute Engine à l'aide des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API Python Compute Engine.

Pour vous authentifier auprès de Compute Engine, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour les bibliothèques clientes.

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

Pour créer un clone de disque pour un disque source chiffré par CSEK, effectuez une requête POST à la méthode compute.disks.insert et fournissez la clé de chiffrement du disque source à l'aide de la propriété kmsKeyName. Si vous utilisez une clé encapsulée en RSA, utilisez la version beta de la méthode.

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

Remplacez les éléments suivants :

  • PROJECT_ID : ID de projet dans lequel cloner le disque.
  • ZONE : zone de la source et du nouveau disque.
  • TARGET_DISK_NAME : nom du nouveau disque.
  • SOURCE_DISK_NAME : nom du disque source.
  • KMS_PROJECT_ID : ID du projet pour la clé de chiffrement.
  • REGION : région de la clé de chiffrement.
  • KEY_RING : trousseau de clés de la clé de chiffrement.
  • KEY : nom de la clé de chiffrement.

Étape suivante