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

35

我在我的项目上创建了一个自定义服务帐户travisci-deployer@PROJECT_ID.iam.gserviceaccount.com,并将其授予Cloud Run管理员角色:

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命令时,出现了一个关于“计算引擎默认服务帐号”没有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服务账号吗?

我该如何解决这个问题?

5个回答

55

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

如果我们仔细阅读 此处 Cloud Run 的 IAM 参考页面的文档,我们会发现以下文字:

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

  • 在项目级别上具有 run.services.createrun.services.update 权限。通常通过 roles/run.admin 角色分配。可以在项目权限管理页面中更改此设置。
  • 针对 Cloud Run 运行时服务帐户的 iam.serviceAccounts.actAs 权限。默认情况下,此为 PROJECT_NUMBER-compute@developer.gserviceaccount.com。通常通过 roles/iam.serviceAccountUser 角色分配。

我认为这些额外步骤可以解释您所看到的情况。


2
特别是,如果没有检查 roles/iam.serviceAccountUser,那么拥有 run.* 权限之一的用户可以做服务帐户运行的服务所能做的任何事情(通过持有执行该操作的代码,可能包括使用已知登录凭据启动计算 VM)。要求具有 actAs 服务帐户的权限可以通过明确要求所需的权限来关闭此漏洞。 - E. Anderson
现在我明白了,谢谢!我一直在看如何使用Travis CI部署到GAE的教程https://cloud.google.com/solutions/continuous-delivery-with-travis-ci,但是没有看到类似这样的内容,让我感到困惑。 - ahmet alp balkan
15
FYI:拥有“Cloud Run管理员”角色不足以进行部署,您还需要拥有“Cloud Run服务代理”的角色。 - CenterOrbit
我对GCP特别是IAM部分的遗憾是,在添加角色时,无法直接在列表中搜索到所需特权的技术名称。你怎么能快速找到iam.serviceAccounts.actAs等同于Service Account User?如果你在文本框中快速输入"service accounts",它不会出现...因为它是复数形式...搜索引擎应该允许同时搜索技术名称和人类名称。 - undefined

14

这就是上面被接受的答案所说的字面意思。 - ahmet alp balkan
1
你说得没错,但我发现按照我回答中提供的链接中的说明更容易理解(对于那些不太熟悉配置 IAM 权限的人也是如此)。 - Tobi
@ahmet,不是的。这提供了明确的步骤链接,而不是一般性的解释。两者都有用,但并不相同。 - thclark

1
为了最佳实践,您应该仅为Cloud Run实例允许特定权限。
参考文献:https://cloud.google.com/run/docs/reference/iam/roles#additional-configuration 假设您在GCP中有两个服务帐户。
一个是Clound Run身份服务帐户/运行时服务帐户。
让它成为identity-cloudrun@project-id.iam.gserviceaccount.com,这个服务帐户不需要分配任何权限,因为它只是作为Cloud Run的标识。如果您需要此Cloud Run实例访问其他GCP资源,则可以为此服务帐户添加一些权限。
另一个是用于部署Cloud Run的Deployment Service account
将其设置为deploy-cloudrun@project-id.iam.gserviceaccount.com 对于Deployment Service account,您需要授予Cloud Run管理员权限,以针对your-cloudrun-instance进行特定配置。因此,它无法访问其他Cloud Run实例。
gcloud run services add-iam-policy-binding your-cloudrun-instance \
--member="serviceAccount:deploy-cloudrun@project-id.iam.gserviceaccount.com" \
--role="roles/run.admin" \
--region=europe-west1

此外,您需要授予身份服务账户iam.serviceAccounts.actAs权限给您的部署服务账户。文档中已经提到了这一点。
gcloud iam service-accounts add-iam-policy-binding \
identity-cloudrun@project-id.iam.gserviceaccount.com \
--member="serviceAccount:deploy-cloudrun@project-id.iam.gserviceaccount.com" \
--role="roles/iam.serviceAccountUser"

因此,您可以通过您的部署服务帐户来部署您的云运行如下。

注意:实际上,您应该使用工作负载身份联合而不是直接使用您的部署服务帐户

gcloud run deploy your-cloudrun-instance \
--image="us-docker.pkg.dev/cloudrun/container/hello" \
--service-account="identity-cloudrun@project-id.iam.gserviceaccount.com"

-2

虽然你可以通过授予该帐户代表Compute Engine默认服务帐户的权限来解决这个特定的错误,但是这违背了“最佳实践建议”:

默认情况下,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服务在beta版中都作为默认计算帐户运行(与Google Compute Engine默认服务帐户相同)。

将来的版本中将提供使用不同服务帐户运行服务的功能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接