【问题标题】:Dataflow setting Controller Service Account数据流设置控制器服务帐户
【发布时间】:2019-05-13 08:20:49
【问题描述】:

我尝试为 Dataflow 设置控制器服务帐户。在我的数据流选项中,我有:

options.setGcpCredential(GoogleCredentials.fromStream(
                         new FileInputStream("key.json")).createScoped(someArrays)); 
options.setServiceAccount("xxx@yyy.iam.gserviceaccount.com");

但我得到了:

WARNING: Request failed with code 403, performed 0 retries due to IOExceptions,         
         performed 0 retries due to unsuccessful status codes, HTTP framework says 
         request can be retried, (caller responsible for retrying): 
         https://dataflow.googleapis.com/v1b3/projects/MYPROJECT/locations/MYLOCATION/jobs
Exception in thread "main" java.lang.RuntimeException: Failed to create a workflow 
         job: (CODE): Current user cannot act as 
         service account "xxx@yyy.iam.gserviceaccount.com. 
         Causes: (CODE): Current user cannot act as 
         service account "xxx@yyy.iam.gserviceaccount.com.
    at org.apache.beam.runners.dataflow.DataflowRunner.run(DataflowRunner.java:791)
    at org.apache.beam.runners.dataflow.DataflowRunner.run(DataflowRunner.java:173)
    at org.apache.beam.sdk.Pipeline.run(Pipeline.java:311)
    at org.apache.beam.sdk.Pipeline.run(Pipeline.java:297)

...

Caused by: com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
  "code" : 403,
  "errors" : [ {
    "domain" : "global",
    "message" : "(CODE): Current user cannot act as service account 
                 xxx@yyy.iam.gserviceaccount.com. Causes: (CODE): Current user
                 cannot act as service account xxx@yyy.iam.gserviceaccount.com.",
    "reason" : "forbidden"
  } ],
  "message" : "(CODE): Current user cannot act as service account 
               xxx@yyy.iam.gserviceaccount.com. Causes: (CODE): Current user 
               cannot act as service account xxx@yyy.iam.gserviceaccount.com.",
  "status" : "PERMISSION_DENIED"
}

我是否缺少某些角色或权限?

