kubernetes调度之污点(taint)和容忍(toleration)

系列目录html

节点亲和性(affinity),是节点的一种属性,让符合条件的pod亲附于它(倾向于或者硬性要求).污点是一种相反的行为,它会使pod抗拒此节点(即pod调度的时候不被调度到此节点)node

污点和容易结合在一块儿以确保pod不会被调度到不适合的节点上.当一个或者多个污点添加到某个节点上,则意味着此节点不会接受任何不容忍这些污点的pod.Tolerations做用于pod上,容许(但不是必须)pod被调度到有符合的污点(taint)的节点上网络

概念

可使用kubectl taint为一个节点(node)添加污点(taint),例如:ide

kubectl taint nodes node1 key=value:NoSchedule

这样就把键为key,值为value,效果为NoSchedule的污点添加到了节点node1上.这样除非pod有符合的容忍(toleration),不然不会被调度到此节点上测试

能够经过如下命令删除刚添加的taintcode

kubectl taint nodes node1 key:NoSchedule-

你能够在建立pod的yml里指定一个关于toleration的PodSpec,如下两个容忍都会匹配前面建立的taint,所以它们中的任意一个建立的pod都会被调度到节点node1htm

tolerations:
- key: "key"
  operator: "Equal"
  value: "value"
  effect: "NoSchedule"
tolerations:
- key: "key"
  operator: "Exists"
  effect: "NoSchedule"

只有pod的keyeffect都和某一个污点的key与effect匹配,才被认为是匹配,而且要符合如下情形:blog

  • operatorExists(这种状况下value不该当指定)
  • operatorEqual 而且value相同

若是operator没有指定,则默认是Equal生命周期

如下两种状况为特殊状况:内存

1) 若是key是空(是指key没有指定,而不是指key为空字符串),operatorExists则匹配全部的key,valueeffect,也即匹配任何node,

tolerations:
- operator: "Exists"

2) 空的effect匹配全部effect

tolerations:
- key: "key"
  operator: "Exists"

以上会匹配全部key为key的全部taint节点

前面的示例中使用了NoSchedule类型的effect.此外,也可使用PreferNoSchedule类型的effect,这是一个优先选择或者软性版本的NoSchedule,调度系统会尽可能避免调度不容忍这种污点的pod到带有此污点的节点上,可是并非硬性要求.第三种effect类型:NoExecute会在晚些时候讲到

你能够为一个节点(node)添加多个污点,也能够为一个pod添加多个容忍(toleration).kubernetes处理多个污点(taint)或者多个容忍(toleration)相似于过滤器:起初包含全部污点,而后忽略掉pod匹配的污点,剩下不可被忽略的污点决定此节点对pod的效果,特别地:

1) 若是至少有一个不可忽略的NoSchedule类型的效果(effect),kubernetes不会调度pod到此节点上来.

2) 若是没有不可忽略的NoSchedule类型的效果(effect),可是至少有一个PreferNoSchedule类型的效果,则kubernetes会尝试调度pod到此节点上

3) 若是至少有一个NoExecute类型的效果(effect),则此pod会被驱离此节点(固然,前提此pod在此节点上),而且若是pod不在此节点上,也不会被调度到此节点上

所谓驱离是指pod被今后节点上移除,调度到其它节点上

示例,假如你有一个如下类型的节点

kubectl taint nodes node1 key1=value1:NoSchedule
kubectl taint nodes node1 key1=value1:NoExecute
kubectl taint nodes node1 key2=value2:NoSchedule

和如下类型的pod

tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoSchedule"
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoExecute"

这种状况下,pod不会被调度到node1上,由于没有容忍(toleration)来匹配第三个taint.可是若是它运行在此节点上,它仍然能够继续运行在此节点上,由于它仅仅不匹配第三个taint.(而第三个taint的效果是NoSchedule,指示不要被调度到此节点)

一般状况下,一个效果类型为NoExecutetaint被添加到一个节点上后,全部不容忍此taint的pod会被立刻驱离,容忍的永远不会被驱离.可是效果类型NoExecute能够指定一个tolerationSeconds字段来指示当NoExecute效果类型的污点被添加到节点之后,pod仍然能够继续在在指定时间内留存在此节点上.

例如:

tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoExecute"
  tolerationSeconds: 3600

它意味着若是pod运行在一个能够容忍的节点上,则它能够继续运行3600秒,而后被驱离,在此段时间内若是污点被移除,则pod不会被驱离.

以上能够理解为有条件容忍,即使匹配也不能一直运行在此节点上,只能在符合条件的时段内运行在此节点上.

实例:

tainttoleration能够很是灵活地把指示pod不要调度到不合适的节点或者把已经存在的pod驱离节点,如下列举出一些用例:

  • 专用节点 假如你想让某些节点供特定的用户专用,你能够为这些节点添加污点,例如:(kubectl taint nodes nodename dedicated=groupName:NoSchedule),而后给专用这些节点的pod添加容忍(toleration),容忍节点污点的pod被容许调度到节点上,固然也能够调度到集群中的其它节点上(没有taint的节点,有taint的必须容忍).若是你想要pod仅被调度到专用的节点,则须要添加标签(使用前面讲到过的亲和属性)

