使用快照备份数据

本页面介绍如何通过创建快照来备份存储在 Vertex AI Workbench 用户管理的笔记本实例上的数据。

实例上的数据存储在可用区级永久性磁盘中。您可以创建并使用此磁盘的快照来备份数据,创建周期性备份计划,以及将数据恢复到新实例。

创建快照

即使磁盘已挂接到了正在运行的实例上,您也可以为这些磁盘创建快照。快照是全球性资源,因此您可以使用快照将数据恢复到同一项目内的新磁盘或实例。您还可以在多个项目之间共享快照

控制台

  1. 在 Google Cloud 控制台中,转到虚拟机实例页面。

    进入“虚拟机实例”
    其余步骤将自动显示在 Google Cloud 控制台中。

  2. 选择包含您的虚拟机实例的项目。
  3. 名称列中,点击拥有要备份的永久性磁盘的虚拟机的名称。
  4. 存储部分:
    • 若要备份启动磁盘,请在启动磁盘部分点击启动磁盘的名称
    • 若要备份挂接的永久性磁盘,请在额外磁盘部分点击挂接的永久性磁盘的名称
  5. 点击创建快照
  6. 名称中,输入一个唯一的名称以帮助标识快照的用途,例如:
    • boot-disk-snapshot
    • attached-persistent-disk-snapshot
  7. 类型中,默认值为常规快照,最适合长期备份和灾难恢复。

    选择归档快照,实现更经济高效的数据保留。

  8. 位置部分,选择快照存储位置。系统会自动选择快照设置中定义的预定义或自定义默认位置。(可选)您可以通过执行以下操作来替换快照设置并将快照存储在自定义存储位置:

    1. 选择快照的存储位置类型。

      • 选择多区域,该选项以更高的费用实现更高的可用性。
      • 选择区域级快照,该选项使您能够更好地控制数据的实际位置,并且费用也会更低。
    2. 选择位置字段中,选择要使用的具体区域或多区域。如需使用最靠近源磁盘的区域或多区域,请选择基于磁盘的位置

  9. 如需创建手动快照,请点击创建

gcloud

  1. 在 Google Cloud 控制台中,激活 Cloud Shell。

    激活 Cloud Shell

    Cloud Shell 会话随即会在 Google Cloud 控制台的底部启动,并显示命令行提示符。Cloud Shell 是一个已安装 Google Cloud CLI 且已为当前项目设置值的 Shell 环境。该会话可能需要几秒钟时间来完成初始化。

  2. 使用快照设置定义的存储位置政策或使用您选择的其他存储位置创建快照。如需了解详情,请参阅选择快照存储位置。 您必须指定快照名称。名称的长度必须为 1-63 个字符,并且符合 RFC 1035 的要求。

    • 如需在快照设置中配置的预定义或自定义默认位置创建 Persistent Disk 卷的快照,请使用 gcloud compute snapshots create 命令

      gcloud compute snapshots create SNAPSHOT_NAME \
          --source-disk SOURCE_DISK \
          --snapshot-type SNAPSHOT_TYPE \
          --source-disk-zone SOURCE_DISK_ZONE
      

    • 或者,如需替换快照设置并在自定义存储位置创建快照,请添加 --storage-location 标志以指定快照的存储位置:

      gcloud compute snapshots create SNAPSHOT_NAME \
        --source-disk SOURCE_DISK \
        --source-disk-zone SOURCE_DISK_ZONE \
        --storage-location STORAGE_LOCATION \
        --snapshot-type SNAPSHOT_TYPE

      替换以下内容:

      • SNAPSHOT_NAME:快照的名称。
      • SOURCE_DISK:可用区级永久性磁盘卷的名称,您将根据它创建快照。
      • SNAPSHOT_TYPE:快照类型:STANDARDARCHIVE。如果未指定快照类型,系统会创建 STANDARD 快照。 选择归档,实现更经济高效的数据保留。
      • SOURCE_DISK_ZONE:可用区级永久性磁盘卷的可用区,您将根据该卷创建快照。

      只有在您想要替换在快照设置中配置的预定义或自定义默认存储位置时,才应使用 --storage-location 标志。

    gcloud CLI 会等待操作返回 READYFAILED 状态,或达到超时时间上限并返回快照的最后已知详情。

Terraform

如需创建可用区永久性磁盘的快照,请使用 google_compute_snapshot 资源。

resource "google_compute_snapshot" "snapdisk" {
  name        = "snapshot-name"
  source_disk = google_compute_disk.default.name
  zone        = "us-central1-a"
}

如需了解如何应用或移除 Terraform 配置,请参阅基本 Terraform 命令

