GSP663

概览
运行网站和应用并非易事。即使一切运行正常,也可能出现意外故障。服务器可能崩溃,业务需求的增长会消耗更多资源,而要在不停机的情况下进行更改,更是复杂且压力重重。借助 Kubernetes,您可以完成所有这些操作,甚至可以实现自动化!
在本实验中,您将扮演一家虚构公司 Fancy Store 的开发者,该公司运营着一个电子商务网站。由于网站存在扩缩和服务中断的问题,您的任务是将应用部署到 Google Kubernetes Engine (GKE)。
本实验中的练习顺序旨在再现常见的云开发者体验:
- 创建 GKE 集群
- 创建 Docker 容器
- 将容器部署到 GKE
- 通过 Service 公开容器
- 将容器扩缩到多个副本
- 修改网站
- 在不停机的情况下发布新版本
架构图

前提条件
设置和要求
点击“开始实验”按钮前的注意事项
请阅读以下说明。实验是计时的,并且您无法暂停实验。计时器在您点击开始实验后即开始计时,显示 Google Cloud 资源可供您使用多长时间。
此实操实验可让您在真实的云环境中开展实验活动,免受模拟或演示环境的局限。为此,我们会向您提供新的临时凭据,您可以在该实验的规定时间内通过此凭据登录和访问 Google Cloud。
为完成此实验,您需要:
- 能够使用标准的互联网浏览器(建议使用 Chrome 浏览器)。
注意:请使用无痕模式(推荐)或无痕浏览器窗口运行此实验。这可以避免您的个人账号与学生账号之间发生冲突,这种冲突可能导致您的个人账号产生额外费用。
注意:请仅使用学生账号完成本实验。如果您使用其他 Google Cloud 账号,则可能会向该账号收取费用。
如何开始实验并登录 Google Cloud 控制台
-
点击开始实验按钮。如果该实验需要付费,系统会打开一个对话框供您选择支付方式。左侧是“实验详细信息”窗格,其中包含以下各项:
- “打开 Google Cloud 控制台”按钮
- 剩余时间
- 进行该实验时必须使用的临时凭据
- 帮助您逐步完成本实验所需的其他信息(如果需要)
-
点击打开 Google Cloud 控制台(如果您使用的是 Chrome 浏览器,请右键点击并选择在无痕式窗口中打开链接)。
该实验会启动资源并打开另一个标签页,显示“登录”页面。
提示:将这些标签页安排在不同的窗口中,并排显示。
注意:如果您看见选择账号对话框,请点击使用其他账号。
-
如有必要,请复制下方的用户名,然后将其粘贴到登录对话框中。
{{{user_0.username | "<用户名>"}}}
您也可以在“实验详细信息”窗格中找到“用户名”。
-
点击下一步。
-
复制下面的密码,然后将其粘贴到欢迎对话框中。
{{{user_0.password | "<密码>"}}}
您也可以在“实验详细信息”窗格中找到“密码”。
-
点击下一步。
重要提示:您必须使用实验提供的凭据。请勿使用您的 Google Cloud 账号凭据。
注意:在本实验中使用您自己的 Google Cloud 账号可能会产生额外费用。
-
继续在后续页面中点击以完成相应操作:
- 接受条款及条件。
- 由于这是临时账号,请勿添加账号恢复选项或双重验证。
- 请勿注册免费试用。
片刻之后,系统会在此标签页中打开 Google Cloud 控制台。
注意:如需访问 Google Cloud 产品和服务,请点击导航菜单,或在搜索字段中输入服务或产品的名称。
激活 Cloud Shell
Cloud Shell 是一种装有开发者工具的虚拟机。它提供了一个永久性的 5GB 主目录,并且在 Google Cloud 上运行。Cloud Shell 提供可用于访问您的 Google Cloud 资源的命令行工具。
-
点击 Google Cloud 控制台顶部的激活 Cloud Shell
。
-
在弹出的窗口中执行以下操作:
- 继续完成 Cloud Shell 信息窗口中的设置。
- 授权 Cloud Shell 使用您的凭据进行 Google Cloud API 调用。
如果您连接成功,即表示您已通过身份验证,且项目 ID 会被设为您的 Project_ID 。输出内容中有一行说明了此会话的 Project_ID:
Your Cloud Platform project in this session is set to {{{project_0.project_id | "PROJECT_ID"}}}
gcloud 是 Google Cloud 的命令行工具。它已预先安装在 Cloud Shell 上,且支持 Tab 自动补全功能。
- (可选)您可以通过此命令列出活跃账号名称:
gcloud auth list
- 点击授权。
输出:
ACTIVE: *
ACCOUNT: {{{user_0.username | "ACCOUNT"}}}
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- (可选)您可以通过此命令列出项目 ID:
gcloud config list project
输出:
[core]
project = {{{project_0.project_id | "PROJECT_ID"}}}
注意:如需查看在 Google Cloud 中使用 gcloud 的完整文档,请参阅 gcloud CLI 概览指南。
设置可用区
gcloud config set compute/zone {{{project_0.default_zone|lab zone}}}
参阅“区域和可用区”文档了解详情。
任务 1. 创建 GKE 集群
您需要一个 Kubernetes 集群来部署网站。首先,确保已启用所需的 API。
- 运行以下命令,创建一个名为
fancy-cluster 且包含 3 个节点的 GKE 集群:
gcloud container clusters create fancy-cluster --num-nodes 3
注意:如果出现错误提示未指定区域/可用区,请参阅环境设置部分,确认已设置默认计算可用区。
创建集群可能需要几分钟时间。
- 现在运行以下命令,查看集群中的三个工作器虚拟机实例:
gcloud compute instances list
输出:
NAME: gke-fancy-cluster-default-pool-fb932da6-4sk6
ZONE: us-central1-f
MACHINE_TYPE: e2-medium
PREEMPTIBLE:
INTERNAL_IP: 10.128.0.3
EXTERNAL_IP: 34.172.106.173
STATUS: RUNNING
NAME: gke-fancy-cluster-default-pool-fb932da6-d6qc
ZONE: us-central1-f
MACHINE_TYPE: e2-medium
PREEMPTIBLE:
INTERNAL_IP: 10.128.0.4
EXTERNAL_IP: 34.133.99.176
STATUS: RUNNING
NAME: gke-fancy-cluster-default-pool-fb932da6-ztnh
ZONE: us-central1-f
MACHINE_TYPE: e2-medium
PREEMPTIBLE:
INTERNAL_IP: 10.128.0.5
EXTERNAL_IP: 34.136.180.45
STATUS: RUNNING
-
在控制台中查看您的 Kubernetes 集群及相关信息。
-
依次点击导航菜单 (
) > Kubernetes Engine > 集群。
您应该会看到名为 fancy-cluster 的集群。
点击检查我的进度以验证是否完成了以下目标:
创建 GKE 集群
任务 2. 克隆源代码库
由于这是一个现有网站,您只需克隆源代码,即可专注于创建 Docker 映像并部署到 GKE。
- 运行以下命令,将 git 代码库克隆到您的 Cloud Shell 实例:
cd ~
git clone https://github.com/googlecodelabs/monolith-to-microservices.git
-
切换到相应的目录。
-
您还将安装 NodeJS 依赖项,以便在部署前测试应用:
cd ~/monolith-to-microservices
./setup.sh
等待几分钟,让脚本运行完成。
- 确保您在 Cloud Shell 中运行的
npm 为最新版本:
nvm install --lts
- 切换到相应目录后,运行以下命令启动 Web 服务器并测试应用:
cd ~/monolith-to-microservices/monolith
npm start
输出:
Monolith listening on port 8080!
- 点击网页预览图标,然后选择在端口 8080 上预览,即可预览应用:

