Crear programaciones de capturas de disco


Puedes crear una programación de capturas para hacer copias de seguridad de forma periódica y automática de los volúmenes de Persistent Disk y Google Cloud Hyperdisk de zona y regionales. Usa la programación de capturas como práctica recomendada para crear copias de seguridad de tus cargas de trabajo de Compute Engine.

Si quieres crear una programación de capturas que registre el estado de los datos de la aplicación en el momento de la copia de seguridad (también denominada captura coherente de aplicaciones, purgado de invitado o captura de VSS), consulta Crear capturas de disco coherentes de aplicaciones de Linux o Crear una captura de disco coherente de aplicaciones de Windows.

Para obtener más información sobre las propiedades de la programación de capturas, consulte Propiedades de la programación de capturas.

Antes de empezar

  • Consulta las limitaciones de las programaciones de instantáneas.
  • Si aún no lo has hecho, configura la autenticación. La autenticación verifica tu identidad para acceder a Google Cloud servicios y APIs. Para ejecutar código o ejemplos desde un entorno de desarrollo local, puedes autenticarte en Compute Engine seleccionando una de las siguientes opciones:

    Select the tab for how you plan to use the samples on this page:

    Console

    When you use the Google Cloud console to access Google Cloud services and APIs, you don't need to set up authentication.

    gcloud

    1. Instala Google Cloud CLI. Después de la instalación, inicializa la CLI de Google Cloud ejecutando el siguiente comando:

      gcloud init

      Si utilizas un proveedor de identidades (IdP) externo, primero debes iniciar sesión en la CLI de gcloud con tu identidad federada.

    2. Set a default region and zone.

    Go

    Para usar las Go muestras de esta página en un entorno de desarrollo local, instala e inicializa la CLI de gcloud y, a continuación, configura las credenciales predeterminadas de la aplicación con tus credenciales de usuario.

      Instala Google Cloud CLI.

      Si utilizas un proveedor de identidades (IdP) externo, primero debes iniciar sesión en la CLI de gcloud con tu identidad federada.

      If you're using a local shell, then create local authentication credentials for your user account:

      gcloud auth application-default login

      You don't need to do this if you're using Cloud Shell.

      If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.

    Para obtener más información, consulta Set up authentication for a local development environment.

    Java

    Para usar las Java muestras de esta página en un entorno de desarrollo local, instala e inicializa la CLI de gcloud y, a continuación, configura las credenciales predeterminadas de la aplicación con tus credenciales de usuario.

      Instala Google Cloud CLI.

      Si utilizas un proveedor de identidades (IdP) externo, primero debes iniciar sesión en la CLI de gcloud con tu identidad federada.

      If you're using a local shell, then create local authentication credentials for your user account:

      gcloud auth application-default login

      You don't need to do this if you're using Cloud Shell.

      If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.

    Para obtener más información, consulta Set up authentication for a local development environment.

    Node.js

    Para usar las Node.js muestras de esta página en un entorno de desarrollo local, instala e inicializa la CLI de gcloud y, a continuación, configura las credenciales predeterminadas de la aplicación con tus credenciales de usuario.

      Instala Google Cloud CLI.

      Si utilizas un proveedor de identidades (IdP) externo, primero debes iniciar sesión en la CLI de gcloud con tu identidad federada.

      If you're using a local shell, then create local authentication credentials for your user account:

      gcloud auth application-default login

      You don't need to do this if you're using Cloud Shell.

      If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.

    Para obtener más información, consulta Set up authentication for a local development environment.

    Python

    Para usar las Python muestras de esta página en un entorno de desarrollo local, instala e inicializa la CLI de gcloud y, a continuación, configura las credenciales predeterminadas de la aplicación con tus credenciales de usuario.

      Instala Google Cloud CLI.

      Si utilizas un proveedor de identidades (IdP) externo, primero debes iniciar sesión en la CLI de gcloud con tu identidad federada.

      If you're using a local shell, then create local authentication credentials for your user account:

      gcloud auth application-default login

      You don't need to do this if you're using Cloud Shell.

      If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.

    Para obtener más información, consulta Set up authentication for a local development environment.

    REST

    Para usar las muestras de la API REST de esta página en un entorno de desarrollo local, debes usar las credenciales que proporciones a la CLI de gcloud.

      Instala Google Cloud CLI.

      Si utilizas un proveedor de identidades (IdP) externo, primero debes iniciar sesión en la CLI de gcloud con tu identidad federada.

    Para obtener más información, consulta el artículo Autenticarse para usar REST de la documentación sobre autenticación de Google Cloud .

Roles y permisos necesarios

Para obtener los permisos que necesitas para crear una programación de capturas, pide a tu administrador que te conceda los siguientes roles de gestión de identidades y accesos en el proyecto:

Para obtener más información sobre cómo conceder roles, consulta el artículo Gestionar el acceso a proyectos, carpetas y organizaciones.

Estos roles predefinidos contienen los permisos necesarios para crear una programación de capturas. Para ver los permisos exactos que se necesitan, despliega la sección Permisos necesarios:

