Skip to content

Pod 优先级和抢占

  • https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/

FEATURE STATE: Kubernetes v1.14 [stable]

Pod 可以拥有优先级(priority)。若一个 pod 不能被调度,调度器会尝试抢占/驱逐(preempt/evict)低优先级的 pods。

1. 如何使用

  1. 添加 PriorityClass
  2. 创建带有 priorityClassName 的 pod。

2. 如何关闭抢占特性

不建议关闭此特性。

Kubernetes >= 1.15,若启用了 NonPreemptingPriority 特性,PriorityClass 有选项设置:preemptionPolicy: Never 。这将防止 PriorityClass 的 Pod 抢占其他Pod。

驱逐性被 kube-scheduler 的 disablePreemption 控制,默认是false。它只能在组件配置中使用,下面是一个例子:

apiVersion: kubescheduler.config.k8s.io/v1alpha1
kind: KubeSchedulerConfiguration
algorithmSource:
  provider: DefaultProvider

...

disablePreemption: true

3. PriorityClass

它是非命名空间对象,值在value字段中指定,值越高则优先级越高。名字必须时合法的DNS子域名,并且不能以syste-作为前缀。

value 可以是任何小于等于10亿的32位整数值。更大的数字被系统保留以便某些系统性的 pod 不会被抢占或驱逐。

PriorityClass 还有两个可选选项:

  • globalDefault:用于那些没有定义优先级的 pod ,并且只能有一个启用了此选项的 PriorityClass 存在于系统之中。若在系统中没有启用了该选项的 PriorityClass,那么 value 就是 0。
  • description

关于已存在的集群有几点要注意的地方:

  • 若你使用了此特性更新了已存在的集群,已存在的 pods 实际上的优先级为 0;
  • 另外,设置了globalDefaulttrue的 PriorityClass 不会改变已存在的 pods 的优先级。这个值只会影响在此值创建之后再创建的 pods;
  • 若你删除了 PriorityClass,使用该 PriorityClass 的已存在的 pods 的优先级不会被改变,但是不能再创建新的使用此 PriorityClass 的 pods了。

例子:

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 1000000
globalDefault: false
description: "This priority class should be used for XYZ service pods only."

3.1 对调度顺序的影响

当启用了 pod 优先级后,优先级越高的 pod 在调度队列中越靠前。若无法调度某个 pod,那么会继续尝试调度低优先级的 pod。

4. Preemption

pod 被创建之后,会进入到一个队列中等待被调度。调度器选择一个 pod P 然后尝试分配给某个 node。若没有 node 满足调度条件,就会触发该 pod P 的抢占逻辑。抢占逻辑会尝试发现一个 node ,该 node 可以移除一个或多个低级 pod 来满足 pod P 的调度条件。当这些低级 pod 消失后,pod P 就可以被调度到该 node 上面了。

P 绝不会抢占同等优先级或更高优先级的 pod。

4.1 向用户公开的信息

当 pod P 在 node N 上面抢占其它的 pod 时,Pod P 状态的naminatedNodeName字段会被设置为 node N 的名字。

但是 P 不一定会被调度到 naminatedNodeName 上面。在驱逐的 pod 被抢占后,它们会被优雅地结束。若正在等待低级 pod 结束的时候有其它 node 可以调度,那么 P 会调度到其它 node 上面。还有另一种情况,若有一个更高优先级的 pod 到了,那么调度器可以将 N 给高级 pod 使用,在这种情况下,调度器会清除 P 的 naminatedNodeName 字段。通过这样做,调度程序使 Pod P 有资格抢占另一个节点上的 Pod 。

4.2 抢占策略的限制

4.2.1 PodDisruptionBudget

Pod Disruption Budget (PDB)(pod 毁坏方案) 是支持的,但不能保证会起作用。只会尽最大努力来保证 PDB。调度器会先查找不会违反 PDB 的 pod,若找不到才会违反 PDB 规则并移除 pod。

一种情况就是若低级的 pod 有 PDB 规则,那么会寻找更高级的 pod。

4.2.2 低优先级 pods 之间的 inter-pod 亲和性

一个 node 能否用于抢占只需要回答一个问题:“如果所有的比待定 pod 优先级低的 pods 都从该 node 上面移除了,这个待定的 pod 可以被调度到此 node 上面吗?” 。当然了,调度器会尽可能地移除少一点的节点。

若待定的 pod 与低级 pod 之间有 inter-pod 亲和性,并且在没有这些 pod 的情况下不能满足亲和性规则。在这种情况下,调度器不会抢占此 node 上面的 pod,它会寻找其它合适的 node 。此时不能保证待定的 pod 被调度。

官方对这种情况的建议是只在相等或更高优先级的 pod 之间建立亲和性关系。

4.2.3 跨节点抢占

调度器不支持跨节点抢占。假设一个 node N 被考虑为了调度 pod P 而驱逐其它 pods,但是此时只有另一个节点上面的某个 pod 也被抢占了之后 P 才能被调度到 N。这时就出现了需要跨节点抢占的情况。这是一个例子:

  • 正在考虑将 Pod P 用于 node N。
  • pod Q 正运行在和 N 同一个域的其它 node 上。
  • P 和 Q 在域的层面上具有反亲和性。
  • P 和同一个域里面其它的 pods 没有反亲和性关系。
  • 为了在 N 上面调度 P,Q 可以被抢占,但是调度器不会执行跨节点抢占,所以 P 会被认为不能在 N 上面调度。