Node“自愈” — Node Eviction & Kubelet Eviction
众所周知,K8S在系统资源紧缺的情况下保证Node的稳定性,主要是通过释放内存和磁盘这些不可压缩的资源,对于那些使用超过request值的容器,kubelet通过oom_killer 来响应系统OOM,杀死那些oom得分较高的容器,以此释放内存资源。对于可压缩的资源,抢占通过request的比值进行分配,而不会进行资源释放。
驱逐功能关闭要解决的以下两种场景,导致的pod驱逐:
节点异常 —> node eviction
资源不足 —> kubelet eviction
对于资源不足导致的异常,k8s通过kubelet 发起驱逐,优先驱逐 BestEffort 类型的容器,这些容器多为无状态应用,他们通过多副本保证业务高可用,或者 离线批处理类业务,他们对可靠性要求稍低。驱逐后释放资源,减缓节点压力,弃卒保帅,保护了该节点的其它容器。
对于节点异常导致的pod不可用,则需要通过外部机制,例如服务发现、健康检测等,来自动摘除相应异常节点,来保证业务可用性。而这部分机制的实际效果,在大量的落地经验实践中,有待商榷。
例如:正常情况下,node节点周期上报心跳给 k8s master,如果心跳超时,则认为计算节点 NotReady,当 NotReady 状态达到一定时间后,kube-controller-manager 发起驱逐。然而造成心跳超时的场景非常多,例如:
- 原生 bug:kubelet 进程彻底阻塞
- 误操作:误把 kubelet 停止
- 基础设施异常:如交换机故障演练,NTP 异常,DNS 异常
- 节点故障:硬件损坏,掉电等
所以,尽量关闭 kube-controller-manager 的驱逐功能,即把驱逐的超时时间设置非常长
。否则,非常容易就搞出大大小小的故障,血泪的教训。 而我们在这里做的改动,不仅仅包括调大–pod-eviction-timeout参数,(该参数让节点在NotReady 状态节点超过该时间后,执行pod驱逐,默认 5 min)。而且针对某些场景,例如node not ready判断不够精准、影响依赖endpoint的业务的可用性,对endpoint自动摘除功能做了相应的测试和修改。
相关参考文档:http://wsfdl.com/kubernetes/2018/05/15/node_eviction.html
我们先从Pod异常中断的角度来看看,大致有哪些场景会影响pod的可用性。
| 不可避免的异常(非自愿性中断) | 人为操作导致的异常(自愿性中断) |
|---|---|
| 机架硬件故障、VM故障、 | 删除了管理pod的 RS/DP/其他 |
| kernel panic | 更新了pod模板导致重启 |
| 网络分区导致集群节点消失 | pod被误删(drain node/ delete pod) |
| 资源耗尽导致pod被驱逐 | 滚动更新/ 自动扩容集群 |