Permisos obligatorios

Para crear una programación de capturas, se necesitan los siguientes permisos:

  • Para crear una programación de capturas, sigue estos pasos: compute.resourcePolicies.create en el proyecto o la organización
  • Para adjuntar una programación de instantáneas a un disco, sigue estos pasos:
    • compute.disks.addResourcePolicies en el disco
    • compute.resourcePolicies.use en la política de recursos
  • Para crear un disco con una programación de capturas, sigue estos pasos:
    • compute.disks.create en el proyecto
    • compute.resourcePolicies.create en el proyecto
    • compute.disks.addResourcePolicies en el disco

También puedes obtener estos permisos con roles personalizados u otros roles predefinidos.

Descripción general de la creación de programaciones de capturas

Cuando creas una programación de instantáneas, creas una política de recursos que puedes aplicar a uno o varios volúmenes de Persistent Disk o Hyperdisk.

Puedes crear programaciones de capturas de las siguientes formas:

Usar el cifrado con programaciones de capturas

Si un disco usa una clave de cifrado gestionada por el cliente (CMEK), cuando uses una programación de capturas para crear capturas de ese disco, todas las capturas creadas se cifrarán automáticamente con la misma clave.

No puedes usar programaciones de capturas con discos que usen una clave de cifrado proporcionada por el cliente (CSEK).

Crear una programación de capturas

Puedes crear una programación de snapshots para tus discos mediante la Google Cloud consola, la interfaz de línea de comandos de Google Cloud o REST. Debes crear la programación de capturas en la misma región en la que se encuentre el disco. Por ejemplo, si tu disco está en la zona us-west1-a, debes crear la programación de capturas en la región us-west1. Sin embargo, puedes almacenar las capturas generadas por la programación de capturas en otra ubicación.

Consola

  1. En la consola de Google Cloud , ve a la página Instancias de VM.

    Ve a Instancias de VM.
    Los pasos restantes aparecerán automáticamente en la Google Cloud consola.

  2. Selecciona el proyecto que contiene tus instancias de VM.
  3. En la columna Nombre, haz clic en el nombre de la VM que tiene el disco persistente para el que quieres crear una programación de capturas.
  4. En Almacenamiento, haz clic en el nombre del disco de arranque o del disco adicional para crear una programación de instantáneas.
  5. Haz clic en Editar. Puede que tengas que hacer clic en el menú Más acciones y, a continuación, Editar.
  6. En Programación de capturas, elige Crear programación.
  7. En Nombre, introduce uno de los siguientes nombres para la programación de capturas:
    • boot-disk-snapshot-schedule
    • attached-persistent-disk-snapshot-schedule
  8. En la sección Ubicación, elige la ubicación de almacenamiento de tu instantánea. Se selecciona automáticamente la ubicación predefinida o personalizada que haya definido en la configuración de la vista general. Si quieres, puedes anular los ajustes de las instantáneas y almacenarlas en una ubicación de almacenamiento personalizada. Para ello, sigue estos pasos:

    1. Elige el tipo de ubicación de almacenamiento que quieras para tu copia.

    2. En el campo Seleccionar ubicación, elige la región o multirregión específica que quieras usar. Para usar la región o multirregión más cercana a tu disco de origen, selecciona Según la ubicación del disco.

  9. Para terminar de crear la programación de capturas, haz clic en Crear.
  10. Para adjuntar esta programación de instantáneas al disco persistente, haz clic en Guardar.

gcloud

  • Para programar snapshots con ámbito global de un disco, usa el comando gcloud compute resource-policies create snapshot-schedule. Define la frecuencia de la programación como horaria, diaria o semanal.

    gcloud compute resource-policies create snapshot-schedule SCHEDULE_NAME \
        --description "SCHEDULE_DESCRIPTION" \
        --max-retention-days MAX_RETENTION_DAYS \
        --start-time START_TIME \
        --hourly-schedule SNAPSHOT_INTERVAL \
        --daily-schedule \
        --weekly-schedule SNAPSHOT_INTERVAL or --weekly-schedule-from-file FILE_NAME \
        --on-source-disk-delete DELETION_OPTION \
        --storage-location=STORAGE_LOCATION
    
  • Vista previa: para programar instantáneas de ámbito regional de un disco, usa el comando gcloud compute resource-policies create snapshot-schedule y especifica la región de la instantánea.

    gcloud beta compute resource-policies create snapshot-schedule SCHEDULE_NAME \
        --description "SCHEDULE_DESCRIPTION" \
        --max-retention-days MAX_RETENTION_DAYS \
        --start-time START_TIME \
        --hourly-schedule SNAPSHOT_INTERVAL \
        --daily-schedule \
        --weekly-schedule SNAPSHOT_INTERVAL or --weekly-schedule-from-file FILE_NAME \
        --on-source-disk-delete DELETION_OPTION \
        --storage-location=STORAGE_LOCATION \
        --region REGION \
        --snapshot-region SNAPSHOT_REGION
    

