排查 Cloud Run 问题

本页面介绍如何解决 Cloud Run 的问题。

对于下文未列出的其他问题,请查看相应问题是否属于已知问题

部署错误

本部分列出了您可能遇到的部署问题,并提供了有关如何解决这些问题的建议。

容器未能启动

尝试部署时发生以下错误:

Container failed to start. Failed to start and then listen on the port defined by the PORT environment variable.

如需解决此问题,请排除以下可能的原因:

  1. 验证您是否可以在本地运行容器映像。如果您的容器映像无法在本地运行,则需要先在本地诊断并修复问题。

  2. 检查您的容器是否正在侦听预期端口上的请求(如容器运行时合同中所述)。您的容器必须侦听由 Cloud Run 定义并在 PORT 环境变量中提供的端口上的传入请求。 如需了解如何指定端口,请参阅配置容器

  3. 检查您的容器是否正在侦听所有网络接口(通常以 0.0.0.0 表示)。

  4. 按照容器运行时合同的要求,验证您的容器映像是否针对 64 位 Linux 进行了编译。

  5. 使用 Cloud Logging 查找 stdoutstderr 日志中的应用错误。您还可以查找 Error Reporting 中捕获的崩溃

    您可能需要更新代码或修订版本设置来修复错误或崩溃。您还可以在本地排查服务问题

内部错误,超出了资源就绪性截止时间

当您尝试部署或尝试调用其他 Google Cloud API 时,会发生以下错误:

The server has encountered an internal error. Please try again later. Resource readiness deadline exceeded.

当 Cloud Run 服务代理不存在,或者没有 Cloud Run Service Agent (roles/run.serviceAgent) 角色时,可能会发生此问题。

如需验证 Cloud Run 服务代理是否存在于您的 Google Cloud 项目中并具有必要的角色,请执行以下步骤:

  1. 打开 Google Cloud 控制台:

    转到“权限”页面

  2. 权限页面的右上角,选中包括 Google 提供的角色授权复选框。

  3. 主账号列表中,找到 Cloud Run 服务代理的 ID,它使用 ID
    service-PROJECT_NUMBER@serverless-robot-prod.iam.gserviceaccount.com

  4. 验证服务代理是否具有 Cloud Run Service Agent 角色。如果服务代理没有该角色,请授予该角色。

错误:在 /etc/passwd 中找不到用户“root”

尝试部署时发生以下错误:

ERROR: "User \"root\""not found in /etc/passwd

如果使用 --key 参数指定客户管理的加密密钥,则会出现此问题

如需解决此问题,请在 Dockerfile 中指定 USER 0,而不是 USER root

默认的 Compute Engine 服务账号已删除

尝试部署时发生以下错误:

ERROR: (gcloud.run.deploy) User EMAIL_ADDRESS does not have permission to access namespace NAMESPACE_NAME (or it may not exist): Permission 'iam.serviceaccounts.actAs' denied on service account PROJECT_NUMBER-compute@developer.gserviceaccount.com (or it may not exist).

此问题会在以下情况之一下发生:

要解决此问题,请执行以下操作:

  1. 使用 --service-account gcloud 标志指定服务账号。
  2. 验证您指定的服务账号是否具有部署所需的权限

如果您想要验证 Google Cloud 项目中是否存在默认的 Compute Engine 服务代理,请执行以下步骤:

  1. 打开 Google Cloud 控制台:

    转到“权限”页面

  2. 权限页面的右上角,选中包括 Google 提供的角色授权复选框。

  3. 主账号列表中,找到 Compute Engine 服务代理的 ID,它使用 ID
    PROJECT_NUMBER-compute@developer.gserviceaccount.com

Cloud Run Service Agent 无权读取映像

尝试使用存储在 PROJECT-ID-2 的 Container Registry 中的映像从 PROJECT-ID 进行部署时,会发生以下错误:

Google Cloud Run Service Agent must have permission to read the image, gcr.io/PROJECT-ID/IMAGE-NAME. Ensure that the provided container image URL is correct and that above account has permission to access the image. If you just enabled the Cloud Run API, the permissions might take a few minutes to propagate. Note that PROJECT-ID/IMAGE-NAME is not in project PROJECT-ID-2. Permission must be granted to the Google Cloud Run Service Agent from this project.