API

使用快照设置定义的存储位置政策或使用您选择的其他存储位置创建快照。如需了解详情,请参阅选择快照存储位置

  • 如需在快照设置中配置的预定义或自定义默认位置创建快照,请向 snapshots.insert 方法发出 POST 请求:

    POST http://compute.googleapis.com/compute/v1/projects/DESTINATION_PROJECT_ID/global/snapshots
    
    {
      "name": SNAPSHOT_NAME
      "sourceDisk": "projects/SOURCE_PROJECT_ID/zones/SOURCE_ZONE/disks/SOURCE_DISK_NAME
      "snapshotType": SNAPSHOT_TYPE
    }
    

    替换以下内容:

    • DESTINATION_PROJECT_ID:您要在其中创建快照的项目的 ID。
    • SNAPSHOT_NAME:快照的名称。
    • SOURCE_PROJECT_ID:来源磁盘项目的 ID。
    • SOURCE_ZONE:来源磁盘的可用区。
    • SOURCE_DISK_NAME:要从中创建快照的永久性磁盘的名称。
    • SNAPSHOT_TYPE:快照类型:STANDARDARCHIVE。如果未指定快照类型,系统会创建 STANDARD 快照。
  • 或者,如需替换快照设置并在自定义存储位置创建快照,请向 snapshots.insert 方法发出 POST 请求,并在请求中添加 storageLocations 属性:

    POST http://compute.googleapis.com/compute/v1/projects/DESTINATION_PROJECT_ID/global/snapshots
    
    {
      "name": SNAPSHOT_NAME
      "sourceDisk": "projects/SOURCE_PROJECT_ID/zones/SOURCE_ZONE/disks/SOURCE_DISK_NAME
      "snapshotType": SNAPSHOT_TYPE
      "storageLocations": STORAGE_LOCATION
    }
    

    替换以下内容:

    • DESTINATION_PROJECT_ID:您要在其中创建快照的项目的 ID。
    • SNAPSHOT_NAME:快照的名称。
    • SOURCE_PROJECT_ID:来源磁盘项目的 ID。
    • SOURCE_ZONE:来源磁盘的可用区。
    • SOURCE_DISK_NAME:要从中创建快照的永久性磁盘的名称。
    • SNAPSHOT_TYPE:快照类型:STANDARDARCHIVE。如果未指定快照类型,系统会创建 STANDARD 快照。
    • STORAGE_LOCATION:您要存储快照的 Cloud Storage 多区域Cloud Storage 区域。请注意,您只能指定一个存储位置。

      仅当您想要替换快照设置中配置的预定义或自定义默认存储位置时,才应使用 storageLocations 参数。

Go

Go

试用此示例之前,请按照 Compute Engine 快速入门:使用客户端库中的设置说明进行操作。

如需向 Compute Engine 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证

import (
	"context"
	"fmt"
	"io"

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

// createSnapshot creates a snapshot of a disk.
func createSnapshot(
	w io.Writer,
	projectID, diskName, snapshotName, zone, region, location, diskProjectID string,
) error {
	// projectID := "your_project_id"
	// diskName := "your_disk_name"
	// snapshotName := "your_snapshot_name"
	// zone := "europe-central2-b"
	// region := "eupore-central2"
	// location = "eupore-central2"
	// diskProjectID = "YOUR_DISK_PROJECT_ID"

	ctx := context.Background()

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

	if zone == "" && region == "" {
		return fmt.Errorf("you need to specify `zone` or `region` for this function to work")
	}

	if zone != "" && region != "" {
		return fmt.Errorf("you can't set both `zone` and `region` parameters")
	}

	if diskProjectID == "" {
		diskProjectID = projectID
	}

	disk := &computepb.Disk{}
	locations := []string{}
	if location != "" {
		locations = append(locations, location)
	}

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

		getDiskReq := &computepb.GetDiskRequest{
			Project: projectID,
			Zone:    zone,
			Disk:    diskName,
		}

		disk, err = disksClient.Get(ctx, getDiskReq)
		if err != nil {
			return fmt.Errorf("unable to get disk: %w", err)
		}
	} else {
		regionDisksClient, err := compute.NewRegionDisksRESTClient(ctx)
		if err != nil {
			return fmt.Errorf("NewRegionDisksRESTClient: %w", err)
		}
		defer regionDisksClient.Close()

		getDiskReq := &computepb.GetRegionDiskRequest{
			Project: projectID,
			Region:  region,
			Disk:    diskName,
		}

		disk, err = regionDisksClient.Get(ctx, getDiskReq)
		if err != nil {
			return fmt.Errorf("unable to get disk: %w", err)
		}
	}

	req := &computepb.InsertSnapshotRequest{
		Project: projectID,
		SnapshotResource: &computepb.Snapshot{
			Name:             proto.String(snapshotName),
			SourceDisk:       proto.String(disk.GetSelfLink()),
			StorageLocations: locations,
		},
	}

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

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

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

	return nil
}

