Taints和Tolerations(污点和容忍)

《K8S之节点亲和性》中,我们说到的的NodeAffinity节点亲和性,是在pod上定义的一种属性,使得Pod能够被调度到某些node上运行。Taint刚好相反,它让Node拒绝Pod的运行。

Taint需要与Toleration配合使用,让pod避开那些不合适的node。在node上设置一个或多个Taint后,除非pod明确声明能够容忍这些“污点”,否则无法在这些node上运行。Toleration是pod的属性,让pod能够(注意,只是能够,而非必须)运行在标注了Taint的node上。

基本用法

  1. 设置污点:
    kubectl taint node [node] key=value[effect]
其中[effect] 可取值: [ NoSchedule | PreferNoSchedule | NoExecute ]
NoSchedule :一定不能被调度。
PreferNoSchedule:尽量不要调度。
NoExecute:不仅不会调度,还会驱逐Node上已有的Pod。 #示例:
kubectl taint node 10.3.1.16 test=16:NoSchedule
  1. 去除污点:
    #比如设置污点:
kubectl taint node 10.3.1.16 test=16:NoSchedule
kubectl taint node 10.3.1.16 test=16:NoExecute #去除指定key及其effect:
kubectl taint nodes node_name key:[effect]- #(这里的key不用指定value) #去除指定key所有的effect:
kubectl taint nodes node_name key- #示例:
kubectl taint node 10.3.1.16 test:NoSchedule-
kubectl taint node 10.3.1.16 test:NoExecute-
kubectl taint node 10.3.1.16 test-

下面是一个简单的示例:

在node1上加一个Taint,该Taint的键为key,值为value,Taint的效果是NoSchedule。这意味着除非pod明确声明可以容忍这个Taint,否则就不会被调度到node1上:

kubectl taint nodes node1  key=value:NoSchedule

然后需要在pod上声明Toleration。下面的Toleration设置为可以容忍具有该Taint的Node,使得pod能够被调度到node1上:

apiVersion: v1
kind: Pod
metadata:
name: pod-taints
spec:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
containers:
- name: pod-taints
image: busybox:latest

也可以写成如下:

tolerations:
- key: "key"
operator: "Exists"
effect: "NoSchedule"

pod的Toleration声明中的key和effect需要与Taint的设置保持一致,并且满足以下条件之一:

  • operator的值为Exists,这时无需指定value
  • operator的值为Equal并且value相等

如果不指定operator,则默认值为Equal。

另外还有如下两个特例:

  • 空的key配合Exists操作符能够匹配所有的键和值
  • 空的effect匹配所有的effect

effect说明

上面的例子中effect的取值为NoSchedule,下面对effect的值作下简单说明:

  • NoSchedule: 如果一个pod没有声明容忍这个Taint,则系统不会把该Pod调度到有这个Taint的node上

  • PreferNoSchedule:NoSchedule的软限制版本,如果一个Pod没有声明容忍这个Taint,则系统会尽量避免把这个pod调度到这一节点上去,但不是强制的。

  • NoExecute:定义pod的驱逐行为,以应对节点故障。NoExecute这个Taint效果对节点上正在运行的pod有以下影响:

    • 没有设置Toleration的Pod会被立刻驱逐

    • 配置了对应Toleration的pod,如果没有为tolerationSeconds赋值,则会一直留在这一节点中

    • 配置了对应Toleration的pod且指定了tolerationSeconds值,则会在指定时间后驱逐

    • 从kubernetes 1.6版本开始引入了一个alpha版本的功能,即把节点故障标记为Taint(目前只针对node unreachable及node not ready,相应的NodeCondition "Ready"的值为Unknown和False)。激活TaintBasedEvictions功能后(在--feature-gates参数中加入TaintBasedEvictions=true),NodeController会自动为Node设置Taint,而状态为"Ready"的Node上之前设置过的普通驱逐逻辑将会被禁用。注意,在节点故障情况下,为了保持现存的pod驱逐的限速设置,系统将会以限速的模式逐步给node设置Taint,这就能防止在一些特定情况下(比如master暂时失联)造成的大量pod被驱逐的后果。这一功能兼容于tolerationSeconds,允许pod定义节点故障时持续多久才被逐出。

多污点与多容忍配置

