You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GCP虚拟机代码执行成功后自动关机,求行业通用稳健解决方案

符合GCP行业标准的2种稳健实现方案

两种方案都解决了你之前遇到的「VM启动后无法登录运维」、「定时时间差不可控」的痛点,你可以根据改动成本选择。

方案一:最小改动兼容现有架构(元数据控制启动逻辑)

这个方案只需要修改VM内部脚本和少量Cloud Function逻辑,不需要调整现有Cloud Scheduler配置,改造成本极低。

核心逻辑

用GCP VM的自定义元数据作为任务执行的开关,启动时先拉取元数据判断是否要执行任务,同时预留固定的运维登录窗口,彻底解决启动后无法登录的问题。

改造步骤

  1. 移除原有Crontab定时任务
    执行crontab -e删除原来的5 * * * * sh /home/danish_bansal/workflow.sh配置。
  2. 配置VM自定义元数据
    在GCP控制台VM实例详情页的「元数据」板块添加2个字段:
  • 键:auto_run_task,默认值:true
  • 键:task_grace_period,默认值:300(单位秒,预留5分钟的运维登录窗口)
  1. 修改workflow.sh脚本
    替换原有内容为以下版本,增加开关判断、日志记录、错误捕获逻辑:
#!/bin/bash
# 日志输出到系统目录,方便排查
exec &>> /var/log/task_runner.log
set -e

echo "=== 任务启动:$(date) ==="

# 拉取VM元数据判断是否要执行任务
AUTO_RUN=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/auto_run_task" -H "Metadata-Flavor: Google")
GRACE_PERIOD=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/task_grace_period" -H "Metadata-Flavor: Google")

if [ "$AUTO_RUN" != "true" ]; then
    echo "检测到auto_run_task为false,跳过任务执行,不自动关机"
    exit 0
fi

# 预留 grace period 时间供运维登录中断任务
echo "预留${GRACE_PERIOD}秒运维窗口,可在此期间登录修改auto_run_task元数据中断任务"
sleep $GRACE_PERIOD

# 二次确认元数据,防止运维在窗口内修改了开关
AUTO_RUN=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/auto_run_task" -H "Metadata-Flavor: Google")
if [ "$AUTO_RUN" != "true" ]; then
    echo "运维窗口内检测到auto_run_task改为false,跳过任务执行"
    exit 0
fi

# 拉取最新代码(建议用git pull代替全量克隆,速度更快)
cd /home/danish_bansal/
if [ -d "repoName" ]; then
    cd repoName
    git pull origin main
else
    git clone https://<token>@github.com/Repo/repoName.git
    cd repoName
fi

# 执行Python脚本,错误时记录日志
echo "开始执行Python脚本"
if ! /usr/bin/python3 Script.py; then
    echo "脚本执行失败,请查看日志排查"
    # 这里可以加自定义告警逻辑,比如调用内部通知webhook发告警
fi

# 关机前判断是否有活跃SSH连接,防止误踢运维
if [ $(who | wc -l) -eq 0 ]; then
    echo "无活跃SSH连接,执行关机"
    sudo shutdown -h now
else
    echo "检测到活跃SSH连接,跳过自动关机"
fi
  1. 配置启动脚本自动执行
    在VM元数据中新增键startup-script,值为:su - danish_bansal -c "sh /home/danish_bansal/workflow.sh",实现VM启动时自动触发脚本。
  2. 优化Cloud Function逻辑
    修改启动VM的Cloud Function,每次启动VM时自动重置auto_run_task为true,避免运维后忘记改回配置导致任务不执行:
from googleapiclient import discovery

def startInstance(r):
    service = discovery.build('compute', 'v1')
    print('VM Instance starting')

    project = 'project-name' 
    zone = 'us-central1-a'  
    instance = 'test-vm'

    # 重置auto_run_task元数据为true
    instance_data = service.instances().get(project=project, zone=zone, instance=instance).execute()
    metadata = instance_data['metadata']
    # 更新元数据项
    has_auto_run = False
    for item in metadata.get('items', []):
        if item['key'] == 'auto_run_task':
            item['value'] = 'true'
            has_auto_run = True
            break
    if not has_auto_run:
        metadata['items'].append({'key': 'auto_run_task', 'value': 'true'})
    
    # 先更新元数据再启动VM
    service.instances().setMetadata(project=project, zone=zone, instance=instance, body=metadata).execute()
    # 启动VM
    request = service.instances().start(project=project, zone=zone, instance=instance)
    response = request.execute()

    print(response,'VM Instance started')

运维操作方式

需要调试VM、安装依赖时,直接在GCP控制台手动启动VM,启动后立刻在元数据中将auto_run_task改为false,即可跳过任务执行和自动关机。


方案二:全托管无状态工作流(Cloud Workflows 方案,行业首推)

这个是GCP官方推荐的定时运行VM任务的标准架构,所有控制逻辑完全托管,不需要在VM内部配置任何定时任务或启动脚本,稳健性最高。

核心逻辑

用Cloud Workflows串联整个执行流程:

  1. Cloud Scheduler每小时触发Cloud Workflows
  2. Workflows第一步调用Compute Engine API启动VM
  3. 第二步调用Cloud OS Login API在VM内部远程执行代码拉取、脚本运行逻辑
  4. 第三步轮询脚本执行状态,待执行完成后调用API关闭VM

优势

  • VM完全无状态,不需要任何内部配置,重装系统也不影响任务执行
  • 可以精确感知每一步的执行状态,执行失败自动触发告警
  • 运维时手动启动VM不会自动执行任务,不需要做任何开关配置
  • 支持灵活配置重试、超时逻辑,避免脚本卡住导致VM一直运行扣费

通用优化建议

  • 配置Cloud Monitoring告警:监控VM运行时长,若超过30分钟未关机自动触发告警,避免异常扣费
  • 代码依赖提前预装到VM镜像,避免每次执行都要安装依赖
  • 敏感的Git token不要硬编码在脚本中,可存在GCP Secret Manager中,运行时动态拉取

内容的提问来源于stack exchange,提问作者Danish Bansal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 23:39:03