学习路线:将单体式应用转换为 GKE 应用 - 将应用部署到 GKE 集群


这是该学习路线中的第五个教程,也是最后一个教程,该教程将介绍如何对单体式应用进行模块化和容器化。

此学习路线包含以下教程:

  1. 概览
  2. 了解单体式应用
  3. 将单体式应用模块化
  4. 准备好模块化应用以实现容器化
  5. 将模块化应用容器化
  6. 将应用部署到 GKE 集群(本教程)

在上一个教程将模块化应用容器化中,您已准备好模块化 Cymbal Books 应用以进行部署。您将应用的模块容器化,测试了生成的容器,并将容器映像推送到 Artifact Registry

在本教程中,您将容器化应用部署到 Google Kubernetes Engine 集群。 此步骤完成了将 Cymbal Books 应用转换为在 Kubernetes 集群上运行的模块化、可扩缩系统的过程。

费用

按照本教程中的步骤操作会导致您的 Google Cloud账号产生费用。当您启用 GKE 并部署 Cymbal Books 示例应用时,费用开始产生。这些费用包括 GKE 的按集群收费(如价格页面中所述)以及运行 Compute Engine 虚拟机的费用。

为避免产生不必要的费用,请务必在完成本教程后停用 GKE 或删除项目。

准备工作

在开始学习本教程之前,请确保您已完成本系列中的前几个教程。如需查看整个系列教程的概览以及指向特定教程的链接,请参阅学习路线:将单体式应用转换为 GKE 应用 - 概览

具体而言,您需要已执行上一教程将模块化应用容器化中的步骤。

设置 GKE 集群

在部署模块化 Cymbal Books 应用之前,您必须先创建一个 GKE 集群。此集群提供应用容器将运行的基础设施。

在本教程中,您将使用 gcloud CLI 创建集群。或者,您也可以使用 Google Cloud 控制台,该控制台提供了一个图形界面 (GUI),用于创建和管理 Google Cloud资源(例如 GKE 集群)。

创建并验证 GKE 集群

GKE 集群提供在 Kubernetes 中运行容器所需的计算资源。按照以下步骤使用 gcloud CLI 创建集群。

  1. 前往 Google Cloud 控制台

  2. 在控制台中,点击激活 Cloud Shell 按钮:激活 Cloud Shell

    控制台下方的框架内会打开一个 Cloud Shell 会话。

  3. 在 Google Cloud CLI 中设置默认项目:

    gcloud config set project PROJECT_ID
    

    PROJECT_ID 替换为您在上一个教程的选择或创建 Google Cloud 项目部分中创建或选择的项目的项目 ID。项目 ID 是一个唯一字符串,用于将您的项目与 Google Cloud中的所有其他项目区分开来。如需查找项目 ID,请前往项目选择器。 在该页面上,您可以查看每个 Google Cloud项目的项目 ID。

  4. 创建 GKE 集群:

    gcloud container clusters create CLUSTER_NAME \
        --zone=ZONE \
        --num-nodes=2
    

    替换以下内容:

    • CLUSTER_NAME:集群的名称,例如 cymbal-cluster

    • ZONE:您希望在其中创建集群的可用区,例如 us-central1-aeurope-west1-b。如需查看可用的可用区的完整列表,请参阅区域和可用区

  5. 检索集群的凭证,以便 kubectl CLI 可以连接到集群:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --zone=ZONE
    

    此命令会更新您的 Kubernetes 配置文件,该文件默认存储在 ~/.kube/config 中。此配置文件包含 kubectl 与 GKE 集群互动所需的凭证。

  6. 通过列出集群节点来验证 kubectl 是否已连接到集群:

    kubectl get nodes
    

    如果设置成功,此命令会列出 GKE 集群中的节点。由于您使用 --num-nodes=2 创建了集群,因此您应该会看到有关两个节点的信息,类似于以下内容:

    NAME                                         STATUS    ROLES    AGE    VERSION
    gke-nov18-default-pool-6a8f9caf-bryg   Ready     <none>   30s    v1.30.8-gke.1128000
    gke-nov18-default-pool-6a8f9caf-ut0i   Ready     <none>   30s    v1.30.8-gke.1128000
    

    在此示例中,两个节点都处于 Ready 状态。此状态表示 GKE 集群已准备好托管您的容器化工作负载!

部署应用

现在您已创建 GKE 集群,可以向其部署 Cymbal Books 应用。如需将应用部署到集群,请将 Kubernetes 清单应用于集群。

应用 Kubernetes 清单

在 Cloud Shell 中,通过运行以下命令将应用部署到 GKE 集群:

  1. 前往容器化应用的根目录:

    cd kubernetes-engine-samples/quickstarts/monolith-to-microservices/containerized/
    
  2. 应用 Kubernetes 清单:

    kubectl apply -f kubernetes_manifest.yaml
    

上述命令指示 Kubernetes 创建 kubernetes-manifest.yaml 文件中指定的资源。这些资源包括 Service、Deployment 和 Pod。

