创建共享预留


本文档介绍如何创建共享预留(在多个项目中共享的预留),以及如何管理组织中哪些项目可以使用共享预留。

托管预留的项目(所有者项目)和共享预留的项目(使用方项目)可以使用共享预留。如果您的组织有多个项目需要使用预留了相同属性的虚拟机 (VM) 实例,请使用共享预留。通过使用共享预留,您可以提高预留利用率,并减少需要创建和管理的预留数量。如需详细了解预留,请参阅 Compute Engine 可用区级资源的预留

如需了解创建预留的其他方法,请参阅以下页面:

  • 如果您在当前项目中具有任何 1 年期或 3 年期承诺,则您的预留资源会自动获得任何适用的承诺使用折扣 (CUD)。您还可以在购买承诺时创建预留并将其附加到该承诺。如需了解详情,请参阅将预留附加到承诺

  • 如需创建只能由单个项目使用的预留,请参阅为单个项目创建预留

准备工作

  • 查看预留的要求限制
  • 查看共享预留的 配额要求 限制条件
  • 确保您用于创建共享预留的项目已被组织策略管理员添加到共享预留所有者项目 (compute.sharedReservationsOwnerProjects) 组织政策限制条件的许可名单中。默认情况下,此许可名单为空,因此在您的组织向一个或多个项目授予此权限之前,您不能创建共享预留。如需详细了解如何查看和修改组织政策限制条件,请参阅本文档中的允许和限制项目创建和修改共享预留
  • 如果您尚未设置身份验证,请进行设置。身份验证是通过其进行身份验证以访问 Google Cloud 服务和 API 的过程。如需从本地开发环境运行代码或示例,您可以选择以下任一选项向 Compute Engine 进行身份验证:

    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. Install the Google Cloud CLI, then initialize it by running the following command:

      gcloud init
    2. Set a default region and zone.
    3. Terraform

      如需在本地开发环境中使用本页面上的 Terraform 示例,请安装并初始化 gcloud CLI,然后使用您的用户凭据设置应用默认凭据。

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. 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.

      如需了解详情,请参阅 Set up authentication for a local development environment

      Go

      如需在本地开发环境中使用本页面上的 Go 示例,请安装并初始化 gcloud CLI,然后使用您的用户凭据设置应用默认凭据。

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. 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.

      如需了解详情,请参阅 Set up authentication for a local development environment

      Java

      如需在本地开发环境中使用本页面上的 Java 示例,请安装并初始化 gcloud CLI,然后使用您的用户凭据设置应用默认凭据。

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. 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.

      如需了解详情,请参阅 Set up authentication for a local development environment

      Node.js

      如需在本地开发环境中使用本页面上的 Node.js 示例,请安装并初始化 gcloud CLI,然后使用您的用户凭据设置应用默认凭据。

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. 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.

      如需了解详情,请参阅 Set up authentication for a local development environment

      Python

      如需在本地开发环境中使用本页面上的 Python 示例,请安装并初始化 gcloud CLI,然后使用您的用户凭据设置应用默认凭据。

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. 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.

      如需了解详情,请参阅 Set up authentication for a local development environment

      REST

      如需在本地开发环境中使用本页面上的 REST API 示例,请使用您提供给 gcloud CLI 的凭据。

        Install the Google Cloud CLI, then initialize it by running the following command:

        gcloud init

      如需了解详情,请参阅 Google Cloud 身份验证文档中的使用 REST 时进行身份验证

所需的角色

如需获得创建共享预留所需的权限,请让您的管理员为您授予以下 IAM 角色:

如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限

这些预定义角色可提供创建共享预留所需的权限。如需查看所需的确切权限,请展开所需权限部分:

所需权限

必须拥有以下权限才能创建共享预留:

  • 针对项目的 compute.reservations.create 权限
  • 查看组织政策:针对组织的 orgpolicy.policy.get 权限
  • 修改组织政策:针对组织的 orgpolicy.policy.set 权限
  • 如需指定实例模板:实例模板的 compute.instanceTemplates.useReadOnly 权限

您也可以使用自定义角色或其他预定义角色来获取这些权限。

最佳做法

创建共享预留时,建议遵循以下最佳实践。通过遵循这些最佳实践,您可以帮助优化组织中共享预留的可管理性和利用率。

  • 让所有者项目创建共享预留但不使用它。
    • 如需在各项目之间分配支出,建议仅允许使用方项目使用共享预留。所有者项目应仅用于创建共享预留。
    • 创建共享预留时,所有者项目必须具有足够的配额,才能预留资源总量。然后,在创建预留后,所有者项目必须具有其想要使用的任何预留资源的配额。如需了解详情,请参阅 共享预留的其他配额要求
  • 尽量减少组织中允许创建共享预留的项目数量。您可以通过共享预留所有者项目 (compute.sharedReservationsOwnerProjects) 组织政策限制条件来控制这种情况。
    • 您只能列出每个项目创建的预留。这意味着共享预留仅在所有者项目中列出,您无法列出与每个项目共享的预留,也无法列出每个组织中的所有共享预留,因此仅拥有少量所有者项目可让您更轻松地监控和管理您的共享预订。
    • 将共享预留的共享限制给几个项目,以便更轻松地管理预留资源的配额。
    • 如需了解详情,请参阅允许和限制项目创建和修改共享预留
  • 最大限度地减少具有相同虚拟机属性的单独共享预留的数量。
    • 对于每个虚拟机属性的唯一组合,组织最多可以有 100 个共享预留。因此,最大限度地减少您创建的具有相同虚拟机属性的共享预留数量有助于缓解此限制。
    • 减少共享预留可提高可管理性。
  • 仅在使用相同 Cloud Billing 账号的项目之间共享预留。
    • 将每个共享预留限制为仅与所有者项目具有相同 Cloud Billing 账号的使用方项目共享。这样,您就可以更轻松地查看预留是否已被使用,并了解其结算方式。
    • 如果您启用了 CUD 共享,并且有资格在 Cloud Billing 账号级层接收 CUD,那么为了最大限度地提高为已使用的预留获得的 CUD,请将共享预留限制为该承诺的 Cloud Billing 账号。这样,您就可以在创建和使用共享预留的项目之间保持一致的结算方式。
  • 对于未来预留请求,请仔细查看您所请求的虚拟机总数。
    • 如果您要创建未来预留请求,请确保请求以下所有数量的虚拟机
      • 将在未来的日期存在的所有匹配的预留虚拟机。
      • 将在未来的日期存在的所有匹配的未预留虚拟机。
      • 将在未来的日期存在的任何匹配且未使用的按需预留。
      • 您希望在未来的日期额外预留的用量。

      例如,假设您需要在未来的日期额外增加 10 个虚拟机,并且那时已有以下资源:

      • 40 个匹配的预留虚拟机
      • 50 个匹配的未预留虚拟机

      • 40 个匹配的预留虚拟机
      • 50 个匹配且未使用的按需预留

      由于未来日期的现有用量已总共添加了 90 个匹配的虚拟机和预留,并且还需要 10 个额外的虚拟机,因此您必须在未来预留请求中指定总数 100

      如需了解详情,请参阅计算和预配预留资源

允许和限制项目创建和修改共享预留

默认情况下,不允许任何项目在组织中创建或修改共享预留。将项目添加到共享预留所有者项目 (compute.sharedReservationsOwnerProjects) 组织政策限制条件,以允许它们创建和修改共享预留。如需详细了解组织政策限制条件,请参阅组织政策服务简介

按照以下步骤查看和修改共享预留所有者项目 (compute.sharedReservationsOwnerProjects) 组织政策限制条件。

查看共享预留组织政策限制条件

如需查看允许哪些项目创建和修改共享预留,请使用 Google Cloud 控制台或 gcloud CLI。

控制台

按照使用共享预留所有者项目限制条件查看组织政策的步骤进行操作。

gcloud

