将单体式网站迁移到 Google Kubernetes Engine 上的微服务

1. 简介

为什么要从单体式应用迁移到微服务架构?将应用分解为微服务具有以下优势:其中大部分原因是微服务是松散耦合的。

  • 微服务可以独立测试和部署。部署单元越小,部署就越简单。
  • 它们能够以不同的语言和框架实现。对于每个微服务,您可以随意选择最适合其特定用例的技术。
  • 它们可以由不同团队管理。微服务之间的边界可让您更轻松地为一个或多个微服务专门安排一个团队。
  • 通过迁移到微服务,您可以解除团队之间的依赖关系。每个团队只需关注其所依赖的微服务的 API。团队无需考虑这些微服务的实现方式、发布周期等。
  • 您可以更轻松地设计故障预防机制。通过在服务之间划分明确边界,您可以更轻松地确定当服务出现故障时该做什么。

与单体式应用相比,一些缺点包括:

  • 由于基于微服务的应用是由不同服务组成的网络,而这些服务通常以不明显的方式进行交互,因此系统的整体复杂性往往会增加。
  • 与单体式应用的内部不同,微服务通过网络进行通信。在某些情况下,这可能会被视为安全问题。Istio 通过自动加密微服务之间的流量来解决此问题。
  • 由于服务之间存在延迟,可能很难实现与单体式应用方法相同水平的性能。
  • 系统的行为不是由单个服务引起的,而是由许多服务及服务交互引起的。因此,了解您的系统在生产环境中的行为方式(其可观测性)更加困难。Istio 也可以解决这一问题。

在本实验中,我们将在 Google Kubernetes Engine (GKE) 中运行微服务。Kubernetes 是一个用于管理、托管、扩缩和部署容器的平台。容器是一种可移植的代码封装和运行方式。它们非常适合微服务模式,使用这种模式时,每个微服务可以在各自的容器中运行。

在本实验中,我们将将现有单体式应用部署到 Google Kubernetes Engine 集群,然后将其分解为微服务!

微服务架构图

首先,我们将单体式应用拆分为三项微服务,一次一个。微服务包括订单、产品和前端。我们使用 Cloud Build 为每个微服务构建 Docker 映像,并从 Cloud Shell 中触发该映像。然后,我们将使用 Kubernetes 服务类型的 LoadBalancer 在 Google Kubernetes Engine (GKE) 上部署和公开我们的微服务。我们将对每项服务执行此操作,同时从单体式应用中重构它们。在此过程中,我们会持续运行单体式应用和微服务,直至我们能够删除单体式应用为止。

636a2d58588b2b87

学习内容

  • 如何将单体式应用分解为微服务
  • 如何创建 Google Kubernetes Engine 集群
  • 如何创建 Docker 映像
  • 如何将 Docker 映像部署到 Kubernetes

前提条件

  • 拥有创建项目的管理员权限的 Google Cloud Platform 账号,或拥有 Project Owner 角色的项目
  • 对 Docker 和 Kubernetes 有基本的了解

2. 环境设置

自定进度的环境设置

如果您还没有 Google 账号(Gmail 或 Google Apps),则必须创建一个。登录 Google Cloud Platform 控制台 ( console.cloud.google.com) 并创建一个新项目:

53dad2cefdae71da.png

2016-02-10 12:45:26 的屏幕截图.png

请记住项目 ID,它在所有 Google Cloud 项目中都是唯一名称(很抱歉,上述名称已被占用,您无法使用!)。它稍后将在此 Codelab 中被称为 PROJECT_ID

接下来,您需要在 Developers Console 中启用结算功能,以便使用 Google Cloud 资源并启用 Container Engine API

在此 Codelab 中运行仅花费几美元,但是如果您决定使用更多资源或继续让它们运行,费用可能更高(请参阅本文档末尾的“清理”部分)。如需了解 Google Kubernetes Engine 价格,请点击此处

Google Cloud Platform 的新用户有资格获享$300 免费试用

Google Cloud Shell

虽然可以通过笔记本电脑远程操作 Google Cloud 和 Kubernetes,但在此 Codelab 中,我们将使用 Google Cloud Shell,这是一个在云端运行的命令行环境。