浏览器会打开一个新窗口,其中展示了 Fancy Store 的实际运行情况!

请保持标签页打开,稍后您将在实验中返回该页。
- 如需停止 Web 服务器进程,请在 Cloud Shell 中按 Ctrl+C。
任务 3. 使用 Cloud Build 创建 Docker 容器
现在您已准备好源文件,接下来使用 Docker 容器化您的应用!
通常,您需要分两步完成该操作。先构建 Docker 容器,然后将其推送到注册表,以便存储映像供 GKE 拉取。使用 Cloud Build,您只需一个命令即可构建 Docker 容器,并将映像放入 Artifact Registry!
Google Cloud Build 会压缩目录中的文件,并将它们移至 Google Cloud Storage 存储桶。然后,构建流程会从存储桶中提取所有文件,并使用 Dockerfile 运行 Docker 构建流程。由于您为 Docker 映像指定了 --tag 标志,并将主机设置为 gcr.io,因此生成的 Docker 映像将推送到 Artifact Registry。
- 首先,为确保您已启用 Cloud Build API,请运行以下命令:
gcloud services enable cloudbuild.googleapis.com
- 运行以下命令以启动构建流程:
cd ~/monolith-to-microservices/monolith
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:1.0.0 .
- 该过程需要几分钟时间。
终端中将显示类似如下所示的输出:
ID CREATE_TIME DURATION SOURCE IMAGES STATUS
1ae295d9-63cb-482c-959b-bc52e9644d53 2019-08-29T01:56:35+00:00 33S gs://_cloudbuild/source/1567043793.94-abfd382011724422bf49af1558b894aa.tgz gcr.io//monolith:1.0.0 SUCCESS
-
如需查看构建历史记录或实时监控构建过程,请点击导航菜单,向下滚动到 CI/CD 部分,然后点击 Cloud Build > 历史记录。在这里,您可以看到之前所有构建版本的列表。
-
点击构建名称即可查看该构建的详细信息,包括日志输出。
可选:在构建详情页面中,点击构建信息部分中的 构建摘要 > 执行详情 > 映像名称,查看容器映像:

