如何在负载下安全终止Pod

问题描述

在某些情况下,需要终止Pod而不减少部署的总容量:

  • 排水节点进行维护
  • 用于装箱的排水节点
  • 行为不当/在不触发OOM Killer的情况下处理内存泄漏

想象一下一个情况,我们有两个Pod占用大量流量,如果使用终止Pod的认工作流程,然后让Kubernetes通过重新创建Pod做出反应,那么在任意时间范围内,我们将拥有50%的处理能力

在高吞吐量应用程序中,这将通过以下一种或多种方式降低服务水平:

  • 像Rails这样的非多线程非异步应用程序中的请求排队会增加响应时间
  • 在异步多线程应用程序中,较高的上下文切换会增加响应时间
  • 具有严格响应时间SLO和超时的应用程序中的超时错误峰值
  • 如果我们不执行严格的响应时间SLO和超时,则依赖于高吞吐量应用程序的服务的级联速度会降低

理想情况下,我要寻找的是销毁前创建模式。诸如此类:我们要求Kube终止Pod,但是在将其从列出的任何服务的端点中删除之前,它会触发放大操作,遵守Readiness Gate,然后开始终止我们要求终止的Pod。在Kubernetes中我还没有提到这种模式。

人们如何应对这种情况?我可以想象以下内容

  • 降低targeAverageutilization的HPA,因此我们可以容忍暂时减少50%的容量,但这意味着我们将支付比我们想要的更多的钱
  • 优化Pod的准备时间,使我们的配置不足几秒钟,但是,例如,当AWS Load Balancer花费至少10秒钟才能使新目标正常运行时,这似乎非常困难
  • 创建一个涉及的工作流程,而不是kubectl delete [pod],我们:
    • 将HPA minReplicas增加到当前副本之上的一个
    • 等待Pod准备就绪
    • 等待几秒钟使其热身
    • 运行kubectl delete [pod]杀死想要的豆荚
    • 等待新的更换吊舱准备就绪
    • 等待几秒钟使其热身
    • 在HPA中恢复minReplicas
    • 冒着与流量增加/峰值同时发生整个操作的风险,并看到我上面列出的任何降级影响

这些似乎都不是好事。尤其是最后一个将不涉及装箱,因为我们无法替代集群自动缩放器耗尽实例的方式。

解决方法

中断预算:

minAvailable设置为90%。