基于 Debian 的这个虚拟机已加载了您需要的所有开发工具。它提供了一个持久的 5GB 主目录,并且在 Google Cloud 中运行,大大增强了网络性能和身份验证。这意味着在本 Codelab 中,您只需要一个浏览器(没错,它适用于 Chromebook)。

  1. 如需从 Cloud Console 激活 Cloud Shell,只需点击激活 Cloud ShellfEbHefbRynwXpq1vj2wJw6Dr17O0np8l-WOekxAZYlZQIORsWQE_xJl-cNhogjATLn-YxLVz8CgLvIW1Ncc0yXKJsfzJGMYgUeLsVB7zSwz7p6ItNgx4tXqQjag7BfWPcZN5kP-X3Q(预配和连接到环境仅需花费一些时间)。

I5aEsuNurCxHoDFjZRZrKBdarPPKPoKuExYpdagmdaOLKe7eig3DAKJitIKyuOpuwmrMAyZhp5AXpmD_k66cBuc1aUnWlJeSfo_aTKPY9aNMurhfegg1CYaE11jdpSTYNNIYARe01A

Screen Shot 2017-06-14 at 10.13.43 PM.png

在连接到 Cloud Shell 后,您应该会看到自己已通过身份验证,并且相关项目已设置为您的 PROJECT_ID

gcloud auth list

命令输出

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

命令输出

[core]
project = <PROJECT_ID>

如果出于某种原因未设置项目,只需发出以下命令即可:

gcloud config set project <PROJECT_ID>

正在查找您的 PROJECT_ID?检查您在设置步骤中使用的 ID,或在 Cloud Console 信息中心查找该 ID:

R7chO4PKQfLC3bvFBNZJALLTUiCgyLEq_67ECX7ohs_0ZnSjC7GxDNxWrJJUaoM53LnqABYamrBJhCuXF-J9XBzuUgaz7VvaxNrkP2TAn93Drxccyj2-5zz4AxL-G3hzxZ4PsM5HHQ

默认情况下,Cloud Shell 还会设置一些环境变量,这对您日后运行命令可能会很有用。

echo $GOOGLE_CLOUD_PROJECT

命令输出

<PROJECT_ID>
  1. 最后,设置默认可用区和项目配置。
gcloud config set compute/zone us-central1-f

您可以选择各种不同的可用区。如需了解详情,请参阅区域和可用区

3. 克隆源代码库

我们使用了一个虚构电子商务网站的现有单体式应用,其中包含一个简单的欢迎页面、产品页面和订单历史记录页面。我们只需从 Git 代码库中克隆源代码,即可专注于将其分解成微服务并部署到 Google Kubernetes Engine (GKE)。

运行以下命令,将 Git 代码库克隆到 Cloud Shell 实例并切换到相应目录。我们还将安装 NodeJS 依赖项,以便在部署之前测试单体式应用。此脚本可能需要几分钟时间才能运行完毕。

cd ~
git clone https://github.com/googlecodelabs/monolith-to-microservices.git
cd ~/monolith-to-microservices
./setup.sh

这将克隆 GitHub 代码库,切换到该目录,并安装在本地运行应用所需的依赖项。此脚本可能需要几分钟时间才能运行完毕。

4. 创建 GKE 集群

现在,您已经有了工作的开发者环境,我们需要一个 Kubernetes 集群来部署单体式应用,最终将微服务部署到!在创建集群之前,我们需要确保启用了正确的 API。运行以下命令来启用容器 API,以便我们可以使用 Google Kubernetes Engine:

gcloud services enable container.googleapis.com

现在,我们可以创建集群了!运行以下命令,创建一个名为 fancy-cluster 且包含 3 个节点的 GKE 集群。

gcloud container clusters create fancy-cluster --num-nodes 3

集群可能需要几分钟才能完成创建。命令完成后,运行以下命令并查看集群的三个工作器虚拟机实例:

gcloud compute instances list

输出:

