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时才会生效否者会报语法错误。
仅登录用户可评论,点击 登录