您第一次接触 Service 是在准备好模块化应用以实现容器化教程中的更改模块化代码部分中。在该教程中,您更新了应用代码,以使用 Service 名称而不是 localhost。该更新使 Kubernetes 能够在模块之间路由请求,并确保模块可以在集群内相互通信。现在,当您应用清单时,Kubernetes 会在集群内创建 Service。

Deployment 是一个 Kubernetes API 对象,可让您运行在集群节点中分布的多个 Pod 副本。下一部分将介绍什么是 Pod。

Kubernetes Pod 是什么?

在上一个教程中,您为 Cymbal Books 应用的每个模块创建了容器映像。例如,您根据 home_appbook_details_app 模块创建了容器映像。

当您使用 kubectl apply 命令部署 Kubernetes 清单时,Kubernetes 会将您的容器映像从 Artifact Registry 拉取到集群中。在集群中,容器映像会变成容器,而容器在 Pod 内运行。

Pod 是容器运行的隔离环境,可执行以下任务:

  • 分配 CPU 和内存:Pod 提供容器运行所需的资源。
  • 提供网络:每个 Pod 都有自己的 IP 地址。这使 Pod 能够与其他 Pod 通信。

Pod 在节点上运行,节点是为集群提供计算能力的机器。Kubernetes 会自动将 Pod 分配给节点,并将 Pod 分布在集群的各个节点上,以降低任何单个节点过载的风险。此分布有助于集群高效使用计算和内存资源。

验证 Deployment

使用 kubectl apply 命令应用 Kubernetes 清单后,验证该应用是否已成功部署到集群。如需验证 Deployment,请检查 Pod 和 Service 是否正常运行。

检查 Pod

如需查看集群中的 Pod,请运行以下命令:

kubectl get pods

此命令会列出 Pod 及其当前状态。查看状态列,确认所有 Pod 都标记为 Running,这表示它们已成功运行并准备好处理请求。预期输出如下所示:

NAME                             READY   STATUS    RESTARTS   AGE
home-app-67d59c6b6d-abcde        1/1     Running   0          30s
book-details-app-6d8bcbc58f-xyz  1/1     Running   0          30s
book-reviews-app-75db4c4d7f-def  1/1     Running   0          30s
images-app-7f8c75c79c-ghi        1/1     Running   0          30s

Pod 在创建时及其容器启动过程中,其状态最初显示为 Pending。如果 Pod 长时间保持 Pending 状态,则集群可能缺少足够的资源来让该 Pod 进入健康的 Running 状态。如果 Pod 的状态为 CrashLoopBackOff,则可能表示容器存在问题。本教程稍后会提供问题排查步骤。

检查 Service

Service 可实现 Pod 之间的通信,并允许外部客户端(例如用户、自动化脚本或监控工具)访问应用。如需查看集群中的 Service,请运行以下命令:

kubectl get services

此命令的输出如下所示:

NAME               TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)        AGE
home-app-service   LoadBalancer   10.12.3.4       35.185.1.2        80:30837/TCP   30s
details-service    ClusterIP      10.12.3.5       <none>            80/TCP         30s
reviews-service    ClusterIP      10.12.3.6       <none>            80/TCP         30s
images-service     LoadBalancer   10.12.3.7       34.125.6.3        80:32014/TCP   30s

输出中需要注意的关键字段如下:

  • TYPE:此字段用于指明 Service 的公开方式。类型为 LoadBalancer 的 Service 可为应用提供外部访问权限。
  • EXTERNAL-IP:对于类型为 LoadBalancer 的 Service,EXTERNAL-IP 字段会显示用户可以在网络浏览器中输入以访问应用的公共 IP 地址。对于类型为 ClusterIP 的 Service,此字段为空,因为 ClusterIP Service 只能在集群内访问。

测试部署

将 Cymbal Books 应用部署到 GKE 集群后,验证该应用是否可访问,以及容器之间是否可以相互通信。

访问应用

请按照以下步骤确认应用是否可访问:

  1. 检索 home-app-service 的外部 IP 地址:

    kubectl get services
    

    在输出中找到 **EXTERNAL-IP** 列,并记下与 home-app-service 关联的 IP 地址。

  2. 打开网络浏览器并输入以下网址:

    http://EXTERNAL-IP
    

    EXTERNAL-IP 替换为您在上一步中找到的 IP 地址。

  3. 验证 Cymbal Books 应用的首页是否正确加载。

验证服务间通信

Cymbal Books 应用中的容器依赖于 Service 来交换信息。请按照以下步骤操作,确保容器可以有效通信:

  1. 按照上文所述,检索 home-app-service 的外部 IP 地址。

  2. 使用应用的接口测试容器之间的互动。为此,请点击应用界面中的所有可用链接,确认以下功能正常运行:

    • 检查图书封面图片:确认图书封面图片在首页和图书详情页面上均能正确加载。如果可以,则表示 home_appbook_details_app 容器已成功与 images_app 容器通信。
    • 查看图书详情:从首页前往图书详情页面。如果您看到图书的详情,表示 home_app 容器正在与 book_details_app 正确通信。
    • 查看书评:点击书评链接以验证 home_app 容器是否可以与 book_reviews_app 容器通信。

您的应用现在正在 GKE 集群上运行!

