比较 App Engine 和 Cloud Run

区域 ID

REGION_ID 是 Google 根据您在创建应用时选择的区域分配的缩写代码。此代码不对应于国家/地区或省,尽管某些区域 ID 可能类似于常用国家/地区代码和省代码。对于 2020 年 2 月以后创建的应用,REGION_ID.r 包含在 App Engine 网址中。对于在此日期之前创建的现有应用,网址中的区域 ID 是可选的。

详细了解区域 ID

本指南向熟悉 App Engine 的用户介绍 Cloud Run。其中介绍了无服务器平台之间的主要异同,以帮助您为从 App Engine 标准环境或 App Engine 柔性环境迁移进行准备。

概览

Cloud Run 以十多年来运行 App Engine 的经验为基础构建而成,是 Google Cloud 无服务器技术的最新发展成果。Cloud Run 在与 App Engine 标准环境大致相同的基础架构上运行,因此这两个平台有许多相似之处。

Cloud Run 整合了 App Engine 标准环境和 App Engine 柔性环境中的许多最佳功能,在 App Engine 体验的基础上加以改进。Cloud Run 服务可以处理与 App Engine 服务相同的工作负载,但 Cloud Run 为客户在实现这些服务时提供了更大的灵活性。这种灵活性以及与 Google Cloud 和第三方服务的加强集成也使得 Cloud Run 能够处理无法在 App Engine 上运行的工作负载。

比较摘要

虽然 App Engine 和 Cloud Run 有许多相似之处和不同之处,但此概览着重介绍了刚开始使用 Cloud Run 的 App Engine 客户最相关的方面。

App Engine 标准环境 App Engine 柔性环境 Cloud Run
术语 应用
Service Service
版本 修订版本

网址端点

应用网址
default 服务)
https://PROJECT_ID.REGION_ID.r.appspot.com
服务网址 https://SERVICE_ID-dot-PROJECT_ID.REGION_ID.r.appspot.com
  • https://SERVICE_NAME-PROJECT_NUMBER.REGION.run.app
  • https://SERVICE_IDENTIFIER.run.app
版本/修订版本网址 https://VERSION-dot-SERVICE-dot-PROJECT_ID.REGION_ID.r.appspot.com
  • https://TAG---SERVICE_NAME-PROJECT_NUMBER.REGION.run.app
  • https://TAG---SERVICE_IDENTIFIER.run.app

扩缩

自动扩缩
手动扩缩 虽然没有特定的手动扩缩设置,但您可以通过将实例数上限配置为实例数下限来复制相同的行为
缩减至零
预热请求 可配置 自动
空闲实例超时(在完成最后一个请求后) 最长 15 分钟 取决于 CPU 分配设置。使用“始终分配 CPU”来模拟 App Engine 行为
请求超时
  • 自动扩缩:10 分钟
  • 手动/基本扩缩:24 小时
60 分钟 可配置的最长时间为 60 分钟(默认:5 分钟)

部署