【问题讨论】:

    标签: google-cloud-platform google-cloud-dataflow dataflow google-cloud-iam


    【解决方案1】:

    也许有人会觉得它有帮助:

    • 对于控制器,它是:Dataflow Worker 和 Storage Object Admin(在 Google's documentation 中找到)。

    • 对于执行者,它是:服务帐户用户。

    【讨论】:

    • 对于我使用过的 terraform:roles = ["dataflow.admin", "dataflow.worker", "storage.admin", "iam.serviceAccountUser"]
    • @Kush - 谢谢。很多。这解决了我的问题。
    • 注意:基于最小权限的最小原则,您希望将角色限制为相应的资源(例如仅适用于存储桶而不是项目级别,还授予服务帐户用户特定的 SA 级别而不是项目级别)
    【解决方案2】:

    我一直遇到这个错误,并认为值得分享我的经验(部分原因是我怀疑我将来会再次遇到这个问题)。

    创建我的数据流作业的 terraform 代码是:

    resource "google_dataflow_job" "wordcount" {
      # https://stackoverflow.com/a/59931467/201657
      name              = "wordcount"
      template_gcs_path = "gs://dataflow-templates/latest/Word_Count"
      temp_gcs_location = "gs://${local.name-prefix}-functions/temp"
      parameters = {
        inputFile = "gs://dataflow-samples/shakespeare/kinglear.txt"
        output = "gs://${local.name-prefix}-functions/wordcount/output"
      }
      service_account_email = "serviceAccount:${data.google_service_account.sa.email}"
    }
    

    错误信息:

    错误:googleapi:错误 400:(c3c0d991927a8658):当前用户无法充当服务帐户 serviceAccount:dataflowdemo@redacted.iam.gserviceaccount.com., badRequest

    从运行 terraform apply 返回。查看日志提供了更多信息:

    gcloud logging read 'timestamp >= "2020-12-31T13:39:58.733249492Z" AND timestamp <= "2020-12-31T13:45:58.733249492Z"' --format="csv(timestamp,severity,textPayload)" --order=asc
    

    它返回了各种日志记录,包括:

    控制器服务帐户的权限验证失败。 IAM 角色角色/dataflow.worker 应授予控制器服务帐户 dataflowdemo@redacted.iam.gserviceaccount.com。

    所以我授予了那个缺失的角色授权

    gcloud projects add-iam-policy-binding $PROJECT \
      --member="serviceAccount:dataflowdemo@${PROJECT}.iam.gserviceaccount.com" \
      --role="roles/dataflow.worker"
    

    然后再次运行terraform apply。这次我在 terraform 输出中遇到了同样的错误,但在日志中没有看到任何错误。

    然后我按照https://cloud.google.com/dataflow/docs/concepts/access-control#creating_jobs 给出的建议也授予角色/dataflow.admin:

    gcloud projects add-iam-policy-binding $PROJECT \
      --member="serviceAccount:dataflowdemo@${PROJECT}.iam.gserviceaccount.com" \
      --role="roles/dataflow.admin"
    

    但与之前的尝试没有明显区别。

    然后我尝试打开提供此信息的terraform debug logging

    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: ---[ REQUEST ]---------------------------------------
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: POST /v1b3/projects/redacted/locations/europe-west1/templates?alt=json&prettyPrint=false HTTP/1.1
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: Host: dataflow.googleapis.com
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: User-Agent: google-api-go-client/0.5 Terraform/0.14.2 (+https://www.terraform.io) Terraform-Plugin-SDK/2.1.0 terraform-provider-google/dev
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: Content-Length: 385
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: Content-Type: application/json
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: X-Goog-Api-Client: gl-go/1.14.5 gdcl/20201023
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: Accept-Encoding: gzip
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: {
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:  "environment": {
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:   "serviceAccountEmail": "serviceAccount:dataflowdemo@redacted.iam.gserviceaccount.com",
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:   "tempLocation": "gs://jamiet-demo-functions/temp"
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:  },
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:  "gcsPath": "gs://dataflow-templates/latest/Word_Count",
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:  "jobName": "wordcount",
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:  "parameters": {
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:   "inputFile": "gs://dataflow-samples/shakespeare/kinglear.txt",
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:   "output": "gs://jamiet-demo-functions/wordcount/output"
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:  }
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: }
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:
    2020-12-31T16:04:13.129Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: -----------------------------------------------------
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: 2020/12/31 16:04:14 [DEBUG] Google API Response Details:
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: ---[ RESPONSE ]--------------------------------------
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: HTTP/1.1 400 Bad Request
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: Connection: close
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: Transfer-Encoding: chunked
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: Alt-Svc: h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: Cache-Control: private
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: Content-Type: application/json; charset=UTF-8
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: Date: Thu, 31 Dec 2020 16:04:15 GMT
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: Server: ESF
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: Vary: Origin
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: Vary: X-Origin
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: Vary: Referer
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: X-Content-Type-Options: nosniff
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: X-Frame-Options: SAMEORIGIN
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: X-Xss-Protection: 0
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: 1f9
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: {
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:   "error": {
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:     "code": 400,
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:     "message": "(dbacb1c39beb28c9): Current user cannot act as service account serviceAccount:dataflowdemo@redacted.iam.gserviceaccount.com.",
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:     "errors": [
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:       {
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:         "message": "(dbacb1c39beb28c9): Current user cannot act as service account serviceAccount:dataflowdemo@redacted.iam.gserviceaccount.com.",
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:         "domain": "global",
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:         "reason": "badRequest"
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:       }
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:     ],
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:     "status": "INVALID_ARGUMENT"
    orm-provider-google_v3.51.0_x5:   }
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: }
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: 0
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5:
    2020-12-31T16:04:14.647Z [DEBUG] plugin.terraform-provider-google_v3.51.0_x5: -----------------------------------------------------
    

    从 dataflow.googleapis.com 返回的错误非常明显:

    当前用户不能作为服务帐号 serviceAccount:dataflowdemo@redacted.iam.gserviceaccount.com

    在这个阶段,我很困惑为什么我可以看到从 Google 的数据流 API 返回的错误,但 GCP 日志中没有任何内容表明发生了错误。

    然后,我有一个灯泡时刻。为什么该错误消息提到“服务帐户 serviceAccount”?然后它击中了我,我错误地定义了服务帐户。 Terraform 代码应该是:

    resource "google_dataflow_job" "wordcount" {
      # https://stackoverflow.com/a/59931467/201657
      name              = "wordcount"
      template_gcs_path = "gs://dataflow-templates/latest/Word_Count"
      temp_gcs_location = "gs://${local.name-prefix}-functions/temp"
      parameters = {
        inputFile = "gs://dataflow-samples/shakespeare/kinglear.txt"
        output = "gs://${local.name-prefix}-functions/wordcount/output"
      }
      service_account_email = data.google_service_account.sa.email
    }
    

    我纠正了它,它立即工作。用户错误!!!

    然后我开始删除我添加的各种权限:

    gcloud projects remove-iam-policy-binding $PROJECT \
      --member="serviceAccount:dataflowdemo@${PROJECT}.iam.gserviceaccount.com" \
      --role="roles/dataflow.admin"
    gcloud projects remove-iam-policy-binding $PROJECT \
      --member="serviceAccount:dataflowdemo@${PROJECT}.iam.gserviceaccount.com" \
      --role="roles/dataflow.worker"
    

    terraform apply 仍然有效。但是,在删除角色 roles/dataflow.worker 的授予后,作业失败并出现错误:

    工作流程失败。原因:控制器服务帐户的权限验证失败。 IAM 角色角色/dataflow.worker 应授予控制器服务帐户 dataflowdemo@redacted.iam.gserviceaccount.com。

    关于授予的适当角色 (https://cloud.google.com/dataflow/docs/concepts/access-control#creating_jobs) 的文档非常清楚。

    显然,我在知道问题出在哪里之前就开始写这篇文章,并且我认为在某处记录我的调查可能会很有用。现在我已经完成了调查,问题原来是PEBCAK 之一,它可能与这个线程不再那么相关,当然不应该被接受为答案。尽管如此,这里可能有一些有用的信息,关于如何调查 terraform 调用 Google API 的问题,并且它还重申了所需的角色授予,所以我将把它留在这里,以防它变得有用。

    【讨论】:

      【解决方案3】:

      我又遇到了这个问题,所以在这里发布我的解决方案,因为我完全希望我会在某个时候再次被这个问题所困扰。

      我遇到了错误:

      错误:googleapi:错误 403:(a00eba23d59c1fa3):当前用户无法充当服务帐户 dataflow-controller-sa@myproject.iam.gserviceaccount.com。原因:(a00eba23d59c15ac):当前用户无法充当服务帐户 dataflow-controller-sa@myproject.iam.gserviceaccount.com.,禁止

      我正在部署数据流作业,通过 terraform,使用不同的服务帐户 deployer@myproject.iam.gserviceaccount.com

      解决方案是授予该服务帐户roles/iam.serviceAccountUser 角色:

      gcloud projects add-iam-policy-binding myproject \
          --member=serviceAccount:deployer@myproject.iam.gserviceaccount.com \
          --role=roles/iam.serviceAccountUser
      

      对于那些更喜欢自定义 IAM 角色而不是预定义 IAM 角色的用户,缺少的特定权限是 iam.serviceAccounts.actAs

      【讨论】:

        【解决方案4】:

        问题已解决!

        转到 GCP -> 控制台 -> IAM -> ServiceAccount 电子邮件 -> 添加权限 -> 服务帐户用户。如下

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-13
          • 1970-01-01
          • 1970-01-01
          • 2011-08-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多