这里介绍Kubernetes调度中的Taint污点、Toleration容忍度
Taint污点
通过在集群节点当中添加Taint污点实现拒绝将某些Pod调度到该节点上。具体地,对于污点而言,其包含三部分:Key键、Value值、Effect效果,其中Value为可选的。而污点的Effect效果则有三种:
- NoSchedule:如果Pod没有容忍该污点,则该Pod不允许被调度到该节点
- PreferNoSchedule:其可以视为NoSchedule的宽松版本,如果Pod没有容忍该污点,则该Pod会被尽量阻止调度到该节点。比如如果实在没有其他节点可用,则该Pod依然还是会被调度到该节点
- NoExecute:其不同于NoExecute、PreferNoSchedule,后二者只会作用于Pod调度期间。而对于NoExecute而言,其还会影响正在该节点上运行的Pod。如果给一个节点添加该效果的污点后,则那些运行于其上的Pod如果没有容忍该污点会被从该节点上移除
添加污点
可通过下述命令向指定节点添加污点信息
1 | # 给指定节点添加污点信息 |
效果如下所示。这里说明下为了便于在命令行中对JSON数据进行格式化,在Mac环境下可通过brew按照jq工具实现格式化
修改污点
可以看出对于污点而言,其是由Key键、Effect效果共同唯一确定的。故如果期望修改该污点的值,可通过—overwrite选项实现
删除污点
删除污点只需在后面添加-减号即可
1 | # 对指定节点删除指定键名、效果的污点 |
Toleration容忍度
基本实践
Toleration容忍度是应用于Pod上的。通过对Pod添加相应的容忍度,使得调度器允许调度该Pod到有相应污点的节点上运行。这里需要注意,并不保证Pod一定会被调度存在相应污点的节点上,因为调度器还会结合其他参数进行最后的综合评判。下面即是一个典型的在Pod当中定义容忍度信息的示例
1 | # Pod 1 |
所谓Pod的容忍度与节点的污点相匹配是指它们有相同的键名和效果,并且:
- 如果operator是Exists,则此时容忍度不能指定value
- 如果operator是Equal,则还需要保证Pod的容忍度中的value与节点的污点中的value相同。此外,operator默认为Equal
与此同时,由于一个节点可以拥有多个污点、一个Pod也可以拥有多个容忍度。故只有当该Pod能够容忍该节点上的全部污点,才说明该Pod能够容忍该节点
据此就可以解释下图结果了。Pod 1的容忍度与my-k8s-cluster-2-node-worker节点的污点在键名、效果、值完全相同,故该Pod是允许被调度到my-k8s-cluster-2-node-worker节点上;而对于Pod 2而言,其与与my-k8s-cluster-2-node-worker节点的污点虽然在键名、值上均相同,但由于效果不同。故该Pod的容忍度与节点的污点并不匹配,即该Pod不允许被调度到该节点上。所以其只能被调度到my-k8s-cluster-2-node-worker2节点当中
特例
这里存在两种特殊场景:
1. 如果一个容忍度的key为空且operator为Exists,则表示这个容忍度与任意的key、value和effect都相同,即这个容忍度能容忍任何污点
Pod配置如下所示
1 | # Pod 3 |
效果如下所示,集群中所有节点均存在污点。Pod 4由于容忍任何节点,故可以被成功调度其中一个存在污点的节点上;而Pod 3由于无法容忍任何节点,无法被调度到任何一个节点上,故被挂起
2. 如果Effect为空,则可以与该键名的效果相匹配
Pod配置如下所示
1 | # Pod 5 |
这里我们对集群中所有节点设置相同的污点,效果如下所示
- 对于Pod 5而言,其容忍度没有匹配节点的全部污点,故只能被挂起
- 对于Pod 6而言,其容忍度匹配了节点的全部污点,故可以被调度任一个节点上
- 对于Pod 7而言,虽然Effect为空,其键名为DiskType的容忍度 可以和 节点中键为DiskType的所有效果的污点进行匹配。但由于operator为Equal,还需要保证容忍度的值与污点的值相同。所以其容忍度没有匹配节点的全部污点,故只能被挂起
- 对于Pod 8而言,一方面Effect为空,其键名为DiskType的容忍度 可以和 节点中键为DiskType的所有效果的污点进行匹配;另一方面,由于容忍度的值与污点的值相同。所以其容忍度匹配了节点的全部污点,故可以被调度任一个节点上
参考文献
- Kubernetes in Action中文版 Marko Luksa著
- 深入剖析Kubernetes 张磊著