pod的亲和性是以pod为中心的,而节点的污点则是以节点为中心.想要使pod被调度到指定节点,须要亲和属性,想要节点排斥非专用pod,则须要使用taint,同时使用亲和性和污点能够保证专用节点被特定pod专用,特定pod仅使用专用节点

  • 配有特殊硬件的节点 在一个集群中,有部分节点包含特殊硬件(例如特殊GPU),理想的状况是把让不须要特殊硬件的pod不被调度到这些节点上以便为可能须要特殊硬件的节点留存空间,这种状况下就能够用给指定节点添加污点(taint)的方法来实现效果.(例如kubectl taint nodes nodename special=true:NoSchedule or kubectl taint nodes nodename special=true:PreferNoSchedule),而后给须要使用特殊硬件的pod添加符合的容忍(toleration).

  • 基于taint的驱离策略(测试功能),当节点出现问题时,把不容忍的pod驱离.

基于taint的驱离策略

前面咱们提到过NoExecute效果类型的taint,它将对已经存在于此节点上的pod产生效果:

  • 不容忍此taint的pod会被立刻驱离

  • 容忍此taint可是没有指定tolerationSeconds的pod将会永远运行在此节点

  • 容忍此taint可是包含tolerationSeconds属性的节点将会在此节点上留存指定时间(虽然容忍,可是是有条件的,仅在一段时间内容忍)

第三点的言外之意即为即使容忍,可是超过容忍时间后仍然会被驱离

此外,kubernetes 1.6引入了对节点问题的展现.也就是说当知足了特定条件,节点控制器会自动为符合条件的节点添加taint,如下是一些内置的taint

  • node.kubernetes.io/not-ready,节点尚未准备好,对应节点状态Ready值为false

  • node.kubernetes.io/unreachable,节点控制器没法触及节点,对应节点状态ready值为Unknown

  • node.kubernetes.io/out-of-disk,磁盘空间不足

  • node.kubernetes.io/memory-pressure,节点存在内存压力

  • node.kubernetes.io/disk-pressure,节点磁盘存在压力

  • node.kubernetes.io/network-unavailable,节点网络不可用

  • node.kubernetes.io/unschedulable,节点不可被调度

  • node.cloudprovider.kubernetes.io/uninitialized

在kubernetes 1.13版本,基于污点的驱离策略提高到beta级别而且默认开启,所以污点被node控制器(kubelete)自动添加,而且普通的以节点的Ready状态为基础的驱离策略被禁用.

这项beta功能,加上tolerationSeconds,容许节点来指定仍然能够留存长时间即使节目有一种或者多种匹配的问题

例如:一个包含多种本地状态的应用在节点发生网络分裂状况时但愿仍然能够留存一点时间,指望在指定的时段内网络能恢复正常以免被驱离.这种状况下容忍此节点的pod编排以下

tolerations:
- key: "node.kubernetes.io/unreachable"
  operator: "Exists"
  effect: "NoExecute"
  tolerationSeconds: 6000

请注意,若是用户没有在pod的配置中指定node.kubernetes.io/not-ready,则kubernetes会自动为pod配置加上node.kubernetes.io/not-ready tolerationSeconds=300属性.一样地,若是没有配置,则自动添加node.kubernetes.io/unreachable tolerationSeconds=300

DaemonSet类型的pod建立时自动为如下两种类型的taint添加NoExecute效果类型而且没有tolerationSeconds

  • node.kubernetes.io/unreachable

  • node.kubernetes.io/not-ready

这确保即使节点出现问题,DaemonSet也不会被驱离.

有条件节点taint

在kubernetes 1.12版,有条件为节点添加taint(TaintNodesByCondition)特征被提高为beta级别,节点生命周期控制器会自动根据节点的状态为节点添加taint.一样地调度器不检测node的状态,而是检测node 的污点(taint).这确保node的状态不影响哪些pod能够调度到此node上,用户能够选择经过添加相应的容忍(toleration)来忽略node的指定的问题(经过node的状态体现).注意TaintNodesByCondition仅添加NoSchedule类型的污点.NoExecute效果类型由TaintBasedEviction控制(此功能为1.13版本的beta功能)

从kubernetes 1.8开始,DaemonSet controller自动如下类型的为全部的daemon添加NoSchedule效果类型的容忍(toleration),来防止DeamonSet分裂

  • node.kubernetes.io/memory-pressure

  • node.kubernetes.io/disk-pressure

  • node.kubernetes.io/out-of-disk (only for critical pods)

  • node.kubernetes.io/unschedulable (1.10 or later)

  • node.kubernetes.io/network-unavailable (host network only)

添加了这些类型的容忍是为了向后兼容,你能够为DaemonSet添加任意类型的容忍

相关文章
相关标签/搜索