LabHub
学习 学习路径 课程

CKAD — Kubernetes 应用开发者

量一量发布是不是真的不停机

在 LabHub 中继续学习

本实验在 Pod 会真实启动和终止的集群中进行

VM 中运行着真正的 k3s。滚动更新会真正逐个替换实例,失败的发布会真正停止,kubectl drain 也会真正被 PodDisruptionBudget 阻止。

CKAD 课程中其他发布实验使用的模拟集群不会实际运行 Pod,因此无法衡量“是否实现了零停机”

环境首次启动大约需要 2 分钟。

预计用时 70 分钟。会话默认持续 60 分钟,请在到期前通过+时间延长(最长 180 分钟)。会话结束后 VM 和文件都会被回收,请另行保存所需结果。

目标

在部署替换前、替换期间和替换后持续发送请求,实际统计 HTTP 失败,并观察失败的发布如何停止,以及回滚究竟会恢复什么。

为什么重要

“零停机部署”并不是选择一个策略名称,而是多项设置相互配合后才能实现的结果。缺少任何一项,都可能悄无声息地失效。

而且,是否发生中断必须实际测量才知道。等部署结束后再检查,看起来总是正常的。

步骤

所有资源都创建在 crol 命名空间中。

  1. 创建 web Deployment(副本数 3、nginx、包含 readinessProbe),并显式设置 maxSurgemaxUnavailable。将内容保存到 /root/crol/rolling.txt
  2. 为 web 配置 replicas=3、maxSurge=1、maxUnavailable=0 和 readinessProbe,然后使用 python3 /opt/fixtures/ckad_rollout_observer.py capture 观测两次真实发布。最初的 Pod 不得包含 preStop。在 /root/crol/nodowntime.txt 中以 key=value 形式写入 totalfailedtotal_before_prestopfailed_before_prestop,并同时写入 scope=single-vm-rollout-samplehook_not_retroactive=yes。失败数必须按观测结果记录。
  3. 更新为不存在的镜像,确认发布会停止,并把期间旧 Pod 仍然存活这一事实一同保存到 /root/crol/stuck.txt
  4. 使用 rollout undo 回滚,并将结果保存到 /root/crol/undo.txt。同时显式设置 revisionHistoryLimit
  5. 使用 rollout pauseresume 制造只替换了部分实例的状态,并将其保存到 /root/crol/pause.txt
  6. 创建 web-pdb PodDisruptionBudget,并将当前最多可以中断多少个实例,以及 PDB 无法阻止什么,保存到 /root/crol/pdb.txt
  7. 创建 legacy Deployment,并使用 Recreate 策略;将需要这种策略的原因保存到 /root/crol/recreate.txt
  8. /root/crol/report.md 中写入 downtime_requests_failed=recreate_causes_downtime=pdb_min_available= 三行及其说明。

参考

两个数值决定替换速度

创建 web Deployment(副本数 3、nginx、包含 readinessProbe),并显式设置 maxSurgemaxUnavailable。将内容保存到 /root/crol/rolling.txt

maxSurge 表示最多可以比目标数量多启动几个实例,maxUnavailable 表示最多允许缺少几个实例。

用数字衡量是否零停机

为 web 配置 replicas=3、maxSurge=1、maxUnavailable=0 和 readinessProbe。最初的 Pod 不得包含 preStop。使用 python3 /opt/fixtures/ckad_rollout_observer.py capture 观测两次真实发布,然后在 /root/crol/nodowntime.txt 中以 key=value 形式写入 total、failed、total_before_prestop、failed_before_prestop。同时写入 scope=single-vm-rollout-sample、hook_not_retroactive=yes,并说明结果。不要假设失败数为 0,应按观测结果记录。

rollout-observation.json 中的 trials 顺序为 without_hook、with_hook。应同时检查各 requests 的 HTTP 状态 200、nginx 正文以及是否存在 error。钩子安装发布在测量之外单独完成,请确认第二次测量中的 before Pod 都已包含钩子。

失败的发布会停止

更新为不存在的镜像,确认发布会停止,并把期间旧 Pod 仍然存活这一事实一同保存到 /root/crol/stuck.txt

更新为不存在的镜像后,新 Pod 无法启动,并会在 progressDeadlineSeconds 后停止。期间请观察旧 Pod。

回滚究竟会恢复什么

使用 rollout undo 回滚,并将结果保存到 /root/crol/undo.txt。同时显式设置 revisionHistoryLimit

rollout undo 会回到上一个版本。保留多少个版本由 revisionHistoryLimit 决定。

只替换一部分后观察

使用 rollout pauseresume 制造只替换了部分实例的状态,并将其保存到 /root/crol/pause.txt

rollout pause 后修改镜像不会立即发生变化。它用于汇总多项修改后一次性发布。

避免同时下线过多实例

创建 web-pdb PodDisruptionBudget,并将当前最多可以中断多少个实例,以及 PDB 无法阻止什么,保存到 /root/crol/pdb.txt

PDB 只会阻止自愿中断。disruptionsAllowed 表示当前允许中断的最大数量。

主动造成停机的策略

创建 legacy Deployment,并使用 Recreate 策略;将需要这种策略的原因保存到 /root/crol/recreate.txt

Recreate 会先停止所有旧实例,再启动新实例。它适用于两个版本绝不能同时存在的情况。

总结学到了什么

/root/crol/report.md 中写入 downtime_requests_failed=recreate_causes_downtime=pdb_min_available= 三行及其说明。

写入 downtime_requests_failed=recreate_causes_downtime=pdb_min_available= 三行及其说明。