如要查看 compute.sharedReservationsOwnerProjects 限制条件允许哪些项目创建和修改共享预留,请执行以下操作:

  1. 使用 gcloud resource-manager org-policies describe 命令下载组织的政策,并命名为 policy.yaml 文件:

    gcloud resource-manager org-policies describe compute.sharedReservationsOwnerProjects --organization=ORGANIZATION_ID > policy.yaml
    

    ORGANIZATION_ID 替换为您的组织的 ID

  2. 使用文本编辑器打开 policy.yaml 文件并查看 compute.sharedReservationsOwnerProjects 限制条件。允许创建和修改共享预留的项目列在其 allowedValues 下:

    ...
    constraint: constraints/compute.sharedReservationsOwnerProjects
    listPolicy:
      allowedValues:
      - projects/PROJECT_NUMBER_1
      - projects/PROJECT_NUMBER_2
      - projects/PROJECT_NUMBER_3
    ...
    

    其中,PROJECT_NUMBER_1PROJECT_NUMBER_2PROJECT_NUMBER_3 是您组织中唯一允许创建共享预留的项目的项目编号

  3. 可选:删除 policy.yaml 文件。

    • 如果您使用的是 Linux 或 macOS 终端,请使用以下命令:

      rm policy.yaml
      
    • 如果您使用的是 Windows 终端,请使用以下命令:

      del policy.yaml
      

修改共享预留组织政策限制条件

如需修改允许哪些项目创建和修改共享预留,请使用 Google Cloud 控制台或 gcloud CLI。

控制台

使用共享预留所有者项目限制条件,按照自定义列表限制条件政策的步骤操作。

gcloud

如需修改 compute.sharedReservationsOwnerProjects 限制条件允许创建和修改共享预留的项目,请使用以下某一方法:

  • 如需向单个项目授予权限以创建和修改共享预留,请使用 gcloud resource-manager org-policies allow 命令。您可以为要授予此权限的每个项目重复此命令。

    gcloud resource-manager org-policies allow compute.sharedReservationsOwnerProjects projects/PROJECT_NUMBER \
        --organization=ORGANIZATION_ID
    

    替换以下内容:

    • PROJECT_NUMBER:组织中您要允许其创建和修改共享预留的项目的编号(而非项目 ID)。
    • ORGANIZATION_ID:您的组织的 ID
  • 如需授予或撤消多个项目的权限以创建和修改共享预留,请替换组织政策限制条件:

    1. 如需将组织的政策下载为名为 policy.yaml 的文件,请使用 gcloud resource-manager org-policies describe 命令

      gcloud resource-manager org-policies describe compute.sharedReservationsOwnerProjects --organization=ORGANIZATION_ID > policy.yaml
      

      ORGANIZATION_ID 替换为您的组织的 ID

    2. 使用文本编辑器修改 policy.yaml 文件,以使 compute.sharedReservationsOwnerProjects 限制条件将您要允许其创建和修改共享预留的所有项目列在 allowedValues 下。

      • 对于要授予其创建和修改共享预留权限的每个项目,请在 allowedValues 下的新行中添加该项目。
      • 对于要撤消创建和修改共享预留权限的每个项目,请删除该项目的行。

      完成后,请确保 policy.yaml 文件类似于以下内容:

      ...
      constraint: constraints/compute.sharedReservationsOwnerProjects
      listPolicy:
        allowedValues:
        - projects/PROJECT_NUMBER_1
        - projects/PROJECT_NUMBER_2
        - projects/PROJECT_NUMBER_3
      ...
      

      其中,PROJECT_NUMBER_1PROJECT_NUMBER_2PROJECT_NUMBER_3 是组织中您要允许其创建和修改共享预留的所有项目的编号(而非项目 ID)。

    3. 保存 policy.yaml 文件并关闭文本编辑器。

    4. 如要使用您的更改更新组织的政策,请使用 gcloud resource-manager org-policies set-policy 命令

      gcloud resource-manager org-policies set-policy --organization=ORGANIZATION_ID policy.yaml
      

      ORGANIZATION_ID 替换为您的组织的 ID

    5. 可选:删除 policy.yaml 文件。

      • 如果您使用的是 Linux 或 macOS 终端,请使用以下命令:

        rm policy.yaml
        
      • 如果您使用的是 Windows 终端,请使用以下命令:

        del policy.yaml
        

您可能需要等待几分钟修改才能生效。

创建共享预留

本部分介绍如何创建共享预留。创建共享预留后,它只能由所有者项目修改,但共享预留的资源可以由所有者项目或任何使用方项目使用。

如需使用预留,虚拟机必须具有与该预留完全匹配的属性。如需指定要预留的虚拟机的属性,请选择本文档中的以下部分之一:

  • 推荐:指定实例模板

    本部分介绍如何使用实例模板定义共享预留的属性。通过使用实例模板,您可以在同一位置定义预留的属性和可以使用预留的虚拟机。但是,由于模板是特定于项目的,因此您无法使用同一模板创建可以在创建预留的项目之外使用预留的虚拟机。对于共享预留的项目,您必须在这些项目中创建类似的模板,或通过直接指定属性来创建虚拟机。

  • 指定现有虚拟机

    本部分介绍了如何使用现有虚拟机来定义预留的属性。通过使用现有虚拟机的属性,您可以通过创建其属性与参考虚拟机匹配的虚拟机来使用该预留。

  • 直接指定属性

    本部分介绍如何直接定义共享预留的属性。此方法要求您手动确保虚拟机和预留的属性完全匹配,任何不匹配的属性都会阻止使用

默认情况下,具有与预留相匹配的属性的虚拟机可以自动使用该预留。如果您想要控制预留的使用,请执行以下一项或多项操作:

指定实例模板

在通过指定实例模板创建预留之前,请确保以下各项:

  • 实例模板包含特定于项目的设置,因此您只能在同一项目中访问和使用实例模板。如果您通过指定实例模板创建共享预留,则不能使用相同的模板创建可以在创建预留的项目之外使用预留的虚拟机。

  • 在实例模板中的资源所在的区域和可用区中创建预留。在实例模板中指定的任何区域级资源可用区级资源(例如机器类型或永久性磁盘卷)会将模板的使用限制在存在这些资源的位置。例如,如果您的实例模板指定了可用区 us-central1-a 中的现有 Persistent Disk 卷,则您只能在同一可用区中创建预留。如需检查现有模板是否指定了任何将模板绑定到特定区域或可用区的资源,请查看实例模板的详细信息,并查找对其中的区域级资源或可用区级资源的引用。

如需通过指定实例模板来创建共享预留,请选择以下选项之一:

控制台

  1. 在 Google Cloud 控制台中,转到预留页面。

    转到“预留”

    随即会出现预留页面。

  2. 点击 创建预留

    此时会显示创建预留页面。

  3. 名称部分,输入预留的名称。

  4. 区域可用区部分,选择您要预留资源的位置。

  5. 共享类型部分,执行以下操作:

    1. 如需指定共享预留,请点击共享

    2. 点击 添加项目,然后从当前项目的组织中选择要共享预留的项目。 您最多可以选择 100 个使用方项目。

  6. 可选:如需允许 GPU 虚拟机的预留供 Vertex AI 中的自定义训练作业预测作业使用,请在 Google Cloud 服务部分中选择共享预留

  7. 搭配虚拟机实例使用部分中,选择以下选项之一:

    • 如需允许匹配的虚拟机实例自动使用此预留,请选择自动使用预留(如果尚未选择)。

    • 如需只有在创建通过名称明确指向此预留的匹配虚拟机时使用此预留的资源,请选择选择特定预留

  8. 虚拟机实例数量部分,输入要预留的虚拟机数量。

  9. 机器配置部分中,选择使用实例模板,然后选择所需的实例模板。如果您选择区域级实例模板,则只能在模板所在的区域内预留资源。

  10. 自动删除部分中,您可以启用自动删除选项,以便让 Compute Engine 在特定日期和时间自动删除预留。当您停止使用预留时,自动删除预留有助于避免产生不必要的费用。

  11. 要创建预留,请点击创建

    此时会打开预留页面。创建共享预留最长可能需要一分钟才能完成。

