排查 Cloud Run functions 问题

本文档介绍了如何在使用 Cloud Run functions 时排查错误消息并解决问题。 如果您是使用 Cloud Run 创建或部署的函数,请参阅 Cloud Run 问题排查

部署

本部分列出了您可能遇到的部署问题,并提供了有关如何解决这些问题的建议。您在部署期间可能遇到的许多问题都与角色和权限或错误配置有关。

您可以使用 Identity and Access Management 授权身份对使用 Cloud Functions v2 API 创建的函数执行管理操作,例如使用 gcloud functions、REST API 或 Terraform 执行操作。管理操作包括创建、更新和删除函数。如需了解详情,请参阅使用 IAM 授予访问权限

部署函数时,用户缺少运行时服务账号的权限

每个函数都与一个服务账号关联,该服务账号充当函数访问其他资源时的身份。此运行时服务账号可以是默认服务账号,也可以是用户管理的服务账号。在多个函数正在访问不同资源的环境中,通常的做法是使用每个函数身份,并使用命名的运行时服务账号而不是默认的运行时服务账号 (PROJECT_NUMBER-compute@developer.gserviceaccount.com)。

如需使用运行时服务账号,部署者必须具有该服务账号的 iam.serviceAccounts.actAs 权限。创建非默认运行时服务账号的用户将自动获得此权限,但其他部署者必须由某一用户授予此权限。

使用 Project Viewer、Cloud Functions Developer 或 Cloud Functions Admin 角色为用户分配运行时服务账号的 iam.serviceAccounts.actAs 权限。

错误消息

控制台

  You must have the iam.serviceAccounts.actAs permission on the selected service account. To obtain this permission, you can grant a role that includes it like the Service Account User role, on the project.

gcloud

默认服务账号:

