系列目录html
Pod能够拥有优先级.优先意味着相对于其它pod某个pod更为重要.若是重要的pod不能被调度,则kubernetes调度器会优先于(驱离)低优先级的pod来让处于pending状态的高优先级pod被调度.node
kubernetes 1.9之后,优先级会影响pod的调度顺序和资源耗尽时pod的驱离顺序算法
警告:在一个不是全部用户都被信任的集群里,可能有恶意用户建立最高可能优先级的pod,致使其它pod被驱离或者没法调度.为了解决这个问题,须要增大资源配额来支持优先pod.集群管理员能够为特定用户建立特定优先级级别,防止他们建立高优先级的pod.这项功能在1.12版本里为beta状态.api
在1.11或之后的版本里,按下面指示来操做:dom
建立一个或者多个PriorityClasses
ide
建立一个pod,并把priorityClassName
设置为以上添加的priorityClassName
中的一个.固然你没必要直接建立pod,你能够把priorityClassName
添加到集合对象(好比deployment)的template里.性能
若是你仅想尝试这项功能而且而后把它禁用,你必须把PodPriority
设置为false,而后重启apiserver和调度器.被禁用之后,已经存在的pod仍然保留有它们的优先级字段,可是抢占不会再生效,而且优先字段被忽略.你也不能再向新的pod添加priorityClassName
字段命令行
在kubernetes 1.12+ 当集群处于较大资源压力时,一些关键的pod依赖抢占调度.所以强烈为建议禁用抢占code
在kubernetes1.11之后版本,抢占被kube-scheduler的的disablePreemption
标识控制,默认设置是false.若是你不顾建议仍然想要禁用它,能够把它设置为truecomponent
这个选项仅仅在组件的配置里有效,在旧式的命令行下无效.下面是一个配置的示例:
apiVersion: componentconfig/v1alpha1 kind: KubeSchedulerConfiguration algorithmSource: provider: DefaultProvider ... disablePreemption: true
当pod被建立,他们进入队列等待被调度.调度器从队列取出一个pod而且尝试把它调度到一个节点上.若是没有节点可以知足这个pod的全部要求,抢占逻辑被触发,咱们把这个挂起的pod称做P.调度器尝试寻找移除一个或者多个比P低的pod后可以使得P被调度的节点.若是找到了一个这样的节点,一个或者多个优先级低的节点被驱离,而后P被调度到这个节点上.
当pod P抢占了Node N上的一个或者多个pod的资源,P的nominatedNodeName(候选节点)
字段被设置为节点N的名字.这个字段帮助调度器追踪为P预留的资源信息,并给用户提供集群资源抢占的一些信息.
须要注意的是pod P并不老是调度到候选节点(nominated Node)上,当受害的pod被抢占,他们进入终止阶段.当受害pod中止的过程当中其它节点变得可用,这时候调度器就会使用这个可用的节点来接收pod P,这样就形成nominatedNodeName
和nodeName
并不老是相同.而且,pod P抢占了节点N上的优先级低的pod的资源时,这时候有更高优先级的pod到达,这时候调度器可能会把节点N让给这个更高优先级的pod使用.这时候调度器会清除pod P的nominatedNodeName
字段,这样,调度器使用pod P能够抢占其它节点上的资源.
当被抢占,受害pod进入优雅终止期,它们将有时间完成工做并退出.不然,会被杀掉.这个优雅终止期在调度器抢占受害pod资源和优先pod被调度到Node N之间建立了一个时间间隔.同时,调度器继续调度其它状态为pending
的pod.为了缩短这个时间间隔,用户能够把优雅终止期设置为0或者一个很小的时间
问题:若是全部低优先级的pod都从一个节点上移除了,那么挂起(pending)的pod是否能够调度到此节点上?
这个问题的意义在于若是全部的pod都被移除,资源仍然不够容纳挂起的pod会怎么样?
仅当以上问题的答案是确定的(yes)的时候,节点的抢占才会发生(也就是若是所有低优先级的pod都被驱离仍然不够容纳新的pod时,节点上不会发生抢占)
须要注意的是,并非老是要移除节点上的全部低优先级的pod.若是仅仅移除一些pod就足以容纳挂起的pod时,仅有部分低优先级的pod被移除.可是以上问题的答案仍然须要是确定的(也就是说低优先级pod的移除创建在移除后资源足以容纳新的挂起的节点的基础上的)
若是挂起的pod(即将被调度的)和一个或者多个节点N上的低优先级的pod有pod间亲和关系,若是低优先级pod离开后pod间的亲和关系不能被知足时,调度器这时候不会再抢占节点N上的pod.调度器可能会找到一个其它的合适的节点,也可能找不到.这就没法保证挂起的pod被调度.
对于这个问题咱们的建议是建立pod间亲和关系时,只向同等优先级和更高优先级的pod建立.
假设Node N 上准备抢占以即是pod P能够被调度到N上,可是P依赖于其它节点上的pod被驱离才能够被调度到N上,如下示例说明这个问题
Pod P准备调度到节点N上
pod Q们于和节点N同一区域的其它节点上
pod P和pod Q有区域级别的反亲和关系(topologyKey: failure-domain.beta.kubernetes.io/zone
)
pod P和同一区域内的其它pod没有反亲和关系
为了把pod P调度到节点N上,Pod Q能够被抢占,可是调度器不会执行跨节点抢占,所以pod P不会被调度到节点N上.
若是pod Q从它的节点上移除,这时候违反亲和关系也消失,此时pod P可能会被调度到节点N上
在将来的版本中若是能找到一个能保证性能的算法,咱们可能会考虑增长跨节点驱离.可是目前咱们什么都不能保证.
pod优先级和资源抢占的编排若是有bug的话则每每是致使节点调度中断的主要缘由之一
如下是若是pod优先级和资源抢占包含bug可能致使的问题的不彻底罗列:
当集群出现资源压力时,调度器会移除优先级低的pod来为优先级高的pod腾出资源,若是用户错误地给分配给一些pod太高的优先权,这些无心分配的高优先权会致使集群抢占.像上面提到的,pod的优先权经过设置podSpec
字段的priorityClassName
来实现的,优先级的整数字段然被解析后传入到podSpec
字段的priority
字段里
为了解决这个问题,priorityClassName
字段必须改变到更小的优先级或者留空,priorityClassName
字段留空会被解析为0
当一个pod被抢占,则它会产生一条event记录来记录这个事件.仅当集群没有足够的资源时抢占才会发生.这种状况仅发生在(挂起)的pod的优先级高于受害pod.若是没有挂起的pod,则抢占事件必定不能发生.若是没有挂起pod,或者挂起pod的优先级等于或小于受害pod时发生抢占事件,则是系统bug,请提交一个issue给咱们.
当pod被抢占,他们将接收到一个优雅中止的时间段,默认是30秒,可是也能够是任意在podSpec里指定的值.若是受害pod没有在指定的时段里中止,他们会被强行终止.当全部受害者都被移除,优先pod能够被调度.
当优先pod等待受害者被移除时,一个适合调度到这个节点上的更高优先级的pod被建立.这时候调度器会优先调度这个更高优先级的pod
调度器会尽力寻找适合的节点来调度挂起的pod,若是找不一节点来调度,调度器会从一个包含低优先级的节点上移除pod来为挂起的pod腾出空间.若是有低优先级pod的节点不适合被调度,调度器可能会选择一个更高优先级的节点来抢占(这里说的更高是相对前面找到的低优先级的pod而言的,而不是对优先pod而言的).被抢占的pod仍然必需要比优先pod(指挂起的须要调度的pod)优先级别低
当有多个节点能够被抢占时,调度器会尝试选择有最低优先级pod的节点来调度.可是若是pod有PodDisruptionBudget
而且抢占可能会违反PodDisruptionBudget
时,调度器可能会选择一个更高优先级的pod来抢占.
当有多个节点能够被抢占而且没有出现以上情形,则调度器会选择优先级最低的pod来抢占,若是不是这样的,则意味着调度器自己存在bug.
pod优先级和QoS是两个正交的功能,几乎没有交叉.调度器的抢占逻辑当选择抢占对象时不会考虑QoS.抢占会考虑pod的优先级并选择出一系列低优先级抢占目标.只有立即便移除低优先级pod也不足以运行挂起的pod或者低优先级的pod被PodDisruptionBudget
保护时,调度器才会选择更高优先级的pod做为抢占对象.
仅有Kubelet的 out-of-resource eviction组件才会同时考虑pod优先级和QoS,kubelet首先会根据使用的资源是否超过请求的值来对要驱离的pod进行排序,而后根据优先级.Kubelet out-of-resource eviction 不会驱离使用资源低于请求资源的pod,若是一个低优先级的pod使用的资源没有超过它请求的,则它不会被驱离.其它的使用资源超过其申请资源的更高优先级的pod可能会被驱离.