有一些场景需要在不减少 Deployment 总容量的情况下终止 Pod:
- 用于维护的排水节点
- 用于装箱的排水节点
- 行为不端的 Pod / 在不触发 OOM Killer 的情况下处理内存泄漏
想象一下我们有两个 Pod 占用大量流量的情况,如果使用终止 Pod 的默认工作流程,然后让 Kubernetes 通过重新创建它来做出反应,我们将在任意时间内拥有 50% 的处理能力。
在高吞吐量应用程序中,这将通过以下一种或多种方式降低服务级别:
- Rails 等非多线程非异步应用程序中的请求队列增加了响应时间
- 在异步多线程应用程序的情况下,更高的上下文切换会增加响应时间
- 具有严格响应时间 SLO 和超时的应用程序中的超时错误峰值
- 如果我们不执行严格的响应时间 SLO 和超时,则依赖于相关高吞吐量应用程序的服务会出现级联减速
理想情况下,我要寻找的是一些先创建后销毁模式。类似于:我们要求 Kube 终止 Pod,但在将其从列出的任何服务中的 Endpoints 中删除之前,它会触发扩展,尊重 Readiness Gate,然后开始终止我们要求它终止的 Pod。我在 Kubernetes 中没有发现任何提及这种模式的内容。
人们如何处理这种情况?我可以想象以下内容:
- 较低
targeAverageUtilization
的 HPA,因此我们可以容忍暂时减少 50% 的容量,但这意味着我们将支付比我们想要的更多的费用 - 优化 Pod 准备就绪时间,使我们在几秒钟内保持供应不足,但这似乎非常困难,例如,AWS 负载均衡器需要至少 10 秒才能使新目标健康运行
- 创建一个涉及的工作流程,而不是
kubectl delete [pod]
我们:- 将 HPA
minReplicas
增加到当前副本的一个以上 - 等待 Pod 准备就绪
- 等待几秒钟让它预热
- 运行
kubectl delete [pod]
以杀死所需的 pod - 等待新的替换吊舱准备就绪
- 等待几秒钟让它预热
minReplicas
在 HPA 中恢复- 冒着整个操作与流量增加/峰值同时发生的风险,并看到我上面列出的任何退化影响
- 将 HPA
这些似乎都不是很好。尤其是最后一个,不会涉及 binpacking,因为我们无法替换 Cluster Autoscaler 排出实例的方式。