当我们使用节点亲和力(Pod 的一个属性)时,它会将Pod吸引到一组节点(作为偏好或硬性要求)。污点的行为完全相反,它们允许一个节点排斥一组 Pod。
在 Kubernetes 中,您可以标记(污染)一个节点,以便在该节点上不能调度任何 Pod,除非它们应用了明确的容忍度。Tolerations 应用于 Pod,并允许(但不要求)Pod 调度到具有匹配污点的节点上。
污点和容忍度协同工作可确保 Pod 不会被调度到不合适的节点上。
key=value:Effect
可以分配三个不同的值effect:
kubectl taint nodes key=value:effect
看看不同节点上已经运行的 pod
root@kube-master:~# kubectl get pods -o wide
查看节点污点
kubectl describe node node01.k8s.org |grep Taint
删除污点
kubectl describe node node01.k8s.org |grep Taint
kubectl taint node node01.k8s.org test:NoSchedule-
kubectl describe node node01.k8s.org |grep Taint
提示:删除污点可以指定对应节点上的污点的key和对应污点的effect,也可以直接在对应污点的key后面加“-”,表示删除对应名为对应key的所有污点;
pod容忍度定义
示例:创建一个pod,其容忍度为对应节点有 node-role.kubernetes.io/master:NoSchedule的污点
[root@master01 ~]# cat pod-demo-taints.yaml
apiVersion: v1
kind: Pod
metadata:
name: redis-demo
labels:
app: db
spec:
containers:
- name: redis
image: redis:4-alpine
ports:
- name: redis
containerPort: 6379
tolerations:
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
[root@master01 ~]#
提示:定义pod对节点污点的容忍度需要用tolerations字段定义,该字段为一个列表对象;其中key是用来指定对应污点的key,这个key必须和对应节点污点上的key相等;operator字段用于指定对应的操作符,即描述容忍度怎么匹配污点,这个操作符只有两个,Equal和Exists;effect字段用于描述对应的效用,该字段的值通常有三个,NoSchedule、PreferNoSchedule、NoExecute;这个字段的值必须和对应的污点相同;上述清单表示,redis-demo这个pod能够容忍节点上有node-role.kubernetes.io/master:NoSchedule的污点;
应用清单
[root@master01 ~]# kubectl apply -f pod-demo-taints.yaml
pod/redis-demo created
[root@master01 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
redis-demo 1/1 Running 0 7s 10.244.4.35 node04.k8s.org
提示:可以看到对应pod运行在node04上;这里需要注意,定义pod容忍度只是表示对应pod可以运行在对应有污点的节点上,并非它一定运行在对应节点上;它也可以运行在那些没有污点的节点上;
验证:删除pod,给node01,node02,03,04都打上test:NoSchedule的污点,再次应用清单,看看对应pod是否能够正常运行?
[root@master01 ~]# kubectl delete -f pod-demo-taints.yaml
pod "redis-demo" deleted
[root@master01 ~]# kubectl taint node node01.k8s.org test:NoSchedule
node/node01.k8s.org tainted
[root@master01 ~]# kubectl taint node node02.k8s.org test:NoSchedule
node/node02.k8s.org tainted
[root@master01 ~]# kubectl taint node node03.k8s.org test:NoSchedule
node/node03.k8s.org tainted
[root@master01 ~]# kubectl taint node node04.k8s.org test:NoSchedule
node/node04.k8s.org tainted
[root@master01 ~]# kubectl describe node node01.k8s.org |grep Taints
Taints: test:NoSchedule
[root@master01 ~]# kubectl describe node node02.k8s.org |grep Taints
Taints: test:NoSchedule
[root@master01 ~]# kubectl describe node node03.k8s.org |grep Taints
Taints: test:NoSchedule
[root@master01 ~]# kubectl describe node node04.k8s.org |grep Taints
Taints: test:NoSchedule
[root@master01 ~]# kubectl apply -f pod-demo-taints.yaml
pod/redis-demo created
[root@master01 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
redis-demo 1/1 Running 0 18s 10.244.0.14 master01.k8s.org
提示:可以看到对应pod,被调度到master节点上运行了;其原因是对应pod能够容忍master节点上的污点;对应其他node节点上的污点,它并不能容忍,所以只能运行在master节点;
删除对应pod中容忍度的定义,再次应用pod清单,看看对应pod是否会正常运行?
root@master01 ~]# kubectl delete pod redis-demo
pod "redis-demo" deleted
[root@master01 ~]# cat pod-demo-taints.yaml
apiVersion: v1
kind: Pod
metadata:
name: redis-demo
labels:
app: db
spec:
containers:
- name: redis
image: redis:4-alpine
ports:
- name: redis
containerPort: 6379
[root@master01 ~]# kubectl apply -f pod-demo-taints.yaml
pod/redis-demo created
[root@master01 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
redis-demo 0/1 Pending 0 6s
可以看到对应pod处于pending状态;其原因是对应pod没法容忍对应节点污点;即所有节点都排斥对应pod运行在对应节点上;