Kubernetes运维:Taints 和 Tolerations
文章目录
Kubernetes 中 Taints 和 Tolerations 是调度系统的重要机制之一,通过它们管理服务可以确保 Pod 不会被调度到不合适的节点上。
本文将简单介绍 Kubernetes 的 Taints 和 Tolerations 机制。
Taints
Taints 是 Kubernetes 中定义在 Node 对象上的一些标签,不同于 Labels 和 Annotations 机制使用 key=values 记录信息,Taints 添加了 effect 属性,使用 key=value:effect 的格式描述,其中,Key 和 Value 可以是用户自定义的字符串,而 effect 表示该 Taints 对 Kubernetes 调度 Pod 产生何种影响,目前支持以下三种类型:
- NoExecute:已经运行在节点的 Pod 将会被驱逐(evicted),并且新的 Pod 不会调度到该节点。
- NoSchedule:已经运行在节点的 Pod 不受到影响,新的 Pod 不会调度到该节点。
- PreferNoSchedule:已经运行在节点的 Pod 不受到影响,尽量避免新的 Pod 调度到该节点。
通过 kubectl taint 命令我们可以在快速给 Node 添加污点:
|
|
Tolerations
Tolerations 是定义在 Pod 上的信息,这些信息告诉 Kubernetes 管理服务,指定的 Taints 是否会对这个 Pod 的调度以及故障迁移(Evicted)产生影响。
用户可以通过以下方式定义多个 Tolerations:
|
|
上述定义表示:污点 key1=value1:NoSchedule 不会对这个 pod 的调度产生影响,用户允许 schedule 将这些 pod 调度到拥有这些污点的 Node 。
|
|
上述定义表示:污点 key1=value1:NoExecute,在前 3600s 内不会对 pod 产生影响,当 Node 上污点存在超过 3600s 时 Pod 将被迁移到其他节点。
在定义 tolerations 是我们可以省略 value 或者同时省略 key 和 value ,此时需要指定 operator 取值为 Exists,如下:
|
|
Taint based Evictions
Kubernetes 的 Node Controller 基于上述 Taint 和 Tolerations 机制实现了节点故障时 Pod 迁移功能。
当节点故障时,Node Controller 将自动在 Node 上添加以下污点:
Key | Effect | 备注 |
---|---|---|
node.kubernetes.io/not-ready | NoExecute | NodeCondition Ready == False |
node.kubernetes.io/unreachable | NoExecute | NodeCondition Ready == Unknown |
node.kubernetes.io/memory-pressure | NoSchedule | 节点内存不足 |
node.kubernetes.io/disk-pressure | NoSchedule | 节点磁盘空间不足 |
node.kubernetes.io/pid-pressure | NoSchedule | 节点Pid不足 |
node.kubernetes.io/unschedulable | NoSchedule | 节点不可调度,主要用于主动 codron 节点的场景 |
Node Controller 基于节点的 NodeCondition 信息添加 Taint,而这些信息由每个节点的 Kubelet 实时更新。Schuduler 在调度 pod 时直接基于节点的 Taint 工作,不再重复考虑 NodeCondition 的具体取值。
上述 Node Controller 管理的 Taint 中只有 node.kubernetes.io/not-ready 和 node.kubernetes.io/unreachable 的 effect 是 NoExecute,其他污点为 NoSchedule。
这是由于设置 NoExecute 污点会立即驱逐节点上的所有 pod,为了提高系统的鲁棒性,kubernetes 采取的方案是:当节点存在 memory 压力时,通过污点将节点标记为 NoSchedule ,此时 Kubelet 后台会执行一次资源回收,优先将低保障级别的 Pod 驱赶到其他节点。此时如果内存资源恢复到警戒线之下,kubelet 将更新 NodeCondition 信息,Taint 也会被移除。换句话说,memory-pressure 等类型污点并不是表明节点完全不可用,其 effect 设置为 NoExecute 是不合适的。
默认情况下,kubernetes 在创建的 Pod 自动添加了一些 tolerations,以实现各种场景的 Pod 自动迁移:
Kubernetes 对除 Daemon 以外其他所有控制器创建的 pod ,自动添加了以下 tolerations:
|
|
对于 daemon 管理的 pod,Kubernetes 注入以下 tolerations:
|
|
官方文档中提及对于 Guaranteed 和 Burstable 类型的 Pod ,Kubernetes 会自动添加 node.kubernetes.io/memory-pressure 类型的 tolerations(甚至当 Burstable 类型的 Pod 没有设置内存配额时)。但在实际测试中,我发现并没有添加。
参考:https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/#taint-nodes-by-condition
参考
文章作者 yoaz
上次更新 2022-09-05
许可协议 MIT