如需解决此问题,请按以下问题排查建议执行操作:

  • 按照从其他 Google Cloud 项目部署容器映像中的说明进行操作,确保您的主账号具有必要的权限。

  • 如果项目位于 VPC Service Controls 边界内,并且 Cloud Storage API 由于存在限制会禁止来自 Cloud Run 服务代理的请求,则也可能会发生此问题。如需修复此问题,请执行以下操作:

    1. 在 Google Cloud 控制台中打开日志浏览器。(请不要使用 Cloud Run 页面中的日志页面):

      转到日志浏览器

    2. 在查询字段中输入以下文本:

      protoPayload.@type="type.googleapis.com/google.cloud.audit.AuditLog"
      severity=ERROR
      protoPayload.status.details.violations.type="VPC_SERVICE_CONTROLS"
      protoPayload.authenticationInfo.principalEmail="service-PROJECT_NUMBER@serverless-robot-prod.iam.gserviceaccount.com"
      
    3. 如果您在使用此查询后看到任何日志条目,请检查日志条目以确定是否需要更新 VPC Service Controls 政策。 这可能表示您需要将 service-PROJECT_NUMBER@serverless-robot-prod.iam.gserviceaccount.com 添加到预先存在的访问权限政策。

容器导入错误

尝试部署时发生以下错误:

The service has encountered an error during container import. Please try again later. Resource readiness deadline exceeded.

如需解决此问题,请排除以下可能的原因:

  1. 确保容器的文件系统不包含非 utf8 字符。

  2. 某些基于 Windows 的 Docker 映像使用外部层。尽管在存在外部层时,Container Registry 不会抛出错误,但 Cloud Run 的控制层面并不支持外部层。如需解决此问题,您可以尝试在 Docker 守护程序中设置 --allow-nondistributable-artifacts 标志。

传送错误

本部分列出了您可能遇到的传送问题,并提供了有关如何解决这些问题的建议。

HTTP 401:客户端未正确进行身份验证

传送期间出现以下错误:

The request was not authorized to invoke this service

要解决此问题,请执行以下操作:

  • 如果由服务账号调用,则 Google 签名 ID 令牌的受众群体声明 (aud) 必须设置为以下内容:

    • 接收服务的 Cloud Run 网址,格式为 https://service-xyz.run.app
      • Cloud Run 服务必须要求进行身份验证
      • Cloud Run 服务可以通过 Cloud Run 网址或负载均衡器网址调用。
    • 类型为 Web 应用的 OAuth 2.0 客户端 ID,格式为 nnn-xyz.apps.googleusercontent.com
    • 使用提供的确切值的已配置自定义受众群体。例如,如果自定义受众群体为 service.example.com,则受众群体声明 (aud) 值也必须是 service.example.com。如果自定义受众群体为 https://service.example.com,则受众群体声明值也必须是 https://service.example.com
  • jwt.io 工具适用于检查 JWT 中的声明。

  • 如果身份验证令牌的格式无效,则会发生 401 错误。如果令牌采用有效格式,但用于生成令牌的 IAM 成员缺少 run.routes.invoke 权限,则会发生 403 错误

HTTP 403:客户端无权调用服务

当 resource.type = "cloud_run_revision" 时,以下错误不一定会在 Cloud Logging 中出现:

The request was not authenticated. Either allow unauthenticated invocations or set the proper Authorization header

返回给客户端的 HTTP 响应中存在以下错误:

403 Forbidden
Your client does not have permission to get URL from this server.

如需在存在 resource.type = "cloud_run_revision" Cloud Logging 错误时解决此问题

  • 如果该服务用于供任何人调用,请更新其 IAM 设置以公开该服务。
  • 如果该服务仅用于供特定身份调用,请确保使用适当的授权令牌调用该服务
    • 如果由开发者调用由最终用户调用:确保开发者或用户拥有 run.routes.invoke 权限,您可以通过 Cloud Run Admin (roles/run.admin) 和 Cloud Run Invoker (roles/run.invoker) 角色提供该权限。
    • 如果由服务账号调用:确保该服务账号是 Cloud Run 服务的成员,并且具有 Cloud Run Invoker (roles/run.invoker) 角色。
    • 如果调用缺少身份验证令牌,或者采用具有有效格式的身份验证令牌,但用于生成令牌的 IAM 成员缺少 run.routes.invoke 权限,则会导致此 403 错误。

如需在不存在 resource.type = "cloud_run_revision" Cloud Logging 错误时解决此问题:

  • 如果服务将入站流量配置为 All,但由于 VPC Service Controls 而被阻止,则系统可能会返回 403 状态代码。如需详细了解如何排查 VPC Service Controls 被拒问题,请参阅下一部分的 404 错误

