前一篇文章讲解了 Kubernetes 亲和性调度, 所涉及的内容都是描述 pod 的属性,来声明此 pod 但愿调度到哪类 nodes。而本文介绍的 Taint(污点)
恰好相反,它是node 的一个属性,容许 node 主动排斥 pod 的调度。
对应的 k8s 又给 pod 新增了配套属性 toleration(容忍)
,用于表示这些 pod 能够(但不强制要求)被调度到具备相应 taints 的 nodes 上。
这二者常常一块儿搭配,来确保不将 pod 调度到不合适的 nodes。node
看下 taint & toleration 结构体,下面足点介绍时会涉及相关字段。git
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" )
咱们能够对 node 设置多个 taints,固然也能够在 pod 配置相同个数的 tolerations。影响调度和运行的具体行为,咱们能够分为如下几类:github
effect == NoSchedule
的 taint 没有被 pod toleration,那么 pod 不会被调度到该节点上。effect == NoSchedule
的 taints 都被 pod toleration,可是至少有一个 effect == PreferNoSchedule
没有被 pod toleration,那么 k8s 将努力尝试不把 pod 调度到该节点上。effect == NoExecute
的 taint 没有被 pod toleration,那么不只这个 pod 不会被调度到该节点,甚至这个节点上已经运行可是也没有设置容忍该污点的 pods,都将被驱逐。再看下 PodSpec 配置 Tolerations,其中的 key、value、effect 与 Node Taint 设置须要保持一致,operator 支持两类:segmentfault
有几个特殊状况:网络
tolerations: - operator: "Exists"
tolerations: - key: "key" operator: "Exists"
还有一个 TolerationSeconds
,该值与 effect 为 NoExecute
配套使用。用来指定在 node 添加了 effect = NoExecute 的 taint 后,能容忍该 taint 的 pods 可停留在 node 上的时间。
例如:ide
tolerations: - key: "key1" operator: "Equal" value: "value1" effect: "NoExecute" tolerationSeconds: 3600
表示若是这个 pod 已经运行在 node 上而且该 node 添加了一个对应的 taint,那么这个 pod 将会在 node 上停留 3600 秒后才会被驱逐。可是若是 taint 在这个时间前被移除,那么这个 pod 也就不会被驱逐了。spa
来个比较形象的图,描述下:code
该图参考: Taints and tolerations, pod and node affinities demystified · Banzai Cloud
kubernetes 1.6 版本,node controller 会跟进系统状况自动设置 node taint 属性。
内置 taint key 以下:blog
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 永远不会被驱逐。
专用节点
kubectl taint nodes nodename dedicated=groupName:NoSchedule
, 而后为 pods 设置对应的 tolerations。dedicated=groupName
),而且为对应的 pods 设置 NodeAffinity,以控制 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。