无法从 GCP 调度程序调用 Google Cloud Function [英] Cannot invoke Google Cloud Function from GCP Scheduler

查看:24
本文介绍了无法从 GCP 调度程序调用 Google Cloud Function的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试从 GCP 调度程序调用 GCP 函数(--runtime nodejs8 --trigger-http),两者都位于同一个项目中.我只能让它工作,如果我通过将 allUsers 成员添加到函数权限来授予未经身份验证的访问权限,并将 Cloud Functions-Invoker 角色应用于它.但是,当我仅使用调度程序的服务帐户作为 Cloud Functions-Invoker 时,我收到 PERMISSION DENIED 错误.

I've been trying to invoke a GCP function (--runtime nodejs8 --trigger-http) from GCP scheduler, both located within the same project. I can only make it work, if I grant unauthenticated access by adding the allUsers member to the functions permissions, with the Cloud Functions-Invoker role applied to it. However, when I only use the service account of the scheduler as the Cloud Functions-Invoker, I get a PERMISSION DENIED Error.

我创建了一个 hello world 示例,以详细展示我的设置.

I created a hello world example, to show in detail, how my setup looks like.

  1. 我设置了一个服务帐户:

gcloud iam service-accounts 创建调度程序 --display-name="Task Schedule Runner"

  1. 设置角色:

svc_policy.json:
{
    "bindings": [
      {
        "members": [
          "serviceAccount:scheduler@mwsdata-1544225920485.iam.gserviceaccount.com"
        ],
        "role": "roles/cloudscheduler.serviceAgent"
      }    
    ]
  }

gcloud iam service-accounts set-iam-policy scheduler@mwsdata-1544225920485.iam.gserviceaccount.com svc_policy.json  -q

  1. 部署云功能:

gcloud 函数部署 helloworld --runtime nodejs8 --trigger-http --entry-point=helloWorld

  1. 将服务帐户作为成员添加到函数中:

gcloud 函数 add-iam-policy-binding helloworld --member serviceAccount:scheduler@mwsdata-1544225920485.iam.gserviceaccount.com --role roles/cloudfunctions.invoker

  1. 创建调度程序作业:

gcloud beta 调度器作业创建 http test-job --schedule "5 * * * *" --http-method=GET --uri=https://us-central1-mwsdata-1544225920485.cloudfunctions.net/helloworld --oidc-service-account-email=scheduler@mwsdata-1544225920485.iam.gserviceaccount.com --oidc-token-audience=https://us-central1-mwsdata-1544225920485.cloudfunctions.net/helloworld

日志:权限被拒绝

{
 httpRequest: {
 }
 insertId: "1ny5xuxf69w0ck"  
 jsonPayload: {
  @type: "type.googleapis.com/google.cloud.scheduler.logging.AttemptFinished"   
  jobName: "projects/mwsdata-1544225920485/locations/europe-west1/jobs/test-job"   
  status: "PERMISSION_DENIED"   
  targetType: "HTTP"   
  url: "https://us-central1-mwsdata-1544225920485.cloudfunctions.net/helloworld"   
 }
 logName: "projects/mwsdata-1544225920485/logs/cloudscheduler.googleapis.com%2Fexecutions"  
 receiveTimestamp: "2020-02-04T22:05:05.248707989Z"  
 resource: {
  labels: {
   job_id: "test-job"    
   location: "europe-west1"    
   project_id: "mwsdata-1544225920485"    
  }
  type: "cloud_scheduler_job"   
 }
 severity: "ERROR"  
 timestamp: "2020-02-04T22:05:05.248707989Z"  
}

更新

这里是相应的设置.

Update

Here are the corresponding settings.

调度程序服务帐户

gcloud iam service-accounts get-iam-policy scheduler@mwsdata-1544225920485.iam.gserviceaccount.com

bindings:
- members:
  - serviceAccount:scheduler@mwsdata-1544225920485.iam.gserviceaccount.com
  role: roles/cloudscheduler.serviceAgent
etag: BwWdxuiGNv4=
version: 1

函数的 IAM 策略:

IAM Policy of the function:

gcloud functions get-iam-policy helloworld    
bindings:
- members:
  - serviceAccount:scheduler@mwsdata-1544225920485.iam.gserviceaccount.com
  role: roles/cloudfunctions.invoker
etag: BwWdxyDGOAY=
version: 1

功能说明

gcloud functions describe helloworld
availableMemoryMb: 256
entryPoint: helloWorld
httpsTrigger:
  url: https://us-central1-mwsdata-1544225920485.cloudfunctions.net/helloworld
ingressSettings: ALLOW_ALL
labels:
  deployment-tool: cli-gcloud