Haz los cambios siguientes:

  • SCHEDULE_NAME: el nombre de la programación de la captura.
  • SCHEDULE_DESCRIPTION: una descripción de la programación de capturas. Escribe la descripción entre comillas.
  • REGION: la ubicación de la política de recursos de la programación de instantáneas.
  • SNAPSHOT_REGION: la región a la que se limita la instantánea programada.
  • MAX_RETENTION_DAYS: número de días que se conservará la instantánea.

    Por ejemplo, si el valor es 3, las capturas se conservarán durante 3 días antes de eliminarse. Debes usar un valor de 1 o superior.

  • START_TIME: hora de inicio en la zona horaria UTC. La hora debe empezar en punto.

    Por ejemplo:

    • Las 14:00 (PST) deben especificarse como 22:00.
    • Si defines una hora de inicio de 22:13, se produce un error.

    Si usas la marca --weekly-schedule-from-file y especificas una hora de inicio en el archivo, no es necesario que incluyas esta marca.

  • SNAPSHOT_INTERVAL: el intervalo entre la creación de capturas sucesivas. Las marcas de frecuencia de las instantáneas hourly-schedule, daily-schedule, weekly-schedule y weekly-schedule-from-file son mutuamente exclusivas. Solo puedes usar una para tu programación de capturas.

    • Configura una programación diaria incluyendo la marca --daily-schedule sin ningún valor.
    • Define una programación por horas con la marca --hourly-schedule establecida en un valor entero entre 1 y 23. Para generar las copias de seguridad a la misma hora todos los días, elige un número de horas que se divida entre 24 de forma uniforme. Por ejemplo, si se define --hourly-schedule como 12, se creará una instantánea cada 12 horas.
    • Define una programación semanal con la marca --weekly-schedule establecida en el día de la semana en el que quieras que se cree la captura. Debes escribir el día de la semana completo. Los valores no distinguen entre mayúsculas y minúsculas. Por ejemplo, para crear una copia de seguridad de tu disco todos los viernes, tu comando incluiría --weekly-schedule=friday.
    • Define una programación semanal avanzada, especificando diferentes días de la semana y con diferentes horas de inicio, incluyendo la marca --weekly-schedule-from-file. Sustituye FILE_NAME por el nombre del archivo que contiene la programación de la instantánea semanal. Aunque puedes especificar diferentes días de la semana y diferentes horas de inicio mediante un archivo, no puedes especificar varios horarios semanales directamente en la línea de comandos. Por ejemplo, puede que en el archivo se especifiquen dos programaciones semanales, una para el lunes y otra para el miércoles, pero no puedes duplicar este ajuste en la línea de comandos:

      [
        {"day": "MONDAY", "startTime": "04:00"},
        {"day": "WEDNESDAY", "startTime": "02:00"}
      ]
      

      Si incluye una hora de inicio en el archivo, no tiene que definir la marca --start-time en la línea de comandos. La programación usa la zona horaria UTC.

  • DELETION_OPTION: determina qué ocurre con tus instantáneas si se elimina el disco de origen. Si quieres conservar todas las capturas generadas, puedes omitir esta marca. De lo contrario, especifica apply-retention-policy para usar los ajustes de una política de conservación.

  • STORAGE_LOCATION: opcional: la ubicación de almacenamiento. Si omite esta marca, se usará la ubicación de almacenamiento predeterminada.

Ejemplos

En todos los ejemplos siguientes:

  • Se incluye la regla de eliminación de discos. La marca --on-source-disk-delete tiene el valor predeterminado keep-auto-snapshots para conservar de forma permanente todas las capturas generadas automáticamente. Otra opción es asignar el valor apply-retention-policy a esta marca para usar tu política de conservación de copias de seguridad.
  • La ubicación de almacenamiento se ha definido manualmente como US, por lo que todas las capturas generadas se almacenan en la multirregión de EE. UU.
  • Las etiquetas env=dev y media=images se aplican a todas las capturas generadas.
  • La política de conservación es de 10 días.

Programación por horas: en este ejemplo, la programación de capturas comienza a las 22:00 UTC (14:00 PST) y se realiza cada 4 horas.

  gcloud compute resource-policies create snapshot-schedule hourly-schedule1 \
      --description "MY HOURLY SNAPSHOT SCHEDULE" \
      --max-retention-days 10 \
      --start-time 22:00 \
      --hourly-schedule 4 \
      --region us-west1 \
      --on-source-disk-delete keep-auto-snapshots \
      --snapshot-labels env=dev,media=images \
      --storage-location US

Programación diaria: en este ejemplo, la programación de la instantánea empieza a las 22:00 UTC (14:00 PST) y se repite todos los días a la misma hora. La marca --daily-schedule debe estar presente, pero sin ningún valor asociado.