点击检查我的进度以验证是否完成了以下目标:
使用 Cloud Build 创建 Docker 容器
任务 4. 将容器部署到 GKE
现在,您已经将网站容器化并将容器推送到了 Artifact Registry,接下来就可以部署到 Kubernetes 了!
如需在 GKE 集群上部署和管理应用,您必须与 Kubernetes 集群管理系统进行通信。您通常使用 kubectl 命令行工具执行该操作。
Kubernetes 将应用表示为 Pod,这是表示一个容器(或一组紧密耦合的容器)的单元。Pod 是 Kubernetes 中最小的可部署单元。在本实验中,每个 Pod 仅包含您的单体式应用容器。
如需部署应用,请创建 Deployment 资源。Deployment 管理应用的多个运行实例(称为副本),并安排这些副本在集群中的各个节点上运行。在本实验中,Deployment 将只运行应用的一个 Pod。Deployment 通过创建 ReplicaSet 来确保这一点。ReplicaSet 负责确保指定数量的副本始终处于运行状态。
接下来您将使用 kubectl create deployment 命令。该命令会让 Kubernetes 在您的集群上创建一个名为 monolith 的 Deployment,其中包含 1 个副本。
kubectl create deployment monolith --image=gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:1.0.0
注意:作为最佳实践,建议使用 YAML 文件和 GitHub 等源代码控制系统来存储这些更改。如需详细了解这些资源,请参阅 Deployments 文档。
点击检查我的进度以验证是否完成了以下目标:
将容器部署到 GKE
验证 Deployment
- 验证 Deployment 是否已成功创建:
kubectl get all
重新运行该命令,直到 Pod 状态为“正在运行”。
输出:
NAME READY STATUS RESTARTS AGE
pod/monolith-7d8bc7bf68-htm7z 1/1 Running 0 6m21s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.27.240.1 443/TCP 24h
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/monolith 1 1 1 1 20m
NAME DESIRED CURRENT READY AGE
replicaset.apps/monolith-7d8bc7bf68 1 1 1 20m
输出显示以下内容:
- 当前部署的 Deployment
- 期望 Pod 数为 1 的 ReplicaSet
- 正在运行的 Pod
看来一切都已成功创建!
注意:您还可以通过控制台查看您的 Kubernetes Deployment,方法是依次打开导航菜单 > Kubernetes Engine > 工作负载。
注意:如果您看到错误或意外状态,可以使用以下命令调试资源,查看详细信息:
kubectl describe pod monolith
kubectl describe pod/monolith-7d8bc7bf68-2bxts
kubectl describe deployment monolith
kubectl describe deployment.apps/monolith
在输出末尾,您会看到一个事件列表,其中列出了错误以及有关资源的详细信息。
可选:您也可以分别运行命令来查看您的 Deployment:
# 显示 Pod
kubectl get pods
# 显示 Deployment
kubectl get deployments
# 显示 ReplicaSet
kubectl get rs
# 您还可以组合查看
kubectl get pods,deployments
为充分了解 Kubernetes 的优势,请通过删除 Pod 来模拟一次服务器崩溃,看看会发生什么!
- 从上一个命令中复制 Pod 名称,然后在运行以下命令以删除该 Pod 时使用该名称:
kubectl delete pod/<POD_NAME>
您可以在工作负载页面上查看删除情况。
-
点击工作负载名称(该过程会很快完成)。
-
如果您操作速度够快,可以再次运行 get all 命令,此时您会看到两个 Pod:一个正在终止,另一个正在创建或运行:
kubectl get all
输出:
NAME READY STATUS RESTARTS AGE
pod/monolith-7d8bc7bf68-2bxts 1/1 Running 0 4s
pod/monolith-7d8bc7bf68-htm7z 1/1 Terminating 0 9m35s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.27.240.1 443/TCP 24h
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/monolith 1 1 1 1 24m
NAME DESIRED CURRENT READY AGE
replicaset.apps/monolith-7d8bc7bf68 1 1 1 24m
为什么会发生这种情况?这是因为 ReplicaSet 检测到 Pod 正在终止,并触发了一个新 Pod 来保持期望副本数。稍后,您将了解如何扩容以确保有多个实例运行,这样即使某个实例出现故障,用户也不会经历服务中断!
任务 5. 公开 GKE Deployment
您已在 GKE 上部署了应用,但目前无法在集群外部访问该应用。默认情况下,您在 GKE 上运行的容器无法通过互联网访问,因为这些容器没有外部 IP 地址。您必须通过 Service 资源明确公开应用,以便允许来自互联网的流量访问。Service 为应用的 Pod 提供网络和 IP 支持。GKE 会为您的应用创建外部 IP 地址和负载均衡器。
kubectl expose deployment monolith --type=LoadBalancer --port 80 --target-port 8080
访问服务
GKE 会将外部 IP 地址分配给 Service 资源,而不是 Deployment。
- 如果要查找 GKE 为应用预配的外部 IP,可以使用
kubectl get service 命令检查 Service:
kubectl get service
输出:
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
monolith 10.3.251.122 203.0.113.0 80:30877/TCP 3d
重新运行该命令,直到您的服务拥有外部 IP 地址。
- 确定应用的外部 IP 地址后,复制该 IP 地址,然后在浏览器中输入该网址(例如 http://203.0.113.0),以检查您的应用是否可访问。
您应该会看到之前测试过的网站。现在,您的网站已完全在 Kubernetes 上运行!
点击检查我的进度以验证是否完成了以下目标:
公开 GKE Deployment
任务 6. 扩缩 GKE Deployment
现在,您的应用已在 GKE 中运行并向互联网公开。现在假设您的网站已变得非常热门!您需要一种方法将应用扩缩到多个实例,以便处理所有这些流量。接下来,您将学习如何将应用扩缩到 3 个副本。
- 在 Cloud Shell 中,运行以下命令将 Deployment 扩缩到 3 个副本:
kubectl scale deployment monolith --replicas=3
- 验证 Deployment 是否已成功扩缩:
kubectl get all
输出:
NAME READY STATUS RESTARTS AGE
pod/monolith-7d8bc7bf68-2bxts 1/1 Running 0 36m
pod/monolith-7d8bc7bf68-7ds7q 1/1 Running 0 45s
pod/monolith-7d8bc7bf68-c5kxk 1/1 Running 0 45s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.27.240.1 443/TCP 25h
service/monolith LoadBalancer 10.27.253.64 XX.XX.XX.XX 80:32050/TCP 6m7s
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/monolith 3 3 3 3 61m
NAME DESIRED CURRENT READY AGE
replicaset.apps/monolith-7d8bc7bf68 3 3 3 61m
现在,您应该会看到 3 个 Pod 实例正在运行。请注意,您的 Deployment 和 ReplicaSet 现在的期望副本数均为 3。
点击检查我的进度以验证是否完成了以下目标:
扩缩 GKE Deployment
任务 7. 更改网站内容
场景:营销团队要求您更改网站的首页,他们希望页面上显示更多关于公司简介和所售产品/服务的信息。
任务:在首页上添加一些文字,满足营销团队的要求。似乎某位开发者已经使用名为 index.js.new 的文件创建了更改。您只需将该文件复制到 index.js,首页上就会反映所做更改。按照以下说明进行适当更改。
- 运行以下命令,为更新后的文件设置正确的文件名:
cd ~/monolith-to-microservices/react-app/src/pages/Home
mv index.js.new index.js
- 输出其内容,验证所做更改是否已经应用:
cat ~/monolith-to-microservices/react-app/src/pages/Home/index.js
最终代码应如下所示:
/*
Copyright 2019 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
\*/
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";
import Typography from "@material-ui/core/Typography";
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1
},
paper: {
width: "800px",
margin: "0 auto",
padding: theme.spacing(3, 2)
}
}));
export default function Home() {
const classes = useStyles();
return (
Fancy 时尚与风格在线
厌倦了主流时尚理念、流行趋势和社会规范?
该系列生活方式产品将助您追赶 Fancy
潮流,展现个人风格。
立即开始选购 Fancy 商品!
);
}
React 组件已更新,但需要构建 React 应用来生成静态文件。
- 运行下面的命令,构建 React 应用并将其复制到单体式应用公共目录:
cd ~/monolith-to-microservices/react-app
npm run build:monolith
现在代码已更新,您需要重新构建 Docker 容器并将其发布到 Artifact Registry。使用与之前相同的命令,但这次要更新版本标签。
- 运行以下命令,以使用更新后的映像版本 2.0.0 触发新的 Cloud Build:
cd ~/monolith-to-microservices/monolith
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0 .
在下一部分中,您将在不停机的情况下使用该映像更新应用。
点击检查我的进度以验证是否完成了以下目标:
更改网站内容
任务 8. 在不停机的情况下更新网站
更改已完成,营销团队对您的更新非常满意!现在需要更新网站,但不能中断用户访问。
GKE 的滚动更新机制可确保您的应用保持正常运行,即使系统将所有正在运行的副本中的旧容器映像实例替换为新容器映像,应用也依然可用。
- 使用以下命令告知 Kubernetes,您要将 Deployment 的映像更新为新版本:
kubectl set image deployment/monolith monolith=gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0
验证 Deployment
- 您可以运行以下命令来验证 Deployment 是否成功更新:
kubectl get pods
输出:
NAME READY STATUS RESTARTS AGE
monolith-584fbc994b-4hj68 1/1 Terminating 0 60m
monolith-584fbc994b-fpwdw 1/1 Running 0 60m
monolith-584fbc994b-xsk8s 1/1 Terminating 0 60m
monolith-75f4cf58d5-24cq8 1/1 Running 0 3s
monolith-75f4cf58d5-rfj8r 1/1 Running 0 5s
monolith-75f4cf58d5-xm44v 0/1 ContainerCreating 0 1s
您将看到 3 个新 Pod 被创建,旧 Pod 被终止。可以通过 AGE 字段判断哪些是新 Pod,哪些是旧 Pod。最终,您将再次看到 3 个 Pod,这 3 个 Pod 即为更新后的 Pod。
- 运行以下命令启动 Web 服务器,测试应用:
npm start
- 如需验证更改,请返回应用网页标签页并刷新页面。请注意,您的应用已更新。
现在,您的网站应该会显示您刚刚添加到首页组件中的文本!