恭喜!您已了解如何将单体式应用转换为在活跃 GKE 集群上运行的模块化容器化系统。在此过程中,您学习了如何将紧密耦合的代码划分为独立的模块、如何构建容器映像并将其推送到代码库、如何定义 Kubernetes 清单,以及如何将应用从注册数据库部署到 GKE。这是一项重大成就,反映了团队为实现应用云端现代化而采取的实际步骤!

问题排查

如果应用不响应或容器无法通信,请使用以下问题排查步骤来诊断和解决常见问题。

检查您的 Pod 的状态

首先,列出集群中的所有 Pod,以确定它们是否按预期运行:

kubectl get pods

查看输出,确认每个 Pod 都处于 Running 状态。如果有任何 Pod 未运行,请记下其名称以供进一步检查。

检查 Pod 日志

如果 Pod 未正确处理请求,请检查日志以查找任何错误消息:

kubectl logs POD_NAME

POD_NAME 替换为您要检查的 Pod 的名称。此命令有助于识别启动问题或运行时错误。

描述 Pod 以获取详细信息

如果 Pod 处于非 Running 状态的时间超过 5 分钟(例如,处于 PendingContainerCreatingCrashLoopBackOff 状态),您可以使用以下命令查看有关 Pod 状态和事件的详细信息:

kubectl describe pod POD_NAME

POD_NAME 替换为您要详细了解的 Pod 的名称。

输出中的 Events 部分可能表示资源限制或映像拉取问题阻止 Pod 正常启动。

验证 Service 配置

确保 Service 设置正确,尤其是通过外部 IP 地址公开首页模块的 Service。使用以下命令列出 Service:

kubectl get services

如果您发现首页模块的 Service 具有列为 PendingEXTERNAL-IP 地址,请运行以下命令:

kubectl describe service SERVICE_NAME

SERVICE_NAME 替换为主页模块 Service 的名称。

此命令提供有关 Service 配置的更多详细信息,并帮助您确定分配外部 IP 地址的延迟或其他配置问题。

检查集群事件

您可以检查集群事件,以确定问题是否会影响集群的多个组件:

kubectl get events

此命令可以确定更广泛的资源或网络问题是否会影响您的部署。

清理资源

运行 GKE 集群会产生费用。完成本教程后,请清理资源,以免产生额外费用。请按照以下步骤移除集群,并可选择移除整个项目。

删除 GKE 集群

如需删除 GKE 集群,请使用以下命令:

gcloud container clusters delete CLUSTER_NAME
    --zone=ZONE

替换以下内容:

  • CLUSTER_NAME:您创建的集群的名称,例如 cymbal-cluster

  • ZONE:在其中创建集群的可用区,例如 us-central1-a

出现提示时,确认删除。

验证是否已删除集群

如需确保已删除集群,请运行以下命令:

gcloud container clusters list

相应集群不应再出现在输出中。如果是,请稍等片刻,然后重试。

(可选)删除 Google Cloud 项目

如果您专门为此教程创建了一个 Google Cloud 项目,但不再需要该项目,您可以删除整个 Google Cloud 项目。删除项目会移除所有资源并停止该项目的结算:

  1. 在 Google Cloud 控制台中,打开管理资源页面。
  2. 选择要删除的项目。
  3. 点击删除项目,然后按照提示进行确认。

系列图书摘要

恭喜!通过完成此学习路线,您已经学习了关于将单体式应用转换为在 Kubernetes 集群上运行的模块化容器化应用的基础知识。以下步骤总结了此流程:

  1. 了解单体式应用

    • 探索了 Cymbal Books 单体式应用的结构。
    • 设置本地 Python 环境以运行单体式应用并测试其端点。
    • 了解应用的代码库,为实现模块化做好准备。
  2. 将单体式应用模块化

    • 学习了如何将单体式代码拆分为单独的模块。每个模块处理一项不同的功能,例如显示图书详情或书评。
    • 了解了如何将这些模块实现为在不同端口上运行的独立 Flask 应用。
    • 测试了模块化应用。
  3. 准备好模块化代码以实现容器化

    • 了解到您必须更新 home.py 中的网址,才能使用 Service 名称而不是 localhost
    • 了解了 Kubernetes 清单如何定义 Service,以使已相互通信的应用模块能够在 Kubernetes 集群的上下文中相互查找。
  4. 将模块化应用容器化

    • 设置了 Google Cloud 项目,并将应用从 GitHub 克隆到 Cloud Shell 中。
    • 使用 Docker 为每个模块构建了容器映像,并在本地测试了容器。
    • 将容器映像推送到 Artifact Registry,以准备将应用部署到集群。
    • 更新了 Kubernetes 清单以引用 Artifact Registry 中的容器映像路径。
  5. 将应用部署到 GKE 集群(您当前所在的教程):

    • 创建了 GKE 集群。
    • 将容器映像从 Artifact Registry 部署到 GKE 集群。
    • 测试了应用的最终版本,此版本现在可扩缩并在 Kubernetes 环境中运行!

后续步骤

如需查看有关如何创建集群的进一步实践培训,请参阅我们的系列图书学习路线:可扩缩应用