Author: xidianwangtao@gmail.com
什么是抢占式调度? 在Kubernetes 1.8版本之前,当集群资源不足时,用户提交新的Pod创建请求后,该Pod会处于Pending状态,直到集群中有某个Node有足够Available Resources时才会调度成功。 从Kubernetes 1.8版本开始,这种情况下scheduler会根据Pod's Priority进行调度,调度时会选择最合适的Node并把该Node上lower Priority的Pods进行Premmption(Eviction)以释放资源供该higher Priority Pod使用。这种调度时考虑Pod Priority的方式就是Kubernetes中的抢占式调度,简称为Preemption。
在后续的版本中,Pod Priority还会用于节点的out-of-resource Eviction,关于kubelet eviction的工作机制和源码分析,请参考我的对应博客:
在Kubernetes 1.8中,Pod Priority和Preemption作为Alpha特性,默认是disable的,如果你要使用该特性,需要给apiserver和scheduler添加如下参数并重启:
反过来,把上面的参数删除并重启,即可disable。
有个问题:如果我开启了这个特性,并且创建了一些PriorityClass,然后还给某些Pod使用了,这个时候我再disable掉这个特性,会不会有问题?
答案是否定的!disable后,那些之前设置的Pod Priority field还会继续存在,但是并没什么用处了,Preemption是关闭的。当然,你也不能给新的Pods引用PriorityClass了。
Enable后,接下来就是创建PriorityClass了:
apiVersion: scheduling.k8s.io/v1alpha1
kind: PriorityClass
metadata:
name: high-priority
value: 1000000
globalDefault: false
description: "This priority class should be used for XYZ service pods only."
注意:PriorityClass是非namespace隔离的,是global的。因此metadata下面是不能设置namespace field的。
注意:
接下来,就是创建对应Priority的Pod了:
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
priorityClassName: high-priority
如果Pod.spec. priorityClassName中指定的PriorityClass不存在,则Pod会创建失败; 前面也提到,创建Pod的时候Priority Admission Controller会根据PriorityClassName找到对应的PriorityClass,并将其value设置给Pod.spec.priority。
在Kubernetes 1.8之前,Node Condition是会直接干预调度的,逻辑是是这样的,并且是无法改变的:
Node Condition | Scheduler Behavior |
---|---|
MemoryPressure | No new BestEffort pods are scheduled to the node. |
DiskPressure | No new pods are scheduled to the node. |
- 当Node Condition包含Memory Pressure时,不再允许BestEffort QoS Pods调度到该节点;
- 当Node Condition包含DiskPressure时,不允许任何pods调度到该节点。
从Kubernetes 1.6开始,kubelet和Node Controller支持自动根据Node Condition给Node打上相应的内置Taints,当时这些Taints只是会影响kubelet eviction,而不会影响调度。这有啥不同呢?区别就是,给Node打上Taints对调度来说是软限制,可以通过给pods加上对应的Tolerations就可能强制调度到那个节点。而在1.8之前,Node Condition影响调度是硬限制。
Node Condition和Taints的Map关系如下:
ConditionType | Condition Status | Effect | Key |
---|---|---|---|
Ready | True | - | |
False | NoExecute | node.kubernetes.io/notReady | |
Unknown | NoExecute | node.kubernetes.io/unreachable | |
OutOfDisk | True | NoSchedule | node.kubernetes.io/outOfDisk |
False | - | ||
Unknown | - | ||
MemoryPressure | True | NoSchedule | node.kubernetes.io/memoryPressure |
False | - | ||
Unknown | - | ||
DiskPressure | True | NoSchedule | node.kubernetes.io/diskPressure |
False | - | ||
Unknown | - | ||
NetworkUnavailable | True | NoSchedule | node.kubernetes.io/networkUnavailable |
False | - | ||
Unknown | - |
Kubernetes 1.8中基于Pod优先级进行抢占式调度的特性都是Alpha,请谨慎在生产中使用,尤其是要注意本文中“Preemption当前还存在的问题”小节中提到的不足。
相信很快就能支持好抢占式调度时支持Pod亲和性、跨节点抢占等特性了,那时就完美了。