Java

Java

试用此示例之前,请按照 Compute Engine 快速入门:使用客户端库中的设置说明进行操作。

如需向 Compute Engine 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证


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.RegionDisksClient;
import com.google.cloud.compute.v1.Snapshot;
import com.google.cloud.compute.v1.SnapshotsClient;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateSnapshot {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // You need to pass `zone` or `region` parameter relevant to the disk you want to
    // snapshot, but not both. Pass `zone` parameter for zonal disks and `region` for
    // regional disks.

    // Project ID or project number of the Cloud project you want to use.
    String projectId = "YOUR_PROJECT_ID";

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

    // Name of the snapshot that you want to create.
    String snapshotName = "YOUR_SNAPSHOT_NAME";

    // The zone of the source disk from which you create the snapshot (for zonal disks).
    String zone = "europe-central2-b";

    // The region of the source disk from which you create the snapshot (for regional disks).
    String region = "your-disk-region";

    // The Cloud Storage multi-region or the Cloud Storage region where you
    // want to store your snapshot.
    // You can specify only one storage location. Available locations:
    // http://cloud.go888ogle.com.fqhub.com/storage/docs/locations#available-locations
    String location = "europe-central2";

    // Project ID or project number of the Cloud project that
    // hosts the disk you want to snapshot. If not provided, the value will be defaulted
    // to 'projectId' value.
    String diskProjectId = "YOUR_DISK_PROJECT_ID";

    createSnapshot(projectId, diskName, snapshotName, zone, region, location, diskProjectId);
  }

  // Creates a snapshot of a disk.
  public static void createSnapshot(String projectId, String diskName, String snapshotName,
      String zone, String region, String location, String diskProjectId)
      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 `snapshotsClient.close()` method on the client to safely
    // clean up any remaining background resources.
    try (SnapshotsClient snapshotsClient = SnapshotsClient.create()) {

      if (zone.isEmpty() && region.isEmpty()) {
        throw new Error("You need to specify 'zone' or 'region' for this function to work");
      }

      if (!zone.isEmpty() && !region.isEmpty()) {
        throw new Error("You can't set both 'zone' and 'region' parameters");
      }

      // If Disk's project id is not specified, then the projectId parameter will be used.
      if (diskProjectId.isEmpty()) {
        diskProjectId = projectId;
      }

      // If zone is not empty, use the DisksClient to create a disk.
      // Else, use the RegionDisksClient.
      Disk disk;
      if (!zone.isEmpty()) {
        DisksClient disksClient = DisksClient.create();
        disk = disksClient.get(projectId, zone, diskName);
      } else {
        RegionDisksClient regionDisksClient = RegionDisksClient.create();
        disk = regionDisksClient.get(diskProjectId, region, diskName);
      }

      // Set the snapshot properties.
      Snapshot snapshotResource;
      if (!location.isEmpty()) {
        snapshotResource = Snapshot.newBuilder()
            .setName(snapshotName)
            .setSourceDisk(disk.getSelfLink())
            .addStorageLocations(location)
            .build();
      } else {
        snapshotResource = Snapshot.newBuilder()
            .setName(snapshotName)
            .setSourceDisk(disk.getSelfLink())
            .build();
      }

      // Wait for the operation to complete.
      Operation operation = snapshotsClient.insertAsync(projectId, snapshotResource)
          .get(3, TimeUnit.MINUTES);

      if (operation.hasError()) {
        System.out.println("Snapshot creation failed!" + operation);
        return;
      }

      // Retrieve the created snapshot.
      Snapshot snapshot = snapshotsClient.get(projectId, snapshotName);
      System.out.printf("Snapshot created: %s", snapshot.getName());

    }
  }
}

Node.js

Node.js

试用此示例之前,请按照 Compute Engine 快速入门:使用客户端库中的设置说明进行操作。

如需向 Compute Engine 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const diskName = 'YOUR_DISK_NAME';
// const snapshotName = 'YOUR_SNAPSHOT_NAME';
// const zone = 'europe-central2-b';
// const region = '';
// const location = 'europe-central2';
// let diskProjectId = 'YOUR_DISK_PROJECT_ID';

const compute = require('@google-cloud/compute');

