LabHub
学习 学习路径 课程

CKAD — Kubernetes 应用开发者

停止营业不等于取消订单

在 LabHub 中继续学习

一句话总结

停止接待新客人与厨房完成已经接下的订单是两回事。Kubernetes 的流量摘除与应用终止处理也必须分别确认。

概念图: 一句话总结 · 为什么需要它 · 它如何运作 · 在实际工作中会遇到的情况

为什么需要它

部署后新版本能正常打开,但部署瞬间恰好有一笔支付或文件生成请求失败,这种情况并不少见。Deployment 完成替换的标志,并不包含该请求的命运。新 Pod 是否就绪、旧 Pod 是否退出新请求目标、它是否完成已经处理的请求,是三个不同问题。用一个绿灯代替三项检查,短状态查询可以通过,长任务却可能中断。

本单元不证明拥有多个副本的整个服务实现无中断,而是在 Service 后只放一个 Pod,完整追踪该 Pod 实际接收的一次请求。缩小实验范围不是为了让数字好看,而是为了明确识别哪个连接与哪个进程产生结果。HTTP 响应会包含通过 Downward API 注入的 Pod UID。名称可以重用,UID 每次创建都会改变。

它如何运作

readinessProbe 表示是否准备成为服务目标,其结果反映到 EndpointSlice 和流量处理路径的过程另行进行。Pod 收到删除请求后,正在终止的 endpoint 的 ready 会变为 false。不能把它理解为立即断开现有 TCP 连接的命令。服务器何时完成已经接收的请求,还取决于服务器的信号处理与连接行为。

EndpointSlice conditions 包含 ready、serving、terminating。terminating 表示正在终止;serving 可以独立于终止状态表达实际就绪状态。因此终止中即使 ready 为 false,也可能观测到 serving 为 true,但并非总会看到这种组合。本服务器开始 drain 后 healthz 也返回 503,随后的就绪检查可能改变 serving。不要把首个终止 endpoint 与之后的 endpoint 混在一起,当作固定状态描述。

这里使用未开启 publishNotReadyAddresses 的普通 Service。开启该设置会产生 ready 解释上的例外。所有可用 endpoint 都在终止时,proxy 还可能把请求路由到 serving 与 terminating 同时为 true 的目标。因此,只有 ready=false 不能保证一个新请求都不会到达。必须同时确认应用 drain 处理与流量路径的真实行为。

实验 helper 会先检查 Service 的 healthz 响应。若只看到 Pod Ready 就立即发送工作请求,可能把 Service 路径尚未就绪导致的连接错误误认为终止效果。随后发送 work 请求,确认服务器 active 为 1,再执行删除。观测顺序是:连接就绪、服务器接收、删除请求、响应或断开。没有接收证据,就不能得出“正在处理的请求被中断”的结论。

在实际工作中会遇到的情况

存在 API gateway、Service Mesh、外部 load balancer 后,选择流量的层级更多。不能把单一 k3s Service 得到的结果转移成其他路径的保证。生产环境必须分别观测:哪一层停止新连接,哪一层维持现有连接。除了成功率,还要检查请求延迟、响应正文,以及重试带来的副作用。

如何统计失败也很重要。curl 传输成功与 HTTP 200 不是同一条件。收到 HTTP 500 时连接正常,可能被误计为成功;反之,也不能把连接准备超时断定为应用被强制终止。本实验分别保存正常完成正文、连接中断异常和 Pod 退出码,以区分不同失败。

后续实验要做什么

比较立即退出的服务器与等待现有请求完成的服务器,记录第一个 terminating endpoint 的 conditions。请用响应和 UID 解释:ready=false 这一个值不能代替已经接收请求的结果。

官方文档:观察 Pod 与 endpoint 的终止过程, EndpointSlice.