22.修神篇:资源调度器与调度机制

22.修神篇:资源调度器与调度机制

2020-02-07 22:50:00

在Kubernetes中,调度是指确保Pod与Node节点的匹配度,以便Kubelet可以运行它们。

1.调度概述

在kubernetes集群的概念中,调度主要是做两件事情:
1.监听新创建,且未被分配至任何node节点的pod资源
2.根据机身集群的计算资源、规则、匹配度等情况,为新的pod资源进行调度

2.调度流程

调度流程图.png

如图所示,调度流程可分为两大块:Filtering和Scoring

2.1.Filtering

预选阶段,也称为predicate。
会按照预选过滤器,首先把不符合要求的node节点直接剔除在外。
这一阶段为可行性筛选。
通常,会有不止一个。 如果筛选列表为空,则该Pod尚无法完成调度。

如图所示,经过Filtering阶段,node01和node03已经标红并剔除在外。

常用的预选过滤器,我整理了一个表格供大家参考,所有过滤器可移步Filtering大全

预选过滤器名 说明
PodFitsHostPorts 检查node节点是否有可用端口
PodFitsHost 检查pod中是否通过hostname定义了node
PodFitsResources 检查标签选择器和node节点标签是否匹配
NoVolumeZoneConflict 检查节点上Pod请求的卷是否可用
NoDiskConflict 检查pod请求的volume是否已经挂载
MaxCSIVolumeCount 评估应该新增多少个CSI卷,以及是否超出配置的限制
CheckNodeMemoryPressure 如果节点处于内存压力,不会将pod调度至此
CheckNodePIDPressure 如果节点pid稀缺,不会将pod调度至此
CheckNodeDiskPressure 如果节点磁盘存在压力,不会将pod调度至此
CheckNodeCondition 检查节点是否具备调度的基础条件,如文件系统是否可用,网络是否可用或者kubelet是否就绪,否则不会将pod调度至此
PodToleratesNodeTaints 检查pod的容忍度是否能容忍节点的污点
CheckVolumeBinding 评估Pod是否适合其所需的容量,这适用于绑定和未绑定的PVC

2.2.Scoring

打分阶段,也称为priority。通过优选函数对节点进行打分,从而决定调度策略。这一阶段为优选阶段,筛选哪个节点更优。

如图所示,经过Scoring阶段,只剩下node04和node06了。

常用的优选过滤器,我也整理了一个表格供大家参考,所有过滤器可移步Scoring大全

优选过滤器名 说明
SelectorSpreadPriority 标签优先级计算
InterPodAffinityPriority pod亲和度计算
LeastRequestedPriority 倾向于调度至请求较少、资源更空闲的节点上
MostRequestedPriority 倾向于调度至请求较多、资源更紧凑的节点上
RequestedToCapacityRatioPriority 使用默认资源打分函数进行优选计算
BalancedResourceAllocation 倾向于调度至资源平衡的节点
NodePreferAvoidPodsPriority 通过scheduler.alpha.kubernetes.io/preferAvoidPods注释,避免pod间调度至同一个node节点
NodeAffinityPriority node亲和度计算
TaintTolerationPriority 根据节点上无法忍受的污点数量,为所有节点准备优先级列表
ImageLocalityPriority 倾向于本地已有pod缓存的节点
ServiceSpreadingPriority 对于给定服务,此策略旨在确保该服务的Pod在不同的节点上运行
CalculateAntiAffinityPriorityMap 此策略有助于实现pod的反亲和力
EqualPriorityMap 所有节点给定一个相同的权重

3.InterPodAffinityPriority与NodeAffinityPriority

        在优选过滤器中,我提到过两个过滤器InterPodAffinityPriority和NodeAffinityPriority,他们是十分重要的,常常也会理解出现偏差。

3.1.InterPodAffinityPriority

我们称之为pod亲和度,pod对pod的亲和性,表示是否愿意与相关pod调度至一个区域(可以是node、机架、也可以是机房)

如何定义同一区域,则需要使用topologyKey(v1.16特性)进行标识,下一章节我会着重讲解的。

同理,还会有pod反亲和,这个你应该很好理解了。

除此之外,pod亲和度分为以下两种:

硬亲和(required):使用requiredDuringSchedulingIgnoredDuringExecution字段定义,如果条件都不满足,则不调度,Pod对象的状态会一直是Pending状态
软亲和(preferred):使用preferredDuringSchedulingIgnoredDuringExecution字段定义,如果条件都不满足,也会从中按照打分,“勉为其难”的选择一个进行调度