gcloud compute resource-policies create snapshot-schedule daily-schedule2 \
    --description "MY DAILY SNAPSHOT SCHEDULE" \
    --max-retention-days 10 \
    --start-time 22:00 \
    --daily-schedule \
    --region us-west1 \
    --on-source-disk-delete keep-auto-snapshots \
    --snapshot-labels env=dev,media=images \
    --storage-location US

Programación semanal: en este ejemplo, la programación de la instantánea empieza a las 22:00 UTC (14:00 PST) y se repite todos los martes.

gcloud compute resource-policies create snapshot-schedule weekly-schedule3 \
    --description "MY WEEKLY SNAPSHOT SCHEDULE" \
    --max-retention-days 10 \
    --start-time 22:00 \
    --weekly-schedule tuesday \
    --region us-west1 \
    --on-source-disk-delete keep-auto-snapshots \
    --snapshot-labels env=dev,media=images \
    --storage-location US

Go

import (
	"context"
	"fmt"
	"io"

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

// createSnapshotSchedule creates a snapshot schedule.
func createSnapshotSchedule(w io.Writer, projectID, scheduleName, region string) error {
	// projectID := "your_project_id"
	// snapshotName := "your_snapshot_name"
	// region := "eupore-central2"

	ctx := context.Background()

	snapshotsClient, err := compute.NewResourcePoliciesRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewResourcePoliciesRESTClient: %w", err)
	}
	defer snapshotsClient.Close()

	req := &computepb.InsertResourcePolicyRequest{
		Project: projectID,
		Region:  region,
		ResourcePolicyResource: &computepb.ResourcePolicy{
			Name:        proto.String(scheduleName),
			Description: proto.String("MY DAILY SNAPSHOT SCHEDULE"),
			Region:      proto.String("europe-central2"),
			SnapshotSchedulePolicy: &computepb.ResourcePolicySnapshotSchedulePolicy{
				RetentionPolicy: &computepb.ResourcePolicySnapshotSchedulePolicyRetentionPolicy{
					MaxRetentionDays: proto.Int32(10),
					// Check the OnSourceDiskDelete enum for the list of possible values.
					OnSourceDiskDelete: proto.String("KEEP_AUTO_SNAPSHOTS"),
				},
				Schedule: &computepb.ResourcePolicySnapshotSchedulePolicySchedule{
					DailySchedule: &computepb.ResourcePolicyDailyCycle{
						DaysInCycle: proto.Int32(1),
						StartTime:   proto.String("22:00"),
					},
				},
				SnapshotProperties: &computepb.ResourcePolicySnapshotSchedulePolicySnapshotProperties{
					StorageLocations: []string{"eu"},
					Labels: map[string]string{
						"env":   "dev",
						"media": "images",
					},
				},
			},
		},
	}
	op, err := snapshotsClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create snapshot schedule: %w", err)
	}

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

	fmt.Fprint(w, "Snapshot schedule created\n")

	return nil
}

Java

import com.google.cloud.compute.v1.InsertResourcePolicyRequest;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.Operation.Status;
import com.google.cloud.compute.v1.ResourcePoliciesClient;
import com.google.cloud.compute.v1.ResourcePolicy;
import com.google.cloud.compute.v1.ResourcePolicyHourlyCycle;
import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicy;
import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicyRetentionPolicy;
import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicyRetentionPolicy.OnSourceDiskDelete;
import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicySchedule;
import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicySnapshotProperties;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateSnapshotSchedule {
  public static void main(String[] args)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Cloud project you want to use.
    String projectId = "YOUR_PROJECT_ID";
    // Name of the region in which you want to create the snapshot schedule.
    String region = "us-central1";
    // Name of the snapshot schedule you want to create.
    String snapshotScheduleName = "YOUR_SCHEDULE_NAME";
    // Description of the snapshot schedule.
    String scheduleDescription = "YOUR_SCHEDULE_DESCRIPTION";
    // Maximum number of days to retain snapshots.
    int maxRetentionDays = 10;
    // Storage location for the snapshots.
    // More about storage locations:
    // https://cloud.google.com/compute/docs/disks/snapshots?authuser=0#selecting_a_storage_location
    String storageLocation = "US";

    createSnapshotSchedule(projectId, region, snapshotScheduleName, scheduleDescription,
            maxRetentionDays, storageLocation);
  }

  // Creates a snapshot schedule policy.
  public static Status createSnapshotSchedule(String projectId, String region,
            String snapshotScheduleName, String scheduleDescription, int maxRetentionDays,
            String storageLocation)
          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.
    try (ResourcePoliciesClient resourcePoliciesClient = ResourcePoliciesClient.create()) {
      int snapshotInterval = 10; // Create a snapshot every 10 hours
      String startTime = "08:00"; // Define the hourly schedule

      ResourcePolicyHourlyCycle hourlyCycle = ResourcePolicyHourlyCycle.newBuilder()
              .setHoursInCycle(snapshotInterval)
              .setStartTime(startTime)
              .build();

      ResourcePolicySnapshotSchedulePolicyRetentionPolicy retentionPolicy =
              ResourcePolicySnapshotSchedulePolicyRetentionPolicy.newBuilder()
                      .setMaxRetentionDays(maxRetentionDays)
                      .setOnSourceDiskDelete(OnSourceDiskDelete.KEEP_AUTO_SNAPSHOTS.toString())
              .build();

      ResourcePolicySnapshotSchedulePolicySnapshotProperties snapshotProperties =
              ResourcePolicySnapshotSchedulePolicySnapshotProperties.newBuilder()
                      .addStorageLocations(storageLocation)
                      .build();

      ResourcePolicySnapshotSchedulePolicy snapshotSchedulePolicy =
              ResourcePolicySnapshotSchedulePolicy.newBuilder()
                      .setRetentionPolicy(retentionPolicy)
                      .setSchedule(ResourcePolicySnapshotSchedulePolicySchedule.newBuilder()
                               .setHourlySchedule(hourlyCycle)
                               .build())
                      .setSnapshotProperties(snapshotProperties)
                      .build();

      ResourcePolicy resourcePolicy = ResourcePolicy.newBuilder()
              .setName(snapshotScheduleName)
              .setDescription(scheduleDescription)
              .setSnapshotSchedulePolicy(snapshotSchedulePolicy)
              .build();
      InsertResourcePolicyRequest request = InsertResourcePolicyRequest.newBuilder()
              .setProject(projectId)
              .setRegion(region)
              .setResourcePolicyResource(resourcePolicy)
              .build();

      Operation response = resourcePoliciesClient.insertAsync(request)
              .get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        throw new Error("Snapshot schedule creation failed! " + response.getError());
      }
      return response.getStatus();
    }
  }
}