系统允许在同一个node上设置多个taint,也可以在pod上设置多个Toleration。Kubernetes调度器处理多个Taint和Toleration能够匹配的部分,剩下的没有忽略掉的Taint就是对Pod的效果了。下面是几种特殊情况:

  • 如果剩余的Taint中存在effect=NoSchedule,则调度器不会把该pod调度到这一节点上。

  • 如果剩余的Taint中没有NoSchedule的效果,但是有PreferNoSchedule效果,则调度器会尝试不会pod指派给这个节点

  • 如果剩余Taint的效果有NoExecute的,并且这个pod已经在该节点运行,则会被驱逐;如果没有在该节点运行,也不会再被调度到该节点上。

下面是一个示例:

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无法被调度到node1上,因为第三个taint没有匹配的toleration。但是如果这个Pod已经在node1上运行了,那么在运行时设置上第三个Taint,它还能继续运行,因为pod可以容忍前两个taint。

一般来 说,如果给node加上effect=NoExecute的Taint,那么该 node上正在运行的所有无对应toleration的pod都会被立刻驱逐,而具有相应toleration的pod则永远不会被逐出。不过系统允许给具有NoExecute效果的Toleration加入一个可选 的tolerationSeconds字段,这个设置表明pod可以在Taint添加到node之后还能在这个node上运行多久(单们为s):

tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
tolerationSeconds: 3600

上面的例子的意思是,如果pod正在运行,所在节点被加入一个匹配的Taint,则这个Pod会持续在这个节点上存活3600s后被驱逐。如果在这个宽限期内taint被移除,则不会触发驱逐事件。

常见应用场景

节点独占

如果想要拿出一部分节点,专门给特定的应用使用,则可以为节点添加这样的Taint:

kubectl taint nodes nodename dedicated=groupName:NoSchedule

然后给这些应用的pod加入相应的toleration,则带有合适toleration的pod就会被允许同使用其他节点一样使用有taint的节点。然后再将这些node打上指定的标签,再通过nodeSelector或者亲和性调度的方式,要求这些pod必须运行在指定标签的节点上。

具有特殊硬件设备的节点

在集群里,可能有一小部分节点安装了特殊的硬件设备,比如GPU芯片。用户自然会希望把不需要占用这类硬件的pod排除在外。以确保对这类硬件有需求的pod能够顺利调度到这些节点上。可以使用下面的命令为节点设置taint:

kubectl taint nodes nodename special=true:NoSchedule
kubectl taint nodes nodename special=true:PreferNoSchedule

然后在pod中利用对应的toleration来保障特定的pod能够使用特定的硬件。然后同样的,我们也可以使用标签或者其他的一些特征来判断这些pod,将其调度到这些特定硬件的服务器上。

应对节点故障

之前说到,在节点故障时,可以通过TaintBasedEvictions功能自动将节点设置Taint,然后将pod驱逐。但是在一些场景下,比如说网络故障造成的master与node失联,而这个node上运行了很多本地状态的应用即使网络故障,也仍然希望能够持续在该节点上运行,期望网络能够快速恢复,从而避免从这个node上被驱逐。Pod的Toleration可以这样定义:

tolerations:
- key: "node.alpha.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 6000

对于Node未就绪状态,可以把key设置为node.alpha.kubernetes.io/notReady

如果没有为pod指定node.alpha.kubernetes.io/noReadyToleration,那么Kubernetes会自动为pod加入tolerationSeconds=300的node.alpha.kubernetes.io/notReady类型的toleration

同样,如果没有为pod指定node.alpha.kubernetes.io/unreachableToleration,那么Kubernetes会自动为pod加入tolerationSeconds=300的node.alpha.kubernetes.io/unreachable类型的toleration

这些系统自动设置的toleration用于在node发现问题时,能够为pod确保驱逐前再运行5min。这两个默认的toleration由Admission Controller "DefaultTolerationSeconds"自动加入。

