【云原生 · Kubernetes】Taint和Toleration(污点和容忍)
Taint和Toleration(污点和容忍)
节点亲和性是pod
的一种属性(优先选择或硬性要求),它使 pod 被优先分配到一类特定的节点上。而Taint
则相反,它使节点
能够排斥
一类特定的 pod。
Taint(污点)和 toleration(容忍)相互配合,可以用来避免 pod 被分配到不合适的节点上。每个节点上都可以应用一个或多个 taint ,这表示对于那些不能容忍这些 taint 的 pod,是不会被该节点接受的。如果将 toleration 应用于 pod 上,则表示这些 pod 可以(但不要求)被调度到具有匹配 taint 的节点上。
概念
您可以使用命令 [kubectl taint]
给节点增加一个 taint。比如,
kubectl taint nodes node1 key=value:NoSchedule
给节点 node1
增加一个 taint,它的 key 是 key
,value 是 value
,effect 是 NoSchedule
。这表示只有拥有和这个 taint 相匹配的 toleration 的 pod 才能够被分配到 node1
这个节点。
选择,你可以在 PodSpec 中定义 pod 的 toleration。下面提供的两个 toleration 例子均与上面例子中使用 kubectl taint
命令创建的 taint 相匹配,因此如果一个 pod 拥有其中的任何一个 toleration 都能够被分配到 node1
:
想删除刚才添加的 taint ,你可以运行:
kubectl taint nodes kube11 key:NoSchedule-
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
tolerations:
- key: "key"
operator: "Exists"
effect: "NoSchedule"
一个 toleration 和一个 taint 相“匹配”是指它们有一样的 key 和 effect ,并且:
- 如果
operator
是Exists
(此时 toleration 不能指定value
),或者 - 如果
operator
是Equal
,则它们的value
应该相等
注意: 存在两种特殊情况:
- 如果一个 toleration 的
key
为空且 operator 为Exists
,表示这个 toleration 与任意的 key 、 value 和 effect 都匹配,即这个 toleration 能容忍任意 taint。
tolerations:
- operator: "Exists"
- 如果一个 toleration 的
effect
为空,则key
值与之相同的相匹配 taint 的effect
可以是任意值。
tolerations:
- key: "key"
operator: "Exists"
上述例子使用到的 effect
的一个值 NoSchedule
,您也可以使用另外一个值 PreferNoSchedule
。这是优化版本的 NoSchedule
—— 系统会尽量避免将 pod 调度到存在其不能容忍 taint 的节点上,但这不是强制的。effect
的值还可以设置为 NoExecute
。
其中 [effect] 可取值: [ NoSchedule | PreferNoSchedule | NoExecute ]
- NoSchedule: 一定不能被调度
- PreferNoSchedule: 尽量不要调度,实在没有地方调度的情况下,才考虑可以调度过来
- NoExecute: 不仅不会调度, 还会立即驱逐Node上已有的Pod
添加多个tainit(污点)
您可以给一个节点添加多个 taint ,也可以给一个 pod 添加多个 toleration。Kubernetes 处理多个 taint 和 toleration 的过程就像一个过滤器:从一个节点的所有 taint 开始遍历,过滤掉那些 pod 中存在与之相匹配的 toleration 的 taint。余下未被过滤的 taint 的 effect 值决定了 pod 是否会被分配到该节点,特别是以下情况:
- 如果未被过滤的 taint 中存在一个以上 effect 值为
NoSchedule
的 taint,则 Kubernetes 不会将 pod 分配到该节点。 - 如果未被过滤的 taint 中不存在 effect 值为
NoSchedule
的 taint,但是存在 effect 值为PreferNoSchedule
的 taint,则 Kubernetes 会尝试将 pod 分配到该节点。 - 如果未被过滤的 taint 中存在一个以上 effect 值为
NoExecute
的 taint,则 Kubernetes 不会将 pod 分配到该节点(如果 pod 还未在节点上运行),或者将 pod 从该节点驱逐(如果 pod 已经在节点上运行)。
例如,假设您给一个节点添加了如下的 taint
kubectl taint nodes node1 key1=value1:NoSchedule
kubectl taint nodes node1 key1=value1:NoExecute
kubectl taint nodes node1 key2=value2:NoSchedule
然后存在一个 pod,它有两个 toleration
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
在这个例子中,上述 pod 不会被分配到上述节点,因为其没有 toleration 和第三个 taint 相匹配。但是如果在给节点添加 上述 taint 之前,该 pod 已经在上述节点运行,那么它还可以继续运行在该节点上,因为第三个 taint 是三个 taint 中唯一不能被这个 pod 容忍的。
通常情况下,如果给一个节点添加了一个 effect 值为 NoExecute
的 taint,则任何不能忍受这个 taint 的 pod 都会马上被驱逐,任何可以忍受这个 taint 的 pod 都不会被驱逐。但是,如果 pod 存在一个 effect 值为 NoExecute
的 toleration 指定了可选属性 tolerationSeconds
的值,则表示在给节点添加了上述 taint 之后,pod 还能继续在节点上运行的时间。例如,
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
tolerationSeconds: 3600
这表示如果这个 pod 正在运行,然后一个匹配的 taint 被添加到其所在的节点,那么 pod 还将继续在节点上运行 3600 秒,然后被驱逐。如果在此之前上述 taint 被删除了,则 pod 不会被驱逐。
使用例子
通过 taint 和 toleration ,可以灵活地让 pod 避开某些节点或者将 pod 从某些节点驱逐。下面是几个使用例子:
专用节点:如果您想将某些节点专门分配给特定的一组用户使用,您可以给这些节点添加一个 taint(即,
kubectl taint nodes nodename dedicated=groupName:NoSchedule
),然后给这组用户的 pod 添加一个相对应的 toleration(通过编写一个自定义的admission controller,很容易就能做到)。拥有上述 toleration 的 pod 就能够被分配到上述专用节点,同时也能够被分配到集群中的其它节点。如果您希望这些 pod 只能被分配到上述专用节点,那么您还需要给这些专用节点另外添加一个和上述 taint 类似的 label (例如:dedicated=groupName
),同时 还要在上述 admission controller 中给 pod 增加节点亲和性要求上述 pod 只能被分配到添加了dedicated=groupName
标签的节点上。配备了特殊硬件的节点:在部分节点配备了特殊硬件(比如 GPU)的集群中,我们希望不需要这类硬件的 pod 不要被分配到这些特殊节点,以便为后继需要这类硬件的 pod 保留资源。要达到这个目的,可以先给配备了特殊硬件的节点添加 taint(例如
kubectl taint nodes nodename special=true:NoSchedule
orkubectl taint nodes nodename special=true:PreferNoSchedule
),然后给使用了这类特殊硬件的 pod 添加一个相匹配的 toleration。和专用节点的例子类似,添加这个 toleration 的最简单的方法是使用自定义 admission controller。比如,我们推荐使用 Extended Resources 来表示特殊硬件,给配置了特殊硬件的节点添加 taint 时包含 extended resource 名称,然后运行一个 ExtendedResourceToleration admission controller。此时,因为节点已经被 taint 了,没有对应 toleration 的 Pod 会被调度到这些节点。但当你创建一个使用了 extended resource 的 Pod 时,ExtendedResourceToleration
admission controller 会自动给 Pod 加上正确的 toleration ,这样 Pod 就会被自动调度到这些配置了特殊硬件件的节点上。这样就能够确保这些配置了特殊硬件的节点专门用于运行 需要使用这些硬件的 Pod,并且您无需手动给这些 Pod 添加 toleration。基于 taint 的驱逐 (alpha 特性): 这是在每个 pod 中配置的在节点出现问题时的驱逐行为,接下来的章节会描述这个特性
基于 taint 的驱逐
前面我们提到过 taint 的 effect 值 NoExecute
,它会影响已经在节点上运行的 pod
- 如果 pod 不能忍受effect 值为
NoExecute
的 taint,那么 pod 将马上被驱逐 - 如果 pod 能够忍受effect 值为
NoExecute
的 taint,但是在 toleration 定义中没有指定tolerationSeconds
,则 pod 还会一直在这个节点上运行。 - 如果 pod 能够忍受effect 值为
NoExecute
的 taint,而且指定了tolerationSeconds
,则 pod 还能在这个节点上继续运行这个指定的时间长度。
此外,Kubernetes 1.6 已经支持(alpha阶段)节点问题的表示。换句话说,当某种条件为真时,node controller会自动给节点添加一个 taint。当前内置的 taint 包括:
node.kubernetes.io/not-ready
:节点未准备好。这相当于节点状态Ready
的值为 “False
”。node.kubernetes.io/unreachable
:node controller 访问不到节点. 这相当于节点状态Ready
的值为 “Unknown
”。node.kubernetes.io/out-of-disk
:节点磁盘耗尽。node.kubernetes.io/memory-pressure
:节点存在内存压力。node.kubernetes.io/disk-pressure
:节点存在磁盘压力。node.kubernetes.io/network-unavailable
:节点网络不可用。node.kubernetes.io/unschedulable
: 节点不可调度。node.cloudprovider.kubernetes.io/uninitialized
:如果 kubelet 启动时指定了一个 “外部” cloud provider,它将给当前节点添加一个 taint 将其标志为不可用。在 cloud-controller-manager 的一个 controller 初始化这个节点后,kubelet 将删除这个 taint。
在启用了 TaintBasedEvictions
这个 alpha 功能特性后(在 Kubernetes controller manager 的 --feature-gates
参数中包含TaintBasedEvictions=true
开启这个功能特性,例如:--feature-gates=FooBar=true,TaintBasedEvictions=true
),NodeController (或 kubelet)会自动给节点添加这类 taint,上述基于节点状态 Ready 对 pod 进行驱逐的逻辑会被禁用。
注意:为了保证由于节点问题引起的 pod 驱逐rate limiting行为正常,系统实际上会以 rate-limited 的方式添加 taint。在像 master 和 node 通讯中断等场景下,这避免了 pod 被大量驱逐。
使用这个 alpha 功能特性,结合 tolerationSeconds
,pod 就可以指定当节点出现一个或全部上述问题时还将在这个节点上运行多长的时间。
比如,一个使用了很多本地状态的应用程序在网络断开时,仍然希望停留在当前节点上运行一段较长的时间,愿意等待网络恢复以避免被驱逐。在这种情况下,pod 的 toleration 可能是下面这样的:
tolerations:
- key: "node.alpha.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 6000
注意,Kubernetes 会自动给 pod 添加一个 key 为 node.kubernetes.io/not-ready
的 toleration 并配置 tolerationSeconds=300
,除非用户提供的 pod 配置中已经已存在了 key 为 node.kubernetes.io/not-ready
的 toleration。同样,Kubernetes 会给 pod 添加一个 key 为 node.kubernetes.io/unreachable
的 toleration 并配置 tolerationSeconds=300
,除非用户提供的 pod 配置中已经已存在了 key 为 node.kubernetes.io/unreachable
的 toleration。
这种自动添加 toleration 机制保证了在其中一种问题被检测到时 pod 默认能够继续停留在当前节点运行 5 分钟。这两个默认 toleration 是由 DefaultTolerationSeconds
admission controller添加的。
DaemonSet 中的 pod 被创建时,针对以下 taint 自动添加的 NoExecute
的 toleration 将不会指定 tolerationSeconds
:
node.alpha.kubernetes.io/unreachable
node.kubernetes.io/not-ready
这保证了出现上述问题时 DaemonSet 中的 pod 永远不会被驱逐,这和 TaintBasedEvictions
这个特性被禁用后的行为是一样的。
基于节点状态添加 taint
1.8 版本引入了一个 alpha 特性,让 node controller 根据节点的状态创建 taint。当开启了这个特性时(通过给 scheduler 的 --feature-gates
添加 TaintNodesByCondition=true
参数,例如:--feature-gates=FooBar=true,TaintNodesByCondition=true
),scheduler不会去检查节点的状态,而是检查节点的 taint。这确保了节点的状态不影响应该调度哪些 Pod 到节点上。用户可以通过给 Pod 添加 toleration 来选择忽略节点的一些问题(节点状态的形式表示)。
从 Kubernetes 1.8 开始,DaemonSet controller 会自动添加如下 NoSchedule
toleration,以防止 DaemonSet 中断。
node.kubernetes.io/memory-pressure
node.kubernetes.io/disk-pressure
node.kubernetes.io/out-of-disk
(只适合 critical pod)node.kubernetes.io/unschedulable
(1.10 或更高版本)node.kubernetes.io/network-unavailable
(只适合 host network)
添加上述 toleration 确保了向后兼容,您也可以选择自由的向 DaemonSet 添加 toleration。
期待下次的分享,别忘了三连支持博主呀~
我是 念舒_C.ying ,期待你的关注~
【云原生 · Kubernetes】Taint和Toleration(污点和容忍)的更多相关文章
- 系列文章:云原生Kubernetes日志落地方案
在Logging这块做了几年,最近1年来越来越多的同学来咨询如何为Kubernetes构建一个日志系统或者是来求助在这过程中遇到一系列问题如何解决,授人以鱼不如授人以渔,于是想把我们这些年积累的经验以 ...
- [云原生]Kubernetes - 集群搭建(第2章)
目录 一.前置知识点 二.kubeadm部署方式介绍 三.安装要求 四.最终目标 五.准备环境 六.环境初始化 6.1 设置系统主机名以及Hosts文件的相互解析 6.2 安装依赖文件(所有节点) 6 ...
- Kubernetes高级调度- Taint和Toleration、Node Affinity分析
此文分享了污点和Node Affinity实际使用过程中的细节.坑和思维误区.同时整理且回答了诸多细节问题,尤其那些在官方文档中不曾提及的细节. 阅读提示:文中的节点指Node (避免Pod和Node ...
- Kubernetes K8S之Taints污点与Tolerations容忍详解
Kubernetes K8S之Taints污点与Tolerations容忍详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master C ...
- Kubernetes v1.16 发布 | 云原生生态周报 Vol. 20
作者:心贵.进超.元毅.心水.衷源.洗兵 业界要闻 Kubernetes v1.16 发布 在这次发布中值得关注的一些特性和 Feature: CRD 正式进入 GA 阶段: Admission We ...
- Kubernetes v1.17 版本解读 | 云原生生态周报 Vol. 31
作者 | 徐迪.李传云.黄珂.汪萌海.张晓宇.何淋波 .陈有坤.李鹏审核 | 陈俊 上游重要进展 1. Kubernetes v1.17 版本发布 功能稳定性是第一要务.v1.17 包含 22 个增强 ...
- [转帖]Kubernetes v1.17 版本解读 | 云原生生态周报 Vol. 31
Kubernetes v1.17 版本解读 | 云原生生态周报 Vol. 31 https://www.kubernetes.org.cn/6252.html 2019-12-13 11:59 ali ...
- Kubernetes对Pod调度指定Node以及Node的Taint 和 Toleration
由于博客园不支持markdown,推荐以下url阅读: 原创url:https://blog.csdn.net/weixin_42495873/article/details/103364868 ## ...
- 从Kubernetes到“云原生全家桶”,网易如何让业务部署提效280%?
近日,网易云轻舟微服务团队接受了CNCF的采访,分享了网易云在云原生领域尤其是Kubernetes方面的实践经验.以下为案例全文:公司:网易地点:中国杭州行业:互联网技术 挑战它的游戏业务是世界上最大 ...
- 如何将云原生工作负载映射到 Kubernetes 中的控制器
作者:Janakiram MSV 译者:殷龙飞 原文地址:https://thenewstack.io/how-to-map-cloud-native-workloads-to-kubernetes- ...
随机推荐
- 第十章 Kubernetes的CNI网络插件--flannel
1.简介 1.1前言 Kubernetes设计了网络模型,但却将它的实现讲给了网络插件,CNI网络插件最重要的功能就是实现Pod资源能够跨主机通信 常见的CNI网络插件如下: Flannel: Cac ...
- logstash客户端传送symantec日志到elasticsearch
一.安装相应版本的logstash wget https://artifacts.elastic.co/downloads/beats/logstash/logstash-7.5.2-x86_64.r ...
- Windows编程之线程
本笔记整理自:<Windows核心编程(第五版)> 目录 何为线程 线程的开始和结束 创建线程 终止线程 线程运行时的调度和线程优先级 挂起(暂停).恢复与睡眠 挂起 恢复 睡眠 线程切换 ...
- jenkins流水线部署springboot应用到k8s集群(k3s+jenkins+gitee+maven+docker)(1)
前言:前面写过2篇文章,介绍jenkins通过slave节点部署构建并发布应用到虚拟机中,本篇介绍k8s(k3s)环境下,部署jenkins,通过流水线脚本方式构建发布应用到k8s(k3s)集群环境中 ...
- 设置HTTP请求自动跳转HTTPS
第一种方式,分两种情况: 第一种情况:修改Nginx安装目录/conf/nginx.conf文件 server { listen 80; server_name localhost; #将localh ...
- k8s中使用到的各种证书图示
- Rust学习入门
介绍 特性: 高性能,内存利用率高,没有运行时和垃圾回收 可靠 , 丰富的类型系统和所有权模型保证内存和线程安全,编译器可以消除各种错误 生产力, 包管理器.构建工具一流, 多编辑器支持自动补齐和格式 ...
- useContext 解决函数父子组件传值
1在父组件外部定义变量A创建上下文,2在父组件使用变量A<A.Provider> <子组件/> </A.Provider> ,3.在子组件中创建变量使用useCon ...
- css 悬停图片改变图片的样式
<style> #div{ text-align: center; } .img{ width: 200px; clip-path: polygon(50% 0,100% 50%,50% ...
- CVPR2022 Oral OGM-GE阅读笔记
标题:Balanced Multimodal Learning via On-the-fly Gradient Modulation(CVPR 2022 Oral) 论文:https://arxiv. ...