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

如何从Google Cloud Functions向启动的虚拟机传递消息或参数

实现方案

你可以通过以下三种常用方式实现Cloud Function启动GCE实例时传递自定义参数,根据你的参数复杂度、敏感程度选择即可:

方案1:使用GCE自定义元数据(最常用,轻量参数首选)

GCE实例默认提供元数据服务器,你可以在启动实例前先给实例写入自定义元数据,实例启动后内部程序直接从元数据接口读取参数即可。

Cloud Function 端修改后的代码:

import googleapiclient.discovery

def start_vm(context, event):
    compute = googleapiclient.discovery.build('compute', 'v1')
    project = 'PROJECT'
    zone = 'ZONE'
    instance = 'NAME'
    
    # 第一步:先获取实例当前的元数据指纹(更新元数据必须要最新指纹防止冲突)
    instance_data = compute.instances().get(project=project, zone=zone, instance=instance).execute()
    current_metadata = instance_data['metadata']
    fingerprint = current_metadata['fingerprint']
    
    # 第二步:添加你要传递的自定义参数到元数据
    custom_params = {
        "run_mode": "test",
        "task_id": "123456",
        "input_path": "gs://your-bucket/input/file.csv"
    }
    # 合并原有元数据和新参数
    new_metadata = {
        "fingerprint": fingerprint,
        "items": current_metadata.get('items', [])
    }
    # 把新参数写入元数据列表,重复key会覆盖
    for k, v in custom_params.items():
        # 先删除原有同名key
        new_metadata['items'] = [item for item in new_metadata['items'] if item['key'] != k]
        new_metadata['items'].append({"key": k, "value": str(v)})
    
    # 第三步:更新元数据
    compute.instances().setMetadata(
        project=project,
        zone=zone,
        instance=instance,
        body=new_metadata
    ).execute()
    
    # 第四步:启动VM
    result = compute.instances().start(project=project, zone=zone, instance=instance).execute()
    return result

VM 内部读取元数据的方式:

VM启动后,内部的程序可以直接访问元数据服务器获取参数,不需要额外鉴权,示例如下:

  • Shell 读取示例:
RUN_MODE=$(curl -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/attributes/run_mode)
TASK_ID=$(curl -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/attributes/task_id)
  • Python 读取示例:
import requests
metadata_url = "http://metadata.google.internal/computeMetadata/v1/instance/attributes/"
headers = {"Metadata-Flavor": "Google"}
run_mode = requests.get(metadata_url + "run_mode", headers=headers).text
task_id = requests.get(metadata_url + "task_id", headers=headers).text

方案2:动态写入启动脚本(适合启动后直接执行固定逻辑的场景)

如果你需要VM启动后直接根据参数执行指定代码,不需要后续程序主动读取,可以直接把参数和执行逻辑写到startup-script元数据中,VM启动时会自动执行该脚本:
在Cloud Function更新元数据的步骤,把自定义参数直接写到启动脚本里即可:

# 构造启动脚本,把参数直接写进去
startup_script = f"""#!/bin/bash
RUN_MODE={custom_params['run_mode']}
TASK_ID={custom_params['task_id']}
# 这里直接写你要执行的代码
echo "当前执行模式: $RUN_MODE"
python3 /opt/your_code.py --task-id $TASK_ID
"""
# 把启动脚本写入元数据
new_metadata['items'] = [item for item in new_metadata['items'] if item['key'] != 'startup-script']
new_metadata['items'].append({"key": "startup-script", "value": startup_script})

方案3:通过Pub/Sub传递参数(适合大参数、多实例消费场景)

如果你的参数体积很大(超过元数据256KB的限制),或者需要多个实例消费同一份参数、需要消息确认机制,可以用Pub/Sub中转:

  1. 提前创建一个Pub/Sub主题,给Cloud Function授予发布权限,给VM实例的服务账号授予订阅权限
  2. Cloud Function在启动VM前,把参数作为消息发布到Pub/Sub主题
  3. VM启动后自动订阅该主题,拉取消息获取参数即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 20:39:03