无法从 GCP 调度程序调用 Google Cloud Function

Mar*_*rko 9 node.js google-cloud-platform google-cloud-functions google-cloud-scheduler

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

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

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

gcloud iam service-accounts create scheduler --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
Run Code Online (Sandbox Code Playgroud)
  1. 部署云功能:

gcloud functions deploy helloworld --runtime nodejs8 --trigger-http --entry-point=helloWorld

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

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

  1. 创建调度程序作业:

gcloud beta scheduler jobs create 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"  
}
Run Code Online (Sandbox Code Playgroud)

更新

下面是相应的设置。

调度程序服务帐户

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
Run Code Online (Sandbox Code Playgroud)

函数的 IAM 策略:

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

功能说明

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'
Run Code Online (Sandbox Code Playgroud)

调度员职位描述

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'
Run Code Online (Sandbox Code Playgroud)

Dan*_*ndo 13

以下是我使 Cloud Scheduler 触发 HTTP 触发的 Cloud Function(不允许未经身份验证的调用)所遵循的步骤:

  1. 创建一个服务帐户,其格式如下:[SA-NAME]@[PROJECT-ID].iam.gserviceaccount.com。
  2. 添加服务帐户 [SA-NAME]@[PROJECT-ID].iam.gserviceaccount.com 作为项目成员,并向该服务帐户添加以下角色:Cloud Functions InvokerCloud Scheduler Admin
  3. 部署一个 HTTP 触发的云函数,该函数不允许公共(未经身份验证)访问(如果您使用的是 UI,只需取消选中“允许未经身份验证的调用”复选框)并且使用最近创建的服务帐户 [SA-NAME]@[PROJECT-ID ].iam.gserviceaccount.com 在服务帐户字段上(单击更多并查找服务帐户字段,默认情况下应将其设置为 App Engine 默认服务帐户)并注意 Cloud Function 的 URL。
  4. 通过从 Cloud Shell 发出以下命令来创建具有身份验证的 Cloud Scheduler 作业: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 服务帐户。将其更改为您在前面的步骤中指定的创建的服务帐户。


Nat*_*uer 8

@Marko 我遇到了同样的问题,似乎重新启用(禁用/启用)调度程序 API 完成了修复。这就是为什么创建一个新项目是有意义的,因为您可能通过这样做获得了一个调度程序服务帐户。因此,如果您的项目没有从谷歌创建的调度程序服务帐户,那么执行此技巧将为您提供一个。尽管您不需要将此特定服务帐户分配给您的任何任务,但它必须可用。您可以在这里看到我的工作:如何通过身份验证从 Cloud Scheduler 调用 Cloud Function


小智 5

我有类似的问题。

在我们的例子中,我们很久以前就启用了 Cloud Scheduler。

根据文档,如果您在2019 年 3 月 19 日Cloud Scheduler API 之前 启用,则需要手动将角色添加到您的服务帐户。Cloud Scheduler Service AgentCloud Scheduler

所以我们必须创建一个新的服务帐户,如下所示service-[project-number]@gcp-sa-cloudscheduler.iam.gserviceaccount.com

希望这对其他人有帮助。

  • 看起来这也适用于 Pub/Sub 触发器,而文档适用于 HTTP (2认同)