这是学习路线中的第三个教程,该学习路线旨在教您如何将单体式应用模块化和容器化。
此学习路线包含以下教程:
- 概览
- 了解单体应用
- 将单体式应用模块化
- 准备将模块化应用容器化(本教程)
- 将模块化应用容器化
- 将应用部署到 GKE 集群
在上一篇教程将单体应用模块化中,您了解了如何将 Cymbal Books 应用拆分为独立的 Flask 模块。在本教程中,您将了解需要对模块化应用进行的一项更改,以便为容器化做好准备。
费用
您可以免费完成本教程。不过,按照本系列最后一篇教程中的步骤操作会使您的Google Cloud 账号产生费用。当您启用 GKE 并将 Cymbal Books 应用部署到 GKE 集群时,费用开始产生。这些费用包括 GKE 的集群费用(如价格页面中所述)以及运行 Compute Engine 虚拟机的费用。
为避免产生不必要的费用,请务必在本教程完成后停用 GKE 或删除项目。
准备工作
在开始本教程之前,请确保您已完成本系列中的前几个教程。如需查看整个系列教程的概览以及指向特定教程的链接,请参阅学习路线:将单体应用转换为 GKE 应用 - 概览。
如果您已完成第一个教程,则克隆了 GitHub 代码库。Cymbal Books 应用的所有三个版本都位于该代码库中的以下文件夹内:
monolith/
modular/
containerized/
请先检查您的计算机上是否有这些文件夹,然后再继续。
更改模块化代码
在上一个教程中,您了解到首页模块会与其他模块通信。它会向其他模块的端点发送请求,以检索图书详情、评价和图片,然后以 HTML 页面的形式呈现这些数据。
在 modular/
文件夹中,端点在 home.py
中使用 localhost
进行硬编码,如下所示:
BOOK_SERVICE_URL = "http://localhost:8081" # Book details module listens on port 8081
REVIEW_SERVICE_URL = "http://localhost:8082" # Book reviews module listens on port 8082
IMAGE_SERVICE_URL = "http://localhost:8083" # Image module listens on port 8083
当所有模块在同一台机器上运行时,这些网址会正常运行。但在 Kubernetes 环境中,模块可以移至不同的机器来处理故障或平衡负载,这意味着它们的 IP 地址可能会发生变化。
为确保首页模块仍能访问其他模块,网址必须使用 Kubernetes 服务名称,而不是 localhost
。服务名称就像一个别名,Kubernetes 会使用它将请求路由到正确的模块,无论该模块在何处运行。例如,当首页模块向 http://book-details-service/book/1
发送请求时,Kubernetes 会确保该请求到达 book-details 模块。
您无需自行更新这些网址。containerized/
文件夹中的应用版本已包含此项更改:硬编码的 localhost
网址已替换为 Kubernetes 服务名称。您可以在 containerized/home_app/home_app.py
中查看更新后的版本:
BOOK_SERVICE_URL = "http://book-details-service"
REVIEW_SERVICE_URL = "http://book-reviews-service"
IMAGE_SERVICE_URL = "http://images-service"
此更新可确保应用在 Kubernetes 环境中运行时能够正常运行。
Kubernetes 清单
在上一部分中,您了解了如何更新模块的端点以使用 Kubernetes 服务名称。您可以在 Kubernetes 清单中定义服务名称。
Kubernetes 清单是一个配置文件,用于定义您要创建哪种 Kubernetes 集群来托管模块化应用。清单以 YAML 或 JSON 格式编写。在该文件中,您可以定义各种内容,例如服务(用于在模块之间进行路由)、每个模块的副本(实例)数量,以及每个模块允许使用的 CPU 和内存量。
关于 Kubernetes 清单,可以写一整个教程系列。
清单之所以复杂,是因为它定义了 Kubernetes 集群的所有方面,包括结构、行为和功能。在本教程中,您将仅了解清单中的服务名称如何与模块端点中使用的名称相匹配。在后续教程中,您将运行 kubectl apply
命令,以根据清单中定义的配置创建 GKE 集群,但在本教程中,您只需查看清单。
查看清单
在本部分中,您将检查为您编写的 Kubernetes 清单中是如何定义服务的。清单文件(一个 YAML 文件)位于您在本系列教程的第一个教程中克隆的 GitHub 代码库的 containerized/
文件夹中。如需查看服务定义,请按以下步骤操作:
在终端中,导航到克隆的代码库中的容器化目录:
cd containerized
在文本编辑器中,打开 Kubernetes 清单文件:
cat kubernetes_manifest.yaml
查找
book-details
模块的服务定义。它看起来类似于以下示例:apiVersion: v1 kind: Service metadata: name: book-details-service spec: selector: app: book-details-app ports: - protocol: TCP port: 80 # External traffic on port 80 targetPort: 8080 # Targeting container port 8080 type: ClusterIP
清单中的 book-details-service
服务名称与模块端点中使用的名称一致:http://book-details-service
。当应用在 Kubernetes 中运行时,Kubernetes 会使用这些服务名称将请求路由到正确的模块。
Kubernetes 清单定义了 Kubernetes 集群的各项功能,包括处理请求路由的服务。应用中的每个模块都有一个在清单中定义的相应服务。通过更新模块化代码中的网址以匹配这些服务名称,您可以确保当应用在集群中运行时,Kubernetes 可以将请求路由到正确的模块。
摘要
在本教程中,您已了解模块化代码中的网址如何更新为使用 Kubernetes 服务名称,例如 http://book-details-service
。借助这些服务名称,即使模块在集群中的位置发生变化,Kubernetes 也能在模块之间路由请求。您还检查了 Kubernetes 清单,并了解了模块化代码中的服务名称与清单中定义的名称如何匹配。
后续步骤
在下一个教程将模块化应用容器化中,您将学习如何通过将模块打包到称为容器映像的内容中来将模块容器化。然后,您将了解如何将容器映像作为容器运行、测试其功能,以及将容器映像推送到 Google 的 Artifact Registry。