gcloud

如需创建共享预留,请将 gcloud compute reservations create 命令--share-setting=projects--share-with 标志结合使用。

如需通过指定实例模板而不添加任何可选标志来创建共享预留,请运行以下命令:

gcloud compute reservations create RESERVATION_NAME \
    --share-setting=projects \
    --share-with=CONSUMER_PROJECT_IDS \
    --source-instance-template=projects/PROJECT_ID/LOCATION/instanceTemplates/INSTANCE_TEMPLATE_NAME \
    --vm-count=NUMBER_OF_VMS \
    --zone=ZONE

替换以下内容:

  • RESERVATION_NAME:要创建的预留的名称。

  • PROJECT_ID:要在其中预留资源以及实例模板所在的项目的 ID。

  • CONSUMER_PROJECT_IDS:可以使用此预留的项目 ID 的英文逗号分隔列表,例如 project-1,project-2。您最多可以添加 100 个使用方项目。 这些项目必须与所有者项目位于同一组织中。请勿包含所有者项目。默认情况下,已允许使用该预留。

  • LOCATION:实例模板的位置。 请指定以下某个值:

    • 对于全球实例模板:global

    • 对于区域级实例模板:regions/REGION。 将 REGION 替换为实例模板所在的区域。如果您指定区域级实例模板,则只能预留与模板区域相同的区域内的虚拟机。

  • INSTANCE_TEMPLATE_NAME:现有实例模板的名称。如果实例模板指定了 A3 机器类型,则必须添加 --require-specific-reservation 标志。这表示只有明确指向预留的虚拟机才能使用它。如需了解详情,请参阅使用特定预留中的虚拟机

  • NUMBER_OF_VMS:要预留的虚拟机数量。

  • ZONE:预留资源的可用区。

例如,如需通过在可用区 us-central1-a 中指定全局实例模板来创建预留,请与项目 project-1project-2 共享预留,并预留 10 个虚拟机,每个虚拟机使用一个 N2 具有 4 个 vCPU 的预定义机器类型,请运行以下命令:

gcloud compute reservations create my-reservation \
    --share-setting=projects \
    --share-with=project-1,project-2 \
    --source-instance-template=projects/example-project/global/example-instance-template \
    --vm-count=10 \
    --zone=us-central1-a

您可以选择执行以下一项或多项操作:

  • 如需指定只有明确指向此预留的虚拟机才能使用它,请添加 --require-specific-reservation 标志。

    gcloud compute reservations create RESERVATION_NAME \
        --require-specific-reservation \
        --share-setting=projects \
        --share-with=CONSUMER_PROJECT_IDS \
        --source-instance-template=projects/PROJECT_ID/LOCATION/instanceTemplates/INSTANCE_TEMPLATE_NAME \
        --vm-count=NUMBER_OF_VMS \
        --zone=ZONE
    
  • 如需允许 GPU 虚拟机的预留供 Vertex AI 中的自定义训练作业预测作业使用,请将 gcloud beta compute reservations create 命令--reservation-sharing-policy=ALLOW_ALL 标志结合使用。

    gcloud beta compute reservations create RESERVATION_NAME \
        --reservation-sharing-policy=ALLOW_ALL \
        --share-setting=projects \
        --share-with=CONSUMER_PROJECT_IDS \
        --source-instance-template=projects/PROJECT_ID/LOCATION/instanceTemplates/INSTANCE_TEMPLATE_NAME \
        --vm-count=NUMBER_OF_VMS \
        --zone=ZONE
    
  • 如需让 Compute Engine 自动删除预留,请选择以下方法之一:

    • 如需在特定日期和时间删除预留,请使用带有 --delete-at-time 标志的 gcloud beta compute reservations create 命令

      gcloud beta compute reservations create RESERVATION_NAME \
          --delete-at-time=DELETE_AT_TIME \
          --share-setting=projects \
          --share-with=CONSUMER_PROJECT_IDS \
          --source-instance-template=projects/PROJECT_ID/LOCATION/instanceTemplates/INSTANCE_TEMPLATE_NAME \
          --vm-count=NUMBER_OF_VMS \
          --zone=ZONE
      

      DELETE_AT_TIME 替换为格式为 RFC 3339 时间戳(时间戳必须如下所示)的日期和时间:

      YYYY-MM-DDTHH:MM:SSOFFSET
      

      替换以下内容:

      • YYYY-MM-DD:格式为 4 位数年份、2 位数月份和 2 位数日期而且相互之间以连字符 (-) 分隔的日期。

      • HH:MM:SS:格式为 2 位数小时、2 位数分钟和 2 位数秒而且相互之间以冒号 (:) 分隔的采用 24 小时制的时间。

      • OFFSET:采用世界协调时间 (UTC) 的偏移量格式的时区。例如,要使用太平洋标准时间 (PST),请指定 -08:00。或者,如果不使用偏移量,请指定 Z

    • 如需在特定时间段后删除预留,请使用带有 --delete-after-duration 标志的 gcloud beta compute reservations create 命令

      gcloud beta compute reservations create RESERVATION_NAME \
          --delete-after-duration=DELETE_AFTER_DURATION \
          --share-setting=projects \
          --share-with=CONSUMER_PROJECT_IDS \
          --source-instance-template=projects/PROJECT_ID/LOCATION/instanceTemplates/INSTANCE_TEMPLATE_NAME \
          --vm-count=NUMBER_OF_VMS \
          --zone=ZONE
      

      DELETE_AFTER_DURATION 替换为以天、小时、分钟或秒为单位的时长。例如,指定 30m 表示 30 分钟,或指定 1d2h3m4s 表示 1 天 2 小时 3 分钟 4 秒。

Go

