Kubernetes--Taints(污点)和Tolerations(容忍)

一、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"
  Pod的Toleration声明中的key和effect需要与Taint的设置保持一致,并且满足以下条件:
  • operator的值是Exists(无需指定value)
  • operator的值是Equal并且value相等   
如果不指定operator,则默认值为Equal,另外还有两个特例:
  • 空的key配合Exists操作符能够匹配所有的键和值
  • 空的effect匹配所有的effect
    在上面的例子中,effect的取值为NoSchedule,还可以取值为PreferNoSchedule,这个值是优先,也可以算作NoSchedule的软限制版本 - 一个Pod如果没有声明容忍这个Taint,则系统会尽量避免把Pod调度到这一节点,但不强制。
    系统允许在同一个Node上设置多个Taint,也可以在Pod上设置多个Toletation。Kubernetes调度器处理多个Taint和Toletation的逻辑顺序为:
  1. 列出节点中所有的Taint
  2. 忽略Pod的Toletation能够匹配的部分
  3. 剩下没有忽略的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
  然后给这些应用的Pod加入对应的Toletation。这样,带有合适的Toletation的Pod会被允许同时使用其它节点一样使用这个Taint节点。
    通过自定义Admission Controller也可以实现这一目标。如果希望这些应用独占这一批节点,并且确保它们只能使用这些节点,则可以给这些Taint节点加入类似的标签 dedicated=groupName,然后Adminssion Controller需要加入节点亲和性设置,要求Pod只会被调度到具有这一标签的节点上。
  • 具有特殊硬件的节点
    在一个集群里可能有一小部分节点安装了特殊的硬件设备(如GPU芯片),用户自然希望把不需要占用这类硬件的Pod排除在外,已确保对这类硬件有需求的Pod能够被顺利调度到这些节点:
    设置Taint:
kubectl taint nodes nodename special=true:Noshcedule
kubectl taint nodes nodename special=true:PreferNoSchedule
      然后在Pod中利用对应的Toleration来保障特定的Pod能给使用特定的硬件。
      与独占节点的示例类似,使用Adminssion Controller来完成这一任务更方便。例如,Adminssion Controller使用Pod的一些特征来判断这些Pod,如果可以使用这些硬件,就添加Toleration来完成这一工作。要保障需要使用特殊硬件的Pod只能被调度到安装这些硬件的节点上,则还需要一写额外的工作,比如将这些特殊资源使用opaque-int-resource的方式对自定义资源进行量化,然后再PodSpec中进行请求;也可以使用标签的方式来标注这些安装有特殊硬件的节点,然后在Pod中定义节点亲和性实现。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值