NAME                                          ZONE        MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP    STATUS
gke-fancy-cluster-default-pool-ad92506d-1ng3  us-east4-a  n1-standard-1               10.150.0.7   XX.XX.XX.XX    RUNNING
gke-fancy-cluster-default-pool-ad92506d-4fvq  us-east4-a  n1-standard-1               10.150.0.5   XX.XX.XX.XX    RUNNING
gke-fancy-cluster-default-pool-ad92506d-4zs3  us-east4-a  n1-standard-1               10.150.0.6   XX.XX.XX.XX    RUNNING

您还可以在 Google Cloud 控制台中查看 Kubernetes 集群和相关信息。点击左上角的菜单按钮,向下滚动到“Kubernetes Engine”,然后点击“集群”。您应该会看到名为 fancy-cluster 的集群。

795c794b03c5d2b0

6b394dfb8a6031f2

恭喜!您刚刚创建了您的第一个 Kubernetes 集群!

5. 部署现有的单体式应用

本实验的重点是逐步了解如何将单体式应用分解为微服务,因此我们需要启动并运行单体式应用。出于本实验的目的,运行以下脚本,将单体式应用部署到 GKE 集群:

cd ~/monolith-to-microservices
./deploy-monolith.sh

访问单体式应用

如需查找单体式应用的外部 IP 地址,请运行以下命令。

kubectl get service monolith

您应看到类似于以下内容的输出:

NAME         CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
monolith     10.3.251.122    203.0.113.0     80:30877/TCP     3d

注意:由于需要为此配置外部负载平衡器和 IP,此过程需要一些时间。如果您的输出将外部 IP 列为

<pending> 请稍等几分钟,然后重试。