HTTP 404:未找到

传送期间出现以下问题:

您遇到 HTTP 404 错误。

要解决此问题,请执行以下操作:

  1. 通过检查 Cloud 控制台中的服务详情页面或运行以下命令,验证您请求的网址是否正确:

    gcloud run services describe SERVICE_NAME | grep URL
    
  2. 检查应用逻辑可能会返回 404 错误代码的位置。如果您的应用返回 404,它将显示在 Cloud Logging 中。

  3. 确保您的应用不会在准备好接收请求之前便开始监听其已配置的端口。

  4. 验证应用在本地运行时是否不会返回 404 错误代码。

如果 Cloud Run 服务的入站流量设置设置为“内部”或“内部和 Cloud Load Balancing”,并且请求不满足指定的网络限制,则系统会返回 404。在这种情况下,请求不会到达容器,并且在以下过滤条件下 Cloud Logging 中不会存在 404

resource.type="cloud_run_revision"
log_name="projects/PROJECT_ID/logs/run.googleapis.com%2Frequests"
httpRequest.status=404

如果使用相同的入站流量设置,VPC Service Controls 可能会根据调用者的上下文(包括项目和 IP 地址)来阻止请求。如需检查是否存在 VPC Service Controls 政策违规行为,请执行以下操作:

  1. 在 Google Cloud 控制台中打开日志浏览器(而不是 Cloud Run 的日志页面):

    转到日志浏览器

  2. 在查询字段中输入以下文本:

    resource.type="audited_resource"
    log_name="projects/PROJECT_ID/logs/cloudaudit.googleapis.com%2Fpolicy"
    resource.labels.method="run.googleapis.com/HttpIngress"
    
  3. 如果您在使用此查询后看到任何日志条目,请检查日志条目以确定是否需要更新 VPC Service Controls 政策。

HTTP 429:无可用容器实例

传送期间出现以下错误:

HTTP 429
The request was aborted because there was no available instance.
The Cloud Run service might have reached its maximum container instance
limit or the service was otherwise not able to scale to incoming requests.
This might be caused by a sudden increase in traffic, a long container startup time or a long request processing time.

如需解决此问题,请检查服务的“容器实例数”指标;如果您的用量接近上限,请考虑增大该限值。请检查“实例数上限”设置,如果您需要使用更多实例,请申请增加配额

HTTP 500:Cloud Run 无法管理流量速率

服务期间出现以下错误,当服务尚未达到其容器实例数量上限时,也可能会发生此错误:

HTTP 500
The request was aborted because there was no available instance

此错误可能由以下任一原因引起:

  • 流量突然激增。
  • 冷启动时间较长。
  • 请求处理时间较长,或请求处理时间突然增加。
  • 服务达到其容器实例数量上限 (HTTP 429)。
  • 归因于 Cloud Run 服务的暂时性因素。

要解决此问题,请解决之前列出的问题。

除了解决这些问题之外,作为解决方法,您还可以为客户端不得丢弃的请求实现指数退避算法和重试。

请注意,仅当您放大到 10 秒的分辨率时,Cloud Monitoring 中才会显示流量或请求处理时间的短暂突然增加。

如果问题的根本原因是完全由 Cloud Run 导致的暂时性错误,您可以联系支持团队

HTTP 500/HTTP 503:容器实例超出内存限制

传送期间出现以下错误:

在 Cloud Logging 中:

While handling this request, the container instance was found to be using too much memory and was terminated. This is likely to cause a new container instance to be used for the next request to this revision. If you see this message frequently, you may have a memory leak in your code or may need more memory. Consider creating a new revision with more memory.

要解决此问题,请执行以下操作:

  1. 确定容器实例是否超出可用内存。 在 varlog/system 日志中查找相关错误。
  2. 如果实例超出可用内存,建议提高内存限制