async function createSnapshot() {
  const snapshotsClient = new compute.SnapshotsClient();

  let disk;

  if (!zone && !region) {
    throw new Error(
      'You need to specify `zone` or `region` for this function to work.'
    );
  }

  if (zone && region) {
    throw new Error("You can't set both `zone` and `region` parameters");
  }

  if (!diskProjectId) {
    diskProjectId = projectId;
  }

  if (zone) {
    const disksClient = new compute.DisksClient();
    [disk] = await disksClient.get({
      project: diskProjectId,
      zone,
      disk: diskName,
    });
  } else {
    const regionDisksClient = new compute.RegionDisksClient();
    [disk] = await regionDisksClient.get({
      project: diskProjectId,
      region,
      disk: diskName,
    });
  }

  const snapshotResource = {
    name: snapshotName,
    sourceDisk: disk.selfLink,
  };

  if (location) {
    snapshotResource.storageLocations = [location];
  }

  const [response] = await snapshotsClient.insert({
    project: projectId,
    snapshotResource,
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.GlobalOperationsClient();

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

  console.log('Snapshot created.');
}

createSnapshot();

Python

Python

试用此示例之前,请按照 Compute Engine 快速入门:使用客户端库中的设置说明进行操作。

如需向 Compute Engine 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证

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_snapshot(
    project_id: str,
    disk_name: str,
    snapshot_name: str,
    *,
    zone: str | None = None,
    region: str | None = None,
    location: str | None = None,
    disk_project_id: str | None = None,
) -> compute_v1.Snapshot:
    """
    Create a snapshot of a disk.

    You need to pass `zone` or `region` parameter relevant to the disk you want to
    snapshot, but not both. Pass `zone` parameter for zonal disks and `region` for
    regional disks.

    Args:
        project_id: project ID or project number of the Cloud project you want
            to use to store the snapshot.
        disk_name: name of the disk you want to snapshot.
        snapshot_name: name of the snapshot to be created.
        zone: name of the zone in which is the disk you want to snapshot (for zonal disks).
        region: name of the region in which is the disk you want to snapshot (for regional disks).
        location: The Cloud Storage multi-region or the Cloud Storage region where you
            want to store your snapshot.
            You can specify only one storage location. Available locations:
            http://cloud.go888ogle.com.fqhub.com/storage/docs/locations#available-locations
        disk_project_id: project ID or project number of the Cloud project that
            hosts the disk you want to snapshot. If not provided, will look for
            the disk in the `project_id` project.

    Returns:
        The new snapshot instance.
    """
    if zone is None and region is None:
        raise RuntimeError(
            "You need to specify `zone` or `region` for this function to work."
        )
    if zone is not None and region is not None:
        raise RuntimeError("You can't set both `zone` and `region` parameters.")

    if disk_project_id is None:
        disk_project_id = project_id

    if zone is not None:
        disk_client = compute_v1.DisksClient()
        disk = disk_client.get(project=disk_project_id, zone=zone, disk=disk_name)
    else:
        regio_disk_client = compute_v1.RegionDisksClient()
        disk = regio_disk_client.get(
            project=disk_project_id, region=region, disk=disk_name
        )

    snapshot = compute_v1.Snapshot()
    snapshot.source_disk = disk.self_link
    snapshot.name = snapshot_name
    if location:
        snapshot.storage_locations = [location]

    snapshot_client = compute_v1.SnapshotsClient()
    operation = snapshot_client.insert(project=project_id, snapshot_resource=snapshot)

    wait_for_extended_operation(operation, "snapshot creation")

    return snapshot_client.get(project=project_id, snapshot=snapshot_name)

安排周期性备份

创建快照时间表时,您需要创建一项可应用于一个或多个永久性磁盘的资源政策。您可以通过以下方式创建快照时间表:

快照时间表包括以下属性:

  • 时间表名称
  • 时间表说明
  • 快照频率(每小时、每天、每周)
  • 快照开始时间
  • 快照时间表可用区域
  • 来源磁盘删除政策(用于在来源磁盘遭到删除后处理自动生成的快照)
  • 保留政策(用于定义保留快照时间表所产生快照的时间长短)

限制

  • 一个永久性磁盘一次最多可以挂接 10 个快照时间表。
  • 您无法使用快照时间表创建归档快照。
  • 您最多可以为每个区域创建 1000 个使用中的快照时间表。
  • 快照时间表仅适用于创建它们的项目。快照时间表不能在其他项目或组织中使用。
  • 如果您所在区域需要更多资源,则可能需要通过控制台申请增加资源配额
  • 如果快照时间表已挂接到磁盘,便无法被删除。您必须先从所有磁盘中分离时间表,然后才能删除时间表。
  • 您可以更新现有快照时间表,以更改说明、时间表和标签。如需更新快照时间表的其他值,您必须删除该快照时间表并创建新的快照时间表。
  • 对于使用客户提供的加密密钥 (CSEK) 的永久性磁盘,您无法创建快照时间表。
  • 对于使用客户管理的加密密钥 (CMEK) 的永久性磁盘,使用快照时间表创建的所有快照都将使用相同的密钥自动加密。

创建时间表

使用 Google Cloud 控制台、Google Cloud CLI 或 Compute Engine API 为永久性磁盘创建快照时间表。您必须在永久性磁盘所在的同一个区域中创建快照时间表。例如,如果您的永久性磁盘位于可用区 us-west1-a 中,则快照时间表必须位于 us-west1 区域中。如需了解详情,请参阅选择存储位置

控制台

  1. 在 Google Cloud 控制台中,转到虚拟机实例页面。

    进入“虚拟机实例”
    其余步骤将自动显示在 Google Cloud 控制台中。

  2. 选择包含您的虚拟机实例的项目。
  3. 名称列中,点击包含要为其创建快照时间表的永久性磁盘的虚拟机。
  4. 存储部分,点击要为其创建快照时间表的启动磁盘额外磁盘的名称。
  5. 点击 修改。您可能需要点击 更多操作菜单,然后再点击 修改
  6. 快照时间表中,选择创建时间表
  7. 名称中,为快照时间表输入以下名称之一:
    • boot-disk-snapshot-schedule
    • attached-persistent-disk-snapshot-schedule
  8. 位置部分,选择快照存储位置。系统会自动选择快照设置中定义的预定义或自定义默认位置。(可选)您可以通过执行以下操作来替换快照设置并将快照存储在自定义存储位置:

    1. 选择快照的存储位置类型。

      • 选择多区域,该选项以更高的费用实现更高的可用性。
      • 选择区域级快照,该选项使您能够更好地控制数据的实际位置,并且费用也会更低。
    2. 选择位置字段中,选择要使用的具体区域或多区域。如需使用最靠近源磁盘的区域或多区域,请选择基于磁盘的位置

  9. 如需完成快照时间表的创建,请点击创建
  10. 如需将此快照时间表挂接到永久性磁盘,请点击保存

gcloud

如需为永久性磁盘创建快照时间表,请使用 compute resource-policies create snapshot-schedule gcloud 命令。并将时间表频率设为每小时、每天或每周。

  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] \
      --weekly-schedule-from-file [FILE_NAME] \
      --on-source-disk-delete [DELETION_OPTION]

其中:

  • [SCHEDULE_NAME] 是新快照时间表的名称。
  • "[SCHEDULE_DESCRIPTION]" 是快照时间表的说明。请使用引号将您的说明括起来。
  • [MAX_RETENTION_DAYS] 是保留快照的天数。例如,设为 3 表示快照在删除之前会保留 3 天。您必须将保留政策设为至少 1 天。
  • [START_TIME] 为 UTC 开始时间。时间必须从整点开始。例如:
    • 太平洋标准时间下午 2 点为 22:00
    • 如果您将开始时间设置为 22:13,则会收到错误消息。
  • [SNAPSHOT_INTERVAL] 用于定义截取快照的时间间隔。请使用介于 1 到 23 的整数设置每小时时间表。同时,请选择一个可以整除 24 的小时数。 例如,将 --hourly-schedule 设置为 12 表示每 12 小时生成一次快照。对于每周时间表,请定义您要在哪一天截取快照,并务必写清楚是周几(不区分大小写)。hourly-scheduledaily-scheduleweekly-schedule 这三种快照频率标志是互斥的。您必须为快照时间表选择其中一个标志。

  • 如果您选择以这种格式提供每周快照时间表,则 [FILE_NAME] 是包含该时间表的文件的名称。 请注意,您可以使用文件来为每周时间表指定不同的星期几和不同的时间(但不能直接在命令行上指定多个每周时间表)。例如,您的文件为快照时间表指定了周一和周三:[{"day": "MONDAY", "startTime": "04:00"}, {"day": "WEDNESDAY", "startTime": "02:00"}],如果您在文件中添加开始时间,则无需设置 --start-time 标志。时间表使用 UTC 时间标准。

  • [DELETION_OPTION] 用于确定在来源磁盘遭到删除后系统对快照执行的操作。选择默认的 keep-auto-snapshots 可省略此标志,而使用 apply-retention-policy 则会应用保留政策。

下文介绍了设置快照时间表的其他示例。在下面的所有示例中:

  • 包含了磁盘删除规则;--on-source-disk-delete 标志设为默认值 keep-auto-snapshots,以永久保留所有自动生成的快照。另一种方法是将此标志设为 apply-retention-policy,以使用您的快照保留政策。
  • 存储位置设为 US,因此所有生成的快照将存储在 US 多区域中。
  • 向所有生成的快照应用了标签 env=devmedia=images
  • 保留政策设为 10 天。

每小时时间表:在此示例中,快照时间表的开始时间为世界协调时间 (UTC) 晚上 10 点,每 4 小时运行 1 次。

  gcloud compute resource-policies create snapshot-schedule SCHEDULE_NAME \
      --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

每日时间表:在此示例中,快照时间表的开始时间为世界协调时间 (UTC) 晚上 10 点,并在每天同一时间运行 1 次。--daily-schedule 标志必须存在,但不用设置任何值。

gcloud compute resource-policies create snapshot-schedule SCHEDULE_NAME \
    --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

每周时间表:在此示例中,快照时间表的开始时间为世界协调时间 (UTC) 晚上 10 点,并在每个星期二和星期四各运行 1 次。

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

API

在 API 中构建一个对 resourcePolicies.insertPOST 请求,以创建快照计划。您必须至少包括快照时间表名称、快照存储区域位置和快照频率。

默认情况下,onSourceDiskDelete 参数设置为 keepAutoSnapshots。这意味着,如果来源磁盘遭到删除,系统会无限期地保留为该磁盘自动生成的快照。此外,您也可以将该标志设为 applyRetentionPolicy,以应用您的保留政策。

在以下示例中,每日快照时间表的开始时间设为世界协调时间 (UTC) 中午 12 点,并每天重复。该示例还设置了 5 天的保留政策;5 天后,系统将自动移除快照。

您还可以在请求中包含快照存放区域选项快照标签,以确保快照会存储在您选择的位置。

POST http://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": ["US"]
   }
 }
}