确定单体式应用的外部 IP 地址后,复制该 IP 地址。将浏览器指向此网址(例如 http://203.0.113.0),以检查您的单体式应用是否可访问。

9ed25c3f0cbe62fa.png

您应该会看到单体式应用的欢迎页面,如上图所示。欢迎页面是静态页面,稍后将由前端微服务提供。现在,您的单体式应用已在 Kubernetes 上完全运行!

6. 将订单迁移到微服务

现在,我们已经在 GKE 上运行了现有的单体式应用网站,接下来可以开始将每项服务分解为微服务。通常,您应规划将哪些服务拆分为多个较小的部分,通常围绕应用的特定部分(例如业务领域)进行规划。出于演示目的,我们创建了一个简单的示例,并围绕业务域、订单、产品和前端对每项服务进行了划分。代码已迁移,我们将专注于在 Google Kubernetes Engine (GKE) 上构建和部署服务。

“创建新订单”微服务

我们要介绍的第一项服务是订单服务。我们将使用所提供的单独代码库,并为此服务创建一个单独的 Docker 容器。

使用 Google Cloud Build 创建 Docker 容器

我们已经为您迁移了代码库,因此第一步是使用 Google Cloud Build 创建订单服务的 Docker 容器。

通常,您必须采取两个步骤,即构建 Docker 容器并将其推送到注册表以存储映像供 GKE 拉取。但我们可以简化操作,只需一个命令,即可使用 Google Cloud Build 构建 Docker 容器,并将映像放入 Google Cloud Container Registry!这使我们能够发出单个命令来构建映像并将其移至 Container Registry。如需查看手动创建 Docker 文件并推送该文件的过程,请转到此处

Google Cloud Build 将压缩目录中的文件,并将其移至 Google Cloud Storage 存储分区。然后,构建流程将从存储分区中获取所有文件,并使用 Dockerfile 运行 Docker 构建流程。由于我们为 Docker 映像指定了 --tag 标志,并将主机设置为 gcr.io,因此生成的 Docker 映像将被推送到 Google Cloud Container Registry。

运行以下命令以构建 Docker 容器并将其推送到 Google Container Registry:

cd ~/monolith-to-microservices/microservices/src/orders
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/orders:1.0.0 .

此过程可能需要几分钟时间,但完成后,终端中会显示类似如下所示的输出:

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ID                                    CREATE_TIME                DURATION  SOURCE                                                                                  IMAGES                              STATUS
1ae295d9-63cb-482c-959b-bc52e9644d53  2019-08-29T01:56:35+00:00  33S       gs://<PROJECT_ID>_cloudbuild/source/1567043793.94-abfd382011724422bf49af1558b894aa.tgz  gcr.io/<PROJECT_ID>/orders:1.0.0  SUCCESS

如需查看构建记录或实时观察构建过程,您可以访问 Google Cloud 控制台。点击左上角的菜单按钮,向下滚动到“工具”→“Cloud Build”,然后点击“历史记录”。在这里,您可以看到您之前所有 build 的列表,其中应该只有 1 个您刚刚创建的 build。

4c753ede203255f6

如果您点击构建 ID,就可以查看该构建的所有详细信息,包括日志输出。

在“构建详情”页面中,您可以通过点击“构建信息”部分中的映像名称来查看创建的容器映像。

6e88ed1643dfe629

将容器部署到 GKE

现在,我们已将网站容器化,并将容器推送到 Google Container Registry,是时候部署到 Kubernetes 了!

Kubernetes 将应用表示为 Pod,这是表示一个容器(或一组紧密耦合的容器)的单元。Pod 是 Kubernetes 中最小的可部署单元。在本教程中,每个 Pod 仅包含您的微服务容器。

如需在 GKE 集群上部署和管理应用,您必须与 Kubernetes 集群管理系统进行通信。您通常在 Cloud Shell 中使用 kubectl 命令行工具执行此操作。

首先,我们将创建一个 Deployment 资源。Deployment 会管理应用的多个副本(称为副本),并安排这些副本在集群中的各个节点上运行。在此示例中,Deployment 将仅运行应用的一个 Pod。Deployment 通过创建 ReplicaSet 确保这一点。ReplicaSet 负责确保指定数量的副本始终保持运行状态。

下面的 kubectl create deployment 命令会使 Kubernetes 在具有 1 个副本的集群上创建一个名为 orders 的 Deployment。

运行以下命令以部署应用:

kubectl create deployment orders --image=gcr.io/${GOOGLE_CLOUD_PROJECT}/orders:1.0.0

验证部署

如需验证 Deployment 是否已成功创建,请运行以下命令。Pod 状态可能需要一些时间才会变为“正在运行”:

kubectl get all

输出:

NAME                            READY   STATUS    RESTARTS   AGE
pod/monolith-779c8d95f5-dxnzl   1/1     Running   0          15h
pod/orders-5bc6969d76-kdxkk     1/1     Running   0          21s
NAME                 TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)        AGE
service/kubernetes   ClusterIP      10.39.240.1     <none>         443/TCP        19d
service/monolith     LoadBalancer   10.39.241.130   34.74.209.57   80:30412/TCP   15h
NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/monolith   1/1     1            1           15h
deployment.apps/orders     1/1     1            1           21s
NAME                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/monolith-779c8d95f5   1         1         1       15h
replicaset.apps/orders-5bc6969d76     1         1         1       21s

此输出显示了以下信息。我们可以看到当前的 Deployment 和所需的 Pod 数量为 1 的 ReplicaSet,以及正在运行的 Pod。看起来所有内容都已成功创建!

公开 GKE 容器

我们已将应用部署在 GKE 上,但无法在集群之外访问该应用。默认情况下,您无法从互联网访问您在 GKE 上运行的容器,因为这些容器没有外部 IP 地址。您必须通过 Service 资源向来自互联网的流量明确公开您的应用。Service 为应用的 Pod 提供网络和 IP 支持。GKE 会为您的应用创建外部 IP 和负载平衡器(需要付费)。

部署订单服务时,我们通过 Kubernetes 部署在内部在端口 8081 上公开该服务。为了在外部公开此服务,我们需要创建 LoadBalancer 类型的 Kubernetes 服务,以将流量从外部端口 80 路由到 Orders 服务的内部端口 8081。运行以下命令,在互联网上公开您的网站:

kubectl expose deployment orders --type=LoadBalancer --port 80 --target-port 8081

访问服务

GKE 会将外部 IP 地址分配给 Service 资源,而不是 Deployment。如果要查找 GKE 为应用预配的外部 IP,可以使用 kubectl get service 命令检查 Service:

kubectl get service orders

