构建流程概览

本指南介绍了使用 gcloud functions 命令部署的函数的构建流程概览。如需了解使用 gcloud run 命令部署的函数的构建流程,请参阅:

使用 gcloud functions deploy 命令部署函数的源代码时,该源代码会存储在 Cloud Storage 存储桶中。Cloud Build 随后会自动将您的代码构建到容器映像中,并将该映像推送到映像注册表

构建映像的过程完全自动执行,不需要您直接输入。构建过程中使用的所有资源都会在您自己的用户项目中执行。

在您的项目中执行构建过程意味着:

  • 您可以直接访问所有构建日志。

  • 尽管 Cloud Build 确实有自己的默认并发配额,但没有预设的构建时间配额。

  • 您可以查看当前容器映像和以前部署的容器映像,这两个映像均存储在 Artifact Registry 中。

  • Cloud Storage 会在项目中用于存储函数的源代码目录。请注意以下几点:

    • 如果您使用 Google Cloud CLI 创建函数,系统会创建一个上传存储桶来存储源代码。此上传存储桶的名称为 gcf-v2-uploads-PROJECT_NUMBER-REGION.cloudfunctions.appspot.com
    • 上传代码后,函数代码会存储在单独的源代码存储桶中:
      • 如果您使用的是默认加密,则该存储桶的名称为 gcf-v2-sources-PROJECT_NUMBER-REGION
      • 如果您使用 CMEK 保护数据,则该存储桶的名称为 gcf-v2-sources-PROJECT_NUMBER-REGION-CMEK_KEY_HASH
    • 源存储桶和上传存储桶都没有保留期限。

构建流程的特征

构建流程具有以下特征:

  • 您必须为您的项目启用 Cloud Build API

    如需手动启用 API,请点击前面的链接,从下拉菜单中选择您的项目,然后按照提示启用界面。

  • 因为整个构建流程都是在您的项目环境内进行的,所以该项目需要根据所包含资源的价格进行计费:

    • 如需了解 Cloud Build 价格,请参阅价格页面。此过程使用 Cloud Build 的默认实例大小,因为这些实例已经过预热,可以更快地投入使用。Cloud Build 提供了免费层级:请查看价格文档以进一步了解详情。

    • 如需了解 Cloud Storage 价格,请参阅价格页面。Cloud Storage 提供了免费层级:请查看价格文档以进一步了解详情。

    • 如需了解 Artifact Registry 价格,请参阅价格页面。

  • 由于构建过程需要计费,因此您的项目必须附加 Cloud Billing 账号

查看构建映像日志

将构建映像过程纳入您的用户项目的一个主要好处是可以访问构建日志。您可以使用 gcloud CLI 或 Google Cloud 控制台来访问日志,这些日志可通过 Cloud Logging 获得。

gcloud

  1. 使用 gcloud functions deploy 命令部署函数。

  2. 日志的网址在终端窗口中显示为响应的一部分。例如:

    Deploying function (may take a while - up to 2 minutes)...⠹
    **For Cloud Build Stackdriver Logs**, visit:
    https://console.cloud.google.com/logs/viewer?project=&advancedFilter=resource.type%
    3Dbuild%0Aresource.labels.build_id%3D38d5b662-2315-45dd-8aa2-
    380d50d4f5e8%0AlogName%3Dprojects%2F%
    2Flogs%2Fcloudbuild
    Deploying function (may take a while - up to 2 minutes)...done.

Google Cloud 控制台

如需使用 Cloud Run 页面查看函数日志,请执行以下操作:

  1. 转到 Cloud Run

  2. 在显示的列表中点击所选函数。

  3. 点击日志标签页,以获取此函数的所有修订版本的请求日志及容器日志。您可以按日志严重级别进行过滤。

映像注册表

Artifact Registry 用于存储通过函数源代码构建的映像。映像存储在名为 REGION-docker.pkg.dev/PROJECT_ID/gcf-artifacts 的代码库中,该代码库位于创建函数的项目中。

如需指定自行管理的 Artifact Registry 代码库,请运行以下命令:

gcloud functions deploy FUNCTION_NAME \
   --docker-repository=REPOSITORY \
   [FLAGS...]

替换以下内容:

  • FUNCTION_NAME:函数的名称。
  • REPOSITORY:完全限定的 Artifact Registry 代码库名称,格式如下:projects/PROJECT_NAME/locations/LOCATION/repositories/REPOSITORY

指定位于其他项目或区域的 Artifact Registry 仓库时,您可能需要考虑其他配置:

IAM 配置:

  • IAM 配置:确保 build 服务账号已获得 REPOSITORY 的读写权限的授权。
  • 网络配置:确保当前项目配置可访问目标 REPOSITORY
  • VPC Service Controls 配置:确保 build 服务账号可以访问 VPC-SC 边界内的目标 REPOSITORY
  • 数据驻留限制:如果在与函数所在区域不同的区域中指定 REPOSITORY,系统会跨区域传输数据。

