深入理解K8S——Pod Preemption资源抢占
参考
what
之前有多篇博文分析过调度器,参见深入分析kube-scheduler,k8s-调度算法,k8s-scheduler,对调度器有了基本认识。如果没有node满足Pod P的要求,就会触发Preemption。Preemption逻辑会试图找到一个node,在node上移除低优先级的Pod就可以满足P。找到node之后,Preemption就会删除这些受害者Pods,然后调度P。
Note:
- 删除需要时间,注意
pod.spec.terminationGracePeriodSeconds
,在真正删除容器之前,K8S会先发终止信号(kill -15 {pid})给容器,默认30s。所以就算Preemption提名了node,在终止时间内,如果有其他满足条件的node,P会调度过去。 - Preemption不一定保证PDB
- Preemption必须考虑的问题是:当node上所有低优先级(比P低)的pods都移除了,P是否可以调度到node上。
- 当Preemption与Pod亲和性发送冲突时,即P亲和低优先级的Pod,调度器不会抢占这个node Pod资源。建议P只亲和优先级大于等于自己的Pods
- 跨node抢占暂不支持。考虑以下场景,zone下有node A,node B,Pod A运行在node A上。考虑Pod B抢占 node B,但是Pod B与Pod A在zone下有反亲和性,所以Pod B无法调度在node B上。
where
将Preemption放在调度里面有一下几点好处:
- Preemption也有一些调度逻辑,需要遍历node,找到合适node等等,所以放在调度里面可以减少重复代码
- 减少资源竞争,如果别的组件实现Preemption,会引起资源竞争。不过多调度器也会引起资源竞争。
特别注意
- 避免错误地设置高优先级的Pod,引起资源抢占
- 被抢占的Pod会有时间优雅退出,抢占Pod需要等待这些受害者退出。如果在等待期间,有一个高优先级的Pod,那么可能这个Pod调度到node上,导致抢占Pod无法被调度
- 如果有多个node可以抢占,调度器会选择总Pod优先级最低的node
- 根据优先级排序时,还需要按照QoS排序
- 由于调度器只考虑资源请求(只关注request,不考虑limit),所以不会驱逐BestEffort Pod,因为BestEffort 没有request,所以在调度器看来,删除它并没有释放资源
- 释放资源总量等于P的资源申请总量
ping-pong
考虑这样一个场景,node上运行一些高优先级的BestEffort Pod,调度器调度了一个低优先级的非BestEffort Pod在node。当node处于资源压力时,kubelet会先驱逐低优先级的Pod,不管高优先级的BestEffort 。但是调度器不考虑BestEffort,还是会调度node,造成这种ping-pong
。