输出:

NAME         CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
orders       10.3.251.122    203.0.113.0     80:30877/TCP     3d

确定应用的外部 IP 地址后,请复制该 IP 地址。当我们将单体式应用更改为指向新的订单服务时,请保存该 ID 以供下一步使用!

重新配置单体式应用

由于我们从单体式应用中移除了 Orders 服务,因此必须修改单体式应用以指向新的外部 Orders 微服务。

拆分单体式应用时,我们会从单个代码库中移除一些代码并拆分到多个代码库中,然后分别部署它们。由于微服务在不同的服务器上运行,因此我们无法再将服务网址引用为绝对路径,因此我们需要路由到订单微服务的新服务器地址。请注意,这需要单体式应用服务停机一段时间,才能更新已分解的每项服务的网址。在规划在微服务迁移过程中将微服务和单体式应用迁移到生产环境时,应考虑到这一点。

我们需要更新单体式应用中的配置文件,以指向新的 Orders 微服务 IP 地址。使用 nano 编辑器将本地网址替换为新的 Orders 微服务的 IP 地址。运行以下命令以修改

cd ~/monolith-to-microservices/react-app
nano .env.monolith

编辑器打开后,您的文件应如下所示:

REACT_APP_ORDERS_URL=/service/orders
REACT_APP_PRODUCTS_URL=/service/products

REACT_APP_ORDERS_URL 替换为新格式,同时替换为您的 Orders 微服务 IP 地址,使其如下所示:

REACT_APP_ORDERS_URL=http://<ORDERS_IP_ADDRESS>/api/orders
REACT_APP_PRODUCTS_URL=/service/products

CTRL+O,然后按 ENTERCTRL+X,将文件保存在 nano 编辑器中。

您可以浏览刚刚在此文件中设置的网址,测试新的微服务。网页应从“订单”微服务返回 JSON 响应。

接下来,我们需要重新构建单体式应用前端并重复构建流程,为单体式应用构建容器,然后重新部署到 GKE 集群。运行以下命令可完成以下步骤:

重新构建单体式应用配置文件

npm run build:monolith

使用 Google Cloud Build 创建 Docker 容器

cd ~/monolith-to-microservices/monolith
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0 .

将容器部署到 GKE

kubectl set image deployment/monolith monolith=gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0

在浏览器中进入单体式应用,然后导航到“订单”页面,以验证您的应用现在是否访问了新的“订单”微服务。所有订单 ID 都应以后缀“MICROSERVICE”结尾,如下所示:

1cdd60bb0d4d1148

7. 将产品迁移到微服务

创建新的产品微服务

接下来,我们可以迁移产品服务,继续细分我们的服务。我们要遵循与上一步相同的流程。运行以下命令来构建 Docker 容器,部署容器并通过 Kubernetes 服务将其公开。

使用 Google Cloud Build 创建 Docker 容器

cd ~/monolith-to-microservices/microservices/src/products
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/products:1.0.0 .

将容器部署到 GKE

kubectl create deployment products --image=gcr.io/${GOOGLE_CLOUD_PROJECT}/products:1.0.0

公开 GKE 容器

kubectl expose deployment products --type=LoadBalancer --port 80 --target-port 8082

使用以下命令查找产品服务的公共 IP,具体方法与查找 Orders 服务的方法相同:

kubectl get service products

输出:

NAME         CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
products     10.3.251.122    203.0.113.0     80:30877/TCP     3d

当我们将单体式应用重新配置为指向新的产品微服务时,请保存 IP 地址,以便在下一步中使用。

重新配置单体式应用

使用 nano 编辑器将本地网址替换为我们的新产品微服务的 IP 地址:

cd ~/monolith-to-microservices/react-app
nano .env.monolith

编辑器打开后,您的文件应如下所示:

REACT_APP_ORDERS_URL=http://<ORDERS_IP_ADDRESS>/api/orders
REACT_APP_PRODUCTS_URL=/service/products

REACT_APP_PRODUCTS_URL 替换为新格式,同时替换为您的产品微服务 IP 地址,使其如下所示:

