污点和容忍官方文档:https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration/
污点是定义在节点之上的键值类型的数据,用于让节点有能力拒绝调度器将一些Pod运行到节点上。容忍度是定义在Pod上的,用于配置该Pod可容忍的节点污点。
虽然污点和容忍度与节点亲和的目的都是影响Pod的调度结果,但节点亲和调度使Pod对象被吸引到某一类节点,而污点的作用相反,它为节点提供了排斥Pod的能力
污点和容忍度介绍
污点定义在节点的nodeSpec中,是键值类型的数据,但要额外加一个效用(effect)标识,格式为key=value:effect,其中key和value的用法及格式与标签类似,而效用标识则用于定义节点对Pod对象的排斥等级。效用标识主要有以下3种:
- NoSchedule:不能容忍此污点的Pod对象不可调度至当前节点,属于强制性约束关系,但添加此效用标识的污点不会影响节点上已有Pod运行
- PreferNoSchedule:NoSchedule的柔性约束版本,调度器尽量确保不能容忍此污点的Pod不会被调度至当前节点。添加此效用标识的污点同样不会影响节点上已有Pod运行
- NoExecute:不能容忍此污点的Pod对象不可调度至当前节点,属于强制性约束关系。假如为节点添加此效用标识的污点,节点上现存的Pod中不能容忍此污点的会被驱逐;能容忍此污点,但设置了tolerationSeconds属性,等待tolerationSeconds指定的时间污点还存在Pod也会被驱逐,未设置tolerationSeconds属性的Pod不会被驱逐
在Pod上定义容忍度需要指定key、vlaue、effect和操作符(operator),支持两种操作符:Equal(等值比较,默认)和Exists(存在性判断)
在定义容忍度时,可以使用下面几种形式:
- 指定key、value和effect,operator为Equal,表示容忍度和污点的key、value和effect必须相等
- 指定key和effect,operator为Exists,表示容忍度和污点的key和effect相等即可
- 指定effect,operator为Exists,表示容忍度和污点的effect相等即可
- 指定key,operator为Exists,表示容忍度和污点的key相等即可
- 只指定operator为Exists,表示容忍所有污点
定义节点污点
任何符合键值规范的字符串都可用于定义污点信息。kubectl taint命令用于管理节点的污点,语法如下:
kubectl taint nodes <node-name> <taint-key>=<taint-value>:<effect> ...
例如,为节点192.168.122.20定义一个disktype=ssd:NoSchedule的污点
kubectl taint nodes 192.168.122.20 disktype=ssd:NoSchedule
需要注意,即使key和value完全相同,但effect不同,就代表两个不同的污点。例如,再为192.168.122.20节点添加一个disktype=ssd:NoExecute污点:
kubectl taint nodes 192.168.122.20 disktype=ssd:NoExecute
删除污点的语法如下,省略effect表示删除指定键名的所有污点
kubectl taint nodes <node-name> <taint-key>[:effect]-
例如,删除192.168.122.20上的disktype=ssd:NoExecute污点:
kubectl taint nodes 192.168.122.20 disktype:NoExecute-
如果希望删除节点上的所有污点,可以使用kubectl patch指令将节点的spec.taints属性置空。例如下面的命令:
kubectl patch nodes 192.168.122.21 -p '{"spec":{"taints": []}}'
定义Pod容忍度
Pod对象的容忍度通过spec.tolerations字段定义,根据使用的操作符不同,主要有两种可用形式:一种是与污点信息完全匹配的等值关系;另一种是判断污点信息存在性的匹配方式。
下面是一个示例,基于Equal操作符,表示容忍节点上disktype=ssd:NoSchedule的污点
piVersion: apps/v1
kind: Deployment
metadata:
name: taint-toleration-equal
spec:
replicas: 5
selector:
matchLabels:
app: taint-toleration-equal
template:
metadata:
labels:
app: taint-toleration-equal
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
tolerations:
- key: disktype
value: ssd
effect: NoSchedule
operator: Equal
如下图,Pod可以被调度到192.168.122.20节点,192.168.122.20节点具有污点disktype=ssd:NoSchedule
下面是另一个示例,基于Exists操作符,表示容忍节点上key为disktype,effect为NoExecute的污点
apiVersion: apps/v1
kind: Deployment
metadata:
name: taint-toleration-exists
spec:
replicas: 5
selector:
matchLabels:
app: taint-toleration-exists
template:
metadata:
labels:
app: taint-toleration-exists
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
tolerations:
- key: disktype
effect: NoExecute
operator: Exists
tolerationSeconds: 60 #能容忍此污点的时长,即如果超过此时间段此污点还存在Pod会被驱逐
取消192.168.122.20节点上的NoSchedule污点,然后添加一个NoExecute污点
kubectl taint nodes 192.168.122.20 disktype:NoSchedule-
kubectl taint nodes 192.168.122.20 disktype=ssd:NoExecute
查看Pod,如下图,可以被调度到192.168.122.20节点,但如果60s后192.168.122.20节点的disktype=ssd:NoExecute污点还存在Pod会被驱逐,因为设置了tolerationSeconds属性