GCP:从 Cloud Function 启动 Compute Engine 实例时无法设置元数据
GCP: Cannot set metadata when starting Compute Engine instance from Cloud Function
我正在尝试从另一个 GCP 项目中托管的 Cloud Functions 启动一个 GCP 项目中的 Compute Engine 实例。它运行良好,但我无法添加计算引擎 instance metadata,我收到 HTTP 错误代码 400。
云函数(Node.js,与compute engine client):
const Compute = require('@google-cloud/compute');
const compute = new Compute({
projectId: 'myGcpProject'
});
exports.startVmInstance = async (data, context, callback) => {
let zone = compute.zone('us-central1-a');
let vm = zone.vm('myVmInstance');
let metadata = {
'myMeta': 'myValue'
};
// THIS PART HAS NO EFFECT IN THE COMPUTE ENGINE INSTANCE
await vm.setMetadata(metadata).then((response) => {
console.info('Set metadata response: ' + JSON.stringify(response[1]));
}).catch((error) => {
throw 'Error while setting metadata to VM instance: ' + error;
});
await vm.start().then(() => {
console.info('Compute Engine instance started successfully');
}).catch(error => {
throw 'Error while starting Compute Engine instance: ' + error;
});
callback();
};
日志:
- Function execution took 2235 ms, finished with status: 'ok'
- Compute Engine instance started successfully
- Set metadata response: {"id":"84345484841776xxxxx","name":"operation-1587175048337-5a386fcf3d737-36e59a28-332a95f5","zone":"https://www.googleapis.com/compute/v1/projects/myGcpProject/zones/us-central1-a","operationType":"setMetadata","targetLink":"https://www.googleapis.com/compute/v1/projects/myGcpProject/zones/us-central1-a/instances/myVmInstance","targetId":"48593751438611xxxxx","status":"RUNNING","user":"cloud-function@myCloudFunctionGcpProject.iam.gserviceaccount.com","progress":0,"insertTime":"2020-04-17T18:57:28.704-07:00","startTime":"2020-04-17T18:57:28.721-07:00","selfLink":"https://www.googleapis.com/compute/v1/projects/myGcpProject/zones/us-central1-a/operations/operation-1587175048337-5a386fcf3d737-36e59a28-332a95f5","kind":"compute#operation"}
- Function execution started
当我使用 SSH 登录 Compute Engine 实例时,我无法读取元数据 'myMeta'(只有我默认拥有的启动脚本):
$ gcloud compute instances describe myVmInstance
...
metadata:
fingerprint: 0ay6MSNkjI8=
items:
- key: startup-script
value: |-
#!/bin/bash
echo `date`
kind: compute#metadata
...
我可以看到该操作,但我收到 HTTP 错误代码 400
$ gcloud compute operations list | grep operation-1587175048337-5a386fcf3d737-36e59a28-332a95f5
operation-1587175048337-5a386fcf3d737-36e59a28-332a95f5 setMetadata us-central1-a/instances/myVmInstance 400 DONE 2020-04-17T18:57:28.704-07:00
Cloud Functions 使用的服务帐户在托管 Compute Engine 实例的 GCP 中具有 Compute Admin 角色。
我错过了什么?
@John Hanley 说的对,我需要等待手术完成。
此外,即使 Cloud Functions 使用的服务帐户在托管 Compute Engine 实例的 GCP 项目上被授予 Compute Admin 角色,它也需要在服务帐户上被授予角色 Service Account User由 Compute Engine 实例使用。
否则我会得到下面的错误
Error: The user does not have access to service account '661830xxxxxx-compute@developer.gserviceaccount.com'. User: 'cloud-function@myCloudFunctionGcpProject.iam.gserviceaccount.com'. Ask a project owner to grant you the iam.serviceAccountUser role on the service account
云函数代码(Node.js):
const Compute = require('@google-cloud/compute');
const compute = new Compute({
projectId: 'myGcpProject'
});
exports.startVmInstance = async (data, context, callback) => {
let zone = compute.zone('us-central1-a');
let vm = zone.vm('myVmInstance');
let metadata = {
'myMeta': 'myValue'
};
let setMetadataOperation;
await vm.setMetadata(metadata).then((response) => {
setMetadataOperation = response[0];
console.info('Set metadata response: ' + JSON.stringify(response[1]));
}).catch((error) => {
throw 'Error while setting metadata to VM instance: ' + error;
});
await setMetadataOperation.promise().then(() => {
console.info('The operation setMetadata successfully completed');
}).catch((error) => {
throw 'Error with the operation setMetadata: ' + error;
});
await vm.start().then(() => {
console.info('Compute Engine instance started successfully');
}).catch(error => {
throw 'Error while starting Compute Engine instance: ' + error;
});
callback();
};
我正在尝试从另一个 GCP 项目中托管的 Cloud Functions 启动一个 GCP 项目中的 Compute Engine 实例。它运行良好,但我无法添加计算引擎 instance metadata,我收到 HTTP 错误代码 400。
云函数(Node.js,与compute engine client):
const Compute = require('@google-cloud/compute');
const compute = new Compute({
projectId: 'myGcpProject'
});
exports.startVmInstance = async (data, context, callback) => {
let zone = compute.zone('us-central1-a');
let vm = zone.vm('myVmInstance');
let metadata = {
'myMeta': 'myValue'
};
// THIS PART HAS NO EFFECT IN THE COMPUTE ENGINE INSTANCE
await vm.setMetadata(metadata).then((response) => {
console.info('Set metadata response: ' + JSON.stringify(response[1]));
}).catch((error) => {
throw 'Error while setting metadata to VM instance: ' + error;
});
await vm.start().then(() => {
console.info('Compute Engine instance started successfully');
}).catch(error => {
throw 'Error while starting Compute Engine instance: ' + error;
});
callback();
};
日志:
- Function execution took 2235 ms, finished with status: 'ok'
- Compute Engine instance started successfully
- Set metadata response: {"id":"84345484841776xxxxx","name":"operation-1587175048337-5a386fcf3d737-36e59a28-332a95f5","zone":"https://www.googleapis.com/compute/v1/projects/myGcpProject/zones/us-central1-a","operationType":"setMetadata","targetLink":"https://www.googleapis.com/compute/v1/projects/myGcpProject/zones/us-central1-a/instances/myVmInstance","targetId":"48593751438611xxxxx","status":"RUNNING","user":"cloud-function@myCloudFunctionGcpProject.iam.gserviceaccount.com","progress":0,"insertTime":"2020-04-17T18:57:28.704-07:00","startTime":"2020-04-17T18:57:28.721-07:00","selfLink":"https://www.googleapis.com/compute/v1/projects/myGcpProject/zones/us-central1-a/operations/operation-1587175048337-5a386fcf3d737-36e59a28-332a95f5","kind":"compute#operation"}
- Function execution started
当我使用 SSH 登录 Compute Engine 实例时,我无法读取元数据 'myMeta'(只有我默认拥有的启动脚本):
$ gcloud compute instances describe myVmInstance
...
metadata:
fingerprint: 0ay6MSNkjI8=
items:
- key: startup-script
value: |-
#!/bin/bash
echo `date`
kind: compute#metadata
...
我可以看到该操作,但我收到 HTTP 错误代码 400
$ gcloud compute operations list | grep operation-1587175048337-5a386fcf3d737-36e59a28-332a95f5
operation-1587175048337-5a386fcf3d737-36e59a28-332a95f5 setMetadata us-central1-a/instances/myVmInstance 400 DONE 2020-04-17T18:57:28.704-07:00
Cloud Functions 使用的服务帐户在托管 Compute Engine 实例的 GCP 中具有 Compute Admin 角色。
我错过了什么?
@John Hanley 说的对,我需要等待手术完成。
此外,即使 Cloud Functions 使用的服务帐户在托管 Compute Engine 实例的 GCP 项目上被授予 Compute Admin 角色,它也需要在服务帐户上被授予角色 Service Account User由 Compute Engine 实例使用。
否则我会得到下面的错误
Error: The user does not have access to service account '661830xxxxxx-compute@developer.gserviceaccount.com'. User: 'cloud-function@myCloudFunctionGcpProject.iam.gserviceaccount.com'. Ask a project owner to grant you the iam.serviceAccountUser role on the service account
云函数代码(Node.js):
const Compute = require('@google-cloud/compute');
const compute = new Compute({
projectId: 'myGcpProject'
});
exports.startVmInstance = async (data, context, callback) => {
let zone = compute.zone('us-central1-a');
let vm = zone.vm('myVmInstance');
let metadata = {
'myMeta': 'myValue'
};
let setMetadataOperation;
await vm.setMetadata(metadata).then((response) => {
setMetadataOperation = response[0];
console.info('Set metadata response: ' + JSON.stringify(response[1]));
}).catch((error) => {
throw 'Error while setting metadata to VM instance: ' + error;
});
await setMetadataOperation.promise().then(() => {
console.info('The operation setMetadata successfully completed');
}).catch((error) => {
throw 'Error with the operation setMetadata: ' + error;
});
await vm.start().then(() => {
console.info('Compute Engine instance started successfully');
}).catch(error => {
throw 'Error while starting Compute Engine instance: ' + error;
});
callback();
};