REACT_APP_ORDERS_URL=http://<ORDERS_IP_ADDRESS>/api/orders
REACT_APP_PRODUCTS_URL=http://<PRODUCTS_IP_ADDRESS>/api/products

CTRL+O,然后按 ENTERCTRL+X,将文件保存在 nano 编辑器中。

您可以浏览刚刚在此文件中设置的网址,测试新的微服务。网页应从“商品”微服务返回 JSON 响应。

接下来,我们需要重新构建单体式应用前端并重复构建流程,为单体式应用构建容器,然后重新部署到 GKE 集群。运行以下命令可完成以下步骤:

重新构建单体式应用配置文件

npm run build:monolith

使用 Google Cloud Build 创建 Docker 容器

cd ~/monolith-to-microservices/monolith
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:3.0.0 .

将容器部署到 GKE

kubectl set image deployment/monolith monolith=gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:3.0.0

您可以在浏览器中进入单体式应用,然后导航到“Products”页面,验证您的应用现在是否访问新的“Products”(产品)微服务。所有产品名称均应带有 MS- 前缀,如下所示:

5389b29f4b8c7c69

8. 将前端迁移到微服务

迁移过程的最后一步是将前端代码移至微服务并关闭单体式应用!完成此步骤后,我们就已成功将单体式应用迁移到微服务架构!

创建新的前端微服务

让我们按照与最后两个步骤相同的过程来创建新的前端微服务。

以前,在重新构建单体式应用时,我们将配置更新为指向单体式应用,但现在我们需要对前端微服务使用相同的配置。运行以下命令,将我们的微服务网址配置文件复制到前端微服务代码库:

cd ~/monolith-to-microservices/react-app
cp .env.monolith .env
npm run build

完成后,我们将遵循与之前的步骤相同的流程。运行以下命令来构建 Docker 容器,部署容器并通过 Kubernetes 服务将其公开。

使用 Google Cloud Build 创建 Docker 容器

cd ~/monolith-to-microservices/microservices/src/frontend
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/frontend:1.0.0 .

将容器部署到 GKE

kubectl create deployment frontend --image=gcr.io/${GOOGLE_CLOUD_PROJECT}/frontend:1.0.0

公开 GKE 容器

kubectl expose deployment frontend --type=LoadBalancer --port 80 --target-port 8080

删除单体式应用

现在,我们的所有服务都在以微服务的形式运行,接下来我们可以删除单体式应用了!请注意,在实际迁移中,这还需要执行 DNS 等更改,使现有域名指向应用的新前端微服务。运行以下命令以删除单体式应用:

kubectl delete deployment monolith
kubectl delete service monolith

测试您的工作

为了验证一切是否正常,单体式应用服务中的旧 IP 地址应该不起作用,而前端服务中的新 IP 地址应该托管新应用。如需查看所有服务和 IP 地址的列表,请使用以下命令:

kubectl get services

您的输出应如下所示:

NAME         TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE
frontend     LoadBalancer   10.39.246.135   35.227.21.154    80:32663/TCP   12m
kubernetes   ClusterIP      10.39.240.1     <none>           443/TCP        18d
orders       LoadBalancer   10.39.243.42    35.243.173.255   80:32714/TCP   31m
products     LoadBalancer   10.39.250.16    35.243.180.23    80:32335/TCP   21m

确定前端微服务的外部 IP 地址后,复制该 IP 地址。将浏览器指向此网址(例如 http://203.0.113.0)以检查前端是否可访问。您的网站应该与我们将单体式应用分解为微服务之前一样!

9. 清理

准备就绪后,要清理已执行的所有活动,最简单的方法就是删除项目。删除项目会删除在此 Codelab 中创建的所有资源,以确保不会产生意外的周期性费用。在 Cloud Shell 中执行以下命令,其中 PROJECT_ID 是完整的项目 ID,而不仅仅是项目名称。

gcloud projects delete [PROJECT_ID]

输入“Y”以确认删除。

10. 恭喜!

您已成功将单体式应用分解成多个微服务,并将它们部署在 Google Kubernetes Engine 上!

后续步骤

查看以下 Codelab,详细了解 Kubernetes:

其他资源