pod亲和度的API文档:kubectl explain pod.spec.affinity.podAffinity

pod反亲和度的API文档:kubectl explain pod.spec.affinity.podAntiAffinity

3.2.NodeAffinityPriority

我们称之为node亲和度,pod对node的亲和性,表示是否愿意调度到某个node上,其也细分为以下两种:

硬亲和(required):使用requiredDuringSchedulingIgnoredDuringExecution字段定义,如果条件都不满足,则不调度,Pod对象的状态会一直是Pending状态
软亲和(preferred):使用preferredDuringSchedulingIgnoredDuringExecution字段定义,如果条件都不满足,也会从中按照打分,“勉为其难”的选择一个进行调度

node亲和度的api文档:kubectl explain pod.spec.affinity.nodeAffinity

4.示例:PodAffinity

上面,我提到过pod亲和度的定义,我们再来回顾一下:

pod亲和度,pod对pod的亲和性,表示是否愿意与相关pod调度在一个区域(可以是node、机架、也可以是机房),如何定义同一区域,则需要使用topologyKey(v1.16特性)进行标识。

我们先一起来看一下这个例子:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-with-preferred-pod-affinity
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      name: myapp
      labels:
        app: myapp
    spec:
      affinity:
        podAffinity:           #pod亲和性
          preferredDuringSchedulingIgnoredDuringExecution:    #软亲和
          - weight: 80
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - {key: app, operator: In, values: ["db"]}
              topologyKey: rack
          - weight: 20
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - {key: app, operator: In, values: ["db"]}
              topologyKey: zone
      containers:
      - name: myapp
        image: nginx

上面这个例子表示:
1.定义了一个pod软亲和:preferredDuringSchedulingIgnoredDuringExecution
2.软亲和条件有2个,app标签中是否存在值为db的pod资源,但优先度不同;前者80,后者只有20
3.同一位置指标的定义为topologyKey,一个为rack,另一个为zone

可能你还是有点困惑,这里对于调度的情况我再来归纳一下:

该deployment定义了3个pod,其更愿意调度至存在app=db标签的pod的同一个机柜(rack),其次之选则是会选择调度至存在app=db标签的pod的同一个区域(zone)。
此时他们对同一位置的解释是截然不同的,现在你是否理解了呢?

5.示例:NodeAffinity

这里,我们也再次回顾一下概念,增强记忆。

node亲和度,pod对node的亲和性,表示是否愿意调度到某个node上,也细分为硬亲和和软亲和。

我们现在直接来看下面这个例子,其中:
1.定义了一个软亲和:preferredDuringSchedulingIgnoredDuringExecution
2.表示最期望调度至zone=foo的节点上
3.次期望调度至存在ssd标签的节点

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy-with-node-affinity
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      name: myapp-pod
      labels:
        app: myapp
    spec:
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:         #软亲和
          - weight: 60
            preference:
              matchExpressions:
              - {key: zone, operator: In, values: ["foo"]}
          - weight: 30
            preference:
              matchExpressions:
              - {key: ssd, operator: Exists, values: []}
      containers:
      - name: myapp
        image: nginx

6.表达式的优先级辨析

        我们在实际使用过程中,很可能会使用多个表达式来限制调度的期望,可能是多个标签的过滤、也可能是多个表达式的拼接。
那么这些表达式的优先级是怎么样的呢,如果你没搞明白直接操作,会带来意想不到的后果的!(不建议)

我们先来看一个demo:

apiVersion: v1
kind: Pod
metadata:
  name: required-nodeAffinity-pod-or
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:           #硬亲和
        nodeSelectorTerms:
        - matchExpressions:               #matchExpressions级别是或关系(or)
          - {key: zone, operator: In, values: ["foo"]}   我们是(and)与关系,需要都满足
          - {key: zone, operator: In, values: ["bar"]}   我们是(and)与关系,需要都满足
        - matchExpressions:               #matchExpressions级别是或关系(or)
          - {key: ssd, operator: Exists, values: []}
  containers:
  - name: myapp
    image: nginx
    resources:
      requests:
        cpu: 6
        memory: 20Gi

你可以看到,这是一个多条件的硬亲和例子,对于其中的优先级是这样的:

key级别:是与关系(and)
matchExpressions级别:是或关系(or)

@版权声明:51CTO独家出品,未经允许不能转载,否则追究法律责任

版权声明:
作者:WaterBear
链接:https://l-t.top/2058.html
来源:雷霆运维
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>
文章目录
关闭
目 录