污点Taint和容忍Toleration
一、什么是Taint和Toleration
所谓污点就是故意给某个节点服务器上设置个污点参数,那么你就能让生成pod的时候使用相应的参数去避开有污点参数的node服务器。而容忍呢,就是当资源不够用的时候,即使这个node服务器上有污点,那么只要pod的yaml配置文件中写了容忍参数,最终pod还是会容忍的生成在该污点服务器上。默认master节点是NoSchedule
二、Taint(污点)
2.1、污点(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驱逐出去
2.2、查看某个节点的Taint配置情况
# 1、查看所有node情况
[root@k8s-master01 ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master01 Ready matser 7d19h v1.20.0
k8s-master02 Ready <none> 7d19h v1.20.0
k8s-master03 Ready <none> 7d19h v1.20.0
k8s-node01 Ready <none> 7d19h v1.20.0
k8s-node02 Ready <none> 7d19h v1.20.0
# 2、查看某个节点的Taint信息(kubectl describe node nodename)
[root@k8s-master01 ~]# kubectl describe node k8s-node01 (内容太多不贴全了)
Name: k8s-node01
Roles: <none>
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
disktype=ssd
kubernetes.io/arch=amd64
kubernetes.io/hostname=k8s-node01
kubernetes.io/os=linux
node.kubernetes.io/node=
Annotations: node.alpha.kubernetes.io/ttl: 0
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Mon, 21 Dec 2020 05:13:32 +0800
Taints: <none> # 关注这个地方即可 ---没有设置过污点的节点属性中的参数是这样的Taints: <none>
Unschedulable: false
#添加 尽量不调度 PreferNoSchedule
kubectl taint nodes k8s-master02 node-role.kubernetes.io/master:PreferNoSchedule
#去除污点NoSchedule,最后一个"-"代表删除
kubectl taint nodes k8s-master02 node-role.kubernetes.io/master:NoSchedule-
2.3、给某个节点服务器打上污点标签
# 1、先看一下当前pod都分布到哪些节点上
[root@k8s-master01 ~]# kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-btl2c 1/1 Running 3 6d 172.162.195.26 k8s-master03 <none> <none>
nginx-c9qf5 1/1 Running 3 6d 172.161.125.27 k8s-node01 <none> <none>
nginx-pl9gs 1/1 Running 3 6d 172.169.92.103 k8s-master02 <none> <none>
# 2、给节点k8s-node01服务器打上污点标签NoExecute
[root@k8s-master01 ~]# kubectl taint nodes k8s-node01 check=xtaint:NoExecute
`注释:
check------->键
value: "xtaint"----------->容忍的键对应的键值
"NoExecute"----------->容忍的键对应的影响效果effect
`
# 3、再次查看pod,发现k8s-node01节点上的nginx-c9qf5容器正在被删除,再过一会,就被彻底删除了,这正是我们想要的效果!
[root@k8s-master01 ~]# kubectl get pod -owide
NAME READY STATUS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-c9qf5 1/1 Terminating 6d 172.161.125.27 k8s-node01 <none> <none>
2.4、删除某个节点上的设置的污点
# 跟删除标签的方式有点类似,在后面加个 "-"
[root@k8s-master01 ~]# kubectl taint nodes k8s-node01 check=xtaint:NoExecute-
node/k8s-node01 untainted
"
Taints: test=xtaint:NoExecute
check=xtaint:NoSchedule
test=xtaint:NoSchedule
"
# 以上的Taints这样删,必须得带个"-"
kubectl taint nodes k8s-node02 test=xtaint:NoExecute-
kubectl taint nodes k8s-node02 check=xtaint:NoSchedule-
kubectl taint nodes k8s-node02 test=xtaint:NoSchedule-
三、Toleration(容忍)
3.1、现在k8s-node02节点上打上一个NoSchedule
# 打上NoExecute,k8s-node02、k8s-master01、k8s-master02节点上的pod都会自动被删除
[root@k8s-master01 ~]# kubectl taint nodes k8s-node02 test=xtaint:NoExecute
node/k8s-node02 tainted
3.2、创建一个包含有容忍toleration的配置文件
cat > test-taint-pod.yaml << EFO
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.5.2
tolerations:
- key: "check"
operator: "Equal"
value: "xtaint"
effect: "NoExecute"
tolerationSeconds: 3600
EFO
# create Pod
[root@k8s-master01 app]# kubectl create -f test-taint-pod.yaml
pod/nginx created
参数解释
tolerations:----------->容忍
- key: "check" ----------->容忍的键
operator: "Equal"----------->操作符"等于"
value: "xtaint"----------->容忍的键对应的键值
effect: "NoExecute"----------->容忍的键对应的影响效果
tolerationSeconds: 3600----------->容忍3600秒。本pod配置文件中有这个参数了,然后再给本服务器设置污点NoExecute,那么这个pod也不会像普通pod那样立即被驱逐,而是再等上3600秒才被删除。
3.2、toleration配置方式
方式一:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
方式二:
tolerations:
- key: "key"
operator: "Exists"
effect: "NoSchedule"
一个Toleration和一个Taint相匹配是指它们有一样的key和effect,并且如果operator是Exists(此时toleration不指定value)或者operator是Equal,则它们的value应该相等。
注意两种情况:
如果一个Toleration的key为空且operator为Exists,表示这个Toleration与任意的key、value和effect都匹配,即这个Toleration能容忍任意的Taint:
tolerations:
- operator: "Exists"
如果一个Toleration的effect为空,则key与之相同的相匹配的Taint的effect可以是任意值:
tolerations:
- key: "key"
operator: "Exists"
上述例子使用到effect的一个值NoSchedule,也可以使用PreferNoSchedule,该值定义尽量避免将Pod调度到存在其不能容忍的Taint的节点上,但并不是强制的。effect的值还可以设置为NoExecute。
Kubernetes会自动给Pod添加一个key为node.kubernetes.io/not-ready的Toleration并配置tolerationSeconds=300,同样也会给Pod添加一个key为node.kubernetes.io/unreachable的Toleration并配置tolerationSeconds=300,除非用户自定义了上述key,否则会采用这个默认设置。
一个使用了很多本地状态的应用程序在网络断开时,仍然希望停留在当前节点上运行一段时间,愿意等待网络恢复以避免被驱逐。在这种情况下,Pod的Toleration可以这样配置:
tolerations:
- key: "node.alpha.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 6000