Node.js

// Import the Compute library
const computeLib = require('@google-cloud/compute');
const compute = computeLib.protos.google.cloud.compute.v1;

// Instantiate a resourcePoliciesClient
const resourcePoliciesClient = new computeLib.ResourcePoliciesClient();
// Instantiate a regionOperationsClient
const regionOperationsClient = new computeLib.RegionOperationsClient();

/**
 * TODO(developer): Update/uncomment these variables before running the sample.
 */
// The project name.
const projectId = await resourcePoliciesClient.getProjectId();

// The location of the snapshot schedule resource policy.
// region = 'us-central1';

// The name of the snapshot schedule.
// snapshotScheduleName = 'snapshot-schedule-name';

// The description of the snapshot schedule.
const snapshotScheduleDescription = 'snapshot schedule description...';

async function callCreateSnapshotSchedule() {
  const [response] = await resourcePoliciesClient.insert({
    project: projectId,
    region,
    resourcePolicyResource: new compute.ResourcePolicy({
      name: snapshotScheduleName,
      description: snapshotScheduleDescription,
      snapshotSchedulePolicy:
        new compute.ResourcePolicyInstanceSchedulePolicySchedule({
          retentionPolicy:
            new compute.ResourcePolicySnapshotSchedulePolicyRetentionPolicy({
              maxRetentionDays: 5,
            }),
          schedule: new compute.ResourcePolicySnapshotSchedulePolicySchedule({
            // Similarly, you can create a weekly or monthly schedule.
            // Review the resourcePolicies.insert method for details specific to setting a weekly or monthly schedule.
            // To see more details, open: `https://cloud.google.com/compute/docs/disks/scheduled-snapshots?authuser=0#create_snapshot_schedule`
            dailySchedule: new compute.ResourcePolicyDailyCycle({
              startTime: '12:00',
              daysInCycle: 1,
            }),
          }),
          snapshotProperties:
            new compute.ResourcePolicySnapshotSchedulePolicySnapshotProperties(
              {
                guestFlush: false,
                labels: {
                  env: 'dev',
                  media: 'images',
                },
                // OPTIONAL: the storage location. If you omit this flag, the default storage location is used.
                // storageLocations: 'storage-location',
              }
            ),
        }),
    }),
  });

  let operation = response.latestResponse;

  // Wait for the create operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await regionOperationsClient.wait({
      operation: operation.name,
      project: projectId,
      region,
    });
  }

  console.log(`Snapshot schedule: ${snapshotScheduleName} created.`);
}

await callCreateSnapshotSchedule();