其中:

  • [PROJECT_ID] 是项目名称。
  • [REGION] 是快照时间表资源政策的位置。
  • [SCHEDULE_DESCRIPTION] 是快照时间表的说明。
  • [SCHEDULE_NAME] 是快照时间表的名称。

同样,您也可以创建每周或每月时间表。请查看 API 参考,以了解有关设置每周或每月时间表的详细信息。

例如,以下请求将创建一个每个星期一的 9 点和星期四的 2 点运行的每周时间表。

POST http://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/[REGION]/resourcePolicies

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

将快照时间表挂接到磁盘

创建时间表后,您可以使用控制台、gcloud 命令或 Compute Engine API 方法将其挂接到现有磁盘。

控制台

将快照时间表挂接到现有磁盘。

  1. 在 Google Cloud 控制台中,转到磁盘页面。

    转到“磁盘”页面

  2. 选择要挂接快照时间表的磁盘的名称。此时会打开管理磁盘页面。
  3. 管理磁盘页面上,悬停鼠标,点击 更多操作菜单并选择 修改
  4. 使用快照时间表下拉菜单将时间表添加到对应磁盘,或者创建一个新的时间表。
  5. 如果您创建了新的时间表,请点击创建
  6. 点击保存,以完成该任务。

gcloud

如需将快照时间表挂接到磁盘,请使用 disks add-resource-policies gcloud 命令。

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