K8S调度之Taints and Tolerations的更多相关文章

  1. 从相亲的角度理解 K8S 的 Node Affinity, Taints 与 Tolerations

    这是昨天晚上阅读园子里的2篇 k8s 博文时产生的想法,在随笔中记录一下. 这2篇博文是 K8S调度之节点亲和性 与 K8S调度之Taints and Tolerations . 如果我们把 node ...

  2. k8s调度器、预选策略及调度方式

    一.k8s调度流程 1.(预选)先排除完全不符合pod运行要求的节点2.(优先)根据一系列算法,算出node的得分,最高没有相同的,就直接选择3.上一步有相同的话,就随机选一个 二.调度方式 1.no ...

  3. Kubernetes之Taints与Tolerations 污点和容忍

    NodeAffinity节点亲和性,是Pod上定义的一种属性,使Pod能够按我们的要求调度到某个Node上,而Taints则恰恰相反,它可以让Node拒绝运行Pod,甚至驱逐Pod. Taints(污 ...

  4. 7.k8s.调度器scheduler 亲和性、污点

    #k8s. 调度器scheduler 亲和性.污点 默认调度过程:预选 Predicates (过滤节点) --> 优选 Priorities(优先级排序) --> 优先级最高节点 实际使 ...

  5. Taints 与 Tolerations

    节点亲和性是描述Pods如何分配到一个或一组节点的策略,亲和性的相关资料可以参考Kubernetes中的亲和性与反亲和性.与亲和性规则不同, Taints 描述节点拒绝一个或一组Pods的策略.其实现 ...

  6. Taints和Tolerations

    Taints和Tolerations和搭配使用的,Taints定义在Node节点上,声明污点及标准行为,Tolerations定义在Pod,声明可接受得污点. 可以在命令行为Node节点添加Taint ...

  7. K8S调度之pod亲和性

    目录 Pod Affinity Pod亲和性调度 pod互斥性调度 Pod Affinity 通过<K8S调度之节点亲和性>,我们知道怎么在调度的时候让pod灵活的选择node,但有些时候 ...

  8. k8s 调度 GPU

    最近公司有项目想在 k8s 集群中运行 GPU 任务,于是研究了一下.下面是部署的步骤. 1. 首先得有一个可以运行的 k8s 集群. 集群部署参考 kubeadm安装k8s 2. 准备 GPU 节点 ...

  9. Taints和Tolerations联用,将pod部署到k8s的master节点

    一般,k8s的master为了保持高性能,在这个主节点上只运行一些管理必须的POD. 如果我们限于资源,或是一些监控类的pod要部署到master节点呢? 昨天遇到这个问题,按网上通用的方法,未解决, ...

随机推荐

  1. Daily Scrum (2015/10/31)

    这几天我们组的进度有点慢,剩下这一周的我们必须要加油认真对待. 周末这两天我们是这样安排的: 成员 今日任务 时间 明日任务 符美潇 数据库部分代码的编写 1h 每周小组例会 潘礼鹏 团队博客作业   ...

  2. Daily Srum 10.22

    今天大家的状态比较好,但是还是有很多问题没有解决.首先就是服务器这方面,部分同学还不怎么会用:其次就是看代码出现了困难,不能完整地阅读:还有就是我们的昨天的任务有点困难,部分同学不能按时按量的完成!于 ...

  3. 四则运算结对项目之GUI

    本次结对编程让我学到了许多许多知识,受益匪浅!在此之前,我没想过我能做出一个双击运行的小程序. 感谢我的队友与我同心协力,感谢室友宇欣告诉我操作符为“最多多少”而不是“多少”并教我使用效能分析工具,感 ...

  4. [并查集] 1107. Social Clusters (30)

    1107. Social Clusters (30) When register on a social network, you are always asked to specify your h ...

  5. React鼠标事件

    说明:假设有一个用户名片,当鼠标滑到上面,显示用户详细信息,且用户详情卡片位置随鼠标位置改变而改变. UI框架:Material-ui 实现思路: 1.一个用户简介组件A(用于展示用户列表): 2.一 ...

  6. Vue2.0组件之间通信(转载)

    Vue中组件这个特性让不少前端er非常喜欢,我自己也是其中之一,它让前端的组件式开发更加合理和简单.笔者之前有写过一篇Vue2.0子父组件通信,这次我们就来聊一聊平级组件之间的通信. 首先我们先搭好开 ...

  7. [转帖]一文读懂 HTTP/2

    一文读懂 HTTP/2 http://support.upyun.com/hc/kb/article/1048799/ 又小拍 • 发表于:2017年05月18日 15:34:45 • 更新于:201 ...

  8. [转帖]DAS、SAN、NAS

    http://blog.itpub.net/26736162/viewspace-2214368/ DAS(Direct-attached Storage) 直连存储 直连式存储与服务器主机之间的连接 ...

  9. Python编写登陆接口

    实现功能: 输入用户名和密码 认证成功后显示欢迎信息 输错三次后锁定 # 提示输入用户名和密码 # 验证用户名和密码 # 如果错误,则输出用户名或密码错误 # 如果成功,则输出 欢迎,XXX! #!/ ...

  10. Eclipse中设置新创建文件的默认编码格式

    window-prefenences-web-jsp(或者是其他文件格式,里面是一个列表) 找到之后点击,在右侧区域中选择encoding进行修改即可,然后应用,OK