背景
继上一篇《Kubernetes 的污点和容忍(上篇)》, 这是 https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ 译文的下半部分.
经常看外文文档或书籍多了, 会产生一个问题:"不方便沟通." 不太会用大家习惯的表述方式来阐述一个问题. 所以需要定期看一些中文书籍来学习「行话」.
译文
使用场景
污点和容忍是一种让 Pod 不被调度到指定 node 或者是把不该在某个 node 上运行的 Pod 踢掉的灵活方法. 下面列举一些使用场景.
指定 node: 如果想为特殊的用户指定一组 node, 可以添加一个污点到这组 node 上(运行命令: kubectl taint nodes nodename dedicated=groupName:NoSchedule). 然后添加对应的容忍到这个 Pod 上(这个最容易实现的方法是写一个客户端准入控制器). 带有相应容忍的 Pod 就可以像被调度到集群中其他 node 一样被调度到带有相应污点的 node 上.
特殊硬件的 node: 在一个有一小组特殊硬件 (例如 GPU) 的集群中, 更希望将没有特殊硬件需求的 Pod 不调度到这些 node 上, 留出空间给后来的需要这些特殊硬件的 Pod. 这个通过给特殊硬件打上污点(例如: kubectl taint nodes nodename special=true:NoSchedule or kubectl taint nodes nodename special=true:PreferNoSchedule), 然后添加相应的容忍到 Pod 上来实现. 在这些使用场景, 最容易实现的方法是使用客户端准入控制器来实现. 例如, 推荐使用 Extended Resources 来代表特殊硬件, 将带有扩展资源名的硬件打上污点. 然后运行 ExtendedResourceToleration 准入控制器. 现在, 由于这些 node 已经被打上污点了, 没有容忍的 Pod 不会被调度到上面. 但是当你提交了一个需要扩展资源的 Pod,ExtendedResourceToleration 准入控制器会自动的添加正确的容忍到 Pod 上, Pod 就可以被调度到这个特殊硬件的 node 上了. 这会确保这些特殊硬件的 node 是需要相应的硬件的, 并且不需要手动给 Pod 添加容忍.
基于污点的驱逐(beta 版本特性): 下面我们会介绍当 node 发生故障时基于单个 Pod 配置的驱逐行为.
基于驱逐的污点
早期我们提到了 NoExecute 污点的 effect 会影响已经在 node 上运行的 Pod.
不能容忍污点的 Pod 会被立即驱逐.
Pod 上的容忍没有指定 tolerationSeconds 会好好的呆在 node 上.
Pod 上的容忍带有 tolerationSeconds 的会在 node 上停留指定的时间.
另外, Kubernets 1.6 引入了代表 node 问题的污点(在 1.6 版本是 alpha 版试用). 换句话说, node 控制器当某种条件成立的时候会自动的给 node 打上污点. 下面是其中内置的污点:
node.kubernetes.io/not-ready:node 不是 ready 状态. 对应于 node 的 condition ready=false.
node.kubernetes.io/unreachable:node controller 与 node 失联了. 对应于 node 的 condition ready=unknown
node.kubernetes.io/out-of-disk:node 磁盘空间不足了.
node.kubernetes.io/network-unavailable:node 的网断了
node.kubernets.io/unschedulable:node 不是可调度状态
node.cloudprovider.kubernetes.io/uninitalized:kubelet 是由外部云提供商提供的时候, 刚开始的时候会打上这个污点来标记还未被使用. 当 cloud-controller-manager 控制器初始化完这个 node,kubelet 会自动移除这个污点.
在 1.13 版本中,「基于污点的驱逐」特性被提升至 beta 版, 并且被默认开启. 因为这些污点会被自动添加到 node 控制器 (或 kubelet) 中. 而之前的常使用的逻辑: 基于 condition 中 ready 状态来驱逐 pod 也被禁用了.
注意:
为了维持在 node 故障时对存在的 Pod 驱逐做限流, 系统实际上是用限速的方法来添加污点的. 这种措施防止了 master 与 node 脑裂而产生的大规模驱逐 Pod 的场景.
这个 beta 版本特性再结合 tolerationSeconds, 可以使得 pod 指定当 node 节点出现问题的时候一个 pod 能在 node 上呆多久.
举个栗子:
一个有很多本地状态的应用可能想在产生网络脑裂的时候还能在 node 上呆很久. 这样是希望脑裂会恢复, 从而避免 pod 被驱逐. 为了达到这个目的, 可以这样用:
Kubernetes 会自动给 pod 添加容忍: node.kubernetes.io/not-ready 实效是 tolerationSeconds=300. 但是如果用户自己给这个 pod 添加了 node.kubernets.io/not-ready 的容忍, 用户的配置不会被覆盖.
类似的, 它也会自动给 pod 添加容忍: node.kubernetes.io/unreachable 实效是 tolerationSeconds=300. 但是如果用户自己给这个 pod 添加了 node.kubernetes.io/unreahable, 用户的配置不会被覆盖.
这种自动添加容忍机制确保了默认 pod 如果宿主机发生故障在 5 分钟之内不会被自动驱逐. 这两个默认的容忍都是 https://github.com/kubernetes/kubernetes/tree/master/plugin/pkg/admission/defaulttolerationseconds (DefaultTolerationSeconds admission controller)这个控件来添加的.
DaemonSet 的 pod 会默认添加一个 NoExecute 不带有 tolerationSeconds 的容忍:
- node.kubernetes.io/unreachable
- node.kubernetes.io/not-ready
这种方式确保了 DaemonSet 的 Pod 在发生故障的时候永远不会被驱逐.
condition 驱动的污点
在版本 1.12 中,「condition 驱动的污点」特性被提升到 beta 版, node 的生命周期控制器自动的创建 condition 相应的污点. 类似的, 调度器并不检查 node 的 condition, 而是检查污点. 这种方式是用来保证 node 的 condition 不会影响已经调度到这台 node 的 Pod. 用户可以用添加合适的容忍来忽视 node 的一些问题(condition 是其中的代表). 在这个版本中「condition 驱动的污点」只是打上了 effect=NoSchedule 的污点. 而在 1.13 版本中才将 effect=NoExcute 作为 beta 版默认开启.
从 Kubernetes1.8 版本开始, DaemonSet 控制器自动的添加了 NoSchedule 容忍到所有的 daemon 线程来避免 DaemonSets 中断.
- node.kubernetes.io/memory-pressure
- node.kubernetes.io/disk-pressure
- node.kubernetes.io/out-of-disk(只对重要的 pod 生效)
- node.kubernetes.io/unschedulable(1.10 版本后生效)
- node.kubernetes.io/network-unavailable(只针对主机网络)
添加这些容忍确保了向后兼容, 用户可以随意对 DaemonSets 添加容忍.
来源: https://www.cnblogs.com/xiexj/p/10561237.html