Python

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 snapshot_schedule_create(
    project_id: str,
    region: str,
    schedule_name: str,
    schedule_description: str,
    labels: dict,
) -> compute_v1.ResourcePolicy:
    """
    Creates a snapshot schedule for disks for a specified project and region.
    Args:
        project_id (str): The ID of the Google Cloud project.
        region (str): The region where the snapshot schedule will be created.
        schedule_name (str): The name of the snapshot schedule group.
        schedule_description (str): The description of the snapshot schedule group.
        labels (dict): The labels to apply to the snapshots. Example: {"env": "dev", "media": "images"}
    Returns:
        compute_v1.ResourcePolicy: The created resource policy.
    """

    # # Every hour, starts at 12:00 AM
    # hourly_schedule = compute_v1.ResourcePolicyHourlyCycle(
    #     hours_in_cycle=1, start_time="00:00"
    # )
    #
    # # Every Monday, starts between 12:00 AM and 1:00 AM
    # day = compute_v1.ResourcePolicyWeeklyCycleDayOfWeek(
    #     day="MONDAY", start_time="00:00"
    # )
    # weekly_schedule = compute_v1.ResourcePolicyWeeklyCycle(day_of_weeks=[day])

    # In this example we use daily_schedule - every day, starts between 12:00 AM and 1:00 AM
    daily_schedule = compute_v1.ResourcePolicyDailyCycle(
        days_in_cycle=1, start_time="00:00"
    )

    schedule = compute_v1.ResourcePolicySnapshotSchedulePolicySchedule()
    # You can change the schedule type to daily_schedule, weekly_schedule, or hourly_schedule
    schedule.daily_schedule = daily_schedule

    # Autodelete snapshots after 5 days
    retention_policy = compute_v1.ResourcePolicySnapshotSchedulePolicyRetentionPolicy(
        max_retention_days=5
    )
    snapshot_properties = (
        compute_v1.ResourcePolicySnapshotSchedulePolicySnapshotProperties(
            guest_flush=False, labels=labels
        )
    )

    snapshot_policy = compute_v1.ResourcePolicySnapshotSchedulePolicy()
    snapshot_policy.schedule = schedule
    snapshot_policy.retention_policy = retention_policy
    snapshot_policy.snapshot_properties = snapshot_properties

    resource_policy_resource = compute_v1.ResourcePolicy(
        name=schedule_name,
        description=schedule_description,
        snapshot_schedule_policy=snapshot_policy,
    )

    client = compute_v1.ResourcePoliciesClient()
    operation = client.insert(
        project=project_id,
        region=region,
        resource_policy_resource=resource_policy_resource,
    )
    wait_for_extended_operation(operation, "Resource Policy creation")

    return client.get(project=project_id, region=region, resource_policy=schedule_name)

REST

  • Para crear una programación de capturas de ámbito global, crea una solicitud POST a resourcePolicies.insert. Debes incluir el nombre de la programación de las copias y la frecuencia de las copias.

    También puedes especificar manualmente una ubicación de almacenamiento de la instantánea y añadir etiquetas de recursos a tu solicitud.

    De forma predeterminada, el parámetro onSourceDiskDelete tiene el valor keepAutoSnapshots. Esto significa que, si se elimina el disco de origen, la captura generada automáticamente de ese disco se conservará indefinidamente. También puedes definir la marca en applyRetentionPolicy para aplicar tu política de conservación.

    En el siguiente ejemplo se define una programación de creación de instantáneas diarias que empieza a las 12:00 (UTC) o a las 04:00 (PST) y se repite todos los días. En el ejemplo también se define una política de conservación de 5 días. Después de ese periodo, las capturas se eliminan automáticamente.

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION/resourcePolicies
    
        {
        "name": "SCHEDULE_NAME",
        "description": "SCHEDULE_DESCRIPTION",
        "snapshotSchedulePolicy": {
          "schedule": {
            "dailySchedule": {
              "startTime": "12:00",
              "daysInCycle": "1"
            }
          },
          "retentionPolicy": {
            "maxRetentionDays": "5"
          },
          "snapshotProperties": {
            "guestFlush": "False",
            "labels": {
              "env": "dev",
              "media": "images"
            },
            "storageLocations": "STORAGE_LOCATION"
          }
        }
        }
    
  • (Vista previa) Para crear una programación de capturas de ámbito regional, crea una solicitud POST a resourcePolicies.insert y especifica la región de la captura.

    POST https://compute.googleapis.com/compute/beta/projects/PROJECT_ID/regions/REGION/resourcePolicies
    
        {
        "name": "SCHEDULE_NAME",
        "description": "SCHEDULE_DESCRIPTION",
        "snapshotSchedulePolicy": {
          "schedule": {
            "dailySchedule": {
              "startTime": "12:00",
              "daysInCycle": "1"
            }
          },
          "retentionPolicy": {
            "maxRetentionDays": "5"
          },
          "snapshotProperties": {
            "guestFlush": "False",
            "region": "SNAPSHOT_REGION"
          }
        }
        }
    

Haz los cambios siguientes:

  • PROJECT_ID: nombre del proyecto
  • REGION: la ubicación de la política de recursos de la programación de instantáneas
  • SNAPSHOT_REGION: la región a la que se limita la instantánea programada
  • SCHEDULE_DESCRIPTION: la descripción de la programación de capturas
  • SCHEDULE_NAME: el nombre de la programación de capturas
  • STORAGE_LOCATION: opcional: la ubicación de almacenamiento. Si omite esta marca, se usará la ubicación de almacenamiento predeterminada.

Del mismo modo, puedes crear una programación semanal o mensual. Consulta el método resourcePolicies.insert para obtener información específica sobre cómo configurar una programación semanal o mensual.

Por ejemplo, la siguiente solicitud crea una programación semanal que se ejecuta los martes a las 9:00 UTC.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION/resourcePolicies