其中:

  • [DISK_NAME] 是现有磁盘的名称。
  • [SCHEDULE_NAME] 是快照时间表的名称。
  • [ZONE] 是磁盘的位置。

API

在 API 中,构建对 disks.addResourcePolicies 方法的 POST 请求,以将快照时间表挂接到现有磁盘。

POST http://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/disks/[DISK_NAME]/addResourcePolicies

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

其中:

  • [PROJECT_ID] 是项目名称。
  • [ZONE] 是磁盘的位置。
  • [REGION] 是快照时间表的区域。
  • [DISK_NAME] 是磁盘的名称。
  • [SCHEDULE_NAME] 是您要应用到此磁盘中的区域所含快照时间表的名称。

从快照恢复数据

如果您使用快照备份了启动磁盘或非启动磁盘,则可以根据该快照创建新磁盘。

限制

  • 新磁盘的大小至少应与快照最初的来源磁盘的大小相同。如果您创建的磁盘容量大于快照最初的来源磁盘,则必须调整该永久性磁盘上的文件系统大小才能添加额外的磁盘空间。您可能需要使用其他文件系统大小调整工具,具体取决于您的操作系统和文件系统类型。如需了解详情,请参阅操作系统文档。

根据快照创建磁盘并将其挂接到虚拟机