ERROR: (gcloud.functions.deploy) ResponseError: status=[403], code=[Ok], message=[Caller is missing permission 'iam.serviceaccounts.actAs' on service account projects/-/serviceAccounts/PROJECT_NUMBER-compute@developer.gserviceaccount.com.Grant the role 'roles/iam.serviceAccountUser' to the caller on the service account projects/-/serviceAccounts/PROJECT_NUMBER-compute@developer.gserviceaccount.com.You can do that by running 'gcloud iam service-accounts add-iam-policy-binding projects/-/serviceAccounts/PROJECT_NUMBER-compute@developer.gserviceaccount.com --member MEMBER --role roles/iam.serviceAccountUser'where MEMBER has a prefix like 'user:' or 'serviceAccount:'

非默认服务账号:

ERROR: (gcloud.functions.deploy) ResponseError: status=[403], code=[Ok], message=[Caller is missing permission 'iam.serviceaccounts.actAs' on service account projects/-/serviceAccounts/
SERVICE_ACCOUNT_NAME@PROJECT_ID
.iam.gserviceaccount.com.Grant the role 'roles/iam.serviceAccountUser' to the caller on the service account projects/-/serviceAccounts/
SERVICE_ACCOUNT_NAME@PROJECT_ID
.iam.gserviceaccount.com.You can do that by running 'gcloud iam service-accounts add-iam-policy-binding projects/-/serviceAccounts/
SERVICE_ACCOUNT_NAME@PROJECT_ID
.iam.gserviceaccount.com --member MEMBER --role roles/iam.serviceAccountUser'where MEMBER has a prefix like 'user:' or 'serviceAccount:'

解决方案

在默认或非默认运行时服务账号上为用户分配 Service Account User 角色 (roles/iam.serviceAccountUser)。此角色可提供 iam.serviceAccounts.actAs 权限。

部署事件驱动的函数时,部署服务账号缺少 Pub/Sub 权限

执行管理操作时,Cloud Functions 服务会使用 Cloud Functions Service Agent 服务账号 (service-PROJECT_NUMBER@gcf-admin-robot.iam.gserviceaccount.com)。 默认情况下,此账号拥有 Cloud Functions cloudfunctions.serviceAgent 角色。为了部署事件驱动的函数,Cloud Functions 服务必须访问 Pub/Sub 以配置主题和订阅。如果您更改了分配给服务账号的角色,但未授予适当的权限,则 Cloud Functions 服务将无法访问 Pub/Sub,因此部署将失败。

错误消息

控制台

Validation failed for trigger projects/PROJECT_ID/locations/LOCATION/triggers/FUNCTION_NAME-EVENTARC_ID: Permission "iam.serviceAccounts.ActAs" denied on "EndUserCredentials to PROJECT_NUMBER-compute@developer.gserviceaccount.com"

gcloud

ERROR: (gcloud.functions.deploy) ResponseError: status=[403], code=[Ok], message=[Validation failed for trigger projects/test-project-356312/locations/LOCATION/triggers/FUNCTION_NAME-EVENTARC_ID: Permission "iam.serviceAccounts.ActAs" denied on "EndUserCredentials to PROJECT_NUMBER-compute@developer.gserviceaccount.com"]

解决方案

您可以重置服务账号为默认的 cloudfunctions.serviceAgent 角色。

默认运行时服务账号不存在

如果您未指定用户管理的运行时服务账号,Cloud Functions 会使用默认的计算服务账号作为运行时服务账号。如果您删除默认账号但未指定用户管理的账号,部署将会失败。

错误消息

gcloud

ERROR: (gcloud.functions.deploy) ResponseError: status=[404], code=[Ok], message=[Service account projects/-/serviceAccounts/PROJECT_NUMBER-compute@developer.gserviceaccount.com was not found.]

解决方案

如需解决此问题,请按以下任一解决方案操作:

部署函数时,Cloud Functions Service Agent 服务账号缺少项目存储桶权限

Cloud Run functions 函数只能由来自同一 Google Cloud Platform 项目中的 Cloud Storage 存储桶的事件触发。此外,Cloud Functions Service Agent 服务账号 (service-PROJECT_NUMBER@gcf-admin-robot.iam.gserviceaccount.com) 需要项目的 cloudfunctions.serviceAgent 角色。

错误消息

控制台

ERROR: (gcloud.functions.deploy) ResponseError: status=[403], code=[Ok], message=[Validation failed for trigger projects/PROJECT_ID/locations/LOCATION/triggers/FUNCTION_NAME-EVENTARC_ID: Permission "iam.serviceAccounts.ActAs" denied on "EndUserCredentials to PROJECT_NUMBER-compute@developer.gserviceaccount.com"]

gcloud

ERROR: (gcloud.functions.deploy) ResponseError: status=[403], code=[Ok], message=[Validation failed for trigger projects/<project-id>/locations/LOCATION/triggers/FUNCTION_NAME-EVENTARC_ID: Permission "iam.serviceAccounts.ActAs" denied on "EndUserCredentials to PROJECT_NUMBER-compute@developer.gserviceaccount.com"]

解决方案

如需解决此问题,请重置此服务账号为默认角色。

拥有 Project Editor 角色的用户无法公开函数

Project Editor 角色具有管理项目内资源的广泛权限,但它本身并不授予公开 Cloud Functions 的权限。部署该函数的用户或服务将需要 run.services.setIamPolicy 权限。

错误消息

gcloud

ERROR: (gcloud.run.services.add-iam-policy-binding) PERMISSION_DENIED: Permission 'run.services.setIamPolicy' denied on resource 'projects/PROJECT_ID/locations/LOCATION/functions/FUNCTION_NAME' (or resource may not exist).

解决方案

您可以:

使用资源位置限制条件组织政策时,函数部署失败

如果您的组织使用资源位置限制条件政策,则会限制将函数部署在受该政策限制的区域中。在 Google Cloud 控制台中部署函数时,可选区域下拉列表中不会显示受限区域。

错误消息

gcloud

ResponseError: status=[400], code=[Ok], message=["LOCATION" violates constraint "constraints/gcp.resourceLocations" on the resource "projects/PROJECT_ID/locations/LOCATION/functions/FUNCTION_NAME".]

解决方案

您可以通过资源位置限制条件的 allowed_valuesdenied_values 列表添加或移除位置,以便成功部署。

执行函数的全局范围时函数部署失败

此错误表示您的代码存在问题。部署流水线已完成函数部署,但最后一步完成了,即向该函数发送健康检查。此健康检查用于执行函数的全局范围,这可能会导致异常、崩溃或超时。全局范围是您通常加载的库并初始化客户端的位置。

错误消息

在 Cloud Logging 日志中:

Could not create or update Cloud Run service FUNCTION_NAME, Container Healthcheck failed. Revision REVISION_NAMEE is not ready and cannot serve traffic. The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable. Logs for this revision might contain more information.

解决方案

如需解决此问题,请按以下任一解决方案操作:

  • 如需查看更详细的错误消息,请查看函数的构建日志

  • 如果不清楚函数为何无法执行其全局范围,请考虑使用全局变量延迟加载,暂时将代码移动到请求调用中。这样,您就可以围绕您的客户端库添加额外的日志语句,这些语句可能会在其实例化时超时(尤其是当调用其他服务时),也可能完全崩溃/抛出异常。

  • 此外,请尝试增加函数超时。Cloud Run functions 的超时限制越长,初始化的喘息空间就越大,并且在 Cloud Run 环境中提供了可扩缩的资源分配,从而有可能缓解资源耗尽所造成的这个问题。

  • 源代码必须包含通过 Cloud 控制台gcloud 在部署中正确指定的入口点函数。

具有 Viewer 角色的用户无法部署函数

拥有 Project Viewer 或 Cloud Functions Viewer 角色的用户对函数和函数详细信息具有只读权限,并且无法部署新函数。创建函数功能在Google Cloud 控制台中呈灰显状态,并显示以下错误:

错误消息

gcloud

ERROR: (gcloud.functions.deploy) ResponseError: status=[403], code=[Ok], message=[Permission 'cloudfunctions.functions.generateUploadUrl' denied on 'projects/PROJECT_ID/locations/LOCATION/functions']

解决方案

为用户分配 Cloud Functions Developer 角色。

Build 服务账号缺少权限

错误消息

在函数部署错误或构建日志中,您可能会看到以下错误之一:

The service account running this build does not have permission to write logs. To fix this, grant the Logs Writer (roles/logging.logWriter) role to the service account.
Step #0 - "fetch": failed to Fetch: failed to download archive gs://gcf-v2-sources-PROJECT_NUMBER-LOCATION/FUNCTION_NAME/version-VERSION_NUMBER/function-source.zip: Access to bucket gcf-v2-sources-PROJECT_NUMBER-LOCATION denied. You must grant Storage Object Viewer permission to PROJECT_NUMBER-compute@developer.gserviceaccount.com.
Step #2 - "build": ERROR: failed to create image cache: accessing cache image "LOCATION-docker.pkg.dev/PROJECT/gcf-artifacts/FUNCTION_NAME/cache:latest": connect to repo store "LOCATION-docker.pkg.dev/PROJECT/gcf-artifacts/FUNCTION_NAME/cache:latest": GET https://LOCATION-docker.pkg.dev/v2/token?scope=repository%3APROJECT%2Fgcf-artifacts%2FFUNCTION_NAME%2Fcache%3Apull&service=: DENIED: Permission "artifactregistry.repositories.downloadArtifacts" denied on resource "projects/PROJECT/locations/LOCATION/repositories/gcf-artifacts" (or it may not exist)
Could not build the function due to a missing permission on the build service account. If  you didn't revoke that permission explicitly, this could be caused by a change in the organization policies.

解决方案

Build 服务账号需要具备从源存储桶读取数据的权限以及对制品部署代码库的读写权限。如果 Cloud Build 使用服务账号的默认行为发生了变化,您可能会遇到此错误,详情请参阅 Cloud Build 服务账号更改

如需解决此问题,请使用以下任一解决方案:

Build 服务账号已停用

错误消息

Could not build the function due to disabled service account used by Cloud Build. Please make sure that the service account is active.

解决方案

您需要启用 Build 服务账号才能部署函数。如果 Cloud Build 使用服务账号的默认行为发生了变化,您可能会遇到此错误,详情请参阅 Cloud Build 服务账号更改

如需解决此问题,请使用以下任一解决方案:

服务

本部分列出了您可能遇到的服务问题,并提供了有关如何修复这些问题的建议。

由于函数需要身份验证,服务权限出错

未启用允许未经身份验证的调用的 HTTP 函数将会限制没有适当权限的最终用户和服务账号的访问。此错误消息表示调用者无权调用函数。

错误消息

HTTP 错误响应代码:403 禁止

HTTP 错误响应正文:

Error: Forbidden Your client does not have permission
to get URL /FUNCTION_NAME from this server.

解决方案

如需解决此问题,请按以下任一解决方案操作:

由于 allow internal traffic only 配置问题导致服务错误

入站流量设置可以限制能否通过您的 Google Cloud 项目或 VPC Service Controls 服务边界之外的资源调用 HTTP 函数。如果为入站网络配置了仅允许内部流量设置,则此错误消息会指明仅允许从同一项目或 VPC Service Controls 边界内的 VPC 网络发起请求。这也可能是默认 functions.net 网址的 404 错误

错误消息

HTTP 错误响应代码:404 未找到

解决方案

如需解决此错误,请按以下任一解决方案操作:

  • 确保请求来自您的 Google Cloud 项目或 VPC Service Controls 服务边界。

  • 将函数的入站流量设置更改为允许所有流量

  • Cloud Run functions 源代码也可能会因函数网址、HTTP 方法、逻辑错误等不正确而导致 404 错误。

函数调用缺少有效的身份验证凭据

调用用访问受限设置的 Cloud Run functions 需要 ID 令牌访问令牌刷新令牌不起作用。

错误消息

HTTP 错误响应代码:401 未授权

HTTP 错误响应正文:

Your client does not have permission to the requested URL 'FUNCTION_NAME'

解决方案

如需解决此错误,请按以下任一解决方案操作:

  • 确保您的请求包含 Authorization: Bearer ID_TOKEN 标头,并且该令牌是 ID 令牌,而不是访问令牌或刷新令牌。如果使用服务账号的私钥手动生成此令牌,则必须用自签名 JWT 令牌交换 Google 签名的身份令牌。

    使用请求标头中的身份验证凭据调用 HTTP 函数。例如,您可以使用 gcloud 获取身份令牌,如下所示:

      curl  -H "Authorization: Bearer $(gcloud auth print-identity-token)" 
    https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME

  • 如果您的组织支持进行未经身份验证的调用,请重新部署您的函数以允许未经身份验证的调用。这在测试时非常有用。

  • 确保 JSON Web 令牌 (JWT) 中的 audience (aud) 字段与 Google Cloud 控制台中显示的函数网址完全一致。任何差异(包括额外的相对路径)都会导致身份验证失败并返回 401 响应。

函数停止执行,或在您的代码完成后继续运行

某些 Cloud Run functions 运行时允许用户运行异步任务。如果您的函数创建了此类任务,还必须明确等待这些任务完成。否则,可能会导致您的函数在错误时间停止执行。

错误行为

您的函数具有以下行为之一:

  • 您的函数会在异步任务仍在运行期间,但在指定的超时期限之前终止。
  • 当这些任务完成后,您的函数不会停止运行,而是继续运行,直到超时期结束。

解决方案

如果您的函数提前终止,则应确保在函数执行以下任何操作之前,函数的所有异步任务都已完成:

  • 返回一个值
  • 解决或拒绝返回的 Promise 对象(仅限 Node.js 函数)
  • 抛出未捕获的异常或错误
  • 发送 HTTP 响应
  • 调用回调函数

如果您的函数在完成异步任务后未能终止,您应在函数运行完成后验证其是否正确发出了 Cloud Run functions 信号。特别是,确保在函数完成其异步任务之后,立即执行上面列出的操作之一。

访问受 VPC Service Controls 保护的资源时出现运行时错误

默认情况下,Cloud Run functions 使用公共 IP 地址向其他服务发出出站请求。如果您的函数不在 VPC Service Controls 边界内,则在尝试访问受 VPC Service Controls 保护的 Google Cloud 服务时,可能由于服务边界拒绝而导致收到 HTTP 403 响应。

错误消息

在“已审核的资源”日志中,如下所示的条目:

"protoPayload": {
  "@type": "type.googleapis.com/google.cloud.audit.AuditLog",
  "status": {
    "code": 7,
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.PreconditionFailure",
        "violations": [
          {
            "type": "VPC_SERVICE_CONTROLS",
  ...
  "authenticationInfo": {
    "principalEmail": "CLOUD_FUNCTION_RUNTIME_SERVICE_ACCOUNT",
  ...
  "metadata": {
    "violationReason": "NO_MATCHING_ACCESS_LEVEL",
    "securityPolicyInfo": {
      "organizationId": "ORGANIZATION_ID",
      "servicePerimeterName": "accessPolicies/NUMBER/servicePerimeters/SERVICE_PERIMETER_NAME"
  ...

解决方案

如需解决此错误,请按以下任一解决方案操作:

可伸缩性

本部分列出了可伸缩性问题,并提供了有关如何修复每个问题的建议。

与待处理队列请求中止相关的 Cloud Logging 错误

以下场景可能会发生扩缩故障: