k8s学习笔记-Taints与Tolerations

本文从简单理解的角度介绍了Kubernetes的污点(Taint)和容忍(Toleration)高级调度功能。污点可让Node拒绝运行Pod,容忍则使Pod能容忍Node污点从而被调度。文中还介绍了设置、删除污点的命令,以及利用该特性确保Master节点不执行工作负载等应用实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

污点(Taint)和容忍(Toleration)是从Kubernetes 1.6开始提供的高级调度功能。 在Kubernetes的文档中Taints and Tolerations的介绍已经十分详细。 本文将从简单理解的角度看一下Taint和Toleration。 

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

Taints(污点)是Node的一个属性,设置了Taints(污点)后,因为有了污点,所以Kubernetes是不会将Pod调度到这个Node上的,

于是Kubernetes就给Pod设置了个属性Tolerations(容忍),只要Pod能够容忍Node上的污点,那么Kubernetes就会忽略Node上的污点,就能够(不是必须)把Pod调度过去。

因此 Taints(污点)通常与Tolerations(容忍)配合使用,实际上是对PodToleratesNodeTaints策略和TaintTolerationPriority策略的具体应用

污点(Taint):

使用kubectl taint命令可以给某个Node节点设置污点,Node被设置上污点之后就和Pod之间存在了一种相斥的关系,可以让Node拒绝Pod的调度执行,甚至将Node已经存在的Pod驱逐出去。

kubectl taint --help

kubectl taint node [node] key=value[effect]   

其中[effect] 可取值: [ NoSchedule | PreferNoSchedule | NoExecute ]

effect 定义对Pod 排斥效果:
NoSchedule: 仅影响调度过程,对现存的Pod 不产生影响
NoExecute:影响调度过程,也影响现存的Pod,不满足容忍度就会去除节点的Pod
PreferNoSchedule:属于柔性约束,尽量避免将Pod调度到具有该污点的Node上,不过无其他节点可以调度时也可以允许调度

增加污点

语法:kubectl taint nodes <nodename> <key>=<value>:<effect>......
kubectl taint node k8s-node1 node-type=production:NoSchedule
删除污点

语法:kubectl taint nodes <node-name> <key>[: <effect>]-
kubectl taint node k8s-node1 node-type=production:NoSchedule-
kubectl taint node k8s-node1 node-type- #删除这个key的所有污点

#补丁方式删除节点上的全部污点信息

kubectl patch nodes k8s-node1 -p '{"spec":{"taints":[]}}'

查看master 的污点:

[root@k8s-master ~]# kubectl describe node k8s-master

Name: k8s-master
Roles: master
......
Taints: node- role. kubernetes. io/ master: NoSchedule

这个污点表示默认情况下master节点将不会调度运行Pod,即不运行工作负载。

#定义k8s-node1上的污点
[root@k8s-master ~]# kubectl taint nodes k8s-node1 node-type=production:NoSchedule
node/k8s-node1 tainted
#查看节点污点信息
[root@k8s-master ~]# kubectl get nodes k8s-node1 -o go-template={{.spec.taints}}
[map[effect:NoSchedule key:node-type value:production]]

此时,node1节点上已经存在的Pod对象不受影响,仅对新建Pod对象有影响
需要注意的是,如果是同一个键值数据,但是最后的标识不同,也是属于不同的污点信息,
比如再给node1上添加一个污点的标识为:PreferNoSchedule
[root@k8s-master ~]# kubectl taint nodes k8s-node1 node-type=production:PreferNoSchedule
[root@k8s-master ~]# kubectl get nodes k8s-node01 -o go-template={{.spec.taints}}
[map[value:production effect:PreferNoSchedule key:node-type] map[key:node-type value:production effect:NoSchedule]]

容忍(Tolerations):

设置了污点的Node将根据taint的effect:NoSchedule、PreferNoSchedule、NoExecute和Pod之间产生互斥的关系,Pod将在一定程度上不会被调度到Node上。 但我们可以在Pod上设置容忍(Toleration),意思是设置了容忍的Pod将可以容忍污点的存在,可以被调度到存在污点的Node上。

通过在Pod的spec中设置tolerations字段,给Pod设置上容忍点Toleration:

对于tolerations属性的写法:
其中的key、value、effect 与Node的Taint设置需保持一致, 还有以下几点说明:
1.如果operator的值是Exists,则value属性可省略。
2.如果operator的值是Equal,则表示其key与value之间的关系是equal(等于)。
3.如果不指定operator属性,则默认值为Equal。

