第 5 单元:使用 Cloud Buildpack 从 Google App Engine 迁移到 Cloud Run

1. 概览

这一系列的 Codelab(自定进度的动手教程)旨在帮助 Google App Engine(标准)开发者通过一系列迁移来指导他们的应用现代化。完成此操作后,用户可以通过将其显式容器化以支持 Cloud Run,App Engine 的 Google Cloud 容器托管姊妹服务以及其他容器托管服务,从而使其应用更具可移植性。

本教程教您如何容器化 App Engine 应用,以使用 Cloud Buildpack(Docker 的替代方案)部署到 Cloud Run 全代管式服务。Cloud Buildpack 可将您的应用容器化,而无需管理 Dockerfile 文件,甚至无需了解任何有关 Docker 的信息。

此 Codelab 适用于以下 Python 2 App Engine 开发者:已将应用从原始的内置服务迁移到 Python 3,现在希望在容器中运行这些应用。本 Codelab 从已完成的模块 2 或模块 3 Python 3 应用开始。

您将了解如何

  • 使用 Cloud Buildpack 将应用容器化
  • 将容器映像部署到 Cloud Run

所需条件

调查问卷

如何使用此 Codelab?

仅通读 阅读并完成练习

2. 背景

PaaS 系统(例如 App Engine 和 Cloud Functions)为您的团队和应用提供了许多便利。例如,这些无服务器平台,可让 SysAdmin/Devops 重点打造解决方案。您的应用可根据需要自动扩缩,使用按用量计费的结算方式有助于缩减至零,并使用多种常见的开发语言。

不过,容器的灵活性也具有吸引力,能够选择任何语言、任何库、任何二进制文件。Google Cloud Run 的宗旨就是为用户提供两全其美的体验、无服务器的便利性以及容器的灵活性。

了解如何使用 Cloud Run 不在本 Codelab 的范围之内,而是在 Cloud Run 文档中介绍。这里的目标是让您知道如何为 Cloud Run(或其他服务)容器化 App Engine 应用。在继续前进之前,您需要了解一些事项,主要是您的用户体验会略有不同,因为您将不再使用应用代码进行部署,因此用户体验会稍低一些。

相反,您需要学习一些有关容器的知识,例如如何构建和部署它们。您还可以决定要在容器映像中放入什么,包括网络服务器,因为您将不再使用 App Engine 的网络服务器。如果您不想遵循此路径,那么将应用保持在 App Engine 上并不是一个坏选择。

在本教程中,您将学习如何对应用进行容器化、移除 App Engine 配置文件、管理 Web 服务器(包括如何启动应用)。

此迁移具有以下步骤:

  1. 设置/准备工作
  2. 将应用容器化
    • 替换配置文件
    • 修改应用文件

3. 设置/准备工作

在开始学习本教程的主要部分之前,让我们设置项目、获取代码,然后部署基准应用,以便我们知道我们从工作代码开始。

1.设置项目

如果您完成了模块 2模块 3 的 Codelab,我们建议重复使用同一项目(和代码)。或者,您可以创建一个全新的项目或重复使用另一个现有项目。确保该项目具有有效的结算账号,并且已启用 App Engine(应用)。

2. 获取基准示例应用

此 Codelab 的先决条件之一是拥有一个工作正常的模块 2 或 3 示例应用。如果您没有,我们建议您先完成其中一个教程(上面的链接),然后再继续学习。或者,如果您已经熟悉其内容,可以直接从下面的某个代码文件夹开始。

无论您是使用自己的代码还是我们的代码,本教程都将从这里开始。此 Codelab 将引导您完成迁移,完成之后,代码应与模块 5 FINISH 代码库文件夹中的内容基本一致。

启动文件(您或我们的文件)的目录应如下所示:

$ ls
README.md               main.py                 templates
app.yaml                requirements.txt

3. (重新)部署基准应用

您现在需要执行的剩余预处理步骤:

  1. 重新熟悉 gcloud 命令行工具
  2. 使用 gcloud app deploy 重新部署示例应用
  3. 确认应用在 App Engine 上运行没有任何问题

成功执行完这些步骤后,您就可以对其进行容器化。

4. 将应用容器化

Docker 是当今业界标准的容器化平台。如前所述,使用它的一个挑战是,需要花费精力来精心设计高效的 Dockerfile(用于确定容器映像构建方式的配置文件)。另一方面,Buildpack 需要的工作量很少,因为它使用自检来确定应用的依赖项,从而使 Buildpack 容器尽可能高效地运行您的应用。

如果您希望跳过学习 Docker,并希望容器化 App Engine 应用以在 Cloud Run 或任何其他容器托管平台上运行,那么您来对地方了。如果您有兴趣了解如何使用 Docker 进行应用容器化,可以在完成本 Codelab 后完成模块 4 Codelab。它与此示例相同,但使用 Docker,可帮助您更深入地了解如何管理容器映像。

迁移步骤包括替换 App Engine 配置文件以及指定应如何启动应用。下表总结了每种平台类型所需的配置文件。将 App Engine 列与 Buildpack 列(以及可选的 Docker)进行比较:

说明

App Engine

Docker

