GSP053
![Google Cloud 自学实验的徽标](https://cdn.qwiklabs.com/GMOHykaqmlTHiqEeQXTySaMXYPHeIvaqa2qHEzw6Occ%3D)
概览
DevOps 实践一般是利用多个部署来管理应用部署场景,例如持续部署、蓝绿部署、Canary 部署等等。本实验会教您如何扩缩和管理容器,帮助您实现使用多个异构部署的常见部署场景。
目标
在本实验中,您将学习如何执行以下任务:
- 使用
kubectl
工具
- 创建 Deployment
yaml
文件
- 启动、更新和扩缩部署
- 更新部署并了解部署样式
前提条件
为达到最佳学习效果,建议您为本实验做好以下准备:
- 完成以下 Google Cloud Skills Boost 实验:
- 具备 Linux 系统管理技能。
- 了解 DevOps 理论和持续部署的概念。
部署简介
异构部署通常涉及连接两个或多个不同的基础设施环境或区域,以满足特定的技术或运营需求。根据部署的具体情况,异构部署可分为“混合”“多云端”或“公私”部署。
对于本实验,异构部署包括在单个云环境、多个公有云环境(多云端),或本地和公有云环境(混合或公私)组合中跨多个区域的部署。
仅限于单一环境或区域的部署可能会出现各种业务和技术难题:
-
有限的资源:在任何单一环境中,尤其是在本地环境中,您可能没有充足的计算、网络和存储资源来满足生产需求。
-
有限的地理覆盖范围:单一环境中的部署要求地理位置相距较远的人员访问同一个部署。他们的流量可能会途经世界各地再抵达中心位置。
-
有限的可用性:Web 级的流量模式要求应用保持容错性和弹性。
-
受制于特定供应商:供应商级的平台和基础设施抽象可能会妨碍您移植应用。
-
不够灵活的资源:您的资源可能仅限于一组特定的计算、存储或网络服务。
异构部署可以帮助应对这些挑战,但必须使用程序化的确定性流程和过程进行构建。一次性或临时部署过程可能导致部署或流程变得脆弱且无法容错。临时流程可能会丢失数据或使流量下降。良好的部署流程必须是可重复的,并使用经过验证的方法来管理预配、配置和维护。
异构部署的三种常见场景为:
- 多云端部署
- 前置本地数据
- 持续集成/持续交付 (CI/CD) 流程
在以下练习中,我们将会实际体验异构部署的一些常见使用场景,并采用架构完善的方法,通过使用 Kubernetes 和其他基础设施资源来完成这些部署。
设置和要求
点击“开始实验”按钮前的注意事项
请阅读以下说明。实验是计时的,并且您无法暂停实验。计时器在您点击开始实验后即开始计时,显示 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
。
如果您连接成功,即表示您已通过身份验证,且当前项目会被设为您的 PROJECT_ID 环境变量所指的项目。输出内容中有一行说明了此会话的 PROJECT_ID:
Your Cloud Platform project in this session is set to YOUR_PROJECT_ID
gcloud
是 Google Cloud 的命令行工具。它已预先安装在 Cloud Shell 上,且支持 Tab 自动补全功能。
- (可选)您可以通过此命令列出活跃账号名称:
gcloud auth list
-
点击授权。
-
现在,输出的内容应如下所示:
输出:
ACTIVE: *
ACCOUNT: student-01-xxxxxxxxxxxx@qwiklabs.net
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- (可选)您可以通过此命令列出项目 ID:
gcloud config list project
输出:
[core]
project = <project_ID>
输出示例:
[core]
project = qwiklabs-gcp-44776a13dea667a6
Note: For full documentation of gcloud
, in Google Cloud, refer to the gcloud CLI overview guide.
设置可用区
运行以下命令设置您的工作 Google Cloud 可用区(将 替换为本地可用区):
gcloud config set compute/zone {{{ project_0.default_zone | ZONE }}}
获取本实验的示例代码
- 获取用于创建和运行容器及部署的示例代码:
gsutil -m cp -r gs://spls/gsp053/orchestrate-with-kubernetes .
cd orchestrate-with-kubernetes/kubernetes
- 创建含 3 个节点的集群(此过程可能需要几分钟才能完成):
gcloud container clusters create bootcamp \
--machine-type e2-small \
--num-nodes 3 \
--scopes "https://www.googleapis.com/auth/projecthosting,storage-rw"
任务 1. 了解 Deployment 对象
首先,我们来看看 Deployment 对象。
- 可以使用
kubectl
中的 explain
命令了解 Deployment 对象:
kubectl explain deployment
- 另外,您还可以使用
--recursive
选项查看所有字段:
kubectl explain deployment --recursive
- 在完成本实验的过程中,您可以使用 explain 命令来了解 Deployment 对象的结构以及各个字段的用途:
kubectl explain deployment.metadata.name
任务 2. 创建部署
- 更新
deployments/auth.yaml
配置文件:
vi deployments/auth.yaml
- 启动编辑器:
i
- 将 Deployment 的 containers 部分中的
image
更改为以下内容:
...
containers:
- name: auth
image: "kelseyhightower/auth:1.0.0"
...
- 保存
auth.yaml
文件:按 <Esc>
,然后输入以下内容:
:wq
- 按
<Enter>
。现在来创建一个简单的 Deployment。检查 Deployment 的配置文件:
cat deployments/auth.yaml
输出如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: auth
spec:
replicas: 1
selector:
matchLabels:
app: auth
template:
metadata:
labels:
app: auth
track: stable
spec:
containers:
- name: auth
image: "kelseyhightower/auth:1.0.0"
ports:
- name: http
containerPort: 80
- name: health
containerPort: 81
...
请注意 Deployment 是如何创建一个副本的,而且它使用的是 auth 容器的 1.0.0 版本。
当您运行 kubectl create
命令创建 auth Deployment 时,该命令将生成一个与 Deployment 清单中的数据相符的 Pod。这表示您可以更改 replicas
字段中指定的数值来调整 Pod 数量。
- 继续操作,使用
kubectl create
命令创建 Deployment 对象:
kubectl create -f deployments/auth.yaml
- 创建 Deployment 后,可以使用以下命令验证是否已成功创建该对象:
kubectl get deployments
- 创建 Deployment 后,Kubernetes 将为该 Deployment 创建一个
ReplicaSet
。您可以验证系统是否为此 Deployment 创建了 ReplicaSet
:
kubectl get replicasets
您应该会看到一个名为 auth-xxxxxxx
的 ReplicaSet
- 查看作为 Deployment 的一部分创建的 Pod。仅有的这个 Pod 就是 Kubernetes 在创建
ReplicaSet
时创建的:
kubectl get pods
现在,可以为 auth Deployment 创建 Service 了。您已经了解有关 Service 清单文件的信息,在此我们就不再赘述。
- 使用
kubectl create
命令创建 auth Service:
kubectl create -f services/auth.yaml
- 现在执行相同的操作来创建和公开
hello
Deployment:
kubectl create -f deployments/hello.yaml
kubectl create -f services/hello.yaml
- 再次执行同一过程来创建和公开
frontend
Deployment:
kubectl create secret generic tls-certs --from-file tls/
kubectl create configmap nginx-frontend-conf --from-file=nginx/frontend.conf
kubectl create -f deployments/frontend.yaml
kubectl create -f services/frontend.yaml
注意:您已为 frontend 创建了一个 ConfigMap
。
- 获取 frontend 的外部 IP 地址,然后对其执行 curl 命令,以便与其交互:
kubectl get services frontend
注意:为您的 Service 填充外部 IP 字段可能需要几秒钟时间。这种情况很正常。只需每隔几秒重新运行上述命令,直到字段中填充数据。
curl -ks https://<外部 IP>
之后,您会收到 hello 响应。
- 您也可以使用
kubectl
的输出模板功能,将 curl 作为单行式命令使用:
curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`
验证您已完成的任务
点击下方的检查我的进度,以检查您的实验进度。如果您成功创建了 Kubernetes 集群以及 Auth Deployment、Hello Deployment 和 Frontend Deployment,就会看到一个评估分数。
创建 Kubernetes 集群和 Deployment(Auth、Hello 及 Frontend)
扩缩 Deployment
现在您已经创建了一个 Deployment,下面可以对它进行扩缩了。为此,需要更新 spec.replicas
字段。
- 再次使用
kubectl explain
命令来查看此字段的说明:
kubectl explain deployment.spec.replicas
- 更新 replicas 字段的最简便方法是使用
kubectl scale
命令:
kubectl scale deployment hello --replicas=5
注意:可能需要 1 分钟左右的时间才能启动所有新 Pod。
更新 Deployment 后,Kubernetes 将会自动更新相关联的 ReplicaSet
,并启动新 Pod 以使 Pod 总数达到 5 个。
- 请验证现在是否正在运行 5 个
hello
Pod:
kubectl get pods | grep hello- | wc -l
- 现在对应用进行缩容:
kubectl scale deployment hello --replicas=3
- 再次验证 Pod 数量是否正确:
kubectl get pods | grep hello- | wc -l
至此,您已经了解了 Kubernetes Deployment 以及如何管理和扩缩一组 Pod。
任务 3. 滚动更新
Deployment 支持使用滚动更新机制将映像更新至新版本。当 Deployment 更新至新版本后,它会创建一个新的 ReplicaSet
,并在减少旧 ReplicaSet
中副本的同时,缓慢增加新 ReplicaSet
中的副本数量。
![副本集之间的 Deployment 图示](https://cdn.qwiklabs.com/uc6D9jQ5Blkv8wf%2FccEcT35LyfKDHz7kFpsI4oHUmb0%3D)
触发滚动更新
- 如需更新 Deployment,请运行以下命令:
kubectl edit deployment hello
- 将 Deployment 的 containers 部分中的
image
更改为以下内容:
...
containers:
image: kelseyhightower/hello:2.0.0
...
-
保存并退出。
更新后的 Deployment 将保存到集群中,Kubernetes 将开始执行滚动更新。
- 查看 Kubernetes 创建的新
ReplicaSet
:
kubectl get replicaset
- 您还会在发布历史记录中看到一个新条目:
kubectl rollout history deployment/hello
暂停滚动更新
如果您在发布期间检测到问题,请暂停该发布,以停止更新。
- 运行以下命令暂停该发布:
kubectl rollout pause deployment/hello
- 验证发布的当前状态:
kubectl rollout status deployment/hello
- 您也可以直接在 Pod 上验证状态:
kubectl get pods -o jsonpath --template='{range .items[*]}{.metadata.name}{"\t"}{"\t"}{.spec.containers[0].image}{"\n"}{end}'
恢复滚动更新
如果暂停了发布,则意味着有些 Pod 为新版本,而有些 Pod 为旧版本。
- 使用
resume
命令继续进行发布:
kubectl rollout resume deployment/hello
- 发布完成后,您在运行
status
命令时应该会看到以下内容:
kubectl rollout status deployment/hello
输出如下:
deployment "hello" successfully rolled out
回滚更新
假设您在新版本中检测到一个 bug。由于我们假定新版本有问题,因此任何连接到新 Pod 的用户都会遇到这些问题。
您将需要回滚到先前的版本以便进行调查,然后发布一个已正确修复相关问题的版本。
- 使用
rollout
命令回滚到前一版本:
kubectl rollout undo deployment/hello
- 在历史记录中验证回滚情况:
kubectl rollout history deployment/hello
- 最后,确认所有 Pod 都已回滚至各自的先前版本:
kubectl get pods -o jsonpath --template='{range .items[*]}{.metadata.name}{"\t"}{"\t"}{.spec.containers[0].image}{"\n"}{end}'
太棒了!您已经学习了如何对 Kubernetes Deployment 执行滚动更新,以及如何在不停机的情况下更新应用。
任务 4. Canary 部署
当您想要在生产环境下通过一部分用户来测试某项新部署时,可以使用 Canary 部署。Canary 部署可以让您仅向一小部分用户发布更改,以降低与新版本发布相关的风险。
创建 Canary 部署
Canary 部署由一个包含新版本的独立 Deployment,以及针对正常、稳定的部署和 Canary 部署的 Service 组成。
![Canary 部署图示](https://cdn.qwiklabs.com/qSrgIP5FyWKEbwOk3PMPAALJtQoJoEpgJMVwauZaZow%3D)
- 首先,为新版本创建一个新的 Canary 部署:
cat deployments/hello-canary.yaml
输出如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-canary
spec:
replicas: 1
selector:
matchLabels:
app: hello
template:
metadata:
labels:
app: hello
track: canary
# Use ver 2.0.0 so it matches version on service selector
version: 2.0.0
spec:
containers:
- name: hello
image: kelseyhightower/hello:2.0.0
ports:
- name: http
containerPort: 80
- name: health
containerPort: 81
...
- 现在来创建 Canary 部署:
kubectl create -f deployments/hello-canary.yaml
- 创建 Canary 部署后,您应该就有了
hello
和 hello-canary
两个 Deployment。使用下面的 kubectl
命令进行验证:
kubectl get deployments
在 hello
Service 中,app:hello
选择器将匹配生产部署和 Canary 部署中的 Pod。但是,由于 Canary 部署包含的 Pod 数量较少,因此只会向少数用户显示。
验证 Canary 部署
- 您可以使用以下命令来验证用于处理请求的
hello
版本:
curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
- 多次运行此命令,您应该会发现,有些请求是由 hello 1.0.0 处理的,还有一小部分请求 (1/4 = 25%) 是由 2.0.0 处理的。
验证您已完成的任务
点击下方的检查我的进度,以检查您的实验进度。如果您成功创建了 Canary 部署,则会获得相应的评分。
Canary 部署
生产环境中的 Canary 部署 - 会话亲和性
在本实验中,每一个发送至 Nginx 服务的请求都有可能由 Canary 部署进行处理。但是,如果您想确保某个用户的请求不由 Canary 部署处理,应该怎么做?如果应用的界面发生了变化,而您不想让用户感到困惑,可能就需要这样做。在这种情况下,您希望该用户“继续”使用某个部署或其他部署。
为此,您可以创建一个具有会话亲和性的 Service。这样,同一用户的请求将始终由同一版本来处理。在下面的示例中,Service 仍与之前相同,但新添加了一个设置为 ClientIP
的 sessionAffinity
字段。之后,具有相同 IP 地址的所有客户端都会将其请求发送至同一版本的 hello
应用。
kind: Service
apiVersion: v1
metadata:
name: "hello"
spec:
sessionAffinity: ClientIP
selector:
app: "hello"
ports:
- protocol: "TCP"
port: 80
targetPort: 80
由于很难设置一个环境来进行此测试,因此您在此处无需进行测试,但可以在生产环境中为 Canary 部署使用 sessionAffinity
。
任务 5. 蓝绿部署
滚动更新可以让您缓慢部署应用,同时尽可能地减少开销、降低对性能的影响以及将停机时间缩至最短,因此是一种理想的方式。在有些情况下,最好在新版本完全部署后,才将负载均衡器修改为指向该新版本。这种情况下适合使用蓝绿部署。
为实现该目标,Kubernetes 会创建两个独立的 Deployment,一个用于“蓝色”旧版本,一个用于“绿色”新版本。将您现有的 hello
Deployment 用于“蓝色”版本。通过一个用作路由器的 Service 来访问这些 Deployment。在“绿色”新版本上线并运行后,您可以通过更新 Service 来切换为使用该版本。
![蓝绿部署图示](https://cdn.qwiklabs.com/POW8Q247ZKNY%2ByHIartCsoEu8MAih7k4u1twusCx6pw%3D)
注意:蓝绿部署的主要缺点是,集群至少需要 2 倍的资源来托管应用。因此,在一次部署两个版本的应用之前,请确保您的集群中拥有足够的资源。
Service
使用现有的 hello Service,但将其选择器 app:hello
更新为 version: 1.0.0
。此选择器与现有的“蓝色”部署相匹配。但由于它使用的版本不同,因此与“绿色”部署则不匹配。
kubectl apply -f services/hello-blue.yaml
注意:忽略出现的 resource service/hello is missing
警告消息,因为系统会自动修补此问题。
使用蓝绿部署进行更新
为了支持蓝绿部署方式,您将为新版本创建一个新的“绿色”部署。此绿色部署会更新版本标签和映像路径。
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-green
spec:
replicas: 3
selector:
matchLabels:
app: hello
template:
metadata:
labels:
app: hello
track: stable
version: 2.0.0
spec:
containers:
- name: hello
image: kelseyhightower/hello:2.0.0
ports:
- name: http
containerPort: 80
- name: health
containerPort: 81
resources:
limits:
cpu: 0.2
memory: 10Mi
livenessProbe:
httpGet:
path: /healthz
port: 81
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 15
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /readiness
port: 81
scheme: HTTP
initialDelaySeconds: 5
timeoutSeconds: 1
- 创建绿色部署:
kubectl create -f deployments/hello-green.yaml
- 创建绿色部署并正确启动该部署之后,验证系统是否仍在使用当前版本 1.0.0:
curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
- 现在,更新 Service 以指向新版本:
kubectl apply -f services/hello-green.yaml
- Service 更新后,系统将会立即使用“绿色”部署。现在,您可以验证系统是否一直在使用新版本:
curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
蓝绿回滚
在必要时,您可以使用相同的方法回滚至旧版本。
- 在“蓝色”部署运行期间,只需将 Service 重新更新为旧版本:
kubectl apply -f services/hello-blue.yaml
- Service 更新后,回滚即成功完成。再次验证系统现在使用的是否为正确版本:
curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
大功告成!您已经学习了蓝绿部署,以及如何将更新部署到需要一次性切换所有版本的应用。
恭喜!
您了解了如何更多地使用 kubectl
命令行工具以及 YAML 文件中设置的多种形式的 Deployment 配置,来启动、更新和扩缩 Deployment。有了这些练习作为基础,您应该能够将这些技能熟练运用到自己的 DevOps 实践中。
后续步骤/了解详情
Google Cloud 培训和认证
…可帮助您充分利用 Google Cloud 技术。我们的课程会讲解各项技能与最佳实践,可帮助您迅速上手使用并继续学习更深入的知识。我们提供从基础到高级的全方位培训,并有点播、直播和虚拟三种方式选择,让您可以按照自己的日程安排学习时间。各项认证可以帮助您核实并证明您在 Google Cloud 技术方面的技能与专业知识。
上次更新手册的时间:2024 年 4 月 2 日
上次测试实验的时间:2023 年 8 月 14 日
版权所有 2025 Google LLC 保留所有权利。Google 和 Google 徽标是 Google LLC 的商标。其他所有公司名和产品名可能是其各自相关公司的商标。