目录
调度过程
如果nodeSelectorTterm下面有多个选项的话,满足任何一个条件就可以了,如果matchExpressions有多个选项的话,则必须同时满足这些条件才能正常调度
亲和性
举例:如果把班级当作node,把同桌当作pod,分班了,我想去王老师所在的班级(节点亲和性),张三说我必须要去王老师的班级,不去不行(硬策略),李四说,我比较喜欢王老师,我想去王老师的班级,我能不能去王老师的班级(软策略)。分到了王老师的班级以后,我原来的同桌是小红,我能不能(我一定要)还去和小红坐同桌(pod亲和性)
节点亲和性
pod.spec.nodeAffinity
preferredDuringSchedulingIgnoredDruingExecution:软策略
requiredDuringSchedulingIgnoredDruingExecution: 硬策略
- requiredDuringSchedulingIgnoredDruingExecution: 硬策略
apiVersion: v1
kind: Pod
metadata:
name: affinity #po名字
labels:
app: node-affinity-pod #设置pod标签
spec:
containers:
- name: with-node-affinity #容器的名字
image: busybox #容器使用的镜像
command: ["/bin/sh", "-c", "sleep 6000s"] #启动容器执行指令使之在前台运行
affinity: #设置pod的参数策略
nodeAffinity:
requiredDuringSchedulingIgnoredDruingExecution: #硬亲和性
#preferredDuringSchedulingIgnoredDruingExecution: #软亲和性
nodeSelectorTerms:
- matchExpressions: #当node01的存在key=values键值对时候就能满足matchExpression匹配表达式,即是满足条件的节点
- key: values
operator: In #选择是在node上创建pod 如过设置为NotIn,那么就不在这个node上创建pod
values:
- node01 #选择节点
执行结果:先通过上面yaml文件创建pod,此时会绑定一个节点例如node0,执行kubectl delete pod --all删除所有的pod后,再次通过yaml文件创建pod时,kubectl get pods 会发现pod还是在node0上,即实现了节点的硬亲和性(节点绑定)。如果系统中没有这个node0节点,那么pod将不会被创建,一直处于pending等待状态(脾气很倔)。
- preferendDuringSchedulingIgnoredDruingExecution:软策略
apiVersion: v1
kind: Pod
metadata:
name: affinity #po名字
labels:
app: node-affinity-pod #设置pod标签
spec:
containers:
- name: with-node-affinity #容器的名字
image: busybox #容器使用的镜像
command: ["/bin/sh", "-c", "sleep 6000s"] #启动容器执行指令使之在前台运行
affinity: #设置pod的参数策略
nodeAffinity:
#preferredDuringSchedulingIgnoredDruingExecution: #硬亲和性
preferredDuringSchedulingIgnoredDruingExecution: #软亲和性
- weight: 1 #如果有多个硬策略,会优先匹配权重更高,更亲和的node节点去创建pod
preference:
matchExpressions:
- key: values #当node01的存在key=values键值对时候就能满足matchExpression匹配表达式,即是满足条件的节点
operator: In #选择是在node上创建pod 如过设置为NotIn,那么就不在这个node上创建pod
values:
- node02 #选择节点
对于软亲和策略,比如想选择node1节点,但是系统中没有这个节点,那么它就会随机选择一个节点代替,无论如何都会成功的创建pod
可以合并创建
apiVersion: v1
kind: Pod
metadata:
name: affinity #po名字
labels:
app: node-affinity-pod #设置pod标签
spec:
containers:
- name: with-node-affinity #容器的名字
image: busybox #容器使用的镜像
command: ["/bin/sh", "-c", "sleep 6000s"] #启动容器执行指令使之在前台运行
affinity: #设置pod的参数策略
nodeAffinity:
requiredDuringSchedulingIgnoredDruingExecution: #硬亲和性
#preferredDuringSchedulingIgnoredDruingExecution: #软亲和性
nodeSelectorTerms:
- matchExpressions: #当node01的存在key=values键值对时候就能满足matchExpression匹配表达式,即是满足条件的节点
- key: values
operator: In #选择是在node上创建pod 如过设置为NotIn,那么就不在这个node上创建pod
values:
- node01 #选择节点
preferredDuringSchedulingIgnoredDruingExecution: #软亲和性
- weight: 1 #如果有多个硬策略,会优先匹配权重更高,更亲和的node节点去创建pod
preference:
matchExpressions:
- key: values #当node01的存在key=values键值对时候就能满足matchExpression匹配表达式,即是满足条件的节点
operator: In #选择是在node上创建pod 如过设置为NotIn,那么就不在这个node上创建pod
values:
- node02 #选择节点
pod亲和性
pod.spec.affinity.podAffinity/podAntiAffinity
- preferredDuringSchedulingIgnoredDruingExecution:软策略
- requiredDuringSchedulingIgnoredDruingExecution: 硬策略
apiVersion: v1
kind: Pod
metadata:
name: Pod03 #po名字
labels:
app: Pod03 #设置pod标签
spec:
containers:
- name: with-node-affinity #容器的名字
image: busybox #容器使用的镜像
command: ["/bin/sh", "-c", "sleep 6000s"] #启动容器执行指令使之在前台运行
affinity: #设置pod的参数策略
podAffinity:
#requiredDuringSchedulingIgnoredDruingExecution: #硬亲和性
preferredDuringSchedulingIgnoredDruingExecution: #软亲和性
- labelSelector:
matchExpressions:
- key: source
operator: In #选择是在node上创建pod 如过设置为NotIn,那么就不在这个node上创建pod
values:
- pod01 #选择pod
topologyKey: kubernetes.io/hostname #是以hostname为主要目标,键名判断是否在同一个pod之上
podAntiAffinity: #调度目标方式,不与指定node在同一拓扑区域
#preferredDuringSchedulingIgnoredDruingExecution: #硬亲和性
preferredDuringSchedulingIgnoredDruingExecution: #软亲和性
- weight: 1 #如果有多个硬策略,会优先匹配权重更高,更亲和的node节点去创建pod
podAffinityTerm:
labelSelector:
matchExpressions:
- key: source
operator: In #选择是在node上创建pod 如过设置为NotIn,那么就不在这个node上创建pod
values:
- pod02 #选择节点
topologyKey: kubernetes.io/hostname #拓扑键值判断,是以hostname为主要目标,键名判断是否在同一个pod之上
污点和容忍
例子:小明睡觉打呼噜(Taint污点),小华说可以接受小明打呼噜和他做室友(Toleration),小刚却没办法容忍室友打呼噜,不愿与小明做室友
可以查看本机的污点情况
kubectl describe node yourNodeName
#找到Taints,可以看到键名与键值的设置
可以看到master的Taint的策略是NoSchedule,这也是为什么创建的pod不会部署到master节点上的原因
NoExecute污点还会将node中的pod全部踢出去,如果在这个节点创建pod会一直显示pending状态,即无法创建
容忍(Toleration)
apiVersion: v1
kind: Pod
metadata:
name: Pod04 #po名字
labels:
app: Pod04 #设置pod标签
spec:
containers:
- name: pod04 #容器的名字
image: busybox #容器使用的镜像
command: ["/bin/sh", "-c", "sleep 6000s"] #启动容器执行指令使之在前台运行
tolerations: #设置容忍
- key: "key1" # key\value\effect值和node上设置的taint保持一致
operator: "Equal"
value: "value1"
effect: "NoSchedule"
tolerationSeconds: 3600 #容忍多久,即保留运行的时常,时间一到就无法容忍会被剔除
可以在创建yaml文件中加入tolerations进行污点容忍,比如容忍NoExecute,就可以顺利的进行pod的创建
Ⅲ:当所有节点都不可用时,就可以在master上部署pod
固定节点调度
指定调度节点
通过指定节点的名称或者节点的标签,固定的部署到某个节点上
- 方法1:Pod.spec.nodeName将Pod直接调度到指定的Node节点上,会跳过Scheduler的调度策略,该匹配规则是强匹配
apiVersion: v1
kind: Deployment
metadata:
name: Pod04 #po名字
labels:
app: Pod04 #设置pod标签
spec:
replicas: 7 #创建成功后发现副本全在设置的node01下面
template:
metadata:
labels:
app: myapp
spec:
nodeName: yourNodeName #选择你的node节点的名称,这里假设为node01
containers:
- name: pod04 #容器的名字
image: busybox #容器使用的镜像
command: ["/bin/sh", "-c", "sleep 6000s"] #启动容器执行指令使之在前台运行
- 方法2:Pod.spec.nodeSelector:通过kubernetes的label-selector机制选择节点,由调度器调度策略匹配label,而后调度Pod到目标节点,该匹配规则属于强制约束
apiVersion: v1
kind: Deployment
metadata:
name: Pod05 #po名字
labels:
app: Pod05 #设置pod标签
spec:
replicas: 3
template:
metadata:
labels:
app: myapp5
spec:
nodeSelector: #标签键名的匹配选择,必须匹配键名和键值,即进行节点的匹配
key: value #能匹配上的标签就行,比如disk: ssd 就必须是ssd硬盘才行,使用kubectl label node yourNodename disk=ssd进行打标签
containers:
- name: pod05 #容器的名字
image: busybox #容器使用的镜像
command: ["/bin/sh", "-c", "sleep 6000s"] #启动容器执行指令使之在前台运行
注意:key: value #能匹配上的标签就行,比如disk: ssd 就必须是ssd硬盘才行,使用kubectl label node yourNodename disk=ssd
对节点进行打标签,可以进行实验对比,没有打标签前,pod创建一直处于pending状态,打上标签后,pod立即热更新就创建成功了。