本页面介绍了如何创建和使用抢占式虚拟机 (VM) 实例。与标准虚拟机的价格相比,您可以最高按 60-91% 的折扣获得抢占式虚拟机。但是,如果 Compute Engine 需要将相应资源收回以处理其他任务,则可能会停止(抢占)这些虚拟机。抢占式虚拟机将始终在 24 小时后停止。建议只将抢占式虚拟机用于可承受虚拟机抢占的容错应用。在您决定创建抢占式虚拟机之前,请确保您的应用可以处理抢占。如需了解抢占式虚拟机的风险和价值,请参阅抢占式虚拟机实例文档。
准备工作
- 参阅抢占式虚拟机实例文档。
-
如果您尚未设置身份验证,请进行设置。身份验证是通过其进行身份验证以访问 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
-
Install the Google Cloud CLI, then initialize it by running the following command:
gcloud init
- Set a default region and zone.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
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.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
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.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
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.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
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.
- 将关停脚本复制或下载到本地工作站。
- 打开此文件,以修改并更改以下变量:
[PROGRAM_NAME]
是您要关停的进程或程序的名称,例如apache2
或nginx
。[LOCAL_USER]
是您用于登录虚拟机的用户名。[BUCKET_NAME]
是您要用于保存程序检查点文件的 Cloud Storage 存储桶的名称。请注意,在这种情况下,存储分区名称不以gs://
开头。
- 保存更改。
- 将关停脚本添加到新虚拟机或现有虚拟机。
您已创建至少具备 Cloud Storage 读写权限的虚拟机。如需了解如何创建具有适当范围的虚拟机,请参阅身份验证文档。
您已有一个 Cloud Storage 存储桶,且拥有其写入权限。
在 Google Cloud 控制台中,转到日志页面。
选择您的项目并点击继续。
将
compute.instances.preempted
添加到按标签过滤或搜索文字字段。(可选)如果您要查看特定虚拟机的抢占操作,还可以输入虚拟机名称。
按 Enter 键以应用指定的过滤条件。Google Cloud 控制台会更新日志列表以仅显示虚拟机被抢占的操作。
在列表中选择一项操作,查看被抢占虚拟机的相关详细信息。
Go
如需在本地开发环境中使用本页面上的 Go 示例,请安装并初始化 gcloud CLI,然后使用您的用户凭据设置应用默认凭据。
如需了解详情,请参阅 Set up authentication for a local development environment。
Java
如需在本地开发环境中使用本页面上的 Java 示例,请安装并初始化 gcloud CLI,然后使用您的用户凭据设置应用默认凭据。
如需了解详情,请参阅 Set up authentication for a local development environment。
Node.js
如需在本地开发环境中使用本页面上的 Node.js 示例,请安装并初始化 gcloud CLI,然后使用您的用户凭据设置应用默认凭据。
如需了解详情,请参阅 Set up authentication for a local development environment。
Python
如需在本地开发环境中使用本页面上的 Python 示例,请安装并初始化 gcloud CLI,然后使用您的用户凭据设置应用默认凭据。
如需了解详情,请参阅 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 时进行身份验证。
创建抢占式虚拟机
使用 gcloud CLI 或 Compute Engine API 创建抢占式虚拟机。如需使用 Google Cloud 控制台,请改为创建 Spot 虚拟机。
gcloud
通过
gcloud compute
,使用与您在创建常规虚拟机时相同的instances create
命令,但要添加--preemptible
标志。gcloud compute instances create [VM_NAME] --preemptible
其中,
[VM_NAME]
是虚拟机的名称。Go
Java
Node.js
Python
REST
在 API 中,构造一项常规的创建虚拟机请求,但要在
scheduling
下方添加preemptible
属性并将该属性设置为true
。例如:POST https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances { 'machineType': 'zones/[ZONE]/machineTypes/[MACHINE_TYPE]', 'name': '[INSTANCE_NAME]', 'scheduling': { 'preemptible': true }, ... }
抢占式 CPU 配额
抢占式虚拟机需要可用的 CPU 配额,例如标准虚拟机。为避免抢占式虚拟机消耗标准虚拟机的 CPU 配额,您可以申请一种特殊的“抢占式 CPU”配额。当 Compute Engine 在某个区域中为您授予抢占式 CPU 配额后,所有抢占式虚拟机都将计入该配额,并且所有标准虚拟机都将继续计入标准 CPU 配额。
在您没有抢占式 CPU 配额的区域中,您可以使用标准 CPU 配额来启动抢占式虚拟机。像往常一样,您还将需要足够的 IP 和磁盘配额。抢占式 CPU 配额不会显示在 gcloud CLI 或 Google Cloud 控制台配额页面中,除非 Compute Engine 已授予该配额。
如需详细了解配额,请访问资源配额页面。
启动抢占式虚拟机
与任何其他虚拟机一样,如果抢占式虚拟机停止或被抢占,您可以再次启动虚拟机并将其恢复到
RUNNING
状态。启动抢占式虚拟机会重置 24 小时计数器,但由于它仍然是抢占式虚拟机,因此 Compute Engine 可以在 24 小时后抢占。抢占式虚拟机无法在运行时转换为标准虚拟机。如果 Compute Engine 停止自动扩缩托管式实例组 (MIG) 或 Google Kubernetes Engine (GKE) 集群中的抢占式虚拟机,则当资源再次可用时,该实例组将重启虚拟机。
使用关停脚本处理抢占
如果 Compute Engine 抢占虚拟机,您可以使用关停脚本尝试在虚拟机被抢占前执行清理操作。例如,您可以正常停止正在运行的进程,并将检查点文件复制到 Cloud Storage。 值得注意的是,相对于用户发起的关停,抢占通知的关停时长上限更短。如需详细了解抢占通知的关停期,请参阅概念文档中的抢占进程。
下面是一个关停脚本,您可以将其添加到正在运行的抢占式虚拟机中,或者在创建新的抢占式虚拟机时将其添加到该实例中。该脚本会在虚拟机开始关停之后到操作系统的常规
kill
命令停止所有剩余进程之前这段时间运行。在正常停止所需程序后,该脚本会将检查点文件并行上传到 Cloud Storage 存储分区。#!/bin/bash MY_PROGRAM="[PROGRAM_NAME]" # For example, "apache2" or "nginx" MY_USER="[LOCAL_USERNAME]" CHECKPOINT="/home/$MY_USER/checkpoint.out" BUCKET_NAME="[BUCKET_NAME]" # For example, "my-checkpoint-files" (without gs://) echo "Shutting down! Seeing if ${MY_PROGRAM} is running." # Find the newest copy of $MY_PROGRAM PID="$(pgrep -n "$MY_PROGRAM")" if [[ "$?" -ne 0 ]]; then echo "${MY_PROGRAM} not running, shutting down immediately." exit 0 fi echo "Sending SIGINT to $PID" kill -2 "$PID" # Portable waitpid equivalent while kill -0 "$PID"; do sleep 1 done echo "$PID is done, copying ${CHECKPOINT} to gs://${BUCKET_NAME} as ${MY_USER}" su "${MY_USER}" -c "gcloud storage cp $CHECKPOINT gs://${BUCKET_NAME}/" echo "Done uploading, shutting down."
如需将此脚本添加到虚拟机中,请将此脚本配置为与虚拟机上的应用搭配使用,并将其添加到虚拟机的元数据中。
此脚本假定您满足以下条件:
确定抢占式虚拟机
如需检查虚拟机是否为抢占式虚拟机,请按照确定虚拟机的预配模型和终止操作中的步骤操作。
确定虚拟机是否已被抢占
您可以使用 Google Cloud 控制台、gcloud CLI 或 API 来确定虚拟机是否已被抢占。
控制台
您可以通过查看系统活动日志来检查虚拟机是否已被抢占。
gcloud
搭配 filter 参数使用gcloud compute operations list
命令来获取您的项目中的抢占事件列表。gcloud compute operations list \ --filter="operationType=compute.instances.preempted"
您可以使用 filter 参数来进一步限定结果的范围。例如,如果只想查看托管式实例组中虚拟机的抢占事件,请运行以下命令:
gcloud compute operations list \ --filter="operationType=compute.instances.preempted AND targetLink:instances/[BASE_VM_NAME]"
gcloud
会返回类似于以下内容的响应:NAME TYPE TARGET HTTP_STATUS STATUS TIMESTAMP systemevent-xxxxxxxx compute.instances.preempted us-central1-f/instances/example-vm-xxx 200 DONE 2015-04-02T12:12:10.881-07:00
操作类型
compute.instances.preempted
表示虚拟机已被抢占。您可以使用operations describe
命令来获取特定抢占操作的相关详细信息。gcloud compute operations describe \ systemevent-xxxxxxxx
gcloud
会返回类似于以下内容的响应:... operationType: compute.instances.preempted progress: 100 selfLink: https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-f/operations/systemevent-xxxxxxxx startTime: '2015-04-02T12:12:10.881-07:00' status: DONE statusMessage: Instance was preempted. ...
REST
如要获取最近的系统操作列表,请向地区操作的 URI 发送GET
请求。GET https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/operations
响应会包含最近操作的列表。
{ "kind": "compute#operation", "id": "15041793718812375371", "name": "systemevent-xxxxxxxx", "zone": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-f", "operationType": "compute.instances.preempted", "targetLink": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/us-central1-f/instances/example-vm", "targetId": "12820389800990687210", "status": "DONE", "statusMessage": "Instance was preempted.", ... }
如要将响应范围限定为仅显示抢占操作,您可以在 API 请求中添加
operationType="compute.instances.preempted"
过滤条件。如需查看特定虚拟机的抢占操作,请将targetLink
参数添加到此过滤条件,如下所示:operationType="compute.instances.preempted" AND targetLink="https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances/[VM_NAME]"
。或者,您也可以通过虚拟机本身来确定虚拟机是否已被抢占。如果您要处理因 Compute Engine 抢占而导致的关停事件(与处理因关停脚本而导致的正常关停事件的方式不同),那么这种做法会非常实用。如需实现此目的,只需在元数据服务器中检查虚拟机的默认实例元数据中的
preempted
值即可。例如,在虚拟机中使用
curl
获取preempted
的值:curl "http://metadata.google.internal/computeMetadata/v1/instance/preempted" -H "Metadata-Flavor: Google" TRUE
如果此值为
TRUE
,则表示虚拟机已被 Compute Engine 抢占;否则此值为FALSE
。如果您要在关停脚本外部使用此命令,则可以将 ?wait_for_change=true 附加到该网址。这将执行挂起的 HTTP GET 请求,该请求仅在元数据更改并且虚拟机已被抢占时才会返回。
curl "http://metadata.google.internal/computeMetadata/v1/instance/preempted?wait_for_change=true" -H "Metadata-Flavor: Google" TRUE
测试抢占设置
您可以在虚拟机上运行模拟维护事件来强制进行抢占。使用此功能可以测试应用如何处理抢占式虚拟机。请参阅测试可用性政策,了解如何在虚拟机上测试维护事件。
您还可以通过停止虚拟机来模拟虚拟机抢占,这样做不但可以省去模拟维护事件的操作,还可避免配额限制。
最佳做法
以下是一些可帮助您充分利用抢占式虚拟机实例的最佳做法。
使用批量实例 API
您可以使用批量实例 API,而不是创建单个虚拟机。
选择较小的机器类型
抢占式虚拟机的资源来自于额外及备用的 Google Cloud 容量。对于较小的机器类型,容量通常更容易获取,因为这些机器类型所需的 vCPU 和内存等资源也较少。您可能会发现,通过选择较小的自定义机器类型可以增加抢占式虚拟机的容量;但对于较小的预定义机器类型,容量可能会更大。例如,与
n2-standard-32
预定义机器类型的容量相比,n2-custom-24-96
自定义机器类型的容量可能更大,但n2-standard-16
预定义机器类型的容量可能会比前者还要大。在非高峰时段运行大型抢占式虚拟机集群
Google Cloud 数据中心的负载因地点和时段而异,但通常夜晚和周末的负载最低。因此,夜晚和周末是运行大型抢占式虚拟机集群的最佳时间。
将您的应用设计成容错且容抢占型应用
请务必应对以下情况:抢占模式会随着时间点的不同而发生变化。例如,如果某个地区受到部分中断影响,则大量抢占式虚拟机可能会被抢占,以便为需要在恢复过程中迁移的标准虚拟机腾出空间。在这一小段时间内,抢占率会看起来与其他任何一天完全不同。如果您的应用假设抢占始终以小组形式完成,您可能无法应对此类事件。您可以通过停止虚拟机实例来测试在发生抢占事件时的应用行为。
重新尝试创建已被抢占的虚拟机
如果您的虚拟机实例已被抢占,建议先尝试创建新的抢占式虚拟机一到两次,然后再恢复为标准虚拟机。建议您根据具体要求在集群中结合使用标准虚拟机和抢占式虚拟机,以确保工作能够按照适当的速度继续执行。
使用关停脚本
使用可保存作业进度的关闭脚本来管理关闭和抢占通知,以便作业可以从停止的位置继续执行,而不是从头开始。
后续事项
如未另行说明,那么本页面中的内容已根据知识共享署名 4.0 许可获得了许可,并且代码示例已根据 Apache 2.0 许可获得了许可。有关详情,请参阅 Google 开发者网站政策。Java 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2024-12-22。
-