Node节点亲和性,Pod节点亲和性,污点和容忍度测试
####Node节点亲和性####
查看资源类型help
kubectl explain pods.spec.affinity
Node节点选择器
创建pod.yaml
指定nodeName/nodeSelector
spec:
nodeName: Node1
spec:
nodeSelector:
disk:ceph //需要给node打标签
#查看全部node节点包含指定标签的node
kubectl get nodes -l "zone=bar"
#添加node标签
kubectl label nodes node01 disk=ceph
#删除label
kubectl label nodes node01 disk-
#修改label的值
kubectl label nodes node01 disk-ceph2 --overwrite
#查看全部node标签
kubectl get node --show-labels
#查看指定node节点标签
kubectl get nodes node01 --show-labels
污点和容忍度
node节点亲和性:kubectl explain pods.spec.affinity.nodeAffinity
preferredDuringSchedulingIgnoredDuringExecution //表示有节点尽量满足这个位置定义的亲和性,这不是一个必须的条件,软亲和性
requiredDuringSchedulingIgnoredDuringExecution //表示必须有节点满足这个位置定义的亲和性,这是个硬性条件,硬亲和性
硬亲和性 //kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms
我们检查当前节点中有任意一个节点拥有zone标签的值是foo或者bar,就可以把pod调度到这个node节点的foo或者bar标签上的节点上
[root@master01 yaml]# cat pod-nodeaffinity-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-node-affinity-demo
namespace: default
labels:
app: myapp
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: zone
operator: In
values:
- foo
- bar
软亲和性 //kubectl explain pods.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution
即使node没有标签也是会调度的
[root@master01 yaml]# cat pod-nodeaffinity-demo-2.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-node-affinity-demo-2
namespace: default
labels:
app: myapp
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- preference:
matchExpressions:
- key: zone1
operator: In
values:
- foo1
- bar1
weight: 60
####Pod节点亲和性####
pod自身的亲和性调度有两种表示形式 (Pod需要labelSelector)
podaffinity:pod和pod更倾向腻在一起,把相近的pod结合到相近的位置,如同一区域,同一机架,这样的话pod和pod之间更好通信,比方说有两个机房,这两个机房部署的集群有1000台主机,那么我们希望把nginx和tomcat都部署同一个地方的node节点上,可以提高通信效率;
podunaffinity:pod和pod更倾向不腻在一起,如果部署两套程序,那么这两套程序更倾向于反亲和性,这样相互之间不会有影响。
kubectl explain pods.spec.affinity.podAffinity
requiredDuringSchedulingIgnoredDuringExecution: 硬亲和性
preferredDuringSchedulingIgnoredDuringExecution:软亲和性
例1:pod节点亲和性
定义两个pod,第一个pod做为基准,第二个pod跟着它走
[root@master01 yaml]# cat pod-required-affinity-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-first
labels:
app2: myapp2
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
---
apiVersion: v1
kind: Pod
metadata:
name: pod-second
labels:
app: backend
tier: db
spec:
containers:
- name: busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ["sh","-c","sleep 3600"]
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- {key: app2, operator: In, values: ["myapp2"]}
topologyKey: kubernetes.io/hostname
[root@master01 yaml]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-first 1/1 Running 0 10s 100.95.185.204 node02 <none> <none>
pod-second 1/1 Running 0 10s 100.95.185.205 node02 <none> <none>
例2:pod节点反亲和性
定义两个pod,第一个pod做为基准,第二个pod跟它调度节点相反
[root@master01 yaml]# cat pod-required-anti-affinity-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-first
labels:
app1: myapp1
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
---
apiVersion: v1
kind: Pod
metadata:
name: pod-second
labels:
app: backend
tier: db
spec:
containers:
- name: busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ["sh","-c","sleep 3600"]
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- {key: app1, operator: In, values: ["myapp1"]}
topologyKey: kubernetes.io/hostname
#例3. 修改 topologykey (第一个pod调度到zone标签节点后,第二个pod无法调度zone标签节点)
kubectl label nodes node1 zone=foo
kubectl label nodes node2 zone=foo --overwrite
[root@master01 yaml]# cat pod-first-required-anti-affinity-demo-1.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-first
labels:
app3: myapp3
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
[root@master01 yaml]# cat pod-second-required-anti-affinity-demo-1.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-second
labels:
app: backend
tier: db
spec:
containers:
- name: busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ["sh","-c","sleep 3600"]
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- {key: app3 ,operator: In, values: ["myapp3"]}
topologyKey: zone
第二个节点现是pending,因为两个节点是同一个位置,现在没有不是同一个位置的了,而且我们要求反亲和性,所以就会处于pending状态,如果在反亲和性这个位置把required改成preferred,那么也会运行。
podaffinity:pod节点亲和性,pod倾向于哪个pod
nodeaffinity:node节点亲和性,pod倾向于哪个node
####污点和容忍度####
给了节点选择的主动权,节点打一个污点,不容忍的pod就运行不上来,污点就是定义在节点上的键值属性数据,可以定决定拒绝那些pod;
taints是键值数据,用在节点上,定义污点;
tolerations是键值数据,用在pod上,定义容忍度,能容忍哪些污点
pod亲和性是pod属性;但是污点是节点的属性,污点定义在nodeSelector上
kubectl explain node.spec.taints
[root@master01 yaml]# kubectl explain node.spec.taints
KIND: Node
VERSION: v1
RESOURCE: taints <[]Object>
DESCRIPTION:
If specified, the node's taints.
The node this Taint is attached to has the "effect" on any pod that does
not tolerate the Taint.
FIELDS:
effect <string> -required-
Required. The effect of the taint on pods that do not tolerate the taint.
Valid effects are NoSchedule, PreferNoSchedule and NoExecute.
key <string> -required-
Required. The taint key to be applied to a node.
timeAdded <string>
TimeAdded represents the time at which the taint was added. It is only
written for NoExecute taints.
value <string>
The taint value corresponding to the taint key.
taints的effect用来定义对pod对象的排斥等级(效果):
NoSchedule:
仅影响pod调度过程,当pod能容忍这个节点污点,就可以调度到当前节点,后来这个节点的污点改了,加了一个新的污点,使得之前调度的pod不能容忍了,那这个pod会怎么处理,对现存的pod对象不产生影响
NoExecute:
既影响调度过程,又影响现存的pod对象,如果现存的pod不能容忍节点后来加的污点,这个pod就会被驱逐
PreferNoSchedule:
最好不,也可以,是NoSchedule的柔性版本
在pod对象定义容忍度的时候支持两种操作:
1.等值密钥:key和value上完全匹配
2.存在性判断:key和effect必须同时匹配,value可以是空
在pod上定义的容忍度可能不止一个,在节点上定义的污点可能多个,需要逐个检查容忍度和污点能否匹配,每一个污点都能被容忍,才能完成调度,如果不能容忍怎么办,那就需要看pod的容忍度了
管理节点污点
[root@xianchaomaster1]# kubectl taint –help
例1:把node02当成是生产环境专用的,其他node是测试的
kubectl taint node node02 node-type=production:NoSchedule //执行前的运行的pod不影响,再次新建pod如不添加污点无法调度成功。
例2: node01 污点 kubectl taint node node01 node-type=dev:NoExecute //node01 当前存在的pod全部驱逐
[root@master01 yaml]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-first 1/1 Running 0 97m 100.95.185.207 node02 <none> <none>
pod-second 0/1 Terminating 1 96m 100.117.144.133 node01 <none> <none>
[root@master01 yaml]# cat pod-demo-1.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-deploy
namespace: default
labels:
app: myapp
release: canary
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
tolerations:
- key: "node-type"
operator: "Equal"
value: "production"
effect: "NoExecute"
tolerationSeconds: 3600
[root@master01 yaml]# kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-deploy 0/1 Pending 0 2m6s
pod-first 1/1 Running 0 102m
Warning FailedScheduling <unknown> default-scheduler 0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 1 node(s) had taint {node-type: dev}, that the pod didn't tolerate, 1 node(s) had taint {node-type: production}, that the pod didn't tolerate.
Warning FailedScheduling <unknown> default-scheduler 0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 1 node(s) had taint {node-type: dev}, that the pod didn't tolerate, 1 node(s) had taint {node-type: production}, that the pod didn't tolerate.
还是显示pending,因为我们使用的是equal(等值匹配),所以key和value,effect必须和node节点定义的污点完全匹配才可以,把上面配置effect: "NoExecute"变成
effect: "NoSchedule"成;
tolerationSeconds: 3600这行去掉
修改后正常启动yaml
[root@master01 yaml]# cat pod-demo-1.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-deploy
namespace: default
labels:
app: myapp
release: canary
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
tolerations:
- key: "node-type"
operator: "Equal"
value: "production"
effect: "NoSchedule"
例3:再次修改(只要对应的键是存在的,exists,其值被自动定义成通配符)
apiVersion: v1
kind: Pod
metadata:
name: myapp-deploy
namespace: default
labels:
app: myapp
release: canary
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
tolerations:
- key: "node-type"
operator: "Exists"
value: ""
effect: "NoSchedule"
例4:再次修改(有一个node-type的键,不管值是什么,不管是什么效果,都能容忍)
[root@master01 yaml]# cat pod-demo-1.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-deploy
namespace: default
labels:
app: myapp
release: canary
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
tolerations:
- key: "node-type"
operator: "Exists"
value: ""
effect: ""
删除污点
[root@master01 yaml]# kubectl taint nodes node01 node-type:NoExecute-
node/node01 untainted
[root@master01 yaml]# kubectl taint nodes node02 node-type-
node/node02 untainted
https://www.cnblogs.com/cheyunhua/p/15899059.html