另外,还有两个特殊值:

1.空的key 如果再配合Exists 就能匹配所有的key与value ,也是是能容忍所有node的所有Taints。

2.空的effect 匹配所有的effect。

tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoSchedule"
  tolerationSeconds: 3600
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoExecute"
- key: "key2"
  operator: "Exists"
  effect: "NoSchedule"
  • 其中key, vaule, effect要与Node上设置的taint保持一致
  • operator的值为Exists将会忽略value值
  • tolerationSeconds用于描述当Pod需要被驱逐时可以在Pod上继续保留运行的时间

应用实例

1.Kubernetes master节点不运行工作负载

Kubernetes集群的Master节点是十分重要的,一个高可用的Kubernetes集群一般会存在3个以上的master节点,为了保证master节点的稳定性,一般不推荐将业务的Pod调度到master节点上。

下面将介绍一下我们使用Kubernetes调度的Taints和和Tolerations特性确保Kubernetes的Master节点不执行工作负载的实践。

我们的Kubernetes集群中总共有3个master节点,节点的名称分别为k8s-01k8s-02k8s-03

为了保证集群的稳定性,同时提高master节点的利用率,

我们将其中一个节点设置为node-role.kubernetes.io/master:NoSchedule

另外两个节点设置为node-role.kubernetes.io/master:PreferNoSchedule

kubectl taint nodes k8s-01 node-role.kubernetes.io/master=:NoSchedule
kubectl taint nodes k8s-02 node-role.kubernetes.io/master=:PreferNoSchedule
kubectl taint nodes k8s-03 node-role.kubernetes.io/master=:PreferNoSchedule

这样保证3个节点中的1个无论在任何情况下都将不运行业务Pod,而另外2个载集群资源充足的情况下尽量不运行业务Pod。

另外对于我们部署在集群中的一些非业务组件,

例如Kubernetes Dashboardjaeger-collectorjaeger-queryPrometheuskube-state-metrics等组件,

通过设置Tolerations和Pod Affinity(亲和性)将这些组件运行在master节点上,而其他的业务Pod运行在普通的Node节点上

2.结合NodeAffinity让Pod独占一个Node节点运行

给特定的Node设置一个Taint,只让某些特定的应用来容忍这些污点,容忍后就有可能会被调度到此特定Node,

但是也不一定会调度给此特定Node,设置容忍并不阻止调度器调度给其它Node,那么如何让特定应用的Node

只能被调度到此特定的Node呢,这就要结合NodeAffinity节点亲和性,给Node打个标签,然后在Pod属性里

设置NodeAffinity到Node。如此就能达到要求了。这里不在演示,下面有兴趣的同学可以设置一下。

总结

 

1.可以向单个Pod和Node增加多个tolerations和taints,Kubernetes采用类似过滤器的方式进行处理,首先遍历Node上的Taints,并与Pod的tolerations做匹配,如果有匹配的项目则忽略,最后根据剩下为匹配到的taints做判断:

  • 如果至少有一个未匹配到的taints的效果是NoSchedule,则Pod不会被调度到Node上
  • 如果仅有一个未匹配到的taints的效果是PreferNoSchedule,则尽量不向这个Node调度
  • 如果至少有一个未匹配到的taints的效果是NoExecute,则Pod不会被调度到Node上,已经在Node上运行的Pod会被驱逐。
  • 通常,一个NoExcute添加到节点后,不能容忍的Pod会被立即驱逐,可以通过tolerationSeconds设置延时驱逐。

2.在设置node的Taints(污点)之前,就已经运行了一些Pod,Pod是否还能继续在此Node上运行? 这就要看设置Taints污点时的effect(效果)了。

  • 如果effect的值是NoSchedule或PreferNoSchedule,那么已运行的Pod仍然可以运行,只是新Pod(如果没有容忍)不会再往上调度。
  • 如果effect的值是NoExecute,那么此Node上正在运行的Pod,只要没有容忍的,立刻被驱逐,但是K8S为了彰显人性化有一个可选的tolerationSeconds字段,用来设置可以在这个Node之上运行多久.
  • 如果是以Pod来启动的,那么Pod被驱逐后, 将不会再被运行,就等于把它删除了。
  • 如果是deployment/rc,那么删除的pod会再其它节点运行。
  • 如果是DaemonSet在此Node上启动的Pod,那么也不会再被运行,直到Node上的NoExecute污被去除或者Pod容忍

 

 

 

 

 

转载于:https://www.cnblogs.com/centos-python/articles/10893440.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值