Buildpack

常规配置

app.yaml

Dockerfile

(service.yaml)

第三方库

requirements.txt

requirements.txt

requirements.txt

第三方配置

app.yaml(以及 appengine_config.pylib [仅限 2.x])

(不适用)

(不适用)

启动

(不适用)app.yaml(如果使用 entrypoint

Dockerfile

Procfile

忽略文件

.gcloudignore.gitignore

.gcloudignore.gitignore.dockerignore

.gcloudignore.gitignore

将您的应用容器化后,就可以将其部署到 Cloud Run。其他 Google Cloud 容器平台选项包括 Compute EngineGKEAnthos

常规配置

App Engine 会自动启动应用,但 Cloud Run 不会。Procfile 的作用与 app.yaml entrypoint 指令类似。对于我们的示例应用,Procfile 将执行 python main.py 以启动 Flask 开发服务器。您也可以根据需要使用 gunicorn 等生产 Web 服务器,但如果使用,请务必将其添加到 requirements.txt。如需详细了解如何使用 buildpack 从源代码进行部署,请参阅此 Cloud Run 文档页面

您只需将 app.yaml entrypoint 指令移至 Procfile 中即可。如果您没有,请暂时使用 Flask 开发服务器,因为这只是一个示例测试应用,旨在帮助用户熟悉此迁移。您的应用将是一个特定的启动命令,您最了解。在底层,Cloud Run 服务会创建一个 service.yaml,该 service.yaml 的外观/行为更像 app.yaml。您可以访问类似这样的链接(但要将 SVC_NAMEREGION 替换为您的服务),查看自动生成的 service.yamlhttps://console.cloud.google.com/run/detail/REGION/SVC_NAME/yaml/view

第三方库

requirements.txt 文件无需更改;Flask 连同 Datastore 客户端库(Cloud Datastore 或 Cloud NDB)一起提供。如果您希望使用其他兼容 WSGI 的 HTTP 服务器(例如 Gunicorn,编写文档时的最新版本为 20.0.4),请将 gunicorn==20.0.4 添加到 requirements.txt

第三方配置

Buildpack 不支持 Python 2,因此我们不会在此处讨论相关内容。在 Cloud Run 上的容器中运行的 Python 3 应用与 Python 3 App Engine 应用类似,都必须在 requirements.txt 中指定第三方库。

启动

Python 3 用户可以选择在其 handlers 部分将其 app.yaml 文件转换为具有 entrypoint 而不是 script: auto 指令。如果您在 Python 3 app.yaml 中使用 entrypoint,它将看起来像这样:

runtime: python38
entrypoint: python main.py

entrypoint 指令用于告知 App Engine 如何启动服务器。您可以将这些数据几乎直接迁移到 Procfile。总结一下入口点指令在两个平台之间的位置:这会直接转换为以下内容;还显示了 Docker 等效项,供您参考:

  • Buildpack:Procfile 中的行:web: python main.py
  • Docker:Dockerfile 中的行:ENTRYPOINT ["python", "main.py"]

对于测试和预演,只需像上面那样从 Python 运行 Flask 的开发服务器即可,但开发者可以选择更强大的生产环境,例如使用 gunicornCloud Run 快速入门示例

应用文件

所有模块 2 或模块 3 应用均与 Python 2-3 兼容,这意味着 main.py 的核心组件没有更改;我们只添加了几行启动代码。在 main.py 底部添加一行代码以启动开发服务器,因为 Cloud Run 需要打开端口 8080,以便它可以调用您的应用:

if __name__ == '__main__':
    import os
    app.run(debug=True, threaded=True, host='0.0.0.0',
            port=int(os.environ.get('PORT', 8080)))

5. 构建和部署

将 App Engine 配置替换为 buildpack 并完成源文件更新后,您就可以在 Cloud Run 上运行该模型了。在此之前,我们先简要讨论服务

服务与应用

虽然 App Engine 最初是为托管应用而创建的,但它还是一个托管由微服务集合组成的 Web 服务或应用的平台。在 Cloud Run 中,一切都是服务,无论是实际服务还是具有 Web 界面的应用,因此请考虑将其用作服务的部署而不是应用。

除非您的 App Engine 应用由多项服务组成,否则在部署应用时,您实际上无需进行任何类型的命名。但在 Cloud Run 中,您需要想出一个服务名称。而 App Engine 的 appspot.com 网域包含其项目 ID(例如 https://PROJECT_ID.appspot.com)以及可能的地区 ID 缩写(例如 http://PROJECT_ID.REGION_ID.r.appspot.com)。

不过,Cloud Run 服务的域名具有服务名称、区域 ID 缩写和哈希值,而非项目 ID,例如 https://SVC_NAME-HASH-REG_ABBR.a.run.app。最重要的是,开始考虑服务名称!

部署服务

执行以下命令以构建您的容器映像并部署到 Cloud Run。出现提示时,选择您的区域并允许未经身份验证的连接,以方便测试并选择适当的区域,其中 SVC_NAME 是要部署的服务的名称。

$ gcloud run deploy SVC_NAME --source .
Please choose a target platform:
 [1] Cloud Run (fully managed)
 [2] Cloud Run for Anthos deployed on Google Cloud
 [3] Cloud Run for Anthos deployed on VMware
 [4] cancel
Please enter your numeric choice:  1

To specify the platform yourself, pass `--platform managed`. Or, to make this the default target platform, run `gcloud config set run/platform managed`.

Please specify a region:
 [1] asia-east1
 [2] asia-east2
 [3] asia-northeast1
 [4] asia-northeast2
 [5] asia-northeast3
 [6] asia-south1
 [7] asia-southeast1
 [8] asia-southeast2
 [9] australia-southeast1
 [10] europe-north1
 [11] europe-west1
 [12] europe-west2
 [13] europe-west3
 [14] europe-west4
 [15] europe-west6
 [16] northamerica-northeast1
 [17] southamerica-east1
 [18] us-central1
 [19] us-east1
 [20] us-east4
 [21] us-west1
 [22] us-west2
 [23] us-west3
 [24] us-west4
 [25] cancel
Please enter your numeric choice: <select your numeric region choice>

To make this the default region, run `gcloud config set run/region REGION`.

Allow unauthenticated invocations to [SVC_NAME] (y/N)?  y

Building using Buildpacks and deploying container to Cloud Run service [SVC_NAME] in project [PROJECT_ID] region [REGION]
✓ Building and deploying... Done.
  ✓ Uploading sources...
  ✓ Building Container... Logs are available at [https://console.cloud.google.com/cloud-build/builds/BUILD-HASH?project=PROJECT_NUM].
  ✓ Creating Revision...
  ✓ Routing traffic...
Done.
Service [SVC_NAME] revision [SVC_NAME-00014-soc] has been deployed and is serving 100 percent of traffic.
Service URL: https://SVC_NAME-HASH-REG_ABBR.a.run.app

在浏览器中访问指定网址,确认部署是否成功!

gcloud 命令所示,用户可以设置各种默认设置来减少输出和互动性,如上所示。例如,为了避免所有交互,您可以改用以下单行式部署命令:

$ gcloud beta run deploy SVC_NAME --source . --platform managed --region REGION --allow-unauthenticated

如果您使用此 API,请务必提供相同的服务名称 SVC_NAME 和所需的 REGION 名称,而不是已编入索引的菜单选项(如上所述)。

6. 总结/清理

确认应用在 Cloud Run 上和在 App Engine 上一样。如果您跳过本系列,但未执行任何上述 Codelab,则应用本身不会更改;它会记录对主网页 (/) 的所有访问,在您访问过该网站后,将如下所示:

visitme 应用

您的代码现在应与模块 5 代码库文件夹中的内容相匹配。恭喜您完成本模块 5 的 Codelab。

可选:清理

何不准备好清理,以避免在进入下一个迁移 Codelab 时继续计费?由于您目前使用的是其他产品,请务必查看 Cloud Run 价格指南

可选:停用服务

如果您尚未准备好学习下一个教程,请停用您的服务,以免产生额外费用。准备好继续学习下一个 Codelab 后,您可以重新启用该功能。应用被停用后,不会产生任何流量产生费用,但如果超出免费配额,您可能还需要为 Datastore 使用量付费,因此请删除足够的数据,使使用量低于该上限。

另一方面,如果您不打算继续迁移,并希望完全删除所有内容,则可以删除您的服务或完全关闭您的项目

后续步骤

恭喜,您已将应用容器化,本教程到此结束!接下来,您可以学习如何在模块 4 的 Codelab(链接如下)中使用 Docker 执行相同的操作,也可以完成另一项 App Engine 迁移:

  • 模块 4使用 Docker 迁移到 Cloud Run
    • 使用 Docker 将应用容器化,以便在 Cloud Run 上运行
    • 让您继续使用 Python 2
  • 模块 7:App Engine 推送任务队列(如果您使用 [推送] 任务队列,此为必需参数)
    • 向模块 1 应用添加了 App Engine taskqueue 推送任务
    • 为用户在第 8 模块中迁移到 Cloud Tasks 做准备
  • 模块 3
    • 将 Datastore 访问从 Cloud NDB 迁移到 Cloud Datastore
    • 此库用于 Python 3 App Engine 应用和非 App Engine 应用
  • 模块 6:迁移到 Cloud Firestore
    • 迁移到 Cloud Firestore 以访问 Firebase 功能
    • 虽然 Cloud Firestore 支持 Python 2,但此 Codelab 仅提供 Python 3 版本。

7. 其他资源

App Engine 迁移模块 Codelab 问题/反馈

如果您发现本 Codelab 存在任何问题,请先搜索您的问题,然后再提交。用于搜索和创建新问题的链接:

迁移时可参考的资源

您可以在下表中找到模块 2 和 3(开始)以及模块 5(完成)的 Repo 文件夹的链接。您还可以从所有 App Engine Codelab 迁移的代码库中访问这些示例,您可以克隆该代码库或下载 ZIP 文件。

Codelab

Python 2

Python 3

模块 2

代码

代码

模块 3

代码

代码

模块 5

(不适用)

代码

App Engine 和 Cloud Run 资源

以下是有关此特定迁移的其他资源: