前言:
随着大量的项目上k8s之后,我们通过监控发现有些Node cpu 使用率很高,达到80%+,但有些节点cpu使用率却不到40%。cpu使用率高,cpu负载也同样会升高,这会导致这些Node上的应用出现延迟增加,对影响业务稳定有一定影响。资源利用率严重不均衡,因此一定要解决。
我们尝试重新deploy 应用,驱逐pod,发现并不能有效解决问题,pod还会大概率调度到负载高的Node上。
问题分析
我们知道k8s kube-scheduler调度器会决定将pod 调度到哪个Node,主要由下面两步骤组成:
- 过滤,会将所有满足 Pod 调度需求的 Node 选出来
- 打分,从所有可调度节点中选取一个分值最高最合适的 Node。
cpu 负载较低的Node cpu,内存,磁盘都很充足,肯定会通过过滤筛选,而且分值会很高,应该会最先调度,但不知道为何却没有。
根据分析我们确定主要问题有以下几点:
1.k8s 调度器默认会根据Pod cpu和内存request 值调度,Pod request 值大优先调度到Node 可用资源(可用资源=Node实际资源-Pod request )较多的节点,并不是根据Node 实时动态cpu负载进行资源调度的。
2.有些项目接入k8s时,cpu 和内存的request 设置的不合理,有的偏大,有的偏小。比如,项目cpu 使用率高,request设置的很大,那这个项目会调度到负载低的Node,这样没什么问题;如果项目cpu使用率低,request设置很大,那会导致这个Node可用资源很小,其他Pod 不会调度到这个Node,从而导致资源利用率很低。
3.Pod 使用了一些亲和反亲和策略。
如何解决
针对第一个问题,k8s sig小组开源了一个二次调度工具descheduler,会根据Node实际负载情况,对pod进行二次调度。
只使用descheduler也是不行的,request 设置不合理还是要解决,必须要根据项目Pod 真实资源使用情况进行调整。