Google Cloud Build 中的应用程序默认凭据

Application Default Credentials in Google Cloud Build

在我的代码中,我试图从 Cloud Build 中的关联服务帐户收集应用程序默认凭据:

from google.auth import default

credentials, project_id = default()

这在我的本地 space 中工作正常,因为我已经适当地设置了环境变量 GOOGLE_APPLICATION_CREDENTIALS。但是,当在 Cloud Build 中执行此行(通过我的构建配置中的测试步骤)时,会引发以下错误:

google.auth.exceptions.DefaultCredentialsError: Could not automatically determine credentials. 
Please set GOOGLE_APPLICATION_CREDENTIALS or explicitly create credentials and re-run the application. 
For more information, please see https://cloud.google.com/docs/authentication/getting-started

这让我感到困惑,因为根据文档:

By default, Cloud Build uses a special service account to execute builds on your behalf. This service account is called the Cloud Build service account and it is created automatically when you enable the Cloud Build API in a Google Cloud project. Read Here

If the environment variable GOOGLE_APPLICATION_CREDENTIALS isn't set, ADC uses the service account that is attached to the resource that is running your code. Read Here

那么为什么默认调用无法访问 Cloud Build 服务帐户凭据?

应用程序默认凭据 (ADC) 定义了搜索凭据的方法。

Cloud Build VM 实例正在通过对 169.254.169.254 的网络调用从 元数据 中获取凭据。您所在的容器 运行 无法访问主机的网络,这意味着 Docker 容器内的代码 运行 无法访问主机的元数据。由于您的容器内没有其他凭据,ADC 失败并显示消息 Could not automatically determine credentials.

解决方案:提供在 Docker 容器内可访问的凭据。

一种方法是在 Cloud Storage 中存储服务帐户 JSON 密钥文件。然后配置 Cloud Build 以下载文件。配置 Docker 文件以将文件复制到映像中。

云构建 YAML:

- name: gcr.io/cloud-builders/gsutil
  args: ['cp', 'gs://bucketname/path/service-account.json', 'service-account.json']

Docker文件:

COPY ./service-account.json /path/service-account.json

Google 提供额外的服务,例如也可以使用的 Secret Manager。我更喜欢云存储,因为存储和更新凭据的便利性提供了轻松的文档和管理。

在考虑有关安全、权限分离和管理的问题时Google Cloud 提供了几种方法。

另一种方法是 发布的方法。

在安全性宽松且开发人员被授予广泛权限(IAM 角色)的环境中,Guillaume 的答案简单易行。在严格控制的安全环境中,授予 Cloud Build 广泛的权限存在安全风险。

安全性通常是安全性、实施和易用性之间的权衡。授予 IAM 角色需要仔细考虑如何使用权限以及 what/who.

有一个技巧:您必须定义要在 Docker 构建中使用的网络。使用参数--network=cloudbuild,像那样

steps:
  - name: gcr.io/cloud-builders/docker
    entrypoint: 'docker'
    args: 
      - build
      - '--no-cache'
      - '--network=cloudbuild'
      - '-t'
      - '$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA'
      - .
      - '-f' 
      - 'Dockerfile'
...

您可以找到文档 here