k8s学习(22):调度器-污点

Taint和Toleration(污点和容忍)

节点亲和性,是Pod的一种属性(偏好或硬性要求),它使Pod被吸引到一类特定的节点。Taint则相反,它使节点能够排斥一类特定的Pod

Taint和Toleration相互配合,可以用来避免Pod被分配到不合适的节点上。每个节点上都可以应用一个或多个taint,这表示对于那些不能容忍这些taint的pod,是不会被该节点接受的。如果将toleration应用于pod上,则表示这些pod可以(但不要求)被调度到具有匹配taint的节点上。

污点(Taint)

1 污点(taint)的组成

使用kubectl taint命令可以给某个Node节点设置污点,Node被设置上污点之后就和Pod之间存在一种互斥的关系,可以让Node拒绝Pod的调度执行,甚至将Node已经存在的Pod驱逐出去

每个污点的组成如下:

1
key=value:effect

每个污点有一个key和value作为污点的标签,其中value可以为空,effect描述污点的作用。当前taint effect支持如下三个选项:

  • NoSchedule:表示k8s不会将Pod调度到具有该污点的Node上
  • PreferNoSchedule:表示k8s尽量避免将Pod调度到具有该污点的Node上
  • Noexecute:表示k8s不会将Pod调度到具有该污点的Node上,同时会将Node上已经存在的Pod驱逐出去

master天生就被设置为污点NoSchedule

1
2
[root@k8s-master affinity]# kubectl describe node k8s-master|grep Taints
Taints: node-role.kubernetes.io/master:NoSchedule

2 污点的设置、查看和去除

1
2
3
4
5
6
7
8
# 设置污点
kubectl taint nodes node1 key1=value1:NoSchedule

# 节点说明中,查找Taints字段
kubectl describe pod pod-name

# 去除污点
kubectl taint nodes node1 key1:NoSchedule-

举个栗子

查看该节点上的pod所在的节点,然后设置该节点为NoExecute,可以看到该节点的Pod自动被删除

1
2
3
4
5
6
7
8
9
10
[root@k8s-master affinity]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
affinity-pod 1/1 Running 0 174m 10.244.1.117 k8s-node01 <none> <none>
affinity-pod-3 1/1 Running 0 58m 10.244.1.118 k8s-node01 <none> <none>
affinity-preferred 1/1 Running 0 155m 10.244.2.208 k8s-node02 <none> <none>
[root@k8s-master affinity]# kubectl taint nodes k8s-node01 check=test:NoExecute
node/k8s-node01 tainted
[root@k8s-master affinity]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
affinity-preferred 1/1 Running 0 155m 10.244.2.208 k8s-node02 <none> <none>

查看node01的taint

1
2
3
4
5
6
7
8
[root@k8s-master affinity]# kubectl describe node k8s-node01
...
...
...
Taints: check=test:NoExecute
...
...
...

容忍(Tolerations)

设置了污点的Node将根据taint的effect:NoSchedule、PreferNoschedule、NoExecute和Pod之间产生的互斥欢喜,Pod将一定程度上不会调度到Node上。但我们可以在Pod上设置容忍(Toleration),意思是设置了容忍的Pod将可以容忍污点的存在,可以被调度到存在污点的Node上

pod.spec.tolerations

1
2
3
4
5
6
7
8
9
10
11
12
13
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
tolerationSeconds: 3600
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
- key: "key2"
operator: "Exists"
effect: "NoSchedule"
  • 其中可以,value,effect要与Node上设置的taint保持一致
  • operator的值为Exists将会忽略value的值
  • tolerationSeconds用于描述当Pod需要被驱逐时可以在Pod上继续保留运行的时间

举个栗子

给node02也打上污点

1
2
3
4
5
6
7
[root@k8s-master affinity]# kubectl taint nodes k8s-node02 check=test:NoExecute
node/k8s-node02 tainted
[root@k8s-master affinity]# kubectl get pods
NAME READY STATUS RESTARTS AGE
affinity-preferred 0/1 Terminating 0 166m
[root@k8s-master affinity]# kubectl get pods -o wide
No resources found.

创建pod,可以看到pod处于pending状态,因为所有节点都有污点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@k8s-master ~]# cat pod.yaml 
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: app
image: hub.test.com/library/myapp:v1
[root@k8s-master ~]# kubectl create -f pod.yaml
pod/myapp created
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp 0/1 Pending 0 5s

其他属性

1 当不指定key值时,表示容忍所有的污点key:

1
2
tolerations:
- operator: "Exists"

2 当不指定effect值时,表示容忍所有的污点作用

1
2
3
tolerations:
- key: "key"
operator: "Exists"

3 有多个Master存在时,防止资源浪费,可以如下设置

1
kubectl taint nodes Node-Name node-role.kubernetes.io/master=:PreferNoSchedule

举个栗子

新建Pod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: Pod
metadata:
name: pod-taint-toleration
spec:
containers:
- name: pod-container
image: hub.test.com/library/myapp:v1
tolerations:
- key: "check"
operator: "Equal"
value: "test"
effect: "NoExecute"
tolerationSeconds: 3600
1
2
3
4
5
6
[root@k8s-master ~]# kubectl create -f pod.yaml 
pod/pod-taint-toleration created
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp 0/1 Pending 0 12m
pod-taint-toleration 1/1 Running 0 6s

如果某个node节点需要维护,可以打上NoExecute污点,待所有pod驱逐之后,即可进入维护