Taints(污点)存在于node,Tolerations(容忍度)存在于pod。
污点(Taint)
污点(Taint)的组成
使用kubectl taint
命令可以给某个Node节点设置污点,Node被设置上污点之后就和Pod之间存在了一种相斥的关系,可以让Node拒绝Pod的调度执行,甚至将Node已经存在的Pod驱逐出去。
每个污点的组成如下:
key=value:effect
每个污点有一个key和value作为污点的标签,其中value可以为空,effect描述污点的作用。当前taint effect支持如下三个选项:
-
NoSchedule
:表示k8s将不会将Pod调度到具有该污点的Node上 -
PreferNoSchedule
:表示k8s将尽量避免将Pod调度到具有该污点的Node上 -
NoExecute
:表示k8s将不会将Pod调度到具有该污点的Node上,同时会将Node上已经存在的Pod驱逐出去
污点的设置和去除
查看node污点
$ kubectl get nodes node-1 -o yaml
-
spec:
podCIDR: 10.240.0.0/24
podCIDRs:
- 10.240.0.0/24
taints:
- effect: NoExecute
key: department
value: dev
- effect: NoSchedule
key: department
value: dev
使用kubectl设置和去除污点的命令示例如下:
# 设置污点
kubectl taint nodes node1 key1=value1:NoSchedule
# 修改污点
kubectl taint nodes node-1 department=dev:NoSchedule
# 去除污点
kubectl taint nodes node1 key1:NoSchedule-
容忍(Tolerations)
设置了污点的Node将根据taint的effect:NoSchedule、PreferNoSchedule、NoExecute和Pod之间产生互斥的关系,Pod将在一定程度上不会被调度到Node上。 但我们可以在Pod上设置容忍(Toleration),意思是设置了容忍的Pod将可以容忍污点的存在,可以被调度到存在污点的Node上。
通过在Pod的spec中设置tolerations字段,给Pod设置上容忍点Toleration:
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"
- 其中key, vaule, effect要与Node上设置的taint保持一致
- operator的值为Exists将会忽略value值
- tolerationSeconds用于描述当Pod需要被驱逐时可以在Pod上继续保留运行的时间
下面看一下在Pod上设置容忍的两个特例:
示例1: 当不指定key值时,表示容忍所有的污点key:
tolerations:
- operator: "Exists"
示例2:当不指定effect值时,表示容忍所有的污点作用:
tolerations:
- key: "key"
operator: "Exists"
污点和容忍度示例
集群信息
# 获取集群节点
$ kubectl get nodes
-
NAME STATUS ROLES AGE VERSION
node-1 Ready <none> 70d v1.16.3
node-2 Ready <none> 70d v1.16.3
node-3 Ready <none> 70d v1.16.3
给 node-3节点打上污点(key=department、value=ops、effect=NoSchedule)
# 不允许非法pod调度上来,修改污点后,不会驱逐非法pod(key=department、value=ops、effect=NoSchedule)
$ kubectl taint nodes node-3 department=ops:NoSchedule
-
node/node-3 tainted
以DaemonSet部署一个nginx实例
# 以DaemonSet方式部署
$ kubectl apply -f deploy-nginx.yaml
-
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-1
namespace: default
labels:
web: nginx-1
spec:
selector:
matchLabels:
web: nginx-1
template:
metadata:
labels:
web: nginx-1
spec:
containers:
- name: nginx-1
image: nginx:1.17
ports:
- containerPort: 80
# 查看实例
$ kubectl get pod -o wide
-
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-1-2x6xs 1/1 Running 0 3s 10.240.2.36 node-1 <none> <none>
nginx-1-jvjzg 1/1 Running 0 3s 10.240.1.41 node-3 <none> <none>
结论: nginx实例没有在 node-3节点上部署,污点配置生效。
增加容忍度参数,重新部署nginx实例
# 先删除前面部署的nginx镜像,然后增加容忍度(Tolerations),重新部署
$ kubectl apply -f deploy.yaml
-
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-1
labels:
web: nginx-1
spec:
selector:
matchLabels:
web: nginx-1
template:
metadata:
labels:
web: nginx-1
spec:
containers:
- name: nginx-1
image: nginx:1.17
ports:
- containerPort: 80
tolerations:
- key: "department"
operator: "Equal"
value: "ops"
effect: "NoSchedule"
# 查看实例
$ kubectl get pod -o wide
-
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-1-gz8rn 1/1 Running 0 6s 10.240.1.42 node-1 <none> <none>
nginx-1-j4c5v 1/1 Running 0 6s 10.240.0.47 node-2 <none> <none>
nginx-1-nvxbc 1/1 Running 0 6s 10.240.2.37 node-3 <none> <none>
结论: nginx实例运行在 node-3节点上,新的容忍度配置生效。