从来源配置
容器映像 是(自定义运行时

计算资源

vCPU
实例类别 vCPU* 内存
F/B1 .25 384MB
F/B2 .5 768MB
F/B4 1 1.5GB
F/B4_1G 1 3GB
B8 2 3GB
* vCPU 等效值为近似值
最多 80 个 vCPU 最多 8 个 vCPU
内存 每个 vCPU 最多 6.5GB 最多 32GB

价格模式

按请求收费 否(始终分配 CPU 时)。
是(仅在请求处理期间分配 CPU 时)。
空闲实例数下限 与活跃实例的费用相同 降低空闲实例数下限的费用(请参阅可计费容器实例时间
承诺使用折扣 (CUD)

安全

入站流量设置
调用方角色
IAP 使用 Cloud Load Balancing 进行配置
防火墙 使用 Google Cloud Armor 进行配置

连接

自定义网域 使用 Cloud Load Balancing 进行配置
VPC 连接(包括共享 VPC)
VPC 出站流量设置
多区域负载均衡

访问 Google Cloud 服务

Cloud SQL
Cloud 客户端库 如果您是在 App Engine 中使用 Cloud 客户端库,则无需在迁移到 Cloud Run 时进行任何更改。这些客户端是通用的,这意味着您应用的可移植性更强。
App Engine 旧版捆绑服务 (仅限 Java、Python、Go、PHP)

资源模型

App Engine 和 Cloud Run 资源模型图表

Cloud Run 资源模型App Engine 非常相似,但存在一些关键区别:

  • Cloud Run 没有顶级应用资源或相应的 default 服务。
  • 同一项目中的 Cloud Run 服务可以部署到不同区域。 在 App Engine 中,项目中的所有服务都位于同一区域。
  • Cloud Run 使用“修订版本”而不是“版本”一词,以与 Knative 资源模型保持一致。
  • Cloud Run 修订版本名称采用以下格式:SERVICE_NAME-REVISION_SUFFIX,其中 REVISION_SUFFIX 自动生成,或使用 --revision-suffix=REVISION_SUFFIX 部署标志设置。
  • Cloud Run 修订版本是不可变的,这意味着您无法像使用 App Engine 版本那样重复使用名称(使用 --version=VERSION_ID 部署标志)。
  • Cloud Run 服务网址基于首次部署服务时自动生成的服务标识符。服务标识符使用以下格式:SERVICE_NAME-<auto-generated identifier>。 服务标识符是唯一的,并且在服务的生命周期内不会更改。
  • 在 Cloud Run 中,默认情况下仅公开服务网址(SERVICE_IDENTIFIER.run.apphttps://SERVICE_NAME-PROJECT_NUMBER.REGION.run.app)。如需处理特定修订版本,您必须配置流量标记。在 App Engine 中,系统会自动公开服务网址和版本网址

部署和配置

在 App Engine 中,大多数配置都是在每个部署中包含的 app.yaml 中完成的。这种简单性会产生一定的费用,原因是虽然可以使用 Admin API 更新一些设置,但大多数更改都需要重新部署服务。

虽然 Cloud Run 具有 service.yaml 配置文件,但它与 app.yaml 的使用方式不同。通过源代码部署时,不能使用 Cloud Run service.yaml,因为必需的元素之一是最终容器映像的路径。此外,service.yaml 符合 Knative 规范,对于不熟悉 Kubernetes 样式的配置文件的用户来说,可能难以理解。如需详细了解如何使用 service.yaml 管理配置,请参阅 Cloud Run 文档

对于刚开始使用 Cloud Run 的 App Engine 客户,使用 gcloud CLI 部署标志与 App Engine 部署配置管理更为一致。

如需在 Cloud Run 中部署新代码时设置配置,请使用 gcloud run deploy 标志:

gcloud run deploy SERVICE_NAME \
--cpu CPU \
--memory MEMORY \
--concurrency CONCURRENCY

尽管没有必要在每个部署中使用配置标志(请参阅管理配置),但这样做有助于简化配置管理。

在 Cloud Run 中,您还可以使用 gcloud run services update 更新配置,而无需重新部署源代码:

gcloud run services update SERVICE_NAME \
--cpu CPU \
--memory MEMORY \
--concurrency CONCURRENCY

由于 Cloud Run 修订版本是不可变的,因此该命令会创建具有更新后配置的新修订版本,但使用与现有修订版本相同的容器映像。

管理配置

对于 App Engine 部署,必须为每个部署提供所有设置,并且为任何未提供的设置分配默认值。以 App Engine service-a 为例,其版本使用如下所示的 app.yaml 文件:

App Engine service-a version1 App Engine service-a version2
app.yaml
runtime: python39
service: service-a
instance_class: F4
runtime: python39
service: service-a
已应用的配置
runtime: python39
service: service-a
instance_class: F4
default values:
..
..
runtime: python39
service: service-a
default values:
instance_class: F1
..
..

version1 是使用 instance_class: F4 配置的,而 version2 没有为 instance_class 提供值,而是使用默认 instance_class: F1 配置的。

对于 Cloud Run,任何提供的配置设置都会应用,但任何未提供的配置设置都会保留其现有值。您只需为要更改的设置提供值。例如:

Cloud Run service-a revision1 Cloud Run service-a revision2
部署命令
gcloud run deploy service-a \
--cpu=4
gcloud run deploy service-a
已应用的配置
service: service-a
vCPUs: 4
default values:
..
..
service: service-a
vCPUs: 4
default values:
..
..

在 App Engine 中,如果未使用配置设置进行部署,则系统会使用所有默认设置创建一个版本。在 Cloud Run 中,如果未使用配置设置进行部署,则系统会使用与先前修订版本相同的配置设置创建一个修订版本。对于 Cloud Run 服务的第一个修订版本,不使用配置设置进行部署时将使用所有默认设置创建一个修订版本。

配置默认值

配置设置 App Engine 标准环境 App Engine 柔性环境 Cloud Run
计算资源 F1 1 个 vCPU,6GB 内存 1 个 vCPU,512MB 内存
最大并发数(请求数) 10 80
请求超时
  • 自动扩缩:10 分钟
  • 手动/基本扩缩:24 小时
60 分钟 5 分钟
CPU 利用率目标 60% 50% 60%
实例数上限 20 100
实例数下限 0 2 0

入口点

通过源代码部署时,App Engine 会从 app.yaml 中的 entrypoint 属性读取入口点命令。如果未提供入口点,则系统会使用特定于运行时的默认值。通过源代码部署时,Cloud Run 会使用 Google Cloud 的 Buildpack,并且某些语言没有默认入口点,这意味着您必须提供一个入口点,否则构建会失败。例如,Python Buildpack 需要使用 Procfile 或指定 GOOGLE_ENTRYPOINT 构建环境变量。

如需了解任何特定于语言的配置要求,请参阅 Buildpack 文档。

扩缩

虽然 Cloud Run 和 App Engine 标准环境具有很多相同的扩缩基础架构,但 Cloud Run 已得到简化,从而实现更快的扩缩。在此简化过程中,可配置的设置仅限于:

对于 Cloud Run 实例,目标 CPU 利用率不可配置,固定为 60%。如需详细了解自动扩缩功能,请参阅 Cloud Run 文档

App Engine 柔性环境使用 Compute Engine 自动扩缩器,因此与 App Engine 标准环境和 Cloud Run 的扩缩特性截然不同。

空闲实例超时

在 App Engine 中,空闲实例在最后一个请求处理完成后最长保持活跃状态 15 分钟。Cloud Run 可让您使用 CPU 分配来配置此行为。要获得与 App Engine 相同的行为,请将 CPU 分配设置为始终分配 CPU。或者,使用“仅在处理请求期间分配的 CPU”,立即关停空闲实例(如果没有待处理请求)。

预热请求

Cloud Run 使用容器入口点命令自动预热实例,因此您无需手动启用预热请求或配置 /_ah/warmup 处理程序。如果您要在实例启动时运行代码,则在处理任何请求之前,您可以执行以下任一操作:

静态内容

在 App Engine 标准环境中,您可以通过从 Cloud Storage 传送或通过配置处理程序来传送静态内容,而无需使用计算资源。Cloud Run 没有传送静态内容的处理程序选项,因此您可以从 Cloud Run 服务(与动态内容相同)或从 Cloud Storage 传送内容。

Cloud Run Invoker 角色

Cloud Run 还能够使用 Identity and Access Management (IAM) 控制对服务的访问权限。服务的 IAM 政策绑定可以使用 gcloud CLI、控制台或 Terraform 设置

如需复制 App Engine 行为,您可以通过允许未经身份验证的请求来公开服务。可以在部署时设置此配置,也可以通过更新现有服务的 IAM 政策绑定来设置。

部署

使用 --allow-unauthenticated 部署标志:

gcloud run deploy SERVICE_NAME ... --allow-unauthenticated

现有服务

使用 gcloud run services add-iam-policy-binding 命令:

gcloud run services add-iam-policy-binding SERVICE_NAME \
--member="allUsers" \
--role="roles/run.invoker"

其中,SERVICE_NAME 是 Cloud Run 服务名称。

或者,您可以选择通过授予可按服务配置的 Cloud Run Invoker IAM 角色来控制谁有权访问服务。

部署

gcloud run deploy SERVICE_NAME ... --no-allow-unauthenticated
gcloud run services add-iam-policy-binding SERVICE_NAME \
--member=MEMBER_TYPE \
--role="roles/run.invoker"

其中,SERVICE_NAME 是服务名称,MEMBER_TYPE 是主账号类型。例如 user:email@domain.com

如需查看 MEMBER_TYPE 可接受的值列表,请参阅 IAM 概念页面

现有服务

gcloud run services add-iam-policy-binding SERVICE_NAME \
--member=MEMBER_TYPE \
--role="roles/run.invoker"

其中,SERVICE_NAME 是服务名称,MEMBER_TYPE 是主账号类型。例如 user:email@domain.com

如需查看 MEMBER_TYPE 可接受的值列表,请参阅 IAM 概念页面

环境变量和元数据

App EngineCloud Run 都有特定自动设置的环境变量。下表显示了 App Engine 环境变量以及等效的 Cloud Run 环境变量。与 App Engine 相比,Cloud Run 仅实现少量环境变量,但元数据服务器提供的数据大致相同。

默认环境变量

App Engine 名称 Cloud Run 名称 说明
GAE_SERVICE K_SERVICE 当前服务的名称。在 App Engine 中,如果未指定此变量,则设置为“default”。
GAE_VERSION K_REVISION 服务的当前版本标签。
PORT PORT 接收 HTTP 请求的端口。
K_CONFIGURATION 创建了该修订版本的 Cloud Run 配置的名称。
GOOGLE_CLOUD_PROJECT 与您的应用关联的 Cloud 项目 ID。
GAE_APPLICATION App Engine 应用的 ID。 此 ID 以“区域代码~”为前缀,例如“e~”(对于在欧洲部署的应用)。
GAE_DEPLOYMENT_ID 当前部署的 ID。
GAE_ENV App Engine 环境。如果处于标准环境,则设置为“standard”。
GAE_INSTANCE 当前运行您的服务的实例的 ID。
GAE_MEMORY_MB 可供应用进程使用的内存量,以 MB 为单位。
NODE_ENV(仅在 Node.js 运行时中可用) 当服务已部署时,将其设置为 production。
GAE_RUNTIME 在 app.yaml 文件中指定的运行时。

通用元数据服务器路径

路径 说明 示例
/computeMetadata/v1/project/project-id 服务所属项目的 ID test_projecttest_project
/computeMetadata/v1/project/numeric-project-id 服务所属项目的编号 12345678912
/computeMetadata/v1/instance/id 容器实例的唯一标识符(也可在日志中提供)。 16a61494692b7432806a16
(字母数字字符串)
/computeMetadata/v1/instance/region
** 不适用于 App Engine 柔性环境
此服务的区域,返回 projects/PROJECT_NUMBER/regions/REGION projects/12345678912/regions/us-central1projects/12345678912/regions/us-central1
/computeMetadata/v1/instance/service-accounts/default/email 此服务的运行时服务账号的电子邮件地址。 service_account@test_project.iam.gserviceaccount.com
/computeMetadata/v1/instance/service-accounts/default/token 为此服务的服务账号生成 OAuth2 访问令牌。此端点将返回包含 access_token 特性的 JSON 响应。 {
"access_token":"<TOKEN>",
"expires_in":1799,
"token_type":"Bearer"
}

后续步骤