Pod调度
一、简介
在大多数情况下,我们不关心pod会被调度到哪个节点,只关心pod是否被成功调度到集群的一个可用节点。但是,在真实生产环境中存在一种需求:希望某种pod全部运行在一个或一些节点上。比如需要ssd的pod都运行在具有ssd磁盘的目标节点上。
二、全自动调度
deployment
或rc
的主要功能之一就是自动部署一个容器应用的多份副本,以及持续监控副本的数量,在集群中始终维持用户指定的副本数量。
|
|
使用kubectl create
命令创建这个deployment
:
|
|
可以看到Deployment
已经创建好3个副本,并且所有副本都是最新可用的。从调度策略上来说,这3个pod
由系统全自动完成调度,用户无法干预调度过程和结果。
三、NodeSelector:定向调度
通过Node
的标签(Label)和Pod
的nodeSelector
属性相匹配来讲Pod
调度到指定的一些Node
上。
1、通过kubectl label
命令给目标Node
打上一些标签:
|
|
2、在Pod
的定义中加上nodeSelector
的设置
|
|
如果给多个Node
都定义了相同的标签,则scheduler
会根据调度算法从Node
组中挑选一个可用的Node
进行调度。
除了用户可以自行给Node
添加标签,kubernetes
也会给Node
预定义一些标签。
- kubernetes.io/hostname
- kubernetes.io/os
- kubernetes.io/arch
四、NodeAffinity:Node亲和性调度
NodeAffinity
为Node亲和性的调度策略,是用于替换NodeSelector
的全新调度策略。目前有两种节点亲和性表达。
- RequiredDuringSchedulingIgnoredDuringExecution:必须满足指定的规则才能调度Pod到Node上,相当于硬限制。
- PreferredDuringSchedulingIgnoredDuringExecution:强调优先满足指定规则,调度器会尝试调度Pod到Node上,但不强求,相当于软限制。多个优先级规则还可以设置权重(weight)值,以定义执行的先后顺序。
IgnoredDuringExecution:如果一个Pod所在的结点在Pod运行期间标签发生了变更,不再符合Pod的结点亲和性需求,则系统将忽略Node上的Label变化,该Pod能继续在该节点上运行。
|
|
NodeAffinity
语法支持的操作符包括In
、NotIn
、Exists
、DoesNotExist
、Gt
、Lt
。
NodeAffinity
规则设置的注意事项:
- 如果同时定义了
nodeSelector
和nodeAffinity
,那么必须两个条件都得到满足,Pod才能最终运行在指定的Node上 - 如果
nodeAffinity
指定了多个nodeSelectorTerms
,那么其中一个能够匹配成功即可 - 如果
nodeSelectorTerms
中有多个matchExpressions
,则一个节点必须满足所有matchExpressions
才能运行Pod。
五、PodAffinity:Pod亲和与互斥调度策略
如果在具有标签相同的Node上运行了一个或多个符合条件的Pod,那么Pod应该运行在这个Node上。
topologyKey:节点所属的topoloty
- kubernets.io/hostname
- failure-domain.beta.kubernetse.io/zone
- failure-domain.beta.kubernets.io/region
pod的亲和与互斥的条件设置也是RequiredDuringSchedulingIgnoredDuringExecution和PreferredDuringSchedulingIgnoredDuringExecution。
Pod的亲和性被定义在podAffinity
,Pod的互斥性被定义在podAntiAffinity
。
1、参考目标Pod
创建一个名为pod-flag
的pod,带有标签security=S1
和app=nginx
。
|
|
2、Pod的亲和性调度
|
|
3、Pod的互斥性调度
|
|
新pod与security=S1
的pod为同一个zone
,但不与app=nginx
的Pod为同一个zone
。
topologyKey的限制(出于性能和安全方面考虑):
- 在Pod亲和性和RequiredDuringScheduing的Pod互斥性的定义中,不允许使用空的topologyKey。
- 如果Admission Controller包含了
LimitPodHardAntiAffinityTopology
,那么针对Required DuringScheduling
的Pod互斥性定义就被限制为kubernetes.io/hostname
,要使用自定义的topologyKey
就要改写或禁用该控制器。 - 在
PreferredDruingScheduling
类型的Pod互斥性定义中,空的topologyKey
会被解释为kubernets.io/hostname
、failure-domain.beta.kubernetse.io/zone
、failure-domain.beta.kubernets.io/region
的组合。 - 如果不是上述情况,就可以采用任意合法的
topologyKey
。
PodAffinity
规则设置的注意事项:
- 除了设置
Label Selector
和topologyKey
,用户还可以指定Namespace
列表来进行限制,同样,使用Label Selector
对Namespace
进行选择。 - 在所有关联
requiredDuringSchedulingIgnoredDuringExecution
的matchExpressions
全部满足之后,系统才能将Pod调度到某个Node上。
六、Taints和Tolerations(污点和容忍)
在Node上设置一个或多个Taint之后,除非Pod明确声明能够容忍这些污点,否则无法在这些Node上运行。Toleration是Pod的属性,让Pod能够运行在标注了taint的Node上。
|
|
然后在pod上声明toleration。
|
|
如果不指定operator
,默认值为Equal
。空的key配合Exists能够匹配所有键和值。空的effect能够匹配所有的effect。
- NoSchedule:不调度
- PreferNoSchedule:不优先调度
- NoExecute:不运行,已经在这个节点上的Pod会被驱逐。
七、Pod Priority Preemption:Pod优先级调度
优先级抢占调度策略的核心行为分别是驱逐(Eviction)和抢占(Preemption)。Evection是kubelet行为,即当一个Node发生资源不足情况时,该节点上的kubelet进程会发生驱逐动作,此时kubelet会综合考虑Pod的优先级、资源申请量与实际使用量等信息计算哪些Pod需要被驱逐;当同样优先级的Pod需要被驱逐时,实际使用的资源量超过申请量最大倍数的高耗能Pod会被首先驱逐。
服务质量等级Qos:
- Guaranteed:pod设置了
limit
或limit=request
- Burstable:pod里的一个容器
limit!=request
- Best-Effort:
limit
和request
均未设置
1、创建PriorityClasses
|
|
2、可以在任意pod中引用优先级类别
|
|
八、其他情况
1、DaemonSet:在每个Node上都调度一个Pod
2、Job和CronJob的批处理调度,可以设置任务数completions
和并行度parallelism