Kubernetes taint & toleration

74次阅读

共计 3769 个字符,预计需要花费 10 分钟才能阅读完成。

一、概述
前一篇文章讲解了 Kubernetes 亲和性调度, 所涉及的内容都是描述 pod 的属性,来声明此 pod 希望调度到哪类 nodes。而本文介绍的 Taint(污点) 刚好相反,它是 node 的一个属性,允许 node 主动排斥 pod 的调度。对应的 k8s 又给 pod 新增了配套属性 toleration(容忍),用于表示这些 pod 可以(但不强制要求)被调度到具有相应 taints 的 nodes 上。这两者经常一起搭配,来确保不将 pod 调度到不合适的 nodes。
看下 taint & toleration 结构体,下面足点介绍时会涉及相关字段。
type Taint struct {
Key string
Value string
Effect TaintEffect
// add taint 的时间点
// 只有 Effect = NoExecute, 该值才会被 nodeController 写入
TimeAdded *metav1.Time
}

type Toleration struct {
Key string
Operator TolerationOperator
Value string
Effect TaintEffect
// 容忍时间
TolerationSeconds *int64
}

type TaintEffect string

const (
TaintEffectNoSchedule TaintEffect = “NoSchedule”
TaintEffectPreferNoSchedule TaintEffect = “PreferNoSchedule”
TaintEffectNoExecute TaintEffect = “NoExecute”
)

type TolerationOperator string

const (
TolerationOpExists TolerationOperator = “Exists”
TolerationOpEqual TolerationOperator = “Equal”
)
二、Taint
我们可以对 node 设置多个 taints,当然也可以在 pod 配置相同个数的 tolerations。影响调度和运行的具体行为,我们可以分为以下几类:

如果至少有一个 effect == NoSchedule 的 taint 没有被 pod toleration,那么 pod 不会被调度到该节点上。
如果所有 effect == NoSchedule 的 taints 都被 pod toleration,但是至少有一个 effect == PreferNoSchedule 没有被 pod toleration,那么 k8s 将努力尝试不把 pod 调度到该节点上。
如果至少有一个 effect == NoExecute 的 taint 没有被 pod toleration,那么不仅这个 pod 不会被调度到该节点,甚至这个节点上已经运行但是也没有设置容忍该污点的 pods,都将被驱逐。

三、Toleration
再看下 PodSpec 配置 Tolerations,其中的 key、value、effect 与 Node Taint 设置需要保持一致,operator 支持两类:

Exists: 这个配置下,不需要指定 value。
Equal: 需要配置 value 值。(operator 的默认值)

有几个特殊情况:
key 为空并且 operator 等于 Exists,表示匹配了所有的 keys,values 和 effects。换句话说就是容忍了所有的 taints。
tolerations:
– operator: “Exists”
effect 为空,则表示匹配所有的 effects(NoSchedule、PreferNoSchedule、NoExecute)
tolerations:
– key: “key”
operator: “Exists”
还有一个 TolerationSeconds,该值与 effect 为 NoExecute 配套使用。用来指定在 node 添加了 effect = NoExecute 的 taint 后,能容忍该 taint 的 pods 可停留在 node 上的时间。例如:
tolerations:
– key: “key1”
operator: “Equal”
value: “value1”
effect: “NoExecute”
tolerationSeconds: 3600
表示如果这个 pod 已经运行在 node 上并且该 node 添加了一个对应的 taint,那么这个 pod 将会在 node 上停留 3600 秒后才会被驱逐。但是如果 taint 在这个时间前被移除,那么这个 pod 也就不会被驱逐了。
来个比较形象的图,描述下:
该图参考: Taints and tolerations, pod and node affinities demystified · Banzai Cloud

四、内置行为
kubernetes 1.6 版本,node controller 会跟进系统情况自动设置 node taint 属性。内置 taint key 如下:

node.kubernetes.io/not-ready: 节点尚未就绪
node.kubernetes.io/unreachable: 节点无法被访问
node.kubernetes.io/unschedulable: 节点不可调度
node.kubernetes.io/out-of-disk: 节点磁盘不足
node.kubernetes.io/memory-pressure: 节点有内存压力
node.kubernetes.io/disk-pressure: 节点有磁盘压力
node.kubernetes.io/network-unavailable: 节点网络不可用
node.kubernetes.io/pid-pressure: 节点有 pid 压力
node.cloudprovider.kubernetes.io/uninitialized: 云节点未初始化
node.cloudprovider.kubernetes.io/shutdown: 云节点已下线

kubernetes 会通过 DefaultTolerationSeconds admission controller 为创建的 pod 添加两个默认的 toleration: node.kubernetes.io/not-ready 和 node.kubernetes.io/unreachable,并且设置 tolerationSeconds = 300。当然这个默认配置,用户可以自行覆盖。这些自动添加的默认配置,确保 node 出现问题后,pod 可以继续在 node 上停留 5 分钟。
DefaultTolerationSeconds admission controller 设置的 tolerationSeconds 值,也可以由用户指定。具体参考: https://github.com/kubernetes…

还有一个默认行为,就是 DaemonSet。所有 DaemonSet 创建的 pod 都会添加两个 toleration: node.alpha.kubernetes.io/unreachable 和 node.alpha.kubernetes.io/notReady。设置 effect = NoExecute,并且不指定 tolerationSeconds。目的是确保在 node 出现 unreachable 或 notReady 的问题时,DaemonSet Pods 永远不会被驱逐。
示例

专用节点

如果你希望将一组节点专用于特定的用户,那可以将这些节点设置 taints: kubectl taint nodes nodename dedicated=groupName:NoSchedule, 然后为 pods 设置对应的 tolerations。
如果你希望节点被专用并且确保服务仅使用这批节点,那么你还应该向这批节点设置 labels (dedicated=groupName),并且为对应的 pods 设置 NodeAffinity,以控制 pods 只能跑到这批节点上。

具有特殊硬件的节点
有部分带有特殊硬件的节点,比如 GPU、FPGA 等,要确保不将不需要专用硬件的 pods 调度到这些节点。也可以和 专有节点 一样的方式设置 taints:kubectl taint nodes nodename special=true:NoSchedule 或 kubectl taint nodes nodename special=true:PreferNoSchedule。建议还可以通过 Extended Resources 和 ExtendedResourceToleration admission controller 来更方便的调度依赖特殊硬件的 pods,而不需要手动添加容器的 toleration

基于 taint 的驱逐
前面也提到了,可以通过 NoExecute taint 来驱逐节点上已经运行的 pods。

五、参考资料

community/taint-toleration-dedicated.md at master · kubernetes/community · GitHub
community/taint-node-by-condition.md at master · kubernetes/community · GitHub
Taints and Tolerations
Taints and tolerations, pod and node affinities demystified · Banzai Cloud

正文完
 0