使用自定义服务帐号部署到 Cloud Run 失败并出现 iam.serviceaccounts.actAs 错误

Posted

技术标签:

【中文标题】使用自定义服务帐号部署到 Cloud Run 失败并出现 iam.serviceaccounts.actAs 错误【英文标题】:Deploying to Cloud Run with a custom service account failed with iam.serviceaccounts.actAs error 【发布时间】:2019-09-11 07:27:29 【问题描述】:

我在我的项目上创建了一个自定义服务帐户 travisci-deployer@PROJECT_ID.iam.gserviceaccount.com 并赋予它 Cloud Run Admin 角色:

gcloud projects add-iam-policy-binding "$PROJECT_ID" \
   --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
   --role="roles/run.admin"

然后我将此服务帐户设置为我的 gcloud 命令的身份:

gcloud auth activate-service-account --key-file=google-key.json

但是当我运行gcloud beta run deploy 命令时,我收到一个错误提示“Compute Engine 默认服务帐户”没有iam.serviceAccounts.actAs 权限:

gcloud beta run deploy -q "$SERVICE_NAME" \
  --image="$CONTAINER_IMAGE" \
  --allow-unauthenticated
Deploying container to Cloud Run service [$APP_NAME] in project [$PROJECT_ID] region [us-central1]
Deploying...
Deployment failed
ERROR: (gcloud.beta.run.deploy) PERMISSION_DENIED: Permission 'iam.serviceaccounts.actAs'
denied on service account 1075231960084-compute@developer.gserviceaccount.com

这对我来说似乎很奇怪(因为我没有使用 GCE 默认服务帐户身份,尽管 Cloud Run 应用在部署应用后会使用它)。

所以1075231960084-compute@developer.gserviceaccount.com 帐户被用于API 调用,而不是我在gcloud 上配置的travisci-deployer@PROJECT_ID.iam.gserviceacount 服务帐户?

我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

TLDR:将 Cloud Run AdminService Account User 角色添加到您的服务帐户

如果我们详细阅读 Cloud Run 的 IAM 参考页面的文档,该页面位于 here,我们会发现以下文本:

用户需要以下权限才能部署新的 Cloud Run 服务或修订:

run.services.createrun.services.update 在项目级别。 通常通过roles/run.admin 角色分配。它可以改变 在项目权限管理页面中。 iam.serviceAccounts.actAs 为 Cloud Run 运行时服务帐号。默认情况下,这是 PROJECT_NUMBER-compute@developer.gserviceaccount.com。许可 通常通过roles/iam.serviceAccountUser 角色分配。

我认为这些额外的步骤可以解释你所看到的故事。

【讨论】:

特别是,如果roles/iam.serviceAccountUser 未被选中,则具有run.* 权限的用户可以执行运行该服务的服务帐户可以执行的任何操作(通过持有代码为他们做这件事,可能包括使用已知登录凭据启动计算 VM)。要求对服务的服务帐户actAs 的权限通过明确要求的权限来弥补这个漏洞。 现在说得通了,谢谢!我正在考虑使用 Travis CI 教程 cloud.google.com/solutions/continuous-delivery-with-travis-ci 部署到 GAE,但看不到类似的东西,这让我感到困惑。 仅供参考:拥有Cloud Run Admin 角色不足以部署,您还需要拥有Cloud Run Service Agent 角色。【参考方案2】:

Cloud Run AdminService Account User 角色添加到我自己的服务帐户为我解决了这个问题。请参阅此处文档中的第 2 步: https://cloud.google.com/run/docs/continuous-deployment#continuous

【讨论】:

这就是上面接受的答案所说的。 您是对的,但我发现按照我的答案中链接中提供的说明进行操作要容易得多(也许对于其他不太熟悉配置 IAM 权限的人来说也是如此)。【参考方案3】:

虽然您可以通过授予帐户权限以充当 Compute Engine 默认服务帐户来解决此特定错误,但它违反了"best practices" advice:

默认情况下,Cloud Run 服务作为默认的 Compute Engine 服务帐号运行。但是,Google 建议使用具有最少权限的用户管理服务帐户。在 Cloud Run 服务标识文档中了解如何使用用户管理的服务帐号部署 Cloud Run 服务。

您可以指示 Cloud Run 部署将采用哪个服务帐号身份,如下所示:

gcloud run deploy -q "$SERVICE_NAME" \
  --image="$CONTAINER_IMAGE" \
  --allow-unauthenticated \
  --service-account "$SERVICE_ACCOUNT_EMAIL"

【讨论】:

【参考方案4】:

目前,在测试版中,所有 Cloud Run 服务都作为默认计算帐户运行(与 Google Compute Engine 默认服务帐户相同)。

未来版本将提供以不同服务帐户运行服务的功能。

【讨论】:

以上是关于使用自定义服务帐号部署到 Cloud Run 失败并出现 iam.serviceaccounts.actAs 错误的主要内容,如果未能解决你的问题,请参考以下文章

Google Cloud Run(完全托管):无法自定义域映射

Docker 映像在本地部署,但在 Google Cloud Run 上失败

如何获取或生成Google Cloud Run服务的部署URL

是否可以在同一个 Cloud Run 服务中部署两个不同的 docker 镜像

Google Cloud Run 身份验证服务到服务

为 Google Cloud Run 自定义域禁用弱密码套件?