请注意,在 Cloud Run 中,写入本地文件系统的文件会计入可用内存。此外还包括写入 /var/log/*/dev/log 以外的位置的所有日志文件。

HTTP 503:响应格式不正确或容器实例连接有问题

传送期间出现以下错误之一:

HTTP 503
The request failed because either the HTTP response was malformed or connection to the instance had an error.

如需解决此问题,请按以下问题排查建议执行操作:

  • 检查 Cloud Logging使用 Cloud Logging 查找日志中的内存不足错误。如果您看到有关容器实例超出内存限制的错误消息,请按照解决此问题的建议进行操作。

  • 应用级别超时:如果请求在达到 Cloud Run 中设置的请求超时之前终止并显示错误代码 503,则您可能需要更新语言框架的请求超时设置:

  • 下游网络瓶颈:在某些情况下(例如在负载测试期间),503 错误代码可能是由于下游网络瓶颈间接导致的。例如,如果您的服务通过无服务器 VPC 访问通道连接器路由流量,请按照以下步骤确保该连接器未超过其吞吐量阈值:

    1. 在 Google Cloud 控制台中打开无服务器 VPC 访问通道:

      转到无服务器 VPC 访问通道

    2. 检查吞吐量图表直方图中是否有任何红色的条形。如果存在红色条形,请考虑增加连接器使用的实例数上限或更改实例类型。或者,压缩通过无服务器 VPC 访问通道连接器发送的流量。

  • 单个容器的入站请求限制:有一个已知问题,即如果每个容器的请求速率较高,便会导致出现此 503 错误。如果容器实例每秒接收的请求数超过 800 个,则可用的 TCP 套接字可能会用尽。如需解决此问题,请尝试以下任一操作:

    1. 为您的服务启用 HTTP/2,并对服务进行必要的更改以支持 HTTP/2。

    2. 通过降低已配置的并发设置,避免每秒向单个容器实例发送的请求数超过 800 个。使用以下公式来估算每个容器实例的请求速率:requests/sec/container_instance ~= concurrency * (1sec / median_request_latency)

HTTP 503:由于高并发设置,无法处理某些请求

传送期间出现以下错误:

HTTP 503
The Cloud Run service probably has reached its maximum container instance limit. Consider increasing this limit.

如果您的容器实例使用大量 CPU 处理请求,则会出现此问题,因此,容器实例无法处理所有请求,某些请求会返回 503 错误代码。

如需解决此问题,请尝试以下一项或多项操作:

HTTP 504:网关超时错误

HTTP 504
The request has been terminated because it has reached the maximum request timeout.

如果您的服务正在处理长时间运行的请求,则可以增加请求超时。如果您的服务未在指定时间内返回响应,则请求将结束,服务将返回 HTTP 504 错误,如容器运行时合同中所述。

如需排查此问题,请尝试以下一项或多项操作:

  • 执行日志记录和跟踪操作,以了解您的应用在超过配置的请求超时之前将时间花在哪里。

  • 由于基础设施更新,出站连接偶尔会重置。如果您的应用重复使用长期有效的连接,则我们建议您将应用配置为重新建立连接,以避免重用无效连接。

    • 根据应用的逻辑或错误处理情况,504 错误可能表示应用正在尝试重复使用无效连接,并且请求会被阻止,直到配置的请求超时为止。
    • 您可以使用活跃性探测来帮助终止返回永久性错误的实例。
  • 应用代码内发生的内存不足错误(例如 java.lang.OutOfMemoryError)不一定会终止容器实例。如果内存用量未超过容器内存限制,则实例不会终止。根据应用处理应用级内存不足错误的方式,请求可能会挂起,直到超出配置的请求超时为止。

    • 如果您希望在上述场景中终止容器实例,请将应用级内存限制配置为大于容器内存限制。
    • 您可以使用活跃性探测来帮助终止返回永久性错误的实例。

对等方重置了连接

传送期间出现以下错误之一:

Connection reset by peer
asyncpg.exceptions.ConnectionDoesNotExistError: connection was closed in the middle of operation
grpc.StatusRuntimeException: UNAVAILABLE: io exception
psycopg.OperationalError: the connection is closed
ECONNRESET

当应用通过网络与对等方建立 TCP 连接并且该对等方意外关闭连接时,会出现此错误。

要解决此问题,请执行以下操作:

  • 如果您尝试使用 CPU 节流执行后台工作,请尝试使用“始终分配 CPU”这一 CPU 分配设置。

  • 确保您未超出出站请求超时。如果您的应用在空闲状态下保持任何超出此阈值的连接,则网关需要重新建立连接。

  • 默认情况下,Cloud Run 的 TCP 套接字选项 keepalive 处于停用状态。您无法在 Cloud Run 中直接于服务级别配置 keepalive 选项,但可以在建立新的 TCP 套接字连接时提供正确的套接字选项,为每个套接字连接启用 keepalive 选项,具体取决于您在应用中用于此连接的客户端库。

  • 因基础架构更新,出站连接偶尔会重置。如果您的应用重复使用长期有效的连接,则我们建议您将应用配置为重新建立连接,以避免重用无效连接。

Google 隐去的身份令牌签名

传送期间出现以下错误:

SIGNATURE_REMOVED_BY_GOOGLE

在以下情况下,开发和测试期间可能会出现此错误:

  1. 用户使用 Google Cloud CLI 或 Cloud Shell 登录。
  2. 用户使用 gcloud 命令生成 ID 令牌。
  3. 用户尝试使用 ID 令牌调用非公开的 Cloud Run 服务。

这是设计所致。出于安全考虑,Google 会移除令牌签名,以防止任何非公开的 Cloud Run 服务重放以这种方式生成的 ID 令牌。

如需解决此问题,请使用新的 ID 令牌调用专用服务。 如需了解详情,请参阅测试服务中的身份验证

日志中的 OpenBLAS 警告

如果您将基于 OpenBLAS 的库(例如 NumPy)与第一代执行环境结合使用,可能会在日志中看到以下警告:

OpenBLAS WARNING - could not determine the L2 cache size on this system, assuming 256k

这只是一条警告,不会影响您的服务。出现此警告的原因是第一代执行环境使用的容器沙盒不会公开低级别的硬件功能。如果您不想在日志中收到这些警告,可以选择切换到第二代执行环境

获取要绑定到的机器的 IP 地址时,Spark 失败

传送期间出现以下错误之一:

assertion failed: Expected hostname (not IP) but got <IPv6 ADDRESS>
assertion failed: Expected hostname or IPv6 IP enclosed in [] but got <IPv6 ADDRESS>

要解决此问题,请执行以下操作:

如需更改环境变量值并解决此问题,请在 Dockerfile 中设置 ENV SPARK_LOCAL_IP="127.0.0.1"。在 Cloud Run 中,如果未设置 SPARK_LOCAL_IP 变量,则默认为其 IPv6 对应项,而不是 localhost。请注意,RUN export SPARK_LOCAL_IP="127.0.0.1" 设置在运行时不可用,并且 Spark 会像不存在该设置一样工作。

映射自定义网域

自定义网域卡在证书预配状态

当您尝试映射自定义网域时,会发生以下错误之一:

The domain is available over HTTP.  Waiting for certificate provisioning. You must configure your DNS records for certificate issuance to begin and to accept HTTP traffic.
Waiting for certificate provisioning. You must configure your DNS records for certificate issuance to begin.

要解决此问题,请执行以下操作:

  • 至少等待 24 小时。预配 SSL 证书通常需要大约 15 分钟,但最多可能需要 24 小时。
  • 使用 Google 管理员工具箱 Dig 工具验证您在域名注册商处正确更新了 DNS 记录

    域名注册商处的 DNS 记录必须与 Google Cloud 控制台提示您添加的记录匹配。

  • 使用以下方法之一在您的账号下确认网域的已通过验证:

  • 验证网域的证书是否未过期。如需查看到期时间,请使用以下命令:

    echo | openssl s_client -servername 'ROOT_DOMAIN' -connect 'ROOT_DOMAIN:443' 2>/dev/null | openssl x509 -startdate -enddate -noout
    

Admin API

声明的发布阶段不支持该功能

您调用 Cloud Run Admin API 时发生以下错误:

The feature is not supported in the declared launch stage

如果您直接调用 Cloud Run Admin API 并使用 Beta 版功能但未指定发布阶段注解,则会出现此错误。

要解决此问题,请为资源添加注解,并在请求中将 run.googleapis.com/launch-stage 值设置为 BETA(如果使用了任何 Beta 版功能)。

以下示例在服务要求中添加了发布阶段注释:

kind: Service
metadata:
  annotations:
    run.googleapis.com/launch-stage: BETA

客户端断开连接不会传播到 Cloud Run

在 Cloud Run 上使用 HTTP/1.1 时,客户端断开连接不会传播到 Cloud Run 容器。

解决方案是使用 HTTP/2.0,它会传播客户端断开连接。

排查网络文件系统问题

详细了解如何使用网络文件系统

无法使用 NFS 来访问文件

错误 建议的补救措施
mount.nfs: Protocol not supported 某些基础映像(例如 debianadoptopenjdk/openjdk11)缺少依赖项 nfs-kernel-server
mount.nfs: Connection timed out 如果连接超时,请确保提供 filestore 实例的正确 IP 地址。
mount.nfs: access denied by server while mounting IP_ADDRESS:/FILESHARE 如果服务器拒绝访问,请检查以确保文件共享名称正确无误。

无法使用 Cloud Storage FUSE 来访问文件

请参阅 Cloud Storage FUSE 问题排查指南