使用专用池保护构建

为了允许您的函数使用依赖项(例如 npm 软件包),Cloud Build 默认在构建过程中具有不受限制的互联网访问权限。如果您已设置 VPC Service Controls (VPC SC) 边界,并且希望限制构建仅可访问存储在边界内的依赖项,则可以使用 Cloud Build 专用工作器池功能。

一般来说,请按照以下步骤设置您的专用池:

  1. 创建专用工作器池。请参阅创建和管理专用池
  2. 配置 VPC Service Controls 边界。请参阅使用 VPC Service Controls

  3. 如果专用工作器池与函数不在同一个项目中,则需要向 Cloud Functions Service Agent 服务账号 (service-FUNCTION_PROJECT_NUMBER@gcf-admin-robot.iam.gserviceaccount.com) 授予 cloudbuild.workerPoolUser 角色,以便 Cloud Build 服务可以访问工作器池。

    gcloud projects add-iam-policy-binding PRIVATE_POOL_PROJECT_ID \
        --member serviceAccount:service-FUNCTION_PROJECT_NUMBER@gcf-admin-robot.iam.gserviceaccount.com
        --role roles/cloudbuild.workerPoolUser

    FUNCTION_PROJECT_NUMBER 替换为运行函数的项目的编号,将 PRIVATE_POOL_PROJECT_ID 替换为工作器池所在项目的 ID。如需了解详情,请参阅在专用池中运行构建

  4. 部署函数以使用专用池进行构建:

    gcloud functions deploy FUNCTION_NAME \
       --runtime RUNTIME \
       --build-worker-pool PRIVATE_POOL_NAME
       [FLAGS...]

    FUNCTION_NAME 替换为函数的名称,将 RUNTIME 替换为您正在使用的运行时,将 PRIVATE_POOL_NAME 替换为您的池名称。

如需停止使用给定专用池,并使用默认 Cloud Build 池,请在重新部署时使用 --clear-build-worker-pool 标志。

gcloud functions deploy FUNCTION_NAME \
   --runtime RUNTIME \
   --clear-build-worker-pool
   [FLAGS...]

FUNCTION_NAME 替换为函数的名称,将 RUNTIME 替换为您正在使用的运行时。

使用自定义服务账号保护 build

您的函数的源代码会发送到 Cloud Build 进行容器化。容器化函数存储在 Artifact Registry 中,并作为服务部署到 Cloud Run。Cloud Run functions 在构建和部署 Cloud Run 函数时会利用 Cloud Build。默认情况下,Cloud Run functions 在执行构建时,原则上使用默认的 Cloud Build 服务账号。从 2024 年 7 月开始,Cloud Build 更改了 Cloud Build 在新项目中使用服务账号的默认行为。由于此更改,首次部署函数的新项目可能会使用权限不足的默认 Cloud Build 服务账号来构建函数。

对于在 2024 年 7 月之前创建的 Google Cloud 项目,Cloud Build 会使用旧版 Cloud Build 服务账号。该服务账号旨在帮助用户执行广泛的用例,这些用例可能对于您的项目需求来说过于宽松。如果您想将现有项目从此服务账号中移出,则可以采取以下步骤进一步保护您的函数构建环境:

禁止将旧版 Cloud Build 服务账号用于 build

您可以检查函数 build 的详细信息,以验证您的项目是否使用了旧版 Cloud Build 服务账号。默认 build 服务账号的格式如下:

PROJECT_NUMBER@cloudbuild.gserviceaccount.com

您可以将组织政策限制条件 cloudbuild.useBuildServiceAccount 设置为 Not Enforced,从而强制停用此服务账号。或者,移除其所有角色授权也会限制其访问 Google Cloud资源的权限。

禁止将默认的 compute 服务账号用于 build

默认的 compute 服务账号的格式为 PROJECT_NUMBER-compute@developer.gserviceaccount.com。您可以将组织政策 cloudbuild.useComputeServiceAccount 设为 Not Enforced,以禁止将其用作 build 的默认值。或者,您也可以停用此服务账号,以防止其用于访问 Google Cloud 资源。

提供用于构建函数的服务账号

在配置函数的过程中,您可以在部署函数时指定 build 服务账号。当旧版 Cloud Build 服务账号和默认的 compute 服务账号无法用于 build 时,您必须指定 build 服务账号才能部署函数,如本部分所述。

如果您受到 Cloud Build 服务账号更改中所述更改的影响,可以执行以下操作之一:

  • 查看 Cloud Build 指南,了解默认服务账号更改并选择不进行这些更改

  • 将 Cloud Build 账号角色 (roles/cloudbuild.builds.builder) 添加到默认的 Compute Engine 服务账号。

  • 为函数部署创建自定义 Cloud Build 服务账号。

