本教程介绍了如何使用 Cloud Scheduler 和 Cloud Functions 通过资源标签定期自动启动和停止 Compute Engine 实例。
目标
- 使用 Cloud Functions 编写和部署一组启用和停止 Compute Engine 实例的函数。
- 使用 Cloud Scheduler 创建一组作业,调度带
dev
资源标签的实例在周一至周五的 09:00-17:00 运行,以匹配典型的工作时间。
费用
本教程使用 Google Cloud 的以下收费组件:
- Cloud Scheduler
- 云端函数
- Pub/Sub
- Compute Engine
准备工作
应用架构
此解决方案包含以下 Google Cloud 组件:
- Compute Engine 实例:我们希望按时间表运行的 Compute Engine 实例。
- Cloud Functions 函数:用于启动和停止我们要调度的实例的函数。
- Pub/Sub 消息:针对每个启动和停止事件发送和接收的消息。
- Cloud Scheduler 作业:根据具体时间表进行调用以启动和停止实例的作业。
位置要求
某些组件仅在特定区域受支持:
- Compute Engine 实例:在 Compute Engine 区域和地区下列出的任何区域中皆受支持。
- Cloud Functions 函数:在列为 Cloud Functions 位置的区域中皆受支持。
- Pub/Sub 消息:Pub/Sub 是一项全球服务,因此在全球皆受支持。
- Cloud Scheduler 作业:在当前的任何 App Engine 位置皆受支持。
最佳做法:为什么不用 HTTP 取代 Pub/Sub?
您可能希望使用 Cloud Functions HTTP 触发器取代 Pub/Sub 触发器以简化此架构。
为了创建更安全的设置,我们建议您使用 Pub/Sub 函数。
设置 Compute Engine 实例
控制台
- 转到 Cloud Console 中的虚拟机实例页面。
转到“虚拟机实例”页面。 - 点击创建实例。
- 将名称设置为
dev-instance
。 - 对于区域,请选择
us-west1
。 - 对于地区,请选择
us-west1-b
。 - 展开管理、安全、磁盘、网络、单独租用部分。
- 在管理下,点击添加标签。为 Key 输入
env
,为 Value 输入dev
。 - 点击该页面底部的创建。
gcloud
gcloud compute instances create dev-instance \ --network default \ --zone us-west1-b \ --labels=env=dev
使用 Pub/Sub 设置 Cloud Functions 函数
创建和部署函数
Console
创建启动函数。
- 转到 Cloud Functions 网页。
转到 Cloud Functions 页面。 - 点击创建函数。
- 将函数名称设置为
startInstancePubSub
。 - 保留区域的默认值。
- 对于触发器类型,选择
Cloud Pub/Sub
。 - 在选择 Cloud Pub/Sub 主题部分,选择
Create a topic...
。 - 将出现一个新的 pub/sub 主题对话框。
- 在主题 ID 下,输入
start-instance-event
。 - 点击创建主题以完成对话框。
- 在主题 ID 下,输入
- 点击触发器框底部的保存。
- 点击页面底部的下一步。
- 对于运行时,选择
Node.js 10
。 - 对于入口点,请输入
startInstancePubSub
。 - 在代码编辑器的左侧,选择
index.js
。 使用以下代码替换入门代码:
在代码编辑器的左侧,选择
package.json
。使用以下代码替换入门代码:
点击页面底部的部署 (Deploy)。
创建停止函数。
- 转到 Cloud Console 中的 Cloud Functions 页面。
- 点击创建函数。
- 将函数名称设置为
stopInstancePubSub
。 - 保留区域的默认值。
- 使用分配的内存的默认值。
- 对于触发器类型,选择
Cloud Pub/Sub
。 - 在选择 Cloud Pub/Sub 主题部分,选择
Create a topic...
。 - 将出现一个新的 pub/sub 主题对话框。
- 在主题 ID 下,输入
stop-instance-event
。 - 点击创建主题以完成对话框。
- 在主题 ID 下,输入
- 点击触发器框底部的保存。
- 点击页面底部的下一步。
- 对于运行时,选择
Node.js 10
。 - 对于入口点,请输入
stopInstancePubSub
。 - 在代码编辑器的左侧,选择
index.js
。 使用以下代码替换入门代码:
在代码编辑器的左侧,选择
package.json
。使用以下代码替换入门代码:
点击页面底部的部署 (Deploy)。
gcloud
创建 Pub/Sub 主题。
gcloud pubsub topics create start-instance-event
gcloud pubsub topics create stop-instance-event
获取代码
下载代码。
git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git
或者,您也可以下载该示例的 zip 文件并将其解压缩。
转到正确的目录。
cd nodejs-docs-samples/functions/scheduleinstance/
创建启动和停止函数。
您应该已位于 nodejs-docs-samples/functions/scheduleinstance/
目录中。
gcloud functions deploy startInstancePubSub \ --trigger-topic start-instance-event \ --runtime nodejs10 \ --allow-unauthenticated
gcloud functions deploy stopInstancePubSub \ --trigger-topic stop-instance-event \ --runtime nodejs10 \ --allow-unauthenticated
(可选)验证函数能否正常运行
Console
停止实例
- 转到 Cloud Functions 网页。
转到 Cloud Functions 页面。 - 点击名为
stopInstancePubSub
的函数。 - 您应该会看到许多标签页:常规、触发器、源、权限和测试。点击测试标签页。
对于触发事件,输入以下内容:
{"data":"eyJ6b25lIjoidXMtd2VzdDEtYiIsICJsYWJlbCI6ImVudj1kZXYifQo="}
这只是
{"zone":"us-west1-b", "label":"env=dev"}
的 base64 编码的字符串如果您想要编码生成自己的字符串,则可以随意使用任何在线 base64 编码工具。
点击测试函数按钮。
当函数完成运行时,您应该会看到输出下面显示了
Successfully stopped instance dev-instance
。完成运行可能最多需要 60 秒。如果您看到的是
error: 'Error: function failed to load.'
,只需等待 10 秒左右以便函数完成部署,然后重试。如果您看到的是
error: 'Error: function execution attempt timed out.'
,直接继续下一步,以确定实例是否只是需要较长时间完成关闭。如果函数完成了运行,但没有显示任何内容,则可能也只是超时。直接继续下一步,以确定实例是否只是需要较长时间完成关闭。
转到 Cloud Console 中的虚拟机实例页面。
转到“虚拟机实例”页面。验证名为
dev-instance
的实例的名称旁边是否有灰色方块,该方块表示实例已停止。完成关闭可能最多需要 30 秒。- 如果似乎未完成关闭,尝试点击页面顶部的刷新。
启动实例
- 转到 Cloud Functions 网页。
转到 Cloud Functions 页面。 - 点击名为
startInstancePubSub
的函数。 - 您应该会看到许多标签页:常规、触发器、源、权限和测试。点击测试标签页。
对于触发事件,输入以下内容:
{"data":"eyJ6b25lIjoidXMtd2VzdDEtYiIsICJsYWJlbCI6ImVudj1kZXYifQo="}
- 同样,这只是
{"zone":"us-west1-b", "label":"env=dev"}
的 base64 编码的字符串
- 同样,这只是
点击测试函数按钮。
当函数完成运行时,您应该会看到输出下面显示了
Successfully started instance dev-instance
。转到 Cloud Console 中的虚拟机实例页面。
转到“虚拟机实例”页面。验证名为
dev-instance
的实例的名称旁边是否有绿色对勾标记,该标记表示实例正在运行。完成启动可能最多需要 30 秒。
gcloud
停止实例
调用以下函数来停止实例。
gcloud functions call stopInstancePubSub \ --data '{"data":"eyJ6b25lIjoidXMtd2VzdDEtYiIsICJsYWJlbCI6ImVudj1kZXYifQo="}'
这只是
{"zone":"us-west1-b", "label":"env=dev"}
的 base64 编码的字符串如果您想编码生成自己的字符串,可以使用任何工具。 以下示例中使用了
base64
命令行工具:echo '{"zone":"us-west1-b", "label":"env=dev"}' | base64
eyJ6b25lIjoidXMtd2VzdDEtYiIsICJsYWJlbCI6ImVudj1kZXYifQo=
函数完成后,您将看到以下内容:
result: Successfully stopped instance dev-instance
完成运行可能最多需要 60 秒。
如果您看到以下错误:
error: 'Error: function failed to load.`
只需等待 10 秒左右以便函数完成部署,然后重试。
如果您看到以下错误:
error: `Error: function execution attempt timed out.`
直接继续下一步,以确定实例是否只是需要较长时间完成关闭。
如果您未看到任何结果,该函数可能只是超时。 直接继续下一步,以确定实例是否只是需要较长时间完成关闭。
检查实例的状态是否为
TERMINATED
。完成关闭可能最多需要 30 秒。gcloud compute instances describe dev-instance \ --zone us-west1-b \ | grep status
status: TERMINATED
启动实例
调用以下函数来启动实例。
gcloud functions call startInstancePubSub \ --data '{"data":"eyJ6b25lIjoidXMtd2VzdDEtYiIsICJsYWJlbCI6ImVudj1kZXYifQo="}'
- 同样,这只是
{"zone":"us-west1-b", "label":"env=dev"}
的 base64 编码的字符串
函数完成后,您将看到以下内容:
result: Successfully started instance dev-instance
- 同样,这只是
检查实例的状态是否为
RUNNING
。完成启动可能最多需要 30 秒。gcloud compute instances describe dev-instance \ --zone us-west1-b \ | grep status
status: RUNNING
设置 Cloud Scheduler 作业以调用 Pub/Sub
创建作业
Console
创建启动作业。
- 转到 Cloud Console 中的 Cloud Scheduler 页面。
转到 Cloud Scheduler 页面。 - 点击创建作业。
- 保留默认区域,然后点击页面底部的下一步。
- 将名称设置为
startup-dev-instances
。 - 对于频率,输入
0 9 * * 1-5
。- 此操作会在周一至周五的上午 9 点执行。
- 对于时区,请选择相应的国家/地区和时区。此示例将使用
United States
和Los Angeles
。 - 对于目标,请选择
Pub/Sub
。 - 对于主题,请输入
start-instance-event
。 - 对于负载,键入以下内容:
{"zone":"us-west1-b","label":"env=dev"}
- 点击创建。
创建停止作业。
- 转到 Cloud Console 中的 Cloud Scheduler 页面。
- 点击创建作业。
- 保留默认区域,然后点击页面底部的下一步。
- 将名称设置为
shutdown-dev-instances
。 - 对于频率,输入
0 17 * * 1-5
。- 此操作会在周一至周五的 17:00 执行。
- 对于时区,请选择相应的国家/地区和时区。此示例将使用
United States
和Los Angeles
。 - 对于目标,请选择
Pub/Sub
。 - 对于主题,请输入
stop-instance-event
。 - 对于负载,键入以下内容:
{"zone":"us-west1-b","label":"env=dev"}
- 点击创建。
gcloud
创建启动作业。
gcloud beta scheduler jobs create pubsub startup-dev-instances \ --schedule '0 9 * * 1-5' \ --topic start-instance-event \ --message-body '{"zone":"us-west1-b", "label":"env=dev"}' \ --time-zone 'America/Los_Angeles'
创建停止作业。
gcloud beta scheduler jobs create pubsub shutdown-dev-instances \ --schedule '0 17 * * 1-5' \ --topic stop-instance-event \ --message-body '{"zone":"us-west1-b", "label":"env=dev"}' \ --time-zone 'America/Los_Angeles'
(可选)验证作业能否正常运行
Console
停止实例
- 转到 Cloud Console 中的 Cloud Scheduler 页面。
转到 Cloud Scheduler 页面。 - 对于名为
shutdown-dev-instances
的作业,点击页面最右侧的立即运行按钮。 - 转到 Cloud Console 中的虚拟机实例页面。
转到“虚拟机实例”页面。 - 验证名为
dev-instance
的实例的名称旁边是否有灰色方块,该方块表示实例已停止。完成关闭可能最多需要 30 秒。
启动实例
- 转到 Cloud Console 中的 Cloud Scheduler 页面。
转到 Cloud Scheduler 页面。 - 对于名为
startup-dev-instances
的作业,点击页面最右侧的立即运行按钮。 - 转到 Cloud Console 中的虚拟机实例页面。
转到“虚拟机实例”页面。 - 验证名为
dev-instance
的实例的名称旁边是否有绿色对勾标记,该标记表示实例正在运行。完成启动可能最多需要 30 秒。
gcloud
停止实例
运行调度程序作业以停止实例。
gcloud beta scheduler jobs run shutdown-dev-instances
检查实例的状态是否为
TERMINATED
。完成关闭可能最多需要 30 秒。gcloud compute instances describe dev-instance \ --zone us-west1-b \ | grep status
status: TERMINATED
启动实例
运行调度程序作业以启动实例。
gcloud beta scheduler jobs run startup-dev-instances
检查实例的状态是否为
RUNNING
。完成启动可能最多需要 30 秒。gcloud compute instances describe dev-instance \ --zone us-west1-b \ | grep status
status: RUNNING
清理
完成本实例调度教程后,您可以清理在 Google Cloud 上创建的资源,以避免这些资源占用配额,日后产生费用。以下部分介绍如何删除或关闭这些资源。
删除 Cloud Scheduler 作业
转到 Cloud Console 中的 Cloud Scheduler 页面。
点击作业旁边的复选框。
点击页面顶部的删除按钮并确认删除操作。
删除 Pub/Sub 主题
转到 Cloud Console 中的 Pub/Sub 页面:
点击主题旁边的复选框。
在页面顶部,点击删除并确认删除操作。
删除 Cloud Functions 函数
转到 Cloud Functions 网页。
点击函数旁边的复选框。
点击页面顶部的删除按钮并确认删除操作。
删除 Compute Engine 实例
要删除 Compute Engine 实例,请运行以下命令:
- 在 Cloud Console 中,转到虚拟机实例页面。
- 点击您要删除的实例。
- 点击 delete 删除以删除实例。
删除项目
为了避免产生费用,最简单的方法是删除您为本教程创建的项目。
如需删除项目,请执行以下操作:
- 在 Cloud Console 中,转到管理资源页面。
- 在项目列表中,选择要删除的项目,然后点击删除。
- 在对话框中输入项目 ID,然后点击关闭以删除项目。
后续步骤
- 试用其他 Google Cloud 功能。查阅我们的教程。