GCP创建实例时通过PHP SDK设置setMetadata启动脚本问题求助
GCP Compute Engine PHP SDK 添加启动脚本修复方案
错误点说明
- 变量定义顺序错误:你编写的启动脚本元数据初始化代码位置滞后于Instance对象的初始化逻辑,调用
setMetadata时$metaData变量尚未定义,自然无法生效 - 参数格式错误:
setMetadata方法接收的是Metadata对象实例,你额外包裹了一层数组,不符合SDK参数要求 - 启动脚本格式缺失:Linux环境下执行的启动脚本需要在开头指定脚本解释器
#!/bin/bash,否则可能无法正常执行
完整可运行代码
namespace Google\Cloud\Samples\Compute; require_once 'vendor/autoload.php'; use Google\Cloud\Compute\V1\InstancesClient; use Google\Cloud\Compute\V1\AttachedDisk; use Google\Cloud\Compute\V1\AttachedDiskInitializeParams; use Google\Cloud\Compute\V1\Instance; use Google\Cloud\Compute\V1\NetworkInterface; use Google\Cloud\Compute\V1\Operation; use Google\Cloud\Compute\V1\ZoneOperationsClient; use Google\Cloud\Compute\V1\AccessConfig; use Google\Cloud\Compute\V1\Items; use Google\Cloud\Compute\V1\Metadata; function create_instance() { $projectId = 'impactful-name-324714'; $zone = 'us-central1-c'; $instanceName = 'test1-micro'; $machineType = 'e2-micro'; $sourceImage = 'projects/centos-cloud/global/images/family/centos-7'; $networkName = 'global/networks/default'; $networkTier = 'PREMIUM'; // 拼接实例规格完整路径 $machineTypeFullName = sprintf('zones/%s/machineTypes/%s', $zone, $machineType); // 配置实例启动磁盘参数 $diskInitializeParams = (new AttachedDiskInitializeParams()) ->setSourceImage($sourceImage); $disk = (new AttachedDisk()) ->setBoot(true) ->setInitializeParams($diskInitializeParams); // 配置网络和公网IP参数 $accessConfig = (new AccessConfig()) ->setName('PREMIUM') ->setNetworkTier($networkTier); $network = (new NetworkInterface()) ->setAccessConfigs([$accessConfig]); // 提前初始化启动脚本元数据 $metaItems = (new Items()) ->setKey('startup-script') ->setValue('#!/bin/bash # 下方替换为你需要执行的命令 yum install -y httpd systemctl start httpd systemctl enable httpd echo "实例启动脚本执行成功" > /root/startup_log.txt'); $metaData = (new Metadata()) ->setItems([$metaItems]); // 组装实例配置 $instance = (new Instance()) ->setName($instanceName) ->setDisks([$disk]) ->setMachineType($machineTypeFullName) ->setNetworkInterfaces([$network]) ->setMetadata($metaData); // 直接传入Metadata对象,不需要外层数组 // 发起实例创建请求 $instancesClient = new InstancesClient(); $operation = $instancesClient->insert($instance, $projectId, $zone); // 等待实例创建完成 if ($operation->getStatus() === Operation\Status::RUNNING) { $operationClient = new ZoneOperationsClient(); $operationClient->wait($operation->getName(), $projectId, $zone); } printf('Created instance %s' . PHP_EOL, $instanceName); } putenv('GOOGLE_APPLICATION_CREDENTIALS=keyfile.json'); create_instance();
验证方法
- 实例创建完成后,在GCP控制台进入实例详情页,下拉到「元数据」板块,即可看到
startup-script字段和对应的值 - 启动脚本默认执行日志会写入实例的
/var/log/messages文件,你也可以在脚本中自定义输出日志文件方便排查
内容的提问来源于stack exchange,提问作者Samir Elaissaoui
相关产品推荐
相关产品推荐