控制台

  1. 在 Google Cloud Console 中,转到快照页面。

    转到“快照”

  2. 找到要恢复的快照的名称。

  3. 转到磁盘页面。

    转到“磁盘”页面

  4. 点击创建新磁盘

  5. 指定以下配置参数:

    • 磁盘的名称。
    • 磁盘的类型。
    • (可选)您可以覆盖所选的默认区域和地区。 您可以选择任何区域和地区,无论来源快照存储在什么位置。
  6. 来源类型下方,点击快照

  7. 选择要恢复的快照的名称。

  8. 选择新磁盘的大小(以 GB 为单位)。此数字必须等于或大于快照最初的来源磁盘大小。

  9. 点击创建以创建磁盘。

您随后可以将新磁盘挂接到现有实例。

  1. 转到虚拟机实例页面。

    转到“虚拟机实例”页面

  2. 点击要在其中恢复非启动磁盘的实例的名称。
  3. 在实例详情页面顶部,点击修改
  4. 额外磁盘下,点击挂接现有磁盘
  5. 选择基于快照创建的新磁盘的名称。
  6. 点击完成以挂接磁盘。
  7. 在实例详情页面的底部,点击保存以将更改应用于实例。

gcloud

  1. 使用 gcloud compute snapshots list 命令找到要恢复的快照的名称:

    gcloud compute snapshots list
    
  2. 使用 gcloud compute snapshots describe 命令找到要恢复的快照的大小:

    gcloud compute snapshots describe SNAPSHOT_NAME
    

    SNAPSHOT_NAME 替换为要恢复的快照的名称。

  3. 使用gcloud compute disks create命令来创建一个新区域可用区磁盘。如果您需要使用 SSD 永久性磁盘来实现更高的吞吐量或 IOPS,请添加 --type 标志并指定 pd-ssd

    gcloud compute disks create DISK_NAME \
        --size=DISK_SIZE \
        --source-snapshot=SNAPSHOT_NAME \
        --type=DISK_TYPE
    

    请替换以下内容:

    • DISK_NAME:新磁盘的名称。
    • DISK_SIZE:新磁盘的大小(以 GB 为单位)。此数字必须等于或大于快照最初的来源磁盘大小。
    • SNAPSHOT_NAME:要恢复的快照的名称。
    • DISK_TYPE:磁盘类型的完整或部分网址。例如 http://www.googleapis.com/compute/v1/projects/PROJECT_ID /zones/ZONE/diskTypes/pd-ssd
  4. 使用 gcloud compute instances attach-disk 命令将新磁盘挂接到现有实例:

    gcloud compute instances attach-disk INSTANCE_NAME \
        --disk DISK_NAME
    

    请替换以下内容:

    • INSTANCE_NAME 是实例的名称。
    • DISK_NAME 是通过快照创建的磁盘的名称。

API

  1. 构建对 snapshots.listGET 请求,以在您的项目中显示快照列表。

    GET http://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/snapshots

    PROJECT_ID 替换为您的项目 ID。

  2. 使用 disks.insert 方法构建 POST 请求以创建可用区磁盘。请求应包含 namesizeGbtype 属性。如需使用快照恢复磁盘,您必须添加 sourceSnapshot 属性。

    POST http://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/disks
    
    {
     "name": "DISK_NAME",
     "sizeGb": "DISK_SIZE",
     "type": "zones/ZONE/diskTypes/DISK_TYPE"
     "sourceSnapshot": "SNAPSHOT_NAME"
    }
    

    请替换以下内容:

    • PROJECT_ID:您的项目 ID。
    • ZONE:您的实例和新磁盘所在的可用区。
    • DISK_NAME:新磁盘的名称。
    • DISK_SIZE:新磁盘的大小(以 GB 为单位)。此数字必须等于或大于快照最初的来源磁盘大小。
    • DISK_TYPE:磁盘类型的完整或部分网址。例如:http://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ ZONE/diskTypes/pd-ssd
    • SNAPSHOT_NAME:要恢复的磁盘的来源快照。
  3. 然后,您可以通过以下方法将新磁盘挂接到现有实例:构建一个对 instances.attachDisk 方法POST 请求,并添加您刚刚根据快照创建的可用区级磁盘的网址。

    POST http://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME/attachDisk
    
    {
     "source": "/compute/v1/projects/PROJECT_ID/zones/ZONE/disks/DISK_NAME"
    }
    

    请替换以下内容:

    • PROJECT_ID 是项目 ID。
    • ZONE 是您的实例和新磁盘所在的地区。
    • INSTANCE_NAME 是您要在其中添加新磁盘的实例名称。
    • DISK_NAME 是新磁盘的名称。

Go

Go