在如下一些场景中,您可能需要提供其他服务账号,以便在 Cloud Build 构建函数时使用:

  • 您希望更好地控制要将哪些服务账号添加到 VPC-SC 边界。

  • 您希望 Cloud Build 以与默认服务账号不同的权限运行,而不必单独撤消每项权限。

  • 您希望专门为函数设置精细的 Cloud Build 权限,而不是共享针对其他用途进行优化的 Cloud Build 服务账号。

  • 您的组织已停用默认服务账号。

以下部分介绍了如何为函数部署创建自定义 Cloud Build 服务账号。

创建服务账号

按照创建服务账号中所述创建新的服务账号。

授予权限

您使用的服务账号需要具有以下角色:

  • roles/logging.logWriter - 在 Cloud Logging 中存储构建日志时需要此角色。
  • roles/artifactregistry.writer - 在 Artifact Registry 中存储构建映像时需要此角色。 对于默认行为,服务账号需要访问名为“gcf-artifacts”和“cloud-run-source-deploy”的代码库。您可以在代码库的 IAM 政策中设置对代码库的访问权限。或者,您也可以通过 dockerRepository 字段提供您自己的制品库。
  • roles/storage.objectViewer - 从 Cloud Storage 存储桶检索函数源代码以及将构建映像存储在 Container Registry 中需要此角色。 对于默认行为,服务账号需要访问名为“run-sources-*”“gcf-v2-sources-*”和“gcf-v2-uploads-*”的存储分区。可以通过向角色授予的权限添加 IAM 条件来实现此目的,例如:(resource.type == "storage.googleapis.com/Object" && (resource.name.startsWith("projects/_/buckets/gcf-v2-sources-") || resource.name.startsWith("projects/_/buckets/gcf-v2-uploads-") || resource.name.startsWith("projects/_/buckets/run-sources-")))

使用 Google Cloud CLI 或使用 Google Cloud 控制台授予以下角色。

gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:SA_EMAIL \
    --role=roles/logging.logWriter

gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:SA_EMAIL \
--role=roles/artifactregistry.writer

gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:SA_EMAIL \
--role=roles/storage.objectViewer

替换以下内容:

VPC Service Controls 注意事项

如果您使用 VPC Service Controls 边界来保护项目和 Cloud Run functions API,并且您将 Compute Engine 默认服务账号用作 Cloud Run functions 的 Cloud Build Service Account 角色,则必须创建以下入站流量规则:

  • 允许 Compute Engine 默认服务账号入站流量访问 Cloud Storage API 和 Cloud Logging API 上的所有方法。
  • 允许服务账号 service-[PROJECT_NUMBER]@gcf-admin-robot.iam.gserviceaccount.com 入站流量访问 Cloud Storage API 和 Cloud Logging API 上的所有方法。

使用自定义服务账号部署函数

如需在部署函数时传入用户创建的服务账号,以供 Cloud Build 使用,请运行以下 gcloud 命令:

  • --build-service-account 标志指定其凭据用于构建步骤的 IAM 服务账号。如果未提供自定义服务账号,则该函数会将项目的默认服务账号用于 Cloud Build。
  • 您可以视需要使用通过 --build-worker-pool 标志指定的专用池

gcloud functions deploy FUNCTION_NAME \
   --gen2 \
   --region=REGION \
   --project=PROJECT_ID \
   --runtime=RUNTIME \
   --entry-point=CODE_ENTRYPOINT \
   --build-service-account=projects/PROJECT_ID/serviceAccounts/SA_EMAIL \
   --memory=256Mi \
   --trigger-http \
   --source=.

替换以下内容:

授予 Cloud Build 服务账号访问 VPC Service Controls 边界的权限

Cloud Run functions 使用 Cloud Build 将源代码构建到可运行的容器中。如需将 Cloud Run functions 与 VPC Service Controls 搭配使用,您必须将 Cloud Build 服务账号(无论是默认服务账号还是自定义服务账号)配置为有权访问您的服务边界。

查找服务账号名称

如果您使用的是默认 Cloud Build 服务账号,则可以按以下方式找到其名称:

  1. 使用控制台中的 IAM 页面查找 Cloud Build 服务账号。 Google Cloud

    打开 IAM

  2. 确保项目下拉列表中显示了正确的项目。

  3. 搜索 cloudbuild.gserviceaccount.com。 格式为 PROJECT_NUMBER@cloudbuild.gserviceaccount.com 的电子邮件地址是服务账号名称。

如果您有自定义 Cloud Build 服务账号,请改用该名称。

授予服务账号访问服务边界的权限

获知服务账号名称后,请按照按用户或服务账号限制访问权限指南为服务账号创建一个访问权限级别。然后,按照向现有边界添加访问权限级别的说明,将访问权限级别添加到服务边界。