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中有三个需要定义的字段,分别是 key、operator和values
    key:选择器应用于的标签键
    operator:操作符,而操作符分为集合标签(In、NotIn、Exists)和等值标签(DoesNotExist、Gt、Lt)使用Exists和DoesNotExist时value需要为空,不能有值。
    values:定义标签的值,与上面key互为键值对,值可以有多个,比如上面键为test值分别为1、2。意为节点标签存在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 日
如果觉得我的文章对你有用,请随意赞赏