default_Scheduler默认分三步实现调度过程:
Predicate(预选) --> Priority(优选) --> Select(选定)
高级调度设置机制分为以下两类:
一、节点选择器:

nodeSelector , nodeName 1、nodeSelector: 给一部分节点打上特有标签,而后在Pod.space.nodeSelector去匹配这些标签,节点能适配这些标签的就是Pod能运行的节点之一,否则就不是 2、nodeName: 如果我们期望把Pod调度的某一特定节点上,在Pod.space.nodeName属性当中直接给定node的名称即可

注意:这种方式会极大的缩小预选范围
举例:

apiVersion: v1 Kind: Pod matadata: name: Pod-demo lables: app: myapp tier: fronted spec: containers: - name: myapp image: ikubernetes/myapp:v1 nodeSelector: desktype:ssd 以上Pod一定只能在拥有节点标签为desktype:ssd的节点上运行

查看节点标签:

kubectl get nodes --show-lables

如果创建时Pod中指定的nodeSelector在集群中是不存在的,那么这个Pod会一直处于Pinding状态,因为调度是无法成功的,nodeSelector是一种强约束。
二、节点亲和调度:
1、Affinty
亲和度包括节点亲和(nodeAffinty),Pod亲和度(podAffinty)和Pod反亲和度(podAntiAffinty)位置位于:pods.space.affinity.nodeaffinity

1)、nodeaffinity包括软亲和性和硬亲和性 preferredDuringSchedulingIgnoredDuringExecution(软亲和): 尽量满足其定义的需求,如果没有满足其定义的需求也可以运行,软亲是一个对象列表 requiredDuringSchedulingIgnoredDuringExecution(硬亲和):必须需要满足其定义的要求,否者不会被调度,处于Pinding状态。硬亲和是一个对象 requiredDuringSchedulingIgnoredDuringExecution(硬亲和)的定义方式: 在requiredDuringSchedulingIgnoredDuringExecution(硬亲和)中只有一个需要定义的对象 nodeSelectorTerms:对象列表且必须要定义。 在nodeSelectorTerms下有两个需要定义的对象,分别是matchExpressions和matchFields。 matchExpressions:匹配表达式。 matchFields:节点字段,需要在节点字段中进行定义。 在matchFields中有三个需要定义的字段,分别是 keyoperator和values key:选择器应用于的标签键 operator:操作符,而操作符分为集合标签(In、NotIn、Exists)和等值标签(DoesNotExist、Gt、Lt)使用Exists和DoesNotExist时value需要为空,不能有值。 values:定义标签的值,与上面key互为键值对,值可以有多个,比如上面键为test值分别为12。意为节点标签存在test:1和test:2时都能被调度

举例:

apiVersion: v1 kind:Pod metadata: name:Pod-node-affinity-demo labels: app:myapp tier:frontend spec: containers: - name:myapp image:ikubernetes/myapp:v1 affinity: nodeaffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: test operator: In values: - foo - bar 此配置只能在节点中拥有test标签且标签值是foo或bar时才能被调度,否者就会一直处于Pending状态

preferredDuringSchedulingIgnoredDuringExecution(软亲和)的定义方式:
软亲和中需要定义的选项参数有两个分别是preference和weight

preference:定义倾向的节点, weight:上面的倾向性有多高是由此处决定,而此处定义需要在1-100中取所需要的数值来表示倾向性

举例:

apiVersion: v1 kind:Pod metadata: name:Pod-node-affinity-demo labels: app:myapp tier:frontend spec: containers: - name:myapp image:ikubernetes/myapp:v1 affinity: nodeaffinity: preferredDuringSchedulingIgnoredDuringExecution: - preference: matchExpressions: - key: test operator: In values: - foo - bar weight: 60 #此处可以不写

此配置在节点中拥有test标签且标签值是foo或bar时被调度到该节点上,如果没有符合此标签的节点也可被调度。

三、Pod亲和调度:
1、Pod亲和性与node亲和性相比,pod亲和性并不强制,而是在其相邻节点运行就可以
以节点名称为不同位置,每个节点都不同,因此每个节点都是独特的位置。
以标签为位置,同样的标签为同一位置,这样才可以判断哪些满足亲和性以及其他调度属性
在Pod中也有软硬亲和性之分:

pods.spec.affinity.podAffinity:

preferredDuringSchedulingIgnoredDuringExecution(软亲和)和requiredDuringSchedulingIgnoredDuringExecution(硬亲和)