在尝试此示例之前,请按照《Vertex AI 快速入门:使用客户端库》中的 Go 设置说明执行操作。如需了解详情,请参阅 Vertex AI Go API 参考文档

如需向 Vertex AI 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证

import (
	"context"
	"fmt"
	"io"

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

// createDiskFromSnapshot creates a new disk in a project in given zone.
func createDiskFromSnapshot(
	w io.Writer,
	projectID, zone, diskName, diskType, snapshotLink 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"
	// snapshotLink := "projects/your_project_id/global/snapshots/snapshot_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),
			SourceSnapshot: proto.String(snapshotLink),
			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

在尝试此示例之前,请按照《Vertex AI 快速入门:使用客户端库》中的 Java 设置说明执行操作。如需了解详情,请参阅 Vertex AI Java API 参考文档

如需向 Vertex AI 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证


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 CreateDiskFromSnapshot {

  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 = "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.
    long diskSizeGb = 10;

    // The full path and name of the snapshot that you want to use as the source for the new disk.
    // This value uses the following format:
    // "projects/{projectName}/global/snapshots/{snapshotName}"
    String snapshotLink = String.format("projects/%s/global/snapshots/%s", projectId,
        "SNAPSHOT_NAME");

    createDiskFromSnapshot(projectId, zone, diskName, diskType, diskSizeGb, snapshotLink);
  }

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

      // Set the disk properties and the source snapshot.
      Disk disk = Disk.newBuilder()
          .setName(diskName)
          .setZone(zone)
          .setSizeGb(diskSizeGb)
          .setType(diskType)
          .setSourceSnapshot(snapshotLink)
          .build();

      // Create the insert disk request.
      InsertDiskRequest insertDiskRequest = InsertDiskRequest.newBuilder()
          .setProject(projectId)
          .setZone(zone)
          .setDiskResource(disk)
          .build();

      // Wait for the create disk operation to complete.
      Operation response = disksClient.insertAsync(insertDiskRequest)
          .get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        System.out.println("Disk creation failed!" + response);
        return;
      }
      System.out.println("Disk created. Operation Status: " + response.getStatus());
    }
  }
}

Node.js

Node.js

在尝试此示例之前,请按照《Vertex AI 快速入门:使用客户端库》中的 Node.js 设置说明执行操作。如需了解详情,请参阅 Vertex AI Node.js API 参考文档

如需向 Vertex AI 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const zone = 'europe-central2-b';
// const diskName = 'YOUR_DISK_NAME';
// const diskType = 'zones/us-west3-b/diskTypes/pd-ssd';
// const diskSizeGb = 10;
// const snapshotLink = 'projects/project_name/global/snapshots/snapshot_name';

const compute = require('@google-cloud/compute');

async function createDiskFromSnapshot() {
  const disksClient = new compute.DisksClient();

  const [response] = await disksClient.insert({
    project: projectId,
    zone,
    diskResource: {
      sizeGb: diskSizeGb,
      name: diskName,
      zone,
      type: diskType,
      sourceSnapshot: snapshotLink,
    },
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.ZoneOperationsClient();

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

  console.log('Disk created.');
}

createDiskFromSnapshot();

Python

Python

如需了解如何安装或更新 Python,请参阅安装 Python 版 Vertex AI SDK。 如需了解详情,请参阅 Python API 参考文档

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_snapshot(
    project_id: str,
    zone: str,
    disk_name: str,
    disk_type: str,
    disk_size_gb: int,
    snapshot_link: str,
) -> compute_v1.Disk:
    """
    Creates a new disk in a project in 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
        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 unattached Disk instance.
    """
    disk_client = compute_v1.DisksClient()
    disk = compute_v1.Disk()
    disk.zone = zone
    disk.size_gb = disk_size_gb
    disk.source_snapshot = snapshot_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)

装载磁盘

  1. 在终端中,使用 lsblk 命令列出挂接到实例的磁盘,并找到您要装载的磁盘。

    $ sudo lsblk
    
    NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    sda      8:0    0   10G  0 disk
    └─sda1   8:1    0   10G  0 part /
    sdb      8:16   0  250G  0 disk
    

    在本示例中,sdb 是新的空白永久性磁盘的设备名称。

  2. 使用 mount 工具将磁盘装载到实例,并启用 discard 选项:

    $ sudo mount -o discard,defaults /dev/DEVICE_NAME /home/jupyter
    

    请替换以下内容:

    • DEVICE_NAME:要装载的磁盘的设备名称。
  3. 配置对磁盘的读写权限。对于本示例,请为所有用户授予对磁盘的写入权限。

    $ sudo chmod a+w /home/jupyter
    

后续步骤