本教程介绍了有关创建有状态应用以及升级运行应用的 Google Kubernetes Engine (GKE) 集群的推荐做法。本教程使用 Redis 作为部署有状态应用的示例,但相同的概念也适用于 GKE 上部署的其他类型的有状态应用。
目标
本教程介绍以下步骤:
- 创建在发布渠道中注册的 GKE 集群。
- 在 GKE 上创建 Redis 集群。
- 将 Redis 客户端应用部署到 GKE。
- 遵循以下最佳实践来升级节点池:
- 设置 Pod 中断预算 (PDB)。
- 设置维护期和排除项。
- 将节点升级策略设置为超额配置升级或蓝绿升级。
- 测试应用。
- 升级集群。
- 测试工作负载中断。
下图简要展示了本教程的集群架构:
费用
在本文档中,您将使用 Google Cloud 的以下收费组件:
您可使用价格计算器根据您的预计使用情况来估算费用。
完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理。
准备工作
设置项目
- 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
-
In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.
-
Enable the GKE API.
-
In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.
-
Enable the GKE API.
设置 Google Cloud CLI 的默认值
在 Google Cloud 控制台中,启动 Cloud Shell 实例:
打开 Cloud Shell下载此示例应用的源代码:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples cd kubernetes-engine-samples/quickstarts/hello-app-redis/manifests
设置默认环境变量:
gcloud config set project PROJECT-ID gcloud config set compute/zone COMPUTE-ZONE
替换以下值:
- PROJECT_ID:您的 Google Cloud 项目 ID。
- COMPUTE_ZONE:Compute Engine 可用区。
创建在发布渠道中注册的 GKE 集群
如需创建 GKE 集群,请完成以下步骤:
创建一个名为
redis-test
且具有三个节点的集群:gcloud container clusters create redis-test \ --num-nodes=3 \ --release-channel regular
创建该集群后,您应该会看到类似于以下示例的输出:
NAME: redis-test LOCATION: us-central1-c MASTER_VERSION: 1.22.10-gke.600 MASTER_IP: 34.69.67.7 MACHINE_TYPE: e2-medium NODE_VERSION: 1.22.10-gke.600 NUM_NODES: 3 STATUS: RUNNING
配置
kubectl
以与集群通信:gcloud container clusters get-credentials redis-test
在 GKE 上创建 Redis 集群
在本部分中,您将通过部署 ConfigMap、StatefulSet 和无头 Service,在先前创建的 GKE 集群之上添加一个 Redis 集群。
如需创建 Redis 集群,请完成以下步骤:
请查阅存储 Redis 配置的 ConfigMap 文件 (
redis-configmap.yaml
)。以下代码段展示了就绪性探测和活跃性探测脚本。readiness.sh
和liveness.sh
脚本使用 redis-cli ping 来检查 redis 服务器是否正在运行。如果它返回PONG
,则表示 Redis 服务器已启动并正在运行。这些脚本将用在redis-cluster.yaml
中。如需详细了解此 ConfigMap 中的 Redis 参数,请参阅 Redis 集群教程中的 Redis 集群配置参数部分。
部署 ConfigMap:
kubectl apply -f redis-configmap.yaml
请参阅下面的 StatefulSet (
redis-cluster.yaml
) 代码段,其中使用了就绪性探测和活跃性探测。如需了解如何在 Kubernetes 中配置探测,请参阅配置探测。
我们强烈建议您在升级节点池时使用就绪性探测和活跃性探测,这样可以确保您的 Pod 在升级期间处于准备就绪状态。
部署 StatefulSet:
kubectl apply -f redis-cluster.yaml
名为
redis-service.yaml
的无头 Service 用于 Redis 节点的连接。若要创建无头 Service,需将clusterIP
字段设置为None
。部署 Service:
kubectl apply -f redis-service.yaml
等待大约两分钟,然后使用以下命令验证所有 Pod 是否正在运行:
kubectl get pods
您应该会看到类似于以下示例的输出:
NAME READY STATUS RESTARTS AGE redis-0 1/1 Running 0 2m29s redis-1 1/1 Running 0 2m8s redis-2 1/1 Running 0 107s redis-3 1/1 Running 0 85s redis-4 1/1 Running 0 54s redis-5 1/1 Running 0 23s
通过运行以下命令来验证是否已创建永久性卷:
kubectl get pv
您应该会看到类似于以下示例的输出:
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-HASH 1Gi RWO Delete Bound default/data-redis-5 standard 75s pvc-HASH 1Gi RWO Delete Bound default/data-redis-1 standard 2m59s pvc-HASH 1Gi RWO Delete Bound default/data-redis-3 standard 2m16s pvc-HASH 1Gi RWO Delete Bound default/data-redis-2 standard 2m38s pvc-HASH 1Gi RWO Delete Bound default/data-redis-0 standard 3m20s pvc-HASH 1Gi RWO Delete Bound default/data-redis-4 standard 104s
在此输出中,HASH 表示附加到每个永久性卷名称的哈希值。
向 Redis 集群分配角色
完成配置后,向 Redis 集群分配角色。
以下脚本会获取 Pod IP 地址,然后通过将每个 Pod IP 地址传递给命令来分配主角色和跟随角色:
如需向 Redis 集群分配角色,请完成以下步骤:
运行脚本:
chmod +x ./roles.sh ./roles.sh
出现提示时,请输入
yes
。登录 Redis 节点以检查其角色。例如,如需验证
redis-0
是否具有主角色,请运行以下命令:kubectl exec -it redis-0 -- redis-cli role
您应该会看到类似于以下示例的输出:
1) "master" 2) (integer) 574 3) 1) 1) "10.28.2.3" 2) "6379" 3) "574"
部署 Redis 客户端应用
如需将应用部署到您创建的 GKE 集群,您需为应用定义 Deployment。名为 app-deployment.yaml
的文件包含应用的部署定义。
如需详细了解此 Deployment 中使用的探测和 Pod 亲和性规则,请参阅 GKE 最佳做法:设计和构建高可用性集群。
如需创建 Deployment,请完成以下步骤:
应用 Deployment:
kubectl apply -f app-deployment.yaml
通过负载均衡器公开应用:
kubectl expose deployment hello-web \ --type=LoadBalancer \ --port 80 \ --target-port 8080
等待大约一分钟,然后通过运行以下命令来检索应用的外部 IP 地址:
kubectl get service
在输出中,复制
hello-web's
EXTERNAL-IP
列中列出的值:NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-web LoadBalancer 10.13.10.55 EXTERNAL_IP 80:30703/TCP 166m
通过将 EXTERNAL_IP 粘贴到您的网络浏览器中来验证应用是否正常运行。您应该会看到类似于以下示例的输出:
I have been hit [1] times since deployment!
记下访问次数。在测试应用的中断部分中您需要使用该访问次数。
为刚刚复制的 EXTERNAL_IP 设置变量。在下一部分中创建脚本来测试应用时,您将使用此值:
export IP=EXTERNAL_IP
根据最佳实践配置节点池升级
遵循以下最佳实践优化有状态应用,以便在节点池升级期间提高可用性。
设置 Pod 中断预算 (PDB)
创建 Pod 中断预算以限制在主动中断期间同时关停的 Pod 副本的数量。这对于需要仲裁来确定在升级期间可用的副本数量的有状态应用而言非常有用。
在 PDB 定义中:
app
指定此 PDB 适用的应用。minAvailable
设置在中断期间可用的 Pod 数下限。该参数可以是数值或百分比(例如 30%)。maxUnavailable
设置在中断期间不可用的 Pod 数上限。该参数也可以是数值或百分比。
如需设置 PDB,请完成以下步骤:
部署 PDB:
kubectl apply -f pdb-minavailable.yaml
验证 PDB 是否已创建:
kubectl get pdb
设置维护期和排除项
采用节点自动升级可简化升级过程,同时在系统代表您升级控制层面时,可确保集群中的节点保持最新状态。默认情况下,此功能处于启用状态。 如需了解详情,请参阅自动升级节点。
使用维护期和维护排除项设置时间段来控制 GKE 集群上可以进行维护的时段以及不允许进行维护的时段:
设置从 2022 年 8 月 19 日凌晨 2:00 开始(采用世界协调时间)并持续 4 小时的维护期。此维护期每天运行一次。在此期间,允许自动维护。
gcloud container clusters update redis-test \ --maintenance-window-start 2022-08-19T02:00:00Z \ --maintenance-window-end 2022-08-19T06:00:00Z \ --maintenance-window-recurrence FREQ=DAILY
设置一个排除期,不允许在新年假期期间进行维护。此维护排除项使用
no_upgrades
范围。在此期间,不允许进行任何类型的自动维护。如需了解详情,请参阅要排除的维护范围。gcloud container clusters update redis-test \ --add-maintenance-exclusion-name new-year \ --add-maintenance-exclusion-start 2022-12-26T00:00:00Z \ --add-maintenance-exclusion-end 2023-01-02T02:00:00Z \ --add-maintenance-exclusion-scope no_upgrades
验证维护期和排除项是否均已应用。查看
maintenancePolicy:
下的内容gcloud container clusters describe redis-test
如需了解详情,请参阅配置维护期和排除项。
配置节点升级策略
目前有两种节点升级策略可用于 GKE 集群中的节点池:蓝绿升级和超额配置升级。如需了解详情,请参阅节点升级策略。
蓝绿升级
如果工作负载对中断的容忍度较低,并且能够接受因资源用量增加而导致的临时费用增加,则可选择蓝绿升级。
运行以下命令,将当前节点池更改为蓝绿升级策略。
gcloud container node-pools update default-pool \
--cluster=redis-test \
--enable-blue-green-upgrade \
--zone COMPUTE-ZONE \
--node-pool-soak-duration=120s
在本教程中,节点池过渡时长设置为两分钟,以节省节点池过渡阶段的时间。过渡阶段用于在蓝色池节点排空后验证工作负载的健康状况。我们建议将节点池过渡时段设置为一小时(即 3600 秒)或最适合应用的其他时段。
如需详细了解如何管理 Pod 分配,请参阅将 Pod 部署到特定节点池和将 Service 部署到特定节点池。
如需详细了解如何配置蓝绿升级,请参阅配置蓝绿升级。
超额配置升级
如果费用优化非常重要,并且工作负载可以容忍 60 分钟以内的安全关停(GKE 遵循最长 60 分钟的 PDB),则可以选择超额配置升级。
运行以下命令,将当前节点池更改为超额配置升级策略。
gcloud container node-pools update default-pool \
--max-surge-upgrade=1 \
--max-unavailable-upgrade=0 \
--cluster=redis-test
使用此配置(maxSurge=1
和 maxUnavailable=0
)时,在升级期间只能将一个超额配置节点添加到节点池,因此一次只能升级一个节点。此设置可以在升级期间加快 Pod 重启的速度,同时以保守的方式进行升级。
如需详细了解如何配置超额配置升级,请参阅配置超额配置升级。
检查当前节点池的配置:
gcloud container node-pools describe default-pool \
--cluster redis-test \
--zone COMPUTE-ZONE
如需详细了解如何查看节点池,请参阅查看集群中的节点池。
测试应用
在本部分中,您将使用两个脚本,一个用于向应用发送请求,一个用于衡量请求的成功率。您可以使用这些脚本来衡量升级集群时会发生什么情况。
如需创建脚本,请执行以下操作:
切换到包含脚本的目录:
cd cd kubernetes-engine-samples/quickstarts/hello-app-redis/scripts
请查阅名为
generate_load.sh
的脚本,该脚本会向应用发送每秒查询次数 (QPS) 请求。该脚本会将 HTTP 响应代码保存到当前目录内名为output
的文件中。output
的值用于您在下一步中创建的脚本。请查阅名为
print_error_rate.sh
的脚本,该脚本会根据generate_load.sh
生成的输出计算成功率。授权自己运行脚本的权限:
chmod u+x generate_load.sh print_error_rate.sh
为 QPS 次数设置变量。与您为 EXTERNAL_IP 设置的变量一样,该值用于
generate_load.sh
脚本。我们建议您将值设置为 40。export QPS=40
运行
generate_load.sh
脚本以开始发送 QPS:./generate_load.sh $IP $QPS 2>&1
让
generate_load.sh
脚本保持运行状态,并打开一个新终端。在新终端中,运行print_error_rate.sh
脚本以检查错误率:cd cd kubernetes-engine-samples/quickstarts/hello-app-redis/scripts watch ./print_error_rate.sh
发出 QPS 时,您应该会看到 100% 的成功率和 0% 的错误率。
让这两个脚本保持运行状态,并打开第三个终端,为下一部分做好准备。
升级集群
如需升级集群,请完成以下步骤:
确定
redis-test
集群正在使用的 GKE 版本:V=$(gcloud container clusters describe redis-test | grep "version:" | sed "s/version: //") echo $V
您应该会看到类似于以下示例的输出:
1.22.9-gke.2000
。检索可用 Kubernetes 版本的列表:
gcloud container get-server-config
在该版本列表中,找到
validMasterVersions:
部分,并查找您在上一步中检索到的redis-cluster
版本。为了避免版本倾斜,请从紧跟redis-cluster
版本的列表中复制该版本。将集群的控制层面升级到您选择的版本,并在出现提示时输入
y
:gcloud container clusters upgrade redis-test \ --master \ --cluster-version VERSION
将 VERSION 替换为您在上一步从列表中选择的版本。
控制层面升级需要几分钟时间。
将集群的节点升级到您选择的版本,并在出现提示时输入
y
:gcloud container clusters upgrade redis-test \ --cluster-version=VERSION \ --node-pool=default-pool
将 VERSION 替换为您从列表中选择的版本。
测试工作负载中断
在本部分中,您将测试应用的状态并观察工作负载的中断情况。
返回到运行
./print_error_rate.sh
的终端窗口,并观察升级期间成功率的变化情况。在节点关停以进行升级时,您应该会发现成功率略有下降,应用网络错误率略有增长。在
Success rate
字段中,您会看到成功访问网站的次数。请记下该值。通过在相关终端中输入
CTRL+C
停止运行这两个脚本。通过在浏览器中输入应用的 IP 地址(即您在部署 Redis 客户端应用期间复制的 EXTERNAL_IP),返回到应用的网站。
注意应用的访问次数。您看到的数字应等于:
ORIGINAL_VISIT_NUMBER + SUCCESSFUL_VISIT_NUMBER
其中,ORIGINAL_VISIT_NUMBER 是您在部署 Redis 客户端应用的最后一步中记录的数字,SUCCESSFUL_VISIT_NUMBER 是您在本部分的第一步中记录的值。
清理
完成本教程后,您可以清理您创建的资源,让它们停止使用配额,以免产生费用。以下部分介绍如何删除或关闭这些资源。
删除项目
为了避免产生费用,最简单的方法是删除您为本教程创建的项目。
如需删除项目,请执行以下操作:
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
删除集群
如需删除为本教程创建的集群,请运行以下命令:
gcloud container clusters delete redis-test