这一系列的 Codelab(自定进度的动手教程)旨在帮助 Google App Engine(标准)开发者通过一系列迁移来指导他们的应用现代化。完成此操作后,用户可以通过将其显式容器化以支持 Cloud Run,App Engine 的 Google Cloud 容器托管姊妹服务以及其他容器托管服务,从而使其应用更具可移植性。
本教程教您如何容器化 App Engine 应用,以使用 Docker 部署到 Cloud Run 全代管式服务,Docker 是业界知名的平台,用于在容器中开发、运输和运行应用。对于 Python 2 开发者,本教程从模块 2 Cloud NDB App Engine 示例应用开始,而 Python 3 开发人员从模块 3 Cloud Datastore 示例开始。
您将了解如何
- 使用 Docker 将应用容器化
- 将容器映像部署到 Cloud Run
所需条件
- 符合以下条件的 Google Cloud Platform 项目:
- 基本 Python 技能
- 常用 Linux 命令的实践知识
- 具备开发和部署 App Engine 应用的基础知识
- 推荐:完成模块 2 Codelab 或模块 3 Codelab
- 可随时容器化的工作中 App Engine 应用
- Python 2:模块 2 Cloud NDB 示例
- Python 3:模块 3 Cloud Datastore 示例
调查问卷
如何使用此 Codelab?
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 配置文件,确定将哪些内容放入容器中,然后指定如何启动应用,其中许多事项都是由 App Engine 自动处理。
此迁移具有以下步骤:
- 设置/准备工作
- 容器化应用
- 替换配置文件
- 修改应用文件
在开始学习本教程的主要部分之前,让我们设置项目、获取代码,然后部署基准应用,以便我们知道我们从工作代码开始。
1.设置项目
如果您完成了模块 2 或模块 3 的 Codelab,我们建议重复使用同一项目(和代码)。或者,您可以创建一个全新的项目或重复使用另一个现有项目。确保该项目具有有效的结算帐号,并且已启用 App Engine(应用)。
2.获取基准示例应用
此 Codelab 的先决条件之一是拥有一个工作正常的模块 2 或模块 3 示例应用。如果您没有,请先完成其中一个教程(上面的链接),然后再继续学习。否则,如果您已经熟悉其内容,则可以从下面的模块 2 或 3 代码开始。
无论您使用的是本教程,还是本教程的 Python 2 版本,我们都将在这里开始使用模块 2 代码,而在 Python 3 中,则类似地使用模块 3 代码。这个模块 4 Codelab 将引导您完成每个步骤,并且根据您的选择,最终应该获得类似于模块 4 代码库文件夹 (FINISH) 之一的代码。
- Python 2(Cloud NDB 应用)
- Python 3(Cloud Datastore 应用)
- 整个代码库(用于克隆或下载 ZIP)
Python 2 模块 2 启动文件(您或我们的文件)的目录应如下所示:
$ ls
README.md appengine_config.py requirements.txt
app.yaml main.py templates
如果您使用的是自己的模块 2 (2.x) 代码,那么还会有一个 lib
文件夹。对于 Python 3,lib
和 appengine_config.py
均不适用,其中模块 3 (3.x) START 代码如下所示:
$ ls
README.md main.py templates
app.yaml requirements.txt
3.(重新)部署基准应用
现在,您需要执行剩余的准备工作步骤:
- 重新熟悉
gcloud
命令行工具 - 使用
gcloud app deploy
重新部署示例应用 - 确认应用在 App Engine 上运行没有任何问题
成功执行完这些步骤后,您就可以对其进行容器化。
Docker 是当今行业的标准容器化平台。如上所述,使用该工具的一个挑战是需要投入有效的 Dockerfile
,此配置文件确定容器映像的构建方式。另一方面,Buildpack 不需要花费太多精力,因为它使用内检来确定应用的依赖关系,从而使 Buildpack 容器对您的应用尽可能有效。
如果您已经对容器和 Docker 有所了解,并且想要了解有关为 Cloud Run 容器化 App Engine 应用的更多信息,那么您来对地方了。之后,您还可以随意使用模块 5 Codelab(与本模块相同,但增加了 Cloud Buildpack)。我们的准系统示例应用足够轻巧,可以避免某些上述 Dockerfile
问题。
迁移步骤包括替换 App Engine 配置文件以及指定应如何启动应用。下表总结了每种平台类型所需的配置文件。将 App Engine 列与 Docker 列(以及可选的 Buildpack)进行比较:
说明 | App Engine | Docker | Buildpack |
常规配置 |
|
| ( |
第三方库 |
|
|
|
第三方配置 |
| (不适用) | (不适用) |
启动 | (不适用)或 |
|
|
忽略文件 |
|
|
|
将您的应用容器化后,就可以将其部署到 Cloud Run。其他 Google Cloud 容器平台选项包括 Compute Engine、GKE 和 Anthos。
常规配置
从 App Engine 迁移意味着将 app.yaml
替换为概述如何构建和运行容器的 Dockerfile
。App Engine 自动启动您的应用,但 Cloud Run 不会。Dockerfile
ENTRYPOINT
和 CMD
命令的用途。从此 Cloud Run 文档页面中详细了解 Dockerfile
,并查看生成 gunicorn
的示例 Dockerfile
。
在 Dockerfile
中使用 ENTRYPOINT
或 CMD
的替代方案是使用 Procfile
。最后,.dockerignore
有助于过滤掉非应用文件,以减小容器大小。即将发布更多内容!
删除 app.yaml
并创建 Dockerfile
未在容器中使用 app.yaml
,因此请立即删除。容器配置文件为 Dockerfile
,我们的示例应用只需满足最低要求。使用以下内容创建 Dockerfile
,并将 NNN
替换为 2
或 3
,具体取决于您使用的 Python 版本:
FROM python:NNN-slim
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
ENTRYPOINT ["python", "main.py"]
大多数 Dockerfile
都指定了如何创建容器,除了 ENTRYPOINT
则指定了如何启动容器,在这种情况下,调用 python main.py
来执行 Flask 开发服务器。如果您是 Docker 的新手,那么 FROM
指令指示从其开始的基本映像,而“slim”则是指最小的 Python 发行版。如需了解详情,请参阅 Docker Python 映像页面。
这组命令会创建工作目录 (/app
),接着复制应用文件,然后运行 pip install
以将第三方库放入容器中。WORKDIR
将 Linux mkdir
和 cd
命令组合在一起;如需了解详情,请参阅 WORKDIR
文档。COPY
和 RUN
指令的含义不言自明。
第三方库
requirements.txt
文件可以保持不变;Flask 连同 Datastore 客户端库(Cloud Datastore 或 Cloud NDB)一起提供。如果您希望使用其他兼容 WSGI 的 HTTP 服务器(例如 Gunicorn,编写文档时的最新版本为 20.0.4),请将 gunicorn==20.0.4
添加到 requirements.txt
。
第三方配置
Python 2 App Engine 开发者知道,第三方库复制到 lib
文件夹中、在 requirements.txt
中引用、在 app.yaml
中逐项列出以及受 appengine_config.py
支持。与 Python 3 App Engine 应用一样,容器仅使用 requirements.txt
,因此所有其他项都可以删除,这意味着如果您拥有 2.x App Engine 应用,请删除 appengine_config.py
以及任何 lib
文件夹。
启动
Python 2 用户不会启动 App Engine 的网络服务器,但是当移至容器时,您必须这样做。这是通过在 Dockerfile
中添加 CMD
或 ENTRYPOINT
指令来指定如何启动应用来完成的,下面以与 Python 3 用户相同的方式进行说明。
Python 3 用户可以选择在其 handlers
部分将其 app.yaml
文件转换为具有 entrypoint
而不是 script: auto
指令。如果您在 Python 3 app.yaml
中使用 entrypoint
,它将看起来像这样:
runtime: python38
entrypoint: python main.py
entrypoint
指令告知 App Engine 如何启动服务器。您几乎可以将其直接移到 Dockerfile
中(如果使用 Buildpack,则为 Procfile
[请参阅模块 5])以容器化应用。汇总 entrypoint 指令在两个平台之间的位置:
- Docker:
Dockerfile
中的行:ENTRYPOINT ["python", "main.py"]
- Buildpack:
Procfile
中的行:web: python main.py
使用 Flask 开发服务器可以很好地进行测试,但是如果在您的应用中使用像 gunicorn
这样的生产服务器,请确保将 ENTRYPOINT
或 CMD
指令指向它,像在 Cloud Run 快速入门示例中一样。
忽略文件
我们建议创建一个 .dockerignore
文件以调整容器的大小,并且不要用以下多余的文件造成容器映像混乱:
*.md
*.pyc
*.pyo
.git/
.gitignore
__pycache__
应用文件
所有模块 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)))
完成 Docker 配置和源文件更新后,您就可以在 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 beta 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 Dockerfile and deploying container to Cloud Run service [SVC_NAME] in project [PROJECT_ID] region [REGION] ✓ Building and deploying new service... Done. ✓ Uploading sources... ✓ Building Container... Logs are available at [https://console.cloud.google.com/cloud-build/builds/BUILD-HASH?project=PROJECT_NUM]. ✓ Creating Revision... Deploying Revision. ✓ Routing traffic... ✓ Setting IAM Policy... Done. Service [SVC_NAME] revision [SVC_NAME-00001-vos] 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
名称,而不是已编入索引的菜单选项(如上所述)。
确认应用在 Cloud Run 上和在 App Engine 上一样。如果您跳过本系列,但未执行任何上述 Codelab,则应用本身不会更改;它会记录对主网页 (/
) 的所有访问,在您访问过该网站后,将如下所示:
您的代码现在应与模块 4 代码库文件夹中的内容相匹配,无论它是 2.x 还是 3.x。恭喜您完成本模块 4 的 Codelab。
可选:清理
何不准备好清理,以避免在进入下一个迁移 Codelab 时继续计费?由于您目前使用的是其他产品,请务必查看 Cloud Run 价格指南。
可选:停用服务
如果您尚未准备好下一个教程,请停用您的服务,以避免产生额外费用。准备好运行下一个 Codelab 后,可以重新启用它。在您的应用被停用的情况下,它不会获取任何流量来产生费用,但是您还需要计费的另一事项是,如果 Datastore 使用量超出免费配额,因此请删除一部分使用量,以使其低于该限制。
另一方面,如果您不打算继续迁移,并想删除所有内容,则可以删除您的服务或彻底关停项目。
后续步骤
恭喜,您已对应用进行容器化,本教程结束!下一步,您将了解如何在模块 5 的 Codelab 中通过 Cloud Buildpack 执行相同的操作(下面的链接),或学习另一个 App Engine 迁移:
- 迁移到 Python 3(如果您尚未迁移)。示例应用已兼容 2.x 和 3.x,因此唯一的更改是让 Docker 用户更新其
Dockerfile
以使用 Python 3 映像。 - 模块 5:使用 Cloud Buildpack 迁移到 Cloud Run
- 将应用设置为使用 Cloud Buildpack 在 Cloud Run 上运行
- 您无需了解有关 Docker、容器或
Dockerfile
的任何信息 - 您需要将应用迁移到 Python 3
- 模块 7:App Engine 推送任务队列(如果您使用 [推送] 任务队列,此为必需参数)
- 向模块 1 应用添加 App Engine
taskqueue
推送任务 - 准备用户迁移到模块 8 中的 Cloud Tasks
- 向模块 1 应用添加 App Engine
- 模块 3:
- 对从 Cloud NDB 到 Cloud Datastore 的 Datastore 访问进行现代化改造
- 这是用于 Python 3 App Engine 应用和非 App Engine 应用的库
- 模块 6:迁移到 Cloud Firestore
- 迁移到 Cloud Firestore 以使用 Firebase 功能
- Cloud Firestore 支持 Python 2,但此 Codelab 仅在 Python 3 中可用。
App Engine 迁移模块 Codelab 问题/反馈
如果您遇到此 Codelab 的任何问题,请先搜索您的问题,然后再提交。用于搜索新问题和创建新问题的链接:
迁移资源
下方表格提供了指向模块 2 和模块 3 (START) 以及代码库 4 (FINISH) 的代码库文件夹的链接。您也可以通过所有 App Engine Codelab 迁移的代码库访问这些代码库,该代码库可以克隆或下载 ZIP 文件。
Codelab | Python 2 | Python 3 |
(代码) | ||
(代码) | ||
模块 4 |
App Engine 和 Cloud Run 资源
以下是有关此具体迁移的其他资源: