身为一名云工程师,您的任务是维护一个经常添加功能的关键应用。您需要在发布新功能和更新的同时,尽量减少对用户的影响,并尽可能缩短应用停机时间。该应用已容器化并部署在 Kubernetes 上。有时,您需要根据用户需求的变化进行扩缩。还需要控制从互联网流向应用的流量。在维护和更新应用时,需要考虑的一些注意事项如下:
- 如何为集群创建部署清单?
- 如何手动调整部署中的 Pod 数量?
- 如何创建一项控制应用入站流量的服务?
- 如何以对用户影响最小的方式发布更新?
- 如何执行 Canary 部署,以在全面推出之前测试新功能?
身为熟悉 Azure Kubernetes Service (AKS) 的云专业人员,您可能已经使用过 YAML 清单文件在 AKS 执行 Kubernetes 部署,并可能已经使用过 DevOps 流水线将应用代码和容器提供给您的 Kubernetes 集群。
如需根据需求调整 Pod 数量,您可以手动更改清单文件或使用 kubectl 命令。如需控制应用的入站流量,您需要在 DevOps 流水线中构建负载均衡器部署计划,然后执行流水线。当需要更新容器映像时,可以运行 DevOps 流水线来提供容器映像,然后使用 kubectl 命令触发部署发布。
如需执行 Canary 更新,您需要安装 Prometheus,配置流水线,添加清单文件,然后执行部署流水线。
有了这些概念,现在您将了解如何为 Google Kubernetes Engine (GKE) 创建部署清单,以创建、扩缩和更新部署。
概览
在本实验中,您将学习使用部署清单的基础知识。清单是包含完成部署所需配置的文件,可用于多个不同的 Pod。更改清单十分容易。
目标
在本实验中,您将学习如何执行以下任务:
- 创建部署清单、部署到集群,并验证节点被停用时 Pod 是否会重新安排
- 触发手动增加和减少部署中的 Pod 数量
- 触发部署发布(滚动更新到新版本)和回滚
- 执行 Canary 部署
实验设置
访问实验
对于每个实验,您都会免费获得一个新的 Google Cloud 项目及一组资源,它们都有固定的使用时限。
-
请使用无痕式窗口登录 Qwiklabs。
-
留意实验的访问时限(例如 1:15:00
)并确保能在相应时间段内完成实验。
系统不提供暂停功能。如有需要,您可以重新开始实验,不过必须从头开始。
-
准备就绪时,点击开始实验。
-
请记好您的实验凭据(用户名和密码)。您需要使用这组凭据来登录 Google Cloud 控制台。
-
点击打开 Google 控制台。
-
点击使用其他帐号,然后将此实验的凭据复制并粘贴到相应提示框中。
如果您使用其他凭据,将会收到错误消息或产生费用。
-
接受条款并跳过恢复资源页面。
完成初始登录步骤后,系统会显示项目信息中心。
激活 Google Cloud Shell
Google Cloud Shell 是一种装有开发者工具的虚拟机。它提供了一个永久性的 5GB 主目录,并且在 Google Cloud 上运行。
Google Cloud Shell 提供了可用于访问您的 Google Cloud 资源的命令行工具。
-
在 Cloud 控制台右上角的工具栏中,点击“打开 Cloud Shell”按钮。

-
点击继续。
预配并连接到环境需要一些时间。如果您连接成功,即表示您已通过身份验证,且项目 ID 会被设为您的 PROJECT_ID。例如:

gcloud 是 Google Cloud 的命令行工具。它会预先安装在 Cloud Shell 上,且支持 Tab 自动补全功能。
gcloud auth list
输出:
Credentialed accounts:
- @.com (active)
输出示例:
Credentialed accounts:
- google1623327_student@qwiklabs.net
gcloud config list project
输出:
[core]
project =
输出示例:
[core]
project = qwiklabs-gcp-44776a13dea667a6
注意:有关 gcloud 的完整文档,请参阅 gcloud CLI 概览指南。
任务 1. 创建部署清单并部署到集群
在此任务中,您将为集群中的一个 Pod 创建部署清单。
连接到实验 GKE 集群
- 在 Cloud Shell 中输入以下命令,为可用区和集群名称设置环境变量:
export my_zone={{{project_0.default_zone|Zone}}}
export my_cluster=standard-cluster-1
- 在 Cloud Shell 中配置 kubectl Tab 自动补全功能:
source <(kubectl completion bash)
- 在 Cloud Shell 中,使用以下命令为 kubectl 命令行工具配置对集群的访问权限:
gcloud container clusters get-credentials $my_cluster --zone $my_zone
- 在 Cloud Shell 中输入以下命令,以将代码库克隆到实验 Cloud Shell:
git clone https://github.com/GoogleCloudPlatform/training-data-analyst
- 创建软链接作为工作目录的快捷方式:
ln -s ~/training-data-analyst/courses/ak8s/v1.1 ~/ak8s
- 切换到包含此实验示例文件的目录:
cd ~/ak8s/Deployments/
创建部署清单
您将使用名为 nginx-deployment.yaml
的示例部署清单(已提供给您)创建一个部署作业。这个部署作业配置为运行三个 Pod 副本,每个 Pod 中有一个 nginx 容器监听 TCP 端口 80:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
- 要部署清单,请执行以下命令:
kubectl apply -f ./nginx-deployment.yaml
- 要查看部署列表,请执行以下命令:
kubectl get deployments
输出应如下例所示。
输出:
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 0/3 3 0 3s
- 等待几秒钟,然后重复该命令,直到该命令列出的当前部署数量与预期的部署数量一致。
最终输出应如下示例所示。
输出:
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 42s
点击“检查我的进度”以验证是否完成了以下目标:
创建并部署清单 nginx 部署作业
任务 2. 手动增加和减少部署中的 Pod 数量
有时,您需要关闭 Pod 实例。但有些时候,您又想运行十个 Pod。在 Kubernetes 中,您可以将特定 Pod 调整到所需的实例数量。如需将其关闭,请调整为零。
在此项任务中,您将在 Google Cloud 控制台和 Cloud Shell 中增加和减少 Pod 数量。
在控制台中增加和减少 Pod 数量
- 切换到 Google Cloud 控制台标签页。
- 在导航菜单 (
) 上,点击 Kubernetes Engine > 工作负载。
- 点击 nginx-deployment(您的部署)打开“部署详情”页面。
- 点击顶部的操作 > 扩缩 > 修改副本。
- 输入 1 并点击扩缩。
此操作会将集群缩容。您应该会看到代管式 Pod 中的 Pod 正在更新。您可能需要点击刷新。
在 Shell 中增加和减少 Pod 数量
- 切换回 Cloud Shell 浏览器标签页。
- 要在 Cloud Shell 中查看部署中的 Pod 列表,请执行如下命令:
kubectl get deployments
输出:
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 1/1 1 1 3m
- 要将 Pod 数量重新增至三个副本,请执行如下命令:
kubectl scale --replicas=3 deployment nginx-deployment
- 要查看部署中的 Pod 列表,请执行如下命令:
kubectl get deployments
输出:
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 4m
任务 3. 触发部署发布和部署回滚
仅当部署的 Pod 模板(即 .spec.template
)发生更改时,例如模板的标签或容器映像更新时,系统才会触发部署发布。其他更新(例如扩缩部署)不会触发发布。
在此任务中,您将触发部署发布,然后触发部署回滚。
触发部署发布
- 要更新部署中的 nginx 版本,请执行如下命令:
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record
此命令会将部署中的容器映像更新为 nginx v1.9.1
。
- 要查看发布状态,请执行如下命令:
kubectl rollout status deployment.v1.apps/nginx-deployment
输出应如下例所示。
输出:
Waiting for rollout to finish: 1 out of 3 new replicas updated...
Waiting for rollout to finish: 1 out of 3 new replicas updated...
Waiting for rollout to finish: 1 out of 3 new replicas updated...
Waiting for rollout to finish: 2 out of 3 new replicas updated...
Waiting for rollout to finish: 2 out of 3 new replicas updated...
Waiting for rollout to finish: 2 out of 3 new replicas updated...
Waiting for rollout to finish: 1 old replicas pending termination...
Waiting for rollout to finish: 1 old replicas pending termination...
deployment "nginx-deployment" successfully rolled out
- 获取部署列表以验证变更:
kubectl get deployments
输出应如下例所示。
输出:
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 6m
点击“检查我的进度”以验证是否完成了以下目标:
更新部署中的 nginx 版本
- 查看该部署的发布历史记录:
kubectl rollout history deployment nginx-deployment
输出应如下例所示。您的输出可能不完全相同。
输出:
deployments "nginx-deployment"
REVISION CHANGE-CAUSE
1
2 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true
触发部署回滚
要回滚对象的发布,您可以使用 kubectl rollout undo
命令。
- 要回滚到 nginx 部署的先前版本,请执行如下命令:
kubectl rollout undo deployments nginx-deployment
- 查看该部署更新后的发布历史记录:
kubectl rollout history deployment nginx-deployment
输出应如下例所示。您的输出可能不完全相同。
输出:
deployments "nginx-deployment"
REVISION CHANGE-CAUSE
2 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true
3
- 查看最新部署版本的详细信息:
kubectl rollout history deployment/nginx-deployment --revision=3
输出应如下例所示。您的输出可能不完全相同,但会显示当前版本已回滚到 nginx:1.7.9
。
输出:
deployments "nginx-deployment" with revision #3
Pod Template:
Labels: app=nginx
pod-template-hash=3123191453
Containers:
nginx:
Image: nginx:1.7.9
Port: 80/TCP
Host Port: 0/TCP
Environment:
Mounts:
Volumes:
任务 4:定义清单中的服务类型
在此项任务中,您将创建并验证一个控制应用入站流量的服务。服务可以配置为 ClusterIP、NodePort 或 LoadBalancer 类型。在此实验中,您将配置 LoadBalancer。
在清单中定义服务类型
一个名为 service-nginx.yaml
的清单文件已提供给您,用于部署 LoadBalancer 服务类型。此服务配置为在所有带有 app: nginx
标签的容器上,将 TCP 端口 60000 上的入站流量分配到端口 80。
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- protocol: TCP
port: 60000
targetPort: 80
- 要在 Cloud Shell 中部署清单,请执行如下命令:
kubectl apply -f ./service-nginx.yaml
此清单定义了一个服务,并将该服务应用于与选择器对应的 Pod。在本例中,该清单应用于您在任务 1 中部署的 nginx 容器。此服务也会应用于任何其他带有 app: nginx
标签的 Pod,包括任何在该服务之后创建的 Pod。
验证是否创建了 LoadBalancer
- 要查看 nginx 服务的详细信息,请执行如下命令:
kubectl get service nginx
输出应如下例所示。
输出:
NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR AGE
nginx 10.X.X.X X.X.X.X 60000/TCP run=nginx 1m
- 当外部 IP 出现时,在新的浏览器标签页中打开
http://[EXTERNAL_IP]:60000/
,会看到发往服务器的请求是通过网络负载均衡机制进行分配的。
注意:为服务填充 ExternalIP 字段可能需要几秒钟时间。这种情况很正常。只需每隔几秒重新运行 kubectl get services nginx
命令,直到字段中填充数据。
点击“检查我的进度”以验证是否完成了以下目标:
部署清单文件以部署 LoadBalancer 服务类型
任务 5. 执行 Canary 部署
Canary 部署是一种用于测试应用新版本的独立部署。单个服务同时定位到 Canary 部署和普通部署。还会引导部分用户使用 Canary 版本,以降低新版本的风险。
提供给您的清单文件 nginx-canary.yaml
将部署一个 Pod,这个 Pod 用于运行版本比主部署更新的 nginx。在此任务中,您将使用这个新的部署文件创建一个 Canary 部署作业:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-canary
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
track: canary
Version: 1.9.1
spec:
containers:
- name: nginx
image: nginx:1.9.1
ports:
- containerPort: 80
您在上一个任务中部署的 nginx 服务的清单使用标签选择器来定位带有 app: nginx
标签的 Pod。常规部署和这个新的 Canary 部署都带有 app: nginx
标签。入站连接将由该服务分发到常规部署 Pod 和 Canary 部署 Pod。Canary 部署的副本数量(Pod 数)少于常规部署,因此可使用 Canary 部署的用户数也少于常规部署。
- 基于该配置文件创建 Canary 部署作业:
kubectl apply -f nginx-canary.yaml
- 部署完成后,确认 nginx 和 nginx Canary 部署都在列表中:
kubectl get deployments
- 切换回连接到外部 LoadBalancer 服务 IP 的浏览器标签页并刷新页面。您看到的应该仍是标准的
Welcome to nginx
页面。
- 切换回 Cloud Shell 并将主部署减至 0 个副本:
kubectl scale --replicas=0 deployment nginx-deployment
- 确认正在运行的唯一一个副本现在是 Canary 部署:
kubectl get deployments
- 切换回连接到外部 LoadBalancer 服务 IP 的浏览器标签页并刷新页面。您看到的应该仍是标准的
Welcome to nginx
页面,显示服务正自动将流量均衡分配至 Canary 部署。
点击“检查我的进度”以验证是否完成了以下目标:
创建 Canary 部署作业
会话亲和性
此实验使用的服务配置不能确保来自同一个客户端的所有请求始终连接到同一 Pod。每个请求都是单独处理的,可能连接到常规 nginx 部署,也可能连接到 nginx Canary 部署。
如果 Canary 版本中的功能发生重大变化,那么在不同版本之间切换可能会导致出现问题。如果您需要由客户端的第一个请求来决定所有后续连接将使用哪个 Pod,您可以在服务规范中将 sessionAffinity
字段设置为 ClientIP
,以免发生这种情况。
例如:
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: LoadBalancer
sessionAffinity: ClientIP
selector:
app: nginx
ports:
- protocol: TCP
port: 60000
targetPort: 80
摘要
在本实验中,您了解了 GKE 如何使用清单文件来进行部署和扩缩以及执行针对应用的 Canary 更新。下面列出了 GKE 与 AKS 之间的一些主要相似之处和差异。
相似之处:
GKE 和 EKS 都是托管式 Kubernetes 服务,可让开发者部署、管理和扩缩容器化应用。
- 在 GKE 和 AKS 中,Kubernetes 部署的 YAML 文件的基本结构和语法相同。
- AKS 和 GKE 都使用 kubectl 命令。
差异:
- 在 GKE 中,您可以指定集群、Pod 和管理的属性,而无需像在 AKS 部署中那样创建 DevOps 流水线。这是因为 GKE 具有使用清单文件执行预配任务所需的后端基础架构。
结束实验
完成实验后,请点击结束实验。Google Cloud Skills Boost 会移除您使用过的资源并为您清理帐号。
系统会提示您为实验体验评分。请选择相应的星级数,输入评论,然后点击提交。
星级数的含义如下:
- 1 颗星 = 非常不满意
- 2 颗星 = 不满意
- 3 颗星 = 一般
- 4 颗星 = 满意
- 5 颗星 = 非常满意
如果您不想提供反馈,可以关闭该对话框。
如果要留言反馈、提出建议或做出更正,请使用支持标签页。
版权所有 2020 Google LLC 保留所有权利。Google 和 Google 徽标是 Google LLC 的商标。其他所有公司名和产品名可能是其各自相关公司的商标。