name: projects/mwsdata-1544225920485/locations/us-central1/functions/helloworld
runtime: nodejs8
serviceAccountEmail: mwsdata-1544225920485@appspot.gserviceaccount.com
sourceUploadUrl: https://storage.googleapis.com/gcf-upload-us-central1-671641e6-3f1b-41a1-9ac1-558224a1638a/b4a0e407-69b9-4f3d-a00d-7543ac33e013.zip?GoogleAccessId=service-617967399269@gcf-admin-robot.iam.gserviceaccount.com&Expires=1580854835&Signature=S605ODVtOpnU4LIoRT2MnU4OQN3PqhpR0u2CjgcpRcZZUXstQ5kC%2F1rT6Lv2SusvUpBrCcU34Og2hK1QZ3dOPluzhq9cXEvg5MX1MMDyC5Y%2F7KGTibnV4ztFwrVMlZNTj5N%2FzTQn8a65T%2FwPBNUJWK0KrIUue3GemOQZ4l4fCf9v4a9h6MMjetLPCTLQ1BkyFUHrVnO312YDjSC3Ck7Le8OiXb7a%2BwXjTDtbawR20NZWfgCCVvL6iM9mDZSaVAYDzZ6l07eXHXPZfrEGgkn7vXN2ovMF%2BNGvwHvTx7pmur1yQaLM4vRRprjsnErU%2F3p4JO3tlbbFEf%2B69Wd9dyIKVA%3D%3D
status: ACTIVE
timeout: 60s
updateTime: '2020-02-04T21:51:15Z'
versionId: '1'

调度员职位描述

gcloud scheduler jobs describe test-job
attemptDeadline: 180s
httpTarget:
  headers:
    User-Agent: Google-Cloud-Scheduler
  httpMethod: GET
  oidcToken:
    audience: https://us-central1-mwsdata-1544225920485.cloudfunctions.net/helloworld
    serviceAccountEmail: scheduler@mwsdata-1544225920485.iam.gserviceaccount.com
  uri: https://us-central1-mwsdata-1544225920485.cloudfunctions.net/helloworld
lastAttemptTime: '2020-02-05T09:05:00.054111Z'
name: projects/mwsdata-1544225920485/locations/europe-west1/jobs/test-job
retryConfig:
  maxBackoffDuration: 3600s
  maxDoublings: 16
  maxRetryDuration: 0s
  minBackoffDuration: 5s
schedule: 5 * * * *
scheduleTime: '2020-02-05T10:05:00.085854Z'
state: ENABLED
status:
  code: 7
timeZone: Etc/UTC
userUpdateTime: '2020-02-04T22:02:31Z'

推荐答案

以下是我让 Cloud Scheduler 触发一个不允许未经身份验证的调用的 HTTP 触发的 Cloud Function 的步骤:

Here are the steps I followed to make Cloud Scheduler trigger an HTTP triggered Cloud Function that doesn't allow unauthenticated invocations:

  1. 创建一个服务帐户,它将有以下表格 [SA-NAME]@[PROJECT-ID].iam.gserviceaccount.com.
  2. 将服务帐户 [SA-NAME]@[PROJECT-ID].iam.gserviceaccount.com 添加为 项目成员 并将以下角色添加到服务帐户:Cloud Functions InvokerCloud Scheduler Admin.
  3. 部署一个 HTTP 触发的云函数,它不允许公开(未经身份验证的) 访问(如果您使用的是 UI,只需取消选中 Allow unauthenticated Invocations 复选框)并在服务帐户字段上使用最近创建的服务帐户 [SA-NAME]@[PROJECT-ID].iam.gserviceaccount.com(单击更多并查找服务帐户字段,默认情况下应将其设置为 App Engine 默认服务帐户)并注意 Cloud Function 的 URL.
  4. 创建带有身份验证的 Cloud Scheduler 作业,方法是发出以下来自 Cloud Shell 的命令:gcloud scheduler jobs create http [JOB-NAME] --schedule="* * * * *" --uri=[CLOUD-FUNCTIONS-URL] --oidc-service-account-email=[SA-NAME]@[PROJECT-ID].iam.gserviceaccount.com
  1. Create a service account, which will have the following form [SA-NAME]@[PROJECT-ID].iam.gserviceaccount.com.
  2. Adde the service account [SA-NAME]@[PROJECT-ID].iam.gserviceaccount.com as a project member and added the following roles to the service account: Cloud Functions Invoker and Cloud Scheduler Admin.
  3. Deploy an HTTP triggered Cloud Function that doesn't allow public (unauthenticated) access (if you are using the UI, simply uncheck the Allow unauthenticated Invocations checkbox) and that used the recently created service account [SA-NAME]@[PROJECT-ID].iam.gserviceaccount.com on the Service account field (click more and look for the Service account field, by default it should be set to the App Engine default service account) and take notice of the Cloud Function's URL.
  4. Create a Cloud Scheduler job with authentication by issuing the following command from the Cloud Shell: gcloud scheduler jobs create http [JOB-NAME] --schedule="* * * * *" --uri=[CLOUD-FUNCTIONS-URL] --oidc-service-account-email=[SA-NAME]@[PROJECT-ID].iam.gserviceaccount.com

在您的特定情况下,您将保留 Cloud Functions 的默认 App Engine 服务帐户.将其更改为您在前面步骤中指定的服务帐户.

In your specific case you are leaving the default App Engine service account for your Cloud Functions. Change it to the service account you created as specified on the previous steps.

这篇关于无法从 GCP 调度程序调用 Google Cloud Function的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