{
   "name": "SCHEDULE_NAME",
   "description": "SCHEDULE_DESCRIPTION",
   "snapshotSchedulePolicy": {
      "schedule": {
        "weeklySchedule": {
          "dayOfWeeks": [
          {
            "day": "Tuesday",
            "startTime": "9:00"
          }
          ]
        }
      },
      "retentionPolicy": {
          "maxRetentionDays": "5"
      },
      "snapshotProperties": {
          "guestFlush": "False",
          "labels": {
               "production": "webserver"
          },
          "storageLocations": "US"
      }
  }
}

Adjuntar una programación de capturas a un disco

Una vez que hayas creado una programación, adjúntala a un disco. Usa la consola, la CLI de gcloud o la API de Compute Engine.

Consola

Asocia una programación de instantáneas a un disco.

  1. En la Google Cloud consola, ve a la página Discos.

    Ir a Discos

  2. Selecciona el nombre del disco al que quieras adjuntar una programación de instantáneas. Se abrirá la página Gestionar disco.

  3. En la página Gestionar disco, haz clic en Editar. Puede que primero tengas que hacer clic en el menú Más acciones.

  4. Utilice el menú desplegable Programación de instantáneas para añadir la programación al disco. También puedes crear una nueva programación.

  5. Si has creado una programación, haz clic en Crear.

  6. Haz clic en Guardar para completar la tarea.

gcloud

Para adjuntar una programación de capturas a un disco, usa el comando gcloud disks add-resource-policies.

gcloud compute disks add-resource-policies DISK_NAME \
    --resource-policies SCHEDULE_NAME \
    --zone ZONE

Haz los cambios siguientes:

  • DISK_NAME: el nombre del disco disponible
  • SCHEDULE_NAME: el nombre de la programación de capturas
  • ZONE: la ubicación de tu disco

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
)

// attachSnapshotSchedule attaches a snapshot schedule to disk.
func attachSnapshotSchedule(w io.Writer, projectID, scheduleName, diskName, region string) error {
	// projectID := "your_project_id"
	// snapshotName := "your_snapshot_name"
	// diskName := "your_disk_name"
	// region := "europe-central2"

	ctx := context.Background()

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

	req := &computepb.AddResourcePoliciesRegionDiskRequest{
		Project: projectID,
		Region:  region,
		Disk:    diskName,
		RegionDisksAddResourcePoliciesRequestResource: &computepb.RegionDisksAddResourcePoliciesRequest{
			ResourcePolicies: []string{
				fmt.Sprintf("projects/%s/regions/%s/resourcePolicies/%s", projectID, region, scheduleName),
			},
		},
	}
	op, err := disksClient.AddResourcePolicies(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to attach schedule: %w", err)
	}

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

	fmt.Fprint(w, "Snapshot schedule attached\n")

	return nil
}

Java

import com.google.cloud.compute.v1.AddResourcePoliciesDiskRequest;
import com.google.cloud.compute.v1.DisksAddResourcePoliciesRequest;
import com.google.cloud.compute.v1.DisksClient;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.Operation.Status;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class AttachSnapshotScheduleToDisk {
  public static void main(String[] args) throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Cloud project you want to use.
    String projectId = "YOUR_PROJECT_ID";
    // Name of the zone where your disk is located.
    String zone = "us-central1-a";
    // Name of the disk you want to attach the snapshot schedule to.
    String diskName = "YOUR_DISK_NAME";
    // Name of the snapshot schedule you want to attach.
    String snapshotScheduleName = "YOUR_SNAPSHOT_SCHEDULE_NAME";
    // Name of the region where your snapshot schedule is located.
    String region = "us-central1";

    attachSnapshotScheduleToDisk(projectId, zone, diskName, snapshotScheduleName, region);
  }

  // Attaches a snapshot schedule to a disk.
  public static Status attachSnapshotScheduleToDisk(
        String projectId, String zone, String diskName, String snapshotScheduleName, String region)
        throws IOException, ExecutionException, InterruptedException, TimeoutException {

    String resourcePolicyLink = String.format(
            "projects/%s/regions/%s/resourcePolicies/%s", projectId, region, snapshotScheduleName);
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (DisksClient disksClient = DisksClient.create()) {

      AddResourcePoliciesDiskRequest request = AddResourcePoliciesDiskRequest.newBuilder()
              .setProject(projectId)
              .setZone(zone)
              .setDisk(diskName)
              .setDisksAddResourcePoliciesRequestResource(
                      DisksAddResourcePoliciesRequest.newBuilder()
                              .addResourcePolicies(resourcePolicyLink)
                              .build())
              .build();

      Operation response = disksClient.addResourcePoliciesAsync(request).get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        throw new Error("Error attaching snapshot schedule to disk: " + response.getError());
      }
      return response.getStatus();
    }
  }
}

