【云原生 · 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:NoScheduleorkubectl 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 时,ExtendedResourceTolerationadmission 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/unreachablenode.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-pressurenode.kubernetes.io/disk-pressurenode.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- ...
随机推荐
- 在安装Windows时手动创建分区
目前硬件都已经支持UEFI模式启动了,而且硬盘容量普遍大于MBR磁盘能支持的最大2TB的容量.所以在安装Windows系统的时候优先选用UEFI启用,并将磁盘配置为GPT模式以支持更大的容量.而且Wi ...
- Java SE 19 新增特性
Java SE 19 新增特性 作者:Grey 原文地址: 博客园:Java SE 19 新增特性 CSDN:Java SE 19 新增特性 源码 源仓库: Github:java_new_featu ...
- CentOS yum如何安装php7.4
centos系统下使用yum安装php7.4正式版,当前基于WLNMP提供的一键安装包来安装 1.添加epel源 yum install epel-release 2.添加WLNMP一键安装包源 rp ...
- linux开机自启服务
前言:最近,有一个项目需要用到开机自动启动机房,所以就研究了一下 1.把node的快捷方式放在放在/usr/bin/(环境变量)下面,所有的命令默认是从这里面进行调用的 ln -s /home/too ...
- 把train数据集生成txt(test同理)
import cv2 import numpy as np import os import sys import pickle data_dir = os.path.join("./&qu ...
- POJ2728 Desert King (最小生成树、0/1分数规划)
显然的0/1分数规划问题,用二分来解决,检验mid,就用prim算法求最小生成树,看总边权是否大等于0即可验证. 1 #include<bits/stdc++.h> 2 using nam ...
- ClickHouse(07)ClickHouse数据库引擎解析
目录 Atomic 建表语句 特性 Table UUID RENAME TABLES DROP/DETACH TABLES EXCHANGE TABLES ReplicatedMergeTree in ...
- 5.RabbitMQ系列之headers交换器
headers exchange是根据消息header值而不是routing key将消息路由到队列的交换器. 生产者在消息头中以键值对的形式添加一些值,并将其发送到headers exchange, ...
- springboot+bootstrap实现图书商城管理(大三下学期课程设计)
在csdn上记一次自己的课程设计过程(已经实习两个月了.感觉这个很容易做.支付可能需要多花点时间.): 在此框架基础之上权限认证管理设置成功:https://blog.csdn.net/weixin_ ...
- 33.ModelSerializer详解
ModelSerializer特点 根据Model模型的定义,自动生成字段 自动生成相应的验证器 实现create和update 自动默认将关系字段映射成PrimaryKeyRelatedField主 ...