一、Taints和Tolerations
Taint让Node拒绝Pod的运行,被标记为Taint的节点就是存在问题的节点,比如磁盘要满、资源不足、存在安全隐患要进行升级维护,希望新的Pod不会被调度过来,但被标记为Taint的节点并非故障节点,仍是有效的工作节点,所以仍需将某些Pod调度到这些节点上时,可以通过使用Toleration属性来实现。
在默认情况下,在Node上设置一个或多个Taint之后,除非Pod明确声明能给容忍这些污点,否则无法在这些Node上运行。可以使用kubectl taint命令为Node设置Taint信息:
kubectl taint nodes node1s key=value:NoSchedule #给Node节点加上Taint,该Taint的键为key,值为value,Taint效果是NoSchedule
这个设置为node1加上了一个Taint。该Taint的键为key,值为value,Taint的效果是NoSchedule。这意味着除非Pod明确声明可以容忍Taint,否则不会被调度到node1上。然后,需要在Pod上声明Toleration。下面的两个Toleration都被设置为可以容忍(Tolerate)具有该Taint的Node,使得Pod能给被调度到node1上:
tolerations:
- key: "key"
operation: “Equal”
value: "value"
effect: "NoSchedule"
或
tolerations:
- key: "key"
operation: "Exists"
effect: "NoSchedule"
- operator的值是Exists(无需指定value)
- operator的值是Equal并且value相等
- 空的key配合Exists操作符能够匹配所有的键和值
- 空的effect匹配所有的effect
- 列出节点中所有的Taint
- 忽略Pod的Toletation能够匹配的部分
- 剩下没有忽略的Taint就是对Pod的效果
- 如果在剩余的Taint中存在effect=NoSchedule,则调度器不会把该Pod调度这一节点
- 如果在剩余的Taint中没有NoSchedule效果,但是有PreferNoSchedule效果,则调度器会尝试不把这个Pod指派给这个节点
- 如果在剩余的Taint中有NoScheduke效果,并且这个Pod已经在该节点运行,则会被驱逐;如果没有在该节点上运行,则也不会再被调度到这个节点上
二、测试例子
对一个节点进行Taint设置:
kubectl taint nodes node1 key1=value1:NoSchedule #NoSchedule:表示k8S不会将Pod调度到具有该污点的node上
kubectl taint nodes node1 key1=value1:NoExecute #NoExecute:表示k8s不会将Pod调度到具有该污点的Node上,同时会将Node上已经存在的Pod驱逐
kubectl taint nodes node1 key2=valu2:NoSchedule #NoSchedule:表示k8S不会将Pod调度到具有该污点的node上
在Pod上设置Toletation:
toletations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
这样做的结果是该Pod无法被调度到node1上,这个是因为第3个Taint没有匹配的Toletation。但是如果该Pod已经在node1上运行了,那么在运行时设置第3个Taint,它能继续在node1上运行,这是因为Pod可以容忍前两个Taint。
如果给Node加上effect=NoExecute的Taint,那么在该Node上正在运行的所有无对应Toletation的Pod都会被立即驱逐,而具有相应Toleration的Pod永远不会被驱逐。系统允许给具有NoExecute效果的Toletation加入一个可先的toletationSeconds字段,这个设置表明Pod可以在Taint添加到Node之后还能在这Node上运行多久(单位为s)
toletations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExcute"
toletationSeconds: 3000
如果Pod正在运行,所在节点都被加入一个匹配的Taint,则这个Pod会持续在这个节点上存活3000秒后被驱逐。如果在这个宽限期内Taint被移除,则不会触驱逐事件。
- 独占节点
如果想要拿出一部分节点给一些特定应用使用,可以给节点添加这样Taint:
kubectl taint nodes nodename dedicated=groupName:NoSchedule
- 具有特殊硬件的节点
kubectl taint nodes nodename special=true:Noshcedule
kubectl taint nodes nodename special=true:PreferNoSchedule