requiredDuringSchedulingIgnoredDuringExecution(硬亲和)的定义方式: labelSelector:选择一组Pod的标签 namespaces: 指定labelSelector应用于哪个名称空间;null或空列表表示“此pod的名称空间” topologyKey: 位置拓扑键,用来判断是否在同一位置,只能存在一个且必须定义

举例:

apiVersion: v1 kind:Pod metadata: name: pod-first labels: app:myapp tier:frontend spec: containers: - name:myapp image: ikubernetes/myapp:v1 --- apiVersion: v1 kind:Pod metadata: name: pod-second labels: app:db tier:db spec: containers: - name:busybox image: busybox:latest imagePullPolicy: IfNotPresent command: ["sh","-c","sleep 3600"] affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - myapp topologyKey: kubernetes.io/hostname #检查两个Pod所在节点的主机名称是否一致

以上yaml执行后会在一个节点上创建。

2、Pod反亲和调度

apiVersion: v1 kind:Pod metadata: name: pod-first labels: app:myapp tier:frontend spec: containers: - name:myapp image: ikubernetes/myapp:v1 --- apiVersion: v1 kind:Pod metadata: name: pod-second labels: app:db tier:db spec: containers: - name:busybox image: busybox:latest imagePullPolicy: IfNotPresent command: ["sh","-c","sleep 3600"] affinity: podAntiAffinity: #反亲和度 requiredDuringSchedulingIgnoredDuringExecution: #硬亲和 - labelSelector: matchExpressions: - key: app operator: In values: - myapp topologyKey: kubernetes.io/hostname #检查两个Pod所在节点的主机名称是否一致

以上yaml执行后一定不会在同一个节点之上运行。

四、污点调度
后端倾向度,让pod进行选择,节点是被动选择,给予了节点的选择权,选择让那些pod进行调度到节点
在kubernetes中键值属性数据分为三类:

①标签 ②注解 ③污点

污点一般用在节点之上(node.spec),而标签和注解所有资源对象都可以使用
在node.spec当中可以定义Pod使用的IP地址段(podCIDR)和taints(污点)
定义taints的方式:

effect: 用来定义当Pod不能容忍这个污点时,需要采取的行为是什么

三种行为:

NoSchedule:仅影响调度过程,对现存的Pod不产生影响; NoExecute: 既影响调度过程,也影响现存的Pod对象,不容忍的Pod对象将被驱逐 PreferNoSchedule:NoSchedule的柔性版本,不能容忍就不能调度过来,但是如果没地方调度也可以在此节点上运行。 key: 键与value相呼应 必须定义 value: 值与key相呼应,值可不定义

在Pod定义容忍度的时候有两种选择:

等值比较: 容忍度与污点必须在key、value和effect完全匹配。Equal 存在性判断:二者的key和effect必须匹配,value可以使用空值。Exists

operator: “Exists” #可以写Exists或者Equal,Exists表示只要有key就可以,值一样不一样无关紧要,而Equal表示精准匹配,不光得有key而且value必须是相同的才可以
一个节点可以有多个污点,一个Pod可以有多个容忍。
节点的每一个污点都要被容忍,如果有一个不能容忍,那么就得看污点的效果是什么,也就是上方写到effect的三种行为。
在Pod定义容忍度的时候如果写上CriticalAddonsOnly(附件)时Pod是可以被调度到master上运行的,附件中包含了master的污点node-role.kubernetes.io/master

管理节点中的污点:
语法格式:

kubectl taint NODE NAME KEY_1=VAL_1:TAINT_EFFECT_1...KEY_N=VAL_N:TAINT_EFFECT_N(options)

举例把node1设置为生产环境专用的其他Pod不能调度到本节点,对现存的Pod不影响:

kubectl taint node node1 node-type=production:NoSchedule

此时创建的Pod不定义容忍度,默认不会被调度到node1,而会被调度到其他节点。
如果想让Pod被调度到node1时必须要定义容忍度:

apiVersion: v1 kind:deployment metadata: name:myapp spec: replicas: 3 selector: matchLabels: app:myapp template: metadata: labels: app:myapp spec: containers: - name: myapp image:ikubernetes/myapp:v1 ports: - name: http containerPort: 80 tolerations: - key: "node-type" #node1的污点名称 operator: "Equal" #等值比较 定义为Exists时需要把value设置为空值,value: "" value: "production" #node的污点值 effect: "NoSchedule" #node1的污点效果,效果为空时,默认容忍所有污点 effect: "" #tolerationSeconds:TIME 此项只有污点为NoExecute时才会生效否者会报语法错误。
最后修改:2023 年 06 月 09 日
如果觉得我的文章对你有用,请随意赞赏