Python

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 snapshot_schedule_attach(
    project_id: str, zone: str, region: str, disk_name: str, schedule_name: str
) -> None:
    """
    Attaches a snapshot schedule to a specified disk.
    Args:
        project_id (str): The ID of the Google Cloud project.
        zone (str): The zone where the disk is located.
        region (str): The region where the snapshot schedule was created
        disk_name (str): The name of the disk to which the snapshot schedule will be attached.
        schedule_name (str): The name of the snapshot schedule that you are applying to this disk
    Returns:
        None
    """
    disks_add_request = compute_v1.DisksAddResourcePoliciesRequest(
        resource_policies=[f"regions/{region}/resourcePolicies/{schedule_name}"]
    )

    client = compute_v1.DisksClient()
    operation = client.add_resource_policies(
        project=project_id,
        zone=zone,
        disk=disk_name,
        disks_add_resource_policies_request_resource=disks_add_request,
    )
    wait_for_extended_operation(operation, "Attaching snapshot schedule to disk")

REST

Crea una solicitud POST para disks.addResourcePolicies para adjuntar una programación de capturas a un disco.

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

{
  "resourcePolicies": [
    "regions/REGION/resourcePolicies/SCHEDULE_NAME"
  ]
}

Haz los cambios siguientes:

  • PROJECT_ID: nombre del proyecto
  • ZONE: la zona en la que se encuentra el disco
  • REGION: región en la que se creó la programación de capturas
  • DISK_NAME: el nombre del disco
  • SCHEDULE_NAME: el nombre de la programación de instantáneas que vas a aplicar a este disco

Crear un disco con una programación de capturas

Puedes usar la Google Cloud consola o la CLI de gcloud para crear un disco y una programación de instantáneas al mismo tiempo.

Consola

  1. En la Google Cloud consola, ve a la página Discos.

    Ir a Discos

  2. Haz clic en Crear disco.

  3. Rellena los campos obligatorios para crear un disco de zona o regional.

  4. Crea el disco en la misma región que la programación de capturas.

  5. Rellena los campos de la Programación de capturas.

  6. Usa el menú desplegable y completa los campos para crear la programación.

  7. Haz clic en Crear para crear la programación.

  8. Haz clic en Crear para crear el disco.

gcloud

Usa el comando gcloud disks create para crear un disco persistente o un hiperdisco de zona o regional, y vincularle una programación de capturas.

gcloud compute disks create DISK_NAME \
     --resource-policies SCHEDULE_NAME \
     --zone ZONE

Haz los cambios siguientes:

  • DISK_NAME: el nombre del nuevo disco
  • SCHEDULE_NAME: el nombre de la captura programada
  • ZONE: la ubicación en la que vas a crear el disco. El disco debe estar en una zona que se encuentre en la misma región que la programación de capturas.

Go

import (
	"context"
	"fmt"
	"io"

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

// createDiskWithSnapshotSchedule creates a new empty regional disk with snapshot schedule
func createDiskWithSnapshotSchedule(
	w io.Writer,
	projectID, region, diskName, diskType, scheduleName string,
	replicaZones []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"
	// scheduleName := "your_schedule_name"
	// replicaZones := []string{"us-west3-a", "us-west3-b"}
	// 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),
			SizeGb:       proto.Int64(diskSizeGb),
			ReplicaZones: replicaZoneURLs,
			ResourcePolicies: []string{
				fmt.Sprintf("projects/%s/regions/%s/resourcePolicies/%s", projectID, region, scheduleName),
			},
		},
	}

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

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

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

	return nil
}

Java

import com.google.cloud.compute.v1.Disk;
import com.google.cloud.compute.v1.DisksClient;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.Operation.Status;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateDiskWithSnapshotSchedule {
  public static void main(String[] args)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Cloud project you want to use.
    String projectId = "YOUR_PROJECT_ID";
    // Name of the zone in which you want to create the disk.
    String zone = "us-central1-a";
    // Name of the disk you want to create.
    String diskName = "YOUR_DISK_NAME";
    // Name of the schedule you want to link to the disk.
    String snapshotScheduleName = "YOUR_SCHEDULE_NAME";

    createDiskWithSnapshotSchedule(projectId, zone, diskName, snapshotScheduleName);
  }

  // Creates disk with linked snapshot schedule.
  public static Status createDiskWithSnapshotSchedule(
      String projectId, String zone, String diskName, String snapshotScheduleName)
      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.
    try (DisksClient disksClient = DisksClient.create()) {
      String region = zone.substring(0, zone.lastIndexOf('-'));
      // Get the resource policy to link to the disk
      String resourcePolicyLink = String.format("projects/%s/regions/%s/resourcePolicies/%s",
              projectId, region, snapshotScheduleName);

      Disk disk = Disk.newBuilder()
              .setName(diskName)
              .setZone(zone)
              .addAllResourcePolicies(List.of(resourcePolicyLink))
              .build();

      Operation response = disksClient.insertAsync(projectId, zone, disk).get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        throw new Error("Disk creation failed! " + response.getError());
      }
      return response.getStatus();
    }
  }
}

Siguientes pasos