- 如需停止 Web 服务器进程,请在 Cloud Shell 中按
CTRL+C。
点击检查我的进度以验证是否完成了以下目标:
在不停机的情况下更新网站
任务 9. 清理
虽然完成本实验后所有资源都将被删除,但在您自己的环境中,建议定期清理不再使用的资源。
- 删除 Git 代码库:
cd ~
rm -rf monolith-to-microservices
- 删除 Artifact Registry 映像:
# 删除 monolith 版本 1.0.0 的容器映像
gcloud container images delete gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:1.0.0 --quiet
# 删除 monolith 版本 2.0.0 的容器映像
gcloud container images delete gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0 --quiet
- 从 Google Cloud Storage 中删除 Google Cloud Build 制品:
# 以下命令将从 Cloud Storage 删除所有构建产生的源代码归档文件
# 运行以下命令可输出所有源文件列表:
# gcloud builds list | awk 'NR > 1 {print $4}'
gcloud builds list | grep 'SOURCE' | cut -d ' ' -f2 | while read line; do gsutil rm $line; done
- 删除 GKE Service:
kubectl delete service monolith
kubectl delete deployment monolith
- 删除 GKE 集群:
gcloud container clusters delete fancy-cluster {{{project_0.default_region | lab region}}}
- 输入
Y 以确认该操作。该命令可能需要一点时间才能完成。
恭喜!
您已使用 GKE 成功部署网站,并完成了扩缩和更新。现在,您已经具备使用 Docker 和 Kubernetes 的实践经验!
后续步骤/了解详情
上次更新手册的时间:2024 年 4 月 26 日
上次测试实验的时间:2024 年 2 月 21 日
版权所有 2026 Google LLC 保留所有权利。Google 和 Google 徽标是 Google LLC 的商标。其他所有公司名和产品名可能是其各自相关公司的商标。