node.js - 无法从 GCP 调度程序调用 Google Cloud Function

标签 node.js google-cloud-platform google-cloud-functions google-cloud-scheduler

我一直在尝试从 GCP 调度程序调用 GCP 函数( --runtime nodejs8 --trigger-http ),它们都位于同一个项目中。如果我通过添加 allUsers 授予未经身份验证的访问权限,我只能使其工作。函数权限的成员,具有 Cloud Functions-Invoker作用于它。但是,当我只使用调度程序的服务帐户作为 Cloud Functions-Invoker ,我得到一个许可被拒绝的错误。

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

  • 我设置了一个服务帐号:
  • gcloud iam service-accounts create scheduler --display-name="Task Schedule Runner"
  • 设置角色:
  • 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
    
  • 部署云功能:
  • gcloud functions deploy helloworld --runtime nodejs8 --trigger-http --entry-point=helloWorld
  • 将服务帐户作为成员添加到函数中:
  • gcloud functions add-iam-policy-binding helloworld --member serviceAccount:scheduler@mwsdata-1544225920485.iam.gserviceaccount.com --role roles/cloudfunctions.invoker
  • 创建调度程序作业:
  • 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"  
    }
    

    更新

    以下是相应的设置。

    调度程序服务帐户
    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 功能的政策:
    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 Functions 所遵循的步骤:

  • Create a service account ,其格式如下 [SA-NAME]@[PROJECT-ID].iam.gserviceaccount.com。
  • 将服务帐户 [SA-NAME]@[PROJECT-ID].iam.gserviceaccount.com 添加为 a project member并将以下角色添加到服务帐户:Cloud Functions InvokerCloud Scheduler Admin .
  • Deploy an HTTP triggered Cloud Function不允许公共(public)(未经身份验证)访问(如果您使用 UI,只需取消选中允许未经身份验证的调用复选框)并且使用最近创建的服务帐户 [SA-NAME]@[PROJECT-ID].iam.gserviceaccount。 com 在服务帐户字段上(单击更多并查找服务帐户字段,默认情况下应设置为 App Engine 默认服务帐户)并注意 Cloud Function 的 URL。
  • Create a Cloud Scheduler job with authentication通过从 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 服务帐户。将其更改为您在前面步骤中指定的创建的服务帐户。

    关于node.js - 无法从 GCP 调度程序调用 Google Cloud Function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60055422/

    相关文章:

    javascript - Firestore云功能评论计数器: How to fix "Object is possibly undefined"?

    node.js - 使用 redis pubsub 离线处理订户服务器?

    javascript - Node.js 生成参数导致 git update-index 失败

    Firebase 云函数调用了两次

    javascript - 从更新的项目更新时,在云函数中创建引用的 Firestore 文档

    javascript - 在循环中收集 Firebase 云函数异步调用的结果

    node.js - Node.js 中调用错误名称的函数的错误处理

    node.js - 在 Node js 中安装 aws-sdk 返回 npm 错误

    google-cloud-platform - 如何使用 REST API 从 Google Cloud Identity Platform 注销当前用户?

    google-app-engine - 将图像和结构化数据存储在一起(Google Cloud Platform)