import (
	"context"
	"fmt"
	"io"

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

// Creates shared reservation from given template in particular zone
func createSharedReservation(w io.Writer, client ClientInterface, projectID, baseProjectId, zone, reservationName, sourceTemplate string) error {
	// client, err := compute.NewReservationsRESTClient(ctx)
	// projectID := "your_project_id". Destination of sharing.
	// baseProjectId := "your_project_id2". Project where the reservation will be created.
	// zone := "us-west3-a"
	// reservationName := "your_reservation_name"
	// sourceTemplate: existing template path. Following formats are allowed:
	//  	- projects/{project_id}/global/instanceTemplates/{template_name}
	//  	- projects/{project_id}/regions/{region}/instanceTemplates/{template_name}
	//  	- https://www.googleapis.com/compute/v1/projects/{project_id}/global/instanceTemplates/instanceTemplate
	//  	- https://www.googleapis.com/compute/v1/projects/{project_id}/regions/{region}/instanceTemplates/instanceTemplate

	ctx := context.Background()

	shareSettings := map[string]*computepb.ShareSettingsProjectConfig{
		projectID: {ProjectId: proto.String(projectID)},
	}

	req := &computepb.InsertReservationRequest{
		Project: baseProjectId,
		ReservationResource: &computepb.Reservation{
			Name: proto.String(reservationName),
			Zone: proto.String(zone),
			SpecificReservation: &computepb.AllocationSpecificSKUReservation{
				Count:                  proto.Int64(2),
				SourceInstanceTemplate: proto.String(sourceTemplate),
			},
			ShareSettings: &computepb.ShareSettings{
				ProjectMap: shareSettings,
				ShareType:  proto.String("SPECIFIC_PROJECTS"),
			},
		},
		Zone: zone,
	}

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

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

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

	return nil
}

Java

import com.google.cloud.compute.v1.AllocationSpecificSKUReservation;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.Reservation;
import com.google.cloud.compute.v1.ReservationsClient;
import com.google.cloud.compute.v1.ShareSettings;
import com.google.cloud.compute.v1.ShareSettingsProjectConfig;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateSharedReservation {
  private final ReservationsClient reservationsClient;

  // Constructor to inject the ReservationsClient
  public CreateSharedReservation(ReservationsClient reservationsClient) {
    this.reservationsClient = reservationsClient;
  }

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // The ID of the project where you want to reserve resources
    // and where the instance template exists.
    // By default, no projects are allowed to create or modify shared reservations
    // in an organization. Add projects to the Shared Reservations Owner Projects
    // (compute.sharedReservationsOwnerProjects) organization policy constraint
    // to allow them to create and modify shared reservations.
    // For more information visit this page:
    // https://cloud.google.com/compute/docs/instances/reservations-shared#shared_reservation_constraint
    String projectId = "YOUR_PROJECT_ID";
    // Zone in which the reservation resides.
    String zone = "us-central1-a";
    // Name of the reservation to be created.
    String reservationName = "YOUR_RESERVATION_NAME";
    // The URI of the global instance template to be used for creating the reservation.
    String instanceTemplateUri = String.format(
        "projects/%s/global/instanceTemplates/YOUR_INSTANCE_TEMPLATE_NAME", projectId);
    // Number of instances for which capacity needs to be reserved.
    int vmCount = 3;
    // In your main method, create ReservationsClient
    ReservationsClient client = ReservationsClient.create();
    // Create an instance of your class, passing in the client
    CreateSharedReservation creator = new CreateSharedReservation(client);

    creator.createSharedReservation(projectId, zone, reservationName, instanceTemplateUri, vmCount);
  }

  // Creates a shared reservation with the given name in the given zone.
  public void createSharedReservation(
      String projectId, String zone,
      String reservationName, String instanceTemplateUri, int vmCount)
      throws ExecutionException, InterruptedException, TimeoutException {

    ShareSettings shareSettings = ShareSettings.newBuilder()
        .setShareType(String.valueOf(ShareSettings.ShareType.SPECIFIC_PROJECTS))
        // The IDs of projects that can consume this reservation. You can include up to 100
        // consumer projects. These projects must be in the same organization as
        // the owner project. Don't include the owner project. By default, it is already allowed
        // to consume the reservation.
        .putProjectMap("CONSUMER_PROJECT_ID_1", ShareSettingsProjectConfig.newBuilder().build())
        .putProjectMap("CONSUMER_PROJECT_ID_2", ShareSettingsProjectConfig.newBuilder().build())
        .build();

    // Create the reservation.
    Reservation reservation =
        Reservation.newBuilder()
            .setName(reservationName)
            .setZone(zone)
            .setSpecificReservationRequired(true)
            .setShareSettings(shareSettings)
            .setSpecificReservation(
                AllocationSpecificSKUReservation.newBuilder()
                    .setCount(vmCount)
                    .setSourceInstanceTemplate(instanceTemplateUri)
                    .build())
            .build();

    // Wait for the create reservation operation to complete.
    Operation response =
        this.reservationsClient.insertAsync(projectId, zone, reservation).get(3, TimeUnit.MINUTES);

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

Node.js

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

/**
 * TODO(developer): Uncomment reservationsClient and zoneOperationsClient before running the sample.
 */
// Instantiate a reservationsClient
// reservationsClient = new computeLib.ReservationsClient();
// Instantiate a zoneOperationsClient
// zoneOperationsClient = new computeLib.ZoneOperationsClient();

/**
 * TODO(developer): Update these variables before running the sample.
 */
// The ID of the project where you want to reserve resources and where the instance template exists.
const projectId = await reservationsClient.getProjectId();
// The zone in which to reserve resources.
const zone = 'us-central1-a';
// The name of the reservation to create.
const reservationName = 'reservation-01';
// The number of VMs to reserve.
const vmsNumber = 3;
// The name of an existing instance template.
const instanceTemplateName = 'global-instance-template-name';
// The location of the instance template.
const location = 'global';

async function callCreateComputeSharedReservation() {
  // Create reservation for 3 VMs in zone us-central1-a by specifying a instance template.
  const specificReservation = new compute.AllocationSpecificSKUReservation({
    count: vmsNumber,
    sourceInstanceTemplate: `projects/${projectId}/${location}/instanceTemplates/${instanceTemplateName}`,
  });

  // Create share settings. Share reservation with one customer project.
  const shareSettings = new compute.ShareSettings({
    shareType: 'SPECIFIC_PROJECTS',
    projectMap: {
      // The IDs of projects that can consume this reservation. You can include up to 100 consumer projects.
      // These projects must be in the same organization as the owner project.
      // Don't include the owner project. By default, it is already allowed to consume the reservation.
      consumer_project_id: {
        projectId: 'consumer_project_id',
      },
    },
  });

  // Create a reservation.
  const reservation = new compute.Reservation({
    name: reservationName,
    specificReservation,
    specificReservationRequired: true,
    shareSettings,
  });

  const [response] = await reservationsClient.insert({
    project: projectId,
    reservationResource: reservation,
    zone,
  });

  let operation = response.latestResponse;

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

  console.log(`Reservation: ${reservationName} created.`);
  return response;
}

return await callCreateComputeSharedReservation();

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 create_compute_shared_reservation(
    project_id: str,
    zone: str = "us-central1-a",
    reservation_name="your-reservation-name",
    shared_project_id: str = "shared-project-id",
) -> compute_v1.Reservation:
    """Creates a compute reservation in GCP.
    Args:
        project_id (str): The ID of the Google Cloud project.
        zone (str): The zone to create the reservation.
        reservation_name (str): The name of the reservation to create.
        shared_project_id (str): The ID of the project that the reservation is shared with.
    Returns:
        Reservation object that represents the new reservation.
    """

    instance_properties = compute_v1.AllocationSpecificSKUAllocationReservedInstanceProperties(
        machine_type="n1-standard-1",
        # Optional. Specifies amount of local ssd to reserve with each instance.
        local_ssds=[
            compute_v1.AllocationSpecificSKUAllocationAllocatedInstancePropertiesReservedDisk(
                disk_size_gb=375, interface="NVME"
            ),
        ],
    )

    reservation = compute_v1.Reservation(
        name=reservation_name,
        specific_reservation=compute_v1.AllocationSpecificSKUReservation(
            count=3,  # Number of resources that are allocated.
            # If you use source_instance_template, you must exclude the instance_properties field.
            # It can be a full or partial URL.
            # source_instance_template="projects/[PROJECT_ID]/global/instanceTemplates/my-instance-template",
            instance_properties=instance_properties,
        ),
        share_settings=compute_v1.ShareSettings(
            share_type="SPECIFIC_PROJECTS",
            project_map={
                shared_project_id: compute_v1.ShareSettingsProjectConfig(
                    project_id=shared_project_id
                )
            },
        ),
    )

    # Create a client
    client = compute_v1.ReservationsClient()

    operation = client.insert(
        project=project_id,
        zone=zone,
        reservation_resource=reservation,
    )
    wait_for_extended_operation(operation, "Reservation creation")

    reservation = client.get(
        project=project_id, zone=zone, reservation=reservation_name
    )
    shared_project = next(iter(reservation.share_settings.project_map.values()))

    print("Name: ", reservation.name)
    print("STATUS: ", reservation.status)
    print("SHARED PROJECT: ", shared_project)
    # Example response:
    # Name:  your-reservation-name
    # STATUS:  READY
    # SHARED PROJECT:  project_id: "123456789012"

    return reservation

REST

如需创建共享预留,请向 reservations.insert 方法发出 POST 请求。 在请求正文中,添加以下各项:

  • projectMap 字段。

  • 设置为 SPECIFIC_PROJECTSshareType 字段。

例如,如需通过指定实例模板而不添加任何可选字段来创建共享预留,并与两个使用方项目共享预留,请发出以下 POST 请求:

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/reservations

{
  "name": "RESERVATION_NAME",
  "shareSettings": {
    "shareType": "SPECIFIC_PROJECTS",
    "projectMap": {
      "CONSUMER_PROJECT_ID_1": {
        "projectId": "CONSUMER_PROJECT_ID_1"
      },
      "CONSUMER_PROJECT_ID_2": {
        "projectId": "CONSUMER_PROJECT_ID_2"
      }
    }
  },
  "specificReservation": {
    "count": "NUMBER_OF_VMS",
    "sourceInstanceTemplate": "projects/PROJECT_ID/LOCATION/instanceTemplates/INSTANCE_TEMPLATE_NAME"
  }
}

替换以下内容:

  • PROJECT_ID:要在其中预留资源以及实例模板所在的项目的 ID。

  • ZONE:预留资源的可用区。

  • RESERVATION_NAME:要创建的预留的名称。

  • CONSUMER_PROJECT_ID_1CONSUMER_PROJECT_ID_2:可以使用此预留的项目 ID。您最多可以添加 100 个使用方项目。这些项目必须与所有者项目位于同一组织中。请勿包含所有者项目。默认情况下,已允许它使用该预留。

  • NUMBER_OF_VMS:要预留的虚拟机数量。

  • LOCATION:实例模板的位置。 请指定以下某个值:

    • 对于全球实例模板:global

    • 对于区域级实例模板:regions/REGION。 将 REGION 替换为实例模板所在的区域。如果您指定区域级实例模板,则只能预留与模板区域相同的区域内的虚拟机。

  • INSTANCE_TEMPLATE_NAME:现有实例模板的名称。如果实例模板指定了 A3 机器类型,则必须在请求正文中添加 specificReservationRequired 字段,并将该字段设置为 true。这表示只有明确指向此预留的虚拟机才能使用它。如需了解详情,请参阅使用特定预留中的虚拟机

例如,如需通过指定全局实例模板为可用区 us-central1-a 中的 10 个虚拟机创建预留,并与项目 project-1project-2 共享预留,请进行以下 POST 请求:

POST https://compute.googleapis.com/compute/v1/projects/example-project/zones/us-central1-a/reservations

{
  "name": "my-reservation",
  "shareSettings": {
    "shareType": "SPECIFIC_PROJECTS",
    "projectMap": {
      "project-1": {
        "projectId": "project-1"
      },
      "project-2": {
        "projectId": "project-2"
      }
    }
  },
  "specificReservation": {
    "count": "10",
    "sourceInstanceTemplate": "projects/example-project/global/instanceTemplates/example-instance-template"
  }
}

您可以选择执行以下一项或多项操作:

  • 如需指定只有明确指向此预留的虚拟机才能使用它,请在请求正文中添加 specificReservationRequired 字段,并将该字段设置为 true

    例如,如需通过指定实例模板来创建特定预留,并与两个使用方项目共享预留,请发出如下请求:

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/reservations
    
    {
      "name": "RESERVATION_NAME",
      "shareSettings": {
        "shareType": "SPECIFIC_PROJECTS",
        "projectMap": {
          "CONSUMER_PROJECT_ID_1": {
            "projectId": "CONSUMER_PROJECT_ID_1"
          },
          "CONSUMER_PROJECT_ID_2": {
            "projectId": "CONSUMER_PROJECT_ID_2"
          }
        }
      },
      "specificReservation": {
        "count": "NUMBER_OF_VMS",
        "sourceInstanceTemplate": "projects/PROJECT_ID/LOCATION/instanceTemplates/INSTANCE_TEMPLATE_NAME"
      },
      "specificReservationRequired": true
    }
    
  • 如需允许 GPU 虚拟机的预留供 Vertex AI 中的自定义训练作业预测作业使用,请向 beta.reservations.insert 方法发出 POST 请求。在请求正文中,添加 serviceShareType 字段并将其设置为 ALLOW_ALL

    POST https://compute.googleapis.com/compute/beta/projects/PROJECT_ID/zones/ZONE/reservations
    
    {
      "name": "RESERVATION_NAME",
      "reservationSharingPolicy": {
        "serviceShareType": "ALLOW_ALL"
      },
      "shareSettings": {
        "shareType": "SPECIFIC_PROJECTS",
        "projectMap": {
          "CONSUMER_PROJECT_ID_1": {
            "projectId": "CONSUMER_PROJECT_ID_1"
          },
          "CONSUMER_PROJECT_ID_2": {
            "projectId": "CONSUMER_PROJECT_ID_2"
          }
        }
      },
      "specificReservation": {
        "count": "NUMBER_OF_VMS",
        "sourceInstanceTemplate": "projects/PROJECT_ID/LOCATION/instanceTemplates/INSTANCE_TEMPLATE_NAME"
      }
    }
    
  • 如需让 Compute Engine 自动删除预留,请选择以下方法之一:

    • 如需在特定日期和时间删除预留,请向 beta.reservations.insert 方法发出 POST 请求。在请求正文中,包含 deleteAtTime 字段。

      例如,如需通过指定实例模板来创建预留、在特定日期和时间自动删除预留,并与两个使用方项目共享预留,请发出如下请求:

      POST https://compute.googleapis.com/compute/beta/projects/PROJECT_ID/zones/ZONE/reservations
      
      {
        "deleteAtTime": "DELETE_AT_TIME",
        "name": "RESERVATION_NAME",
        "shareSettings": {
          "shareType": "SPECIFIC_PROJECTS",
          "projectMap": {
            "CONSUMER_PROJECT_ID_1": {
              "projectId": "CONSUMER_PROJECT_ID_1"
            },
            "CONSUMER_PROJECT_ID_2": {
              "projectId": "CONSUMER_PROJECT_ID_2"
            }
          }
        },
        "specificReservation": {
          "count": "NUMBER_OF_VMS",
          "sourceInstanceTemplate": "projects/PROJECT_ID/LOCATION/instanceTemplates/INSTANCE_TEMPLATE_NAME"
        }
      }
      

      DELETE_AT_TIME 替换为格式为 RFC 3339 时间戳(时间戳必须如下所示)的日期和时间:

      YYYY-MM-DDTHH:MM:SSOFFSET
      

      替换以下内容:

      • YYYY-MM-DD:格式为 4 位数年份、2 位数月份和 2 位数日期而且相互之间以连字符 (-) 分隔的日期。

      • HH:MM:SS:格式为 2 位数小时、2 位数分钟和 2 位数秒而且相互之间以冒号 (:) 分隔的采用 24 小时制的时间。

      • OFFSET:采用世界协调时间 (UTC) 的偏移量格式的时区。例如,要使用太平洋标准时间 (PST),请指定 -08:00。或者,如果不使用偏移量,请指定 Z

    • 如需在特定时间段后删除预留,请向 beta.reservations.insert 方法发出 POST 请求。在请求正文中,包含 deleteAfterDuration 字段。

      例如,如需通过指定实例模板来创建预留、在特定时长后自动删除预留,并与两个使用方项目共享预留,请发出如下请求:

      POST https://compute.googleapis.com/compute/beta/projects/PROJECT_ID/zones/ZONE/reservations
      
      {
        "deleteAfterDuration": {
          "seconds": "DELETE_AFTER_DURATION"
        },
        "name": "RESERVATION_NAME",
        "shareSettings": {
          "shareType": "SPECIFIC_PROJECTS",
          "projectMap": {
            "CONSUMER_PROJECT_ID_1": {
              "projectId": "CONSUMER_PROJECT_ID_1"
            },
            "CONSUMER_PROJECT_ID_2": {
              "projectId": "CONSUMER_PROJECT_ID_2"
            }
          }
        },
        "specificReservation": {
          "count": "NUMBER_OF_VMS",
          "sourceInstanceTemplate": "projects/PROJECT_ID/LOCATION/instanceTemplates/INSTANCE_TEMPLATE_NAME"
        }
      }
      

      DELETE_AFTER_DURATION 替换为持续时间,以秒为单位。例如,指定 86400 标识 86400 秒(1 天)。

指定现有虚拟机

您只能根据现有虚拟机在与该虚拟机相同的项目和可用区中创建共享预留。

创建预留后,您可以通过创建其属性与参考虚拟机匹配的虚拟机来使用该预留。为此,您可以执行以下操作之一:

  • 请按如下方式创建和使用实例模板:

    1. 根据参考虚拟机创建实例模板,而无需替换参考虚拟机的属性。

    2. 执行以下一项或两项操作,使用新创建的模板创建虚拟机:

  • 创建一个其属性与参考虚拟机完全匹配的虚拟机,如下所示:

    • 在所有者项目中,根据参考虚拟机创建一个虚拟机,而无需更改您要创建的虚拟机的属性。

    • 在使用方项目中,创建虚拟机,同时手动确保其属性与参考虚拟机的属性匹配。

如需创建使用现有虚拟机的属性的共享预留,请执行以下操作:

  1. 在 Google Cloud 控制台中,转到预留页面。

    转到“预留”

  2. 按需预留标签页(默认)上,点击 创建预留

    此时会打开创建预留页面。

  3. 名称部分,输入预留的名称。

  4. 区域可用区部分,选择您要预留资源的位置。

  5. 共享类型部分,执行以下操作:

    1. 如需指定共享预留,请点击共享

    2. 点击 添加项目,然后从当前项目的组织中选择要共享预留的项目。您最多可以选择 100 个使用方项目。

  6. 搭配虚拟机实例使用部分中,选择以下选项之一:

    • 如需允许匹配的虚拟机自动使用此预留,请选择自动使用预留(如果尚未选择)。

    • 如需只有在创建通过名称明确指向此预留的匹配虚拟机时使用此预留的资源,请选择选择特定预留

  7. 虚拟机实例数量部分,输入要预留的虚拟机数量。

  8. 机器配置部分中,执行以下操作:

    1. 选择使用现有虚拟机

    2. 现有虚拟机部分,选择要使用其属性创建预留的虚拟机。

  9. 自动删除部分中,您可以启用自动删除选项,以便让 Compute Engine 在特定日期和时间自动删除预留。当您停止使用预留时,自动删除预留有助于避免产生不必要的费用。

  10. 要创建预留,请点击创建

    此时会打开预留页面。创建预留最长可能需要一分钟才能完成。

直接指定属性

如需通过直接指定属性来创建共享预留,请选择以下选项之一:

控制台

  1. 在 Google Cloud 控制台中,转到预留页面。

    转到“预留”

  2. 按需预留标签页(默认)上,点击 创建预留

  3. 点击 创建预留

    此时会显示创建预留页面。

  4. 名称部分,输入预留的名称。

  5. 区域可用区部分,选择您要预留资源的位置。

  6. 共享类型部分,执行以下操作:

    1. 如需指定共享预留,请点击共享

    2. 点击 添加项目,然后从当前项目的组织中选择要共享预留的项目。 您最多可以选择 100 个使用方项目。

  7. 可选:如需允许 GPU 虚拟机的预留供 Vertex AI 中的自定义训练作业预测作业使用,请在 Google Cloud 服务部分中选择共享预留

  8. 搭配虚拟机实例使用部分中,选择以下选项之一:

    • 如需允许匹配的虚拟机自动使用此预留,请选择自动使用预留(默认)。

    • 如需只有在创建通过名称明确指向此预留的匹配虚拟机时使用此预留的资源,请选择选择特定预留

  9. 虚拟机实例数量部分,输入要预留的虚拟机数量。

  10. 机器配置部分中,选择指定机器类型,然后指定以下内容:

    1. 机器家族系列机器类型部分,选择机器家族、系列和机器类型。

    2. 可选:如需指定满足最低要求的 CPU 平台或将 GPU 挂接到 N1 虚拟机,请执行以下操作:

      1. 如需展开 CPU 平台和 GPU 部分,请点击 展开箭头。

      2. 可选:如需指定满足最低要求的 CPU 平台,请在 CPU 平台中选择一个选项。

      3. 可选:如需将 GPU 附加到 N1 虚拟机,请点击 添加 GPU。然后,在 GPU 类型GPU 数量部分,选择要挂接到每个 N1 虚拟机的 GPU 的类型和数量。

    3. 可选:如需添加本地 SSD 磁盘,请执行以下操作:

      1. 磁盘数量部分,选择每个虚拟机的本地 SSD 磁盘数量。

      2. 接口类型部分,选择本地 SSD 磁盘的接口。

  11. 自动删除部分中,您可以启用自动删除选项,以让 Compute Engine 在特定日期和时间自动删除预留。当您停止使用预留时,自动删除预留有助于避免产生不必要的费用。

  12. 要创建预留,请点击创建

    此时会打开预留页面。创建共享预留最长可能需要一分钟的时间才能完成。

gcloud

如需创建共享预留,请将 gcloud compute reservations create 命令--share-setting=projects--share-with 标志结合使用。

如需通过直接指定属性而不添加任何可选标志来创建共享预留,请运行以下命令:

gcloud compute reservations create RESERVATION_NAME \
    --machine-type=MACHINE_TYPE \
    --share-setting=projects \
    --share-with=CONSUMER_PROJECT_IDS \
    --vm-count=NUMBER_OF_VMS \
    --zone=ZONE

替换以下内容:

  • RESERVATION_NAME:要创建的预留的名称。

  • MACHINE_TYPE:要用于每个虚拟机的机器类型。如果您指定 A3 机器类型,则必须添加 --require-specific-reservation 标志。这表示只有明确指向预留的虚拟机才能使用它。如需了解详情,请参阅使用特定预留中的虚拟机

  • CONSUMER_PROJECT_IDS:可以使用此预留的项目 ID 的英文逗号分隔列表,例如 project-1,project-2。您最多可以添加 100 个使用方项目。 这些项目必须与所有者项目位于同一组织中。请勿包含所有者项目。默认情况下,已允许它使用该预留。

  • NUMBER_OF_VMS:要预留的虚拟机数量。

  • ZONE:预留资源的可用区。

例如,如需在可用区 us-central1-a 中为 10 个虚拟机创建预留,每个虚拟机使用具有 4 个 vCPU 的 N2 预定义机器类型,并与项目 project-1project-2 共享预留,请运行以下命令:

gcloud compute reservations create my-reservation \
    --machine-type=n2-standard-4 \
    --share-setting=projects \
    --share-with=project-1,project-2 \
    --vm-count=10 \
    --zone=us-central1-a

您可以选择执行以下一项或多项操作:

  • 如需将 GPU 附加到预留的 N1 虚拟机,请添加 --accelerator 标志。

    gcloud compute reservations create RESERVATION_NAME \
        --accelerator=count=NUMBER_OF_ACCELERATORS,type=ACCELERATOR_TYPE
        --machine-type=MACHINE_TYPE \
        --share-setting=projects \
        --share-with=CONSUMER_PROJECT_IDS \
        --vm-count=NUMBER_OF_VMS \
        --zone=ZONE
    

    替换以下内容:

  • 如需向每个预留的虚拟机添加一个或多个本地 SSD 磁盘,请添加一个或多个 --local-ssd 标志。您最多可以指定 24 个本地 SSD 磁盘。每个本地 SSD 磁盘为 375 GB。

    例如,如需在创建共享预留时指定两个本地 SSD 磁盘,请添加两个 --local-ssd 标志,如下所示:

    gcloud compute reservations create RESERVATION_NAME \
        --local-ssd=size=375,interface=INTERFACE_1 \
        --local-ssd=size=375,interface=INTERFACE_2 \
        --machine-type=MACHINE_TYPE \
        --share-setting=projects \
        --share-with=CONSUMER_PROJECT_IDS \
        --vm-count=NUMBER_OF_VMS \
        --zone=ZONE
    

    INTERFACE_1INTERFACE_2 替换为您希望每个本地 SSD 磁盘使用的接口类型。请指定以下某个值:

    • NVME 磁盘接口:nvme

    • SCSI 磁盘接口:scsi

    确保您为已预留虚拟机指定的机器类型支持所选的磁盘接口。否则,创建预留将失败。 如需了解详情,请参阅如何选择磁盘接口

  • 如需让预留的虚拟机使用特定的满足最低要求的 CPU 平台(而不是该可用区的默认 CPU 平台),请添加 --min-cpu-platform 标志。

    gcloud compute reservations create RESERVATION_NAME \
        --machine-type=MACHINE_TYPE \
        --min-cpu-platform="MIN_CPU_PLATFORM" \
        --share-setting=projects \
        --share-with=CONSUMER_PROJECT_IDS \
        --vm-count=NUMBER_OF_VMS \
        --zone=ZONE
    

    MIN_CPU_PLATFORM 替换为满足最低要求的 CPU 平台。为确保 CPU 平台在要预留资源的可用区可用,请按可用区查看可用的 CPU 平台

  • 如需指定只有明确指向此预留的虚拟机才能使用它,请添加 --require-specific-reservation 标志。

    gcloud compute reservations create RESERVATION_NAME \
        --machine-type=MACHINE_TYPE \
        --require-specific-reservation \
        --share-setting=projects \
        --share-with=CONSUMER_PROJECT_IDS \
        --vm-count=NUMBER_OF_VMS \
        --zone=ZONE
    
  • 如需允许 GPU 虚拟机的预留供 Vertex AI 中的自定义训练作业预测作业使用,请将 gcloud beta compute reservations create 命令--reservation-sharing-policy=ALLOW_ALL 标志结合使用。

    gcloud beta compute reservations create RESERVATION_NAME \
        --machine-type=MACHINE_TYPE \
        --reservation-sharing-policy=ALLOW_ALL \
        --share-setting=projects \
        --share-with=CONSUMER_PROJECT_IDS \
        --vm-count=NUMBER_OF_VMS \
        --zone=ZONE
    
  • 如需让 Compute Engine 自动删除预留,请选择以下方法之一:

    • 如需在特定日期和时间删除预留,请使用带有 --delete-at-time 标志的 gcloud beta compute reservations create 命令

      gcloud beta compute reservations create RESERVATION_NAME \
          --delete-at-time=DELETE_AT_TIME \
          --machine-type=MACHINE_TYPE \
          --share-setting=projects \
          --share-with=CONSUMER_PROJECT_IDS \
          --vm-count=NUMBER_OF_VMS \
          --zone=ZONE
      

      DELETE_AT_TIME 替换为格式为 RFC 3339 时间戳(时间戳必须如下所示)的日期和时间:

      YYYY-MM-DDTHH:MM:SSOFFSET
      

      替换以下内容:

      • YYYY-MM-DD:格式为 4 位数年份、2 位数月份和 2 位数日期而且相互之间以连字符 (-) 分隔的日期。

      • HH:MM:SS:格式为 2 位数小时、2 位数分钟和 2 位数秒而且相互之间以冒号 (:) 分隔的采用 24 小时制的时间。

      • OFFSET:采用世界协调时间 (UTC) 的偏移量格式的时区。例如,要使用太平洋标准时间 (PST),请指定 -08:00。或者,如果不使用偏移量,请指定 Z

    • 如需在特定时间段后删除预留,请使用带有 --delete-after-duration 标志的 gcloud beta compute reservations create 命令

      gcloud beta compute reservations create RESERVATION_NAME \
          --delete-after-duration=DELETE_AFTER_DURATION \
          --machine-type=MACHINE_TYPE \
          --share-setting=projects \
          --share-with=CONSUMER_PROJECT_IDS \
          --vm-count=NUMBER_OF_VMS \
          --zone=ZONE
      

      DELETE_AFTER_DURATION 替换为以天、小时、分钟或秒为单位的时长。例如,指定 30m 表示 30 分钟,或指定 1d2h3m4s 表示 1 天 2 小时 3 分钟 4 秒。

Terraform

如需创建预留,请使用 google_compute_reservation Terraform 资源。如需指定共享预留,请定义 share_settings 块:

  • share_type 字段设置为 SPECIFIC_PROJECTS
  • project_map 块中,指定您要与之共享此预留的项目的 ID

如需详细了解如何使用 Terraform,请参阅将 Terraform 与 Google Cloud 搭配使用

REST

如需创建共享预留,请向 reservations.insert 方法发出 POST 请求。 在请求正文中,添加以下各项:

  • projectMap 字段。

  • 设置为 SPECIFIC_PROJECTSshareType 字段。

例如,如需在不添加任何可选字段的情况下创建共享预留并与两个使用方项目共享预留,请发出以下 POST 请求:

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/reservations

{
  "name": "RESERVATION_NAME",
  "shareSettings": {
    "shareType": "SPECIFIC_PROJECTS",
    "projectMap": {
      "CONSUMER_PROJECT_ID_1": {
        "projectId": "CONSUMER_PROJECT_ID_1"
      },
      "CONSUMER_PROJECT_ID_2": {
        "projectId": "CONSUMER_PROJECT_ID_2"
      }
    }
  },
  "specificReservation": {
    "count": "NUMBER_OF_VMS",
    "instanceProperties": {
      "machineType": "MACHINE_TYPE"
    }
  }
}

替换以下内容:

  • PROJECT_ID:您要在其中预留资源的项目的 ID。

  • ZONE:预留资源的可用区。

  • RESERVATION_NAME:要创建的预留的名称。

  • CONSUMER_PROJECT_ID_1CONSUMER_PROJECT_ID_2:可以使用此预留的项目 ID。您最多可以添加 100 个使用方项目。这些项目必须与所有者项目位于同一组织中。请勿包含所有者项目。默认情况下,已允许它使用该预留。

  • NUMBER_OF_VMS:要预留的虚拟机数量。

  • MACHINE_TYPE:要用于每个虚拟机的机器类型。如果您指定 A3 机器类型,则必须在请求正文中添加 specificReservationRequired 字段,并将该字段设置为 true。这表示只有明确指向预留的虚拟机才能使用它。

例如,如需通过在可用区 us-central1-a 中指定全局实例模板来创建预留,请与项目 project-1project-2 共享预留,并预留 10 个虚拟机,每个虚拟机使用一个 N2 具有 4 个 vCPU 的预定义机器类型,请执行以下 POST 请求:

POST https://compute.googleapis.com/compute/v1/projects/example-project/zones/us-central1-a/reservations

{
  "name": "my-reservation",
  "shareSettings": {
    "shareType": "SPECIFIC_PROJECTS",
    "projectMap": {
      "project-1": {
        "projectId": "project-1"
      },
      "project-2": {
        "projectId": "project-2"
      }
    }
  },
  "specificReservation": {
    "count": "10",
    "instanceProperties": {
      "machineType": "n2-standard-4",
    }
  }
}

您可以选择执行以下一项或多项操作:

  • 如需将 GPU 附加到预留的 N1 虚拟机,请在请求正文中添加 guestAccelerators 字段。

    例如,如需创建与两个使用方项目共享的预留,并将 GPU 附加到任何预留的 N1 虚拟机,请发出如下请求:

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/reservations
    
    {
      "name": "RESERVATION_NAME",
      "shareSettings": {
        "shareType": "SPECIFIC_PROJECTS",
        "projectMap": {
          "CONSUMER_PROJECT_ID_1": {
            "projectId": "CONSUMER_PROJECT_ID_1"
          },
          "CONSUMER_PROJECT_ID_2": {
            "projectId": "CONSUMER_PROJECT_ID_2"
          }
        }
      },
      "specificReservation": {
        "count": "NUMBER_OF_VMS",
        "instanceProperties": {
          "guestAccelerators": [
            {
              "acceleratorCount": NUMBER_OF_ACCELERATORS,
              "acceleratorType": "ACCELERATOR_TYPE"
            }
          ],
          "machineType": "MACHINE_TYPE"
        }
      }
    }
    

    替换以下内容:

  • 如需向每个预留的虚拟机添加一个或多个本地 SSD 磁盘,请在请求正文中添加 localSsds 字段。您最多可以指定 24 个本地 SSD 磁盘。每个本地 SSD 磁盘为 375 GB。

    例如,如需在创建共享预留的同时指定两个本地 SSD 磁盘和两个使用方项目,请发出如下请求:

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/reservations
    
    {
      "name": "RESERVATION_NAME",
      "shareSettings": {
        "shareType": "SPECIFIC_PROJECTS",
        "projectMap": {
          "CONSUMER_PROJECT_ID_1": {
            "projectId": "CONSUMER_PROJECT_ID_1"
          },
          "CONSUMER_PROJECT_ID_2": {
            "projectId": "CONSUMER_PROJECT_ID_2"
          }
        }
      },
      "specificReservation": {
        "count": "NUMBER_OF_VMS",
        "instanceProperties": {
          "localSsds": [
            {
              "diskSizeGb": "375",
              "interface": "INTERFACE_1"
            },
            {
              "diskSizeGb": "375",
              "interface": "INTERFACE_2"
            }
          ],
          "machineType": "MACHINE_TYPE"
        }
      }
    }
    

    INTERFACE_1INTERFACE_2 替换为您希望每个本地 SSD 磁盘使用的接口类型。请指定以下某个值:

    • NVME 磁盘接口:NVME

    • SCSI 磁盘接口:SCSI

    确保您为已预留虚拟机指定的机器类型支持所选的磁盘接口。否则,创建预留将失败。 如需了解详情,请参阅如何选择磁盘接口

  • 如需让预留的虚拟机使用特定的满足最低要求的 CPU 平台(而不是可用区的默认 CPU 平台),请在请求正文中添加 minCpuPlatform 字段。

    例如,如需在创建共享预留的同时指定满足最低要求的 CPU 平台和两个使用方项目,请发出如下请求:

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/reservations
    
    {
      "name": "RESERVATION_NAME",
      "shareSettings": {
        "shareType": "SPECIFIC_PROJECTS",
        "projectMap": {
          "CONSUMER_PROJECT_ID_1": {
            "projectId": "CONSUMER_PROJECT_ID_1"
          },
          "CONSUMER_PROJECT_ID_2": {
            "projectId": "CONSUMER_PROJECT_ID_2"
          }
        }
      },
      "specificReservation": {
        "count": "NUMBER_OF_VMS",
        "instanceProperties": {
          "machineType": "MACHINE_TYPE",
          "minCpuPlatform": "MIN_CPU_PLATFORM"
        }
      }
    }
    

    MIN_CPU_PLATFORM 替换为满足最低要求的 CPU 平台。为确保 CPU 平台在要预留资源的可用区可用,请按可用区查看可用的 CPU 平台

  • 如需指定只有明确指向此预留的虚拟机才能使用它,请在请求正文中添加 specificReservationRequired 字段,并将该字段设置为 true

    例如,如需创建特定预留并与两个使用方项目共享该预留,请发出如下请求:

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/reservations
    
    {
      "name": "RESERVATION_NAME",
      "shareSettings": {
        "shareType": "SPECIFIC_PROJECTS",
        "projectMap": {
          "CONSUMER_PROJECT_ID_1": {
            "projectId": "CONSUMER_PROJECT_ID_1"
          },
          "CONSUMER_PROJECT_ID_2": {
            "projectId": "CONSUMER_PROJECT_ID_2"
          }
        }
      },
      "specificReservation": {
        "count": "NUMBER_OF_VMS",
        "instanceProperties": {
          "machineType": "MACHINE_TYPE"
        }
      },
      "specificReservationRequired": true
    }
    
  • 如需允许 GPU 虚拟机的预留供 Vertex AI 中的自定义训练作业预测作业使用,请向 beta.reservations.insert 方法发出 POST 请求。在请求正文中,添加 serviceShareType 字段并将其设置为 ALLOW_ALL

    POST https://compute.googleapis.com/compute/beta/projects/PROJECT_ID/zones/ZONE/reservations
    
    {
      "name": "RESERVATION_NAME",
      "reservationSharingPolicy": {
        "serviceShareType": "ALLOW_ALL"
      },
      "shareSettings": {
        "shareType": "SPECIFIC_PROJECTS",
        "projectMap": {
          "CONSUMER_PROJECT_ID_1": {
            "projectId": "CONSUMER_PROJECT_ID_1"
          },
          "CONSUMER_PROJECT_ID_2": {
            "projectId": "CONSUMER_PROJECT_ID_2"
          }
        }
      },
      "specificReservation": {
        "count": "NUMBER_OF_VMS",
        "instanceProperties": {
          "machineType": "MACHINE_TYPE"
        }
      }
    }
    
  • 如需让 Compute Engine 自动删除预留,请选择以下方法之一:

    • 如需在特定日期和时间删除预留,请向 beta.reservations.insert 方法发出 POST 请求。在请求正文中,包含 deleteAtTime 字段。

      例如,如需在创建预留的同时指定删除预留的日期和时间,并与两个使用方项目共享预留,请发出如下请求:

      POST https://compute.googleapis.com/compute/beta/projects/PROJECT_ID/zones/ZONE/reservations
      
      {
        "deleteAtTime": "DELETE_AT_TIME",
        "name": "RESERVATION_NAME",
        "shareSettings": {
          "shareType": "SPECIFIC_PROJECTS",
          "projectMap": {
            "CONSUMER_PROJECT_ID_1": {
              "projectId": "CONSUMER_PROJECT_ID_1"
            },
            "CONSUMER_PROJECT_ID_2": {
              "projectId": "CONSUMER_PROJECT_ID_2"
            }
          }
        },
        "specificReservation": {
          "count": "NUMBER_OF_VMS",
          "instanceProperties": {
            "machineType": "MACHINE_TYPE"
          }
        }
      }
      

      DELETE_AT_TIME 替换为格式为 RFC 3339 时间戳(时间戳必须如下所示)的日期和时间:

      YYYY-MM-DDTHH:MM:SSOFFSET
      

      替换以下内容:

      • YYYY-MM-DD:格式为 4 位数年份、2 位数月份和 2 位数日期而且相互之间以连字符 (-) 分隔的日期。

      • HH:MM:SS:格式为 2 位数小时、2 位数分钟和 2 位数秒而且相互之间以冒号 (:) 分隔的采用 24 小时制的时间。

      • OFFSET:采用世界协调时间 (UTC) 的偏移量格式的时区。例如,要使用太平洋标准时间 (PST),请指定 -08:00。或者,如果不使用偏移量,请指定 Z

    • 如需在特定时间段后删除预留,请向 beta.reservations.insert 方法发出 POST 请求。在请求正文中,包含 deleteAfterDuration 字段。

      例如,如需创建 Compute Engine 在特定时长后删除的预留并与两个使用方项目共享预留,请发出如下请求:

      POST https://compute.googleapis.com/compute/beta/projects/PROJECT_ID/zones/ZONE/reservations
      
      {
        "deleteAfterDuration": {
          "seconds": "DELETE_AFTER_DURATION"
        },
        "name": "RESERVATION_NAME",
        "shareSettings": {
          "shareType": "SPECIFIC_PROJECTS",
          "projectMap": {
            "CONSUMER_PROJECT_ID_1": {
              "projectId": "CONSUMER_PROJECT_ID_1"
            },
            "CONSUMER_PROJECT_ID_2": {
              "projectId": "CONSUMER_PROJECT_ID_2"
            }
          }
        },
        "specificReservation": {
          "count": "NUMBER_OF_VMS",
          "instanceProperties": {
            "machineType": "MACHINE_TYPE"
          }
        }
      }
      

      DELETE_AFTER_DURATION 替换为持续时间,以秒为单位。例如,指定 86400 标识 86400 秒(1 天)。

问题排查

了解如何排查预留创建问题

后续步骤