k8s之Taint 与 Toleration (污点与容忍)
  5qgUhteqoi3E 2023年11月02日 95 0

背景介绍:

在生产k8s集群环境中,业务的pod数量很多,首先要满足的就是所有pod能够负载均衡的分配到集群中的各个节点,其次就是每台服务器的硬件配置可能不同,特定的业务服务需要运行到特定的node上(比如依赖GPU,业务服务所依赖的高/低硬件配置)而为了达到用户所期望的服务调度,我们可以用到污点/容忍;以及下一篇的亲和/反亲和。

1,什么是污点和容忍度?

污点(Taint):是应用在节点之上的,从这个名字就可以看出来,是为了排斥pod所存在的; 容忍度(Toleration):是应用于pod上的,允许(但并不要求) pod调度到带有与之匹配的污点的节点上。

2,污点和容忍度的作用?

Taint和Toleration可以作用于node和pod上,其目的是优化pod在集群间的调度,这跟节点亲和性类似,只不过它们作用的方式相反,具有taint的node和pod是互斥关系,而具有节点亲和性关系的node和pod是相吸的。另外还有可以给node节点设置label,通过给pod设置NodeSelector将pod调度到具有匹配标签的节点上。

Taint和Toleration相互,可以用来避免pod被分配到不合适的节点上。每个节点上都可以应用一个或多个taint,这表示对于那些不能容忍这些taint的pod,是不会被该节点接受的。如果将toleration应用于pod上,则表示这些pod可以(但不要求)被调度具有相应taint的节点上。

3,设置/查看/删除污点

给节点node1增加一个污点,它的键名是key1,键值是value1,效果式NoSchedule。这表示只有拥有和这个污点相匹配的容忍度的pod才能够被分配到node1这个节点:

//设置污点

kubectl taint nodes k8s-master key1=value1:NoSchedule    

格式:kubectl taint node [node] key=value[effect] 其中[effect]可取值如下:

  • PreferNoSchedule:尽量不要调度
  • NoSchedule: 一定不能被调度
  • NoExecute: 不仅不会调度,还会驱逐node上已有的pod

//查看污点 污点是设置在 Node 节点上,所以我们可以通过查看节点信息来查找该节点是否设置污点以及对污点的信息(输出节点描述信息一栏中 Taints 标题后面的内容,即是污点的信息):

kubectl describe node k8s-master 

image.png

//删除污点

kubectl taint nodes k8s-master key1=values1:NoSchedule-  

image.png

//验证污点是否删除: image.png

4,pod设置容忍tolerations

为了使某些pod禁止调度到某些特定节点上,就可以对节点设置污点taints。当然,如果希望有些pod能够忽略节点的污点,继续能够调度到该节点,就可以对pod设置容忍,让pod能够容忍节点上设置的污点。

1)对pod设置容忍,以下两种方式都可:

//容忍的key,value和对应的effect 也必须和污点 taints保持一致
tolerations:
- key: "key"
  operator: "Equal"
  value: "value"
  effect: "NoSchedule"
//容忍 tolerations的key要和污点 taints的key一致,且设置的effect也相同,不需要设置value
tolerations:
- key: "key"
  operator: "Exists"
  effect: "NoSchedule"

实例: image.png

5,deployment中设置容忍

示例如下:

apiVersion: apps/vl
kind: Deployment
metadata: 
  name: example 
spec: 
  replicas: 5 
  template:
    spec: 
      ......
      tolerations: 
      - key: "key"
        operator: "Equal"
        value: "value"
        effect: "NoSchedule"

6,设置容忍时间

当一个污点带有 effect=NoExecute 被添加到了这个node。那么不能容忍这个污点的所有pod就会立即被踢掉,而带有容忍标签的pod就不会踢掉。然而,一个带有 effect=NoExecute 的容忍可以指定一个 tolerationSeconds 来指定当这个污点被添加的时候在多长时间内不被踢掉。例如:

tolerations:
- key: "key"
  operator: "Equal"
  value: "value"
  effect: "PreferNoSchedule"
  tolerationSeconds: 3600

ps: 如果这个pod已经在这个带污点且effect为NoExecute的node上。这个pod可以一直运行到3600s后再被踢掉。如果这时候node的污点被移除了,这个pod则就不会被踢掉。

7,Operator字段详解

Operator 默认是 Equal,可设置EqualExists 两种; Operator=Exists(此时容忍度不能指定 value) 1)容忍任何污点:例如一个空的key,将匹配所有的key,value,effect。即容忍任何污点;实例如下:

tolerations:
- operator: "Exists"

2)容忍某key值的污点:例如一个空的effect,而key不为空,那么将匹配所有与key相同的effect;实例如下:

tolerations:
- key: "key"
  operator: "Exists"

Operator=Equal(则它们的 value 应该相等) 1)node上有一个污点: node和pod的可以为key1,value1与effect相同则能调度,实例如下:

#污点
key1=value1:NoSchedule

#Pod设置
tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoSchedule"

2)node上有多个污点 point1:node的污点的key,value,effect和pod容忍都相同则能调度;实例如下:

# 设置污点
key1=value1:NoSchedule
key2=value2:NoExecute

# Pod设置容忍
tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoSchedule"
- key: "key2"
  operator: "Equal"
  value: "value2"
  effect: "NoExecute"

point2: node的污点和pod的大部分都相同,不同的是node污点effect为PreferNoSchedule的,可能会调度;实例如下:

# 污点
key1=value1:NoSchedule
key2=value2:NoExecute
key3=value3:PreferNoSchedule

# Pod设置容忍
tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoSchedule"
- key: "key2"
  operator: "Equal"
  value: "value2"
  effect: "NoExecute"

point3: node的污点和pod的大部分都相同,不同的是node污点effect为NoScheduleNoExecute 的,不会被调度;实例如下:

# 污点
key1=value1:NoSchedule
key2=value2:NoExecute
key3=value3:PreferNoSchedule

# Pod设置容忍
tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoSchedule"
- key: "key3"
  operator: "Equal"
  value: "value3"
  effect: "PreferNoSchedule"

8,污染驱逐

上边我们提到了污点的effect可以设置为 NoExecute,它会影响节点上已经运行的pod,如下所示:

  • 立即将没有配置容忍的pod逐出。
  • 设置容忍但是没有指定 tolerationSeconds 参数的,那么该容忍永久生效。
  • 设置容忍但是有指定 tolerationSeconds 参数的,那么在指定的时间内,容忍有效,超出指定时间后将被剔除。

此外,当某些条件为true时,节点控制器会自动污染节点。也就是k8s的内置污点:

  • node.kubernetes.io/not-ready: 节点尚未准备好。这对应于NodeCondition Ready为false。
  • node.kubernetes.io/unreachable: 无法从节点控制器访问节点。这对应于NodeCondition 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-controller-manager的控制器初始化此节点后,kubelet删除此污点。

在版本 1.13 中,该 TaintBasedEvictions 功能提升为 beta 并默认情况下启用,因此 NodeController(或 kubelet)会自动添加污点,并且将禁用基于 Ready NodeCondition 从节点驱逐 Pod 的常规逻辑。

Node和pod对于污点与容忍基本概念总结

1,概念

  • 一个node可以有多个污点;
  • 一个pod可以有多个容忍;
  • 执行多个污点和容忍方法类似于过滤器;

如果一个node有多个污点,且pod上也有多个容忍,只要pod中容忍能包含node上设置的全部污点,就可以将pod调度到该node上。如果pod上设置的容忍不能够包含node上设置的全部污点,且node上剩下不能被包含的污点effect为PreferNoSchedule,那么也可能会被调度到该节点。

2,注意:

  • 1)如果node上带有污点 effect为 NoSchedule,而node上不带相应容忍,k8s就不会调度pod到这台node上。
  • 2)如果node上带有污点 effect 为 PreferNoSchedule,这时候k8s会努力不要调度这个pod到这个node上。
  • 3)如果node上带有污点 effect 为 NoExecute,这个已经在node上运行的pod会从node上驱逐掉。且运行在node的pod不能被调度到这个node节点上。

官方文档参考: https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration/

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

5qgUhteqoi3E