Kubernetes之Taints污点与Tolerations容忍详解
LiuSw Lv6

Kubernetes之Taints污点与Tolerations容忍详解

1.Taints污点和Tolerations容忍概述

节点和Pod亲和力,是将Pod吸引到一组节点【根据拓扑域】(作为优选或硬性要求)。污点(Taints)则相反,它们允许一个节点排斥一组Pod。

容忍(Tolerations)应用于pod,允许(但不强制要求)pod调度到具有匹配污点的节点上。

污点(Taints)和容忍(Tolerations)共同作用,确保pods不会被调度到不适当的节点。一个或多个污点应用于节点;这标志着该节点不应该接受任何不容忍污点的Pod。

说明:我们在平常使用中发现pod不会调度到k8s的master节点,就是因为master节点存在污点

2.Taints污点

Taints污点的组成

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

每个污点的组成如下:

1
2
# key值=value值:影响(NoSchedule,PreferNoSchedule,NoExecute)
key=value:effect

每个污点有一个key和value作为污点的标签,effect描述污点的作用。当前taint effect支持如下选项:

  • NoSchedule:表示K8S将不会把Pod调度到具有该污点的Node节点上
  • PreferNoSchedule:表示K8S将尽量避免把Pod调度到具有该污点的Node节点上
  • NoExecute:表示K8S将不会把Pod调度到具有该污点的Node节点上,同时会将Node上已经存在的Pod驱逐出去

污点taint的NoExecute详解

taint 的 effect 值 NoExecute,它会影响已经在节点上运行的 pod:

  • 如果 pod 不能容忍 effect 值为 NoExecute 的 taint,那么 pod 将马上被驱逐
  • 如果 pod 能够容忍 effect 值为 NoExecute 的 taint,且在 toleration 定义中没有指定 tolerationSeconds,则 pod 会一直在这个节点上运行。
  • 如果 pod 能够容忍 effect 值为 NoExecute 的 taint,但是在toleration定义中指定了 tolerationSeconds,则表示 pod 还能在这个节点上继续运行的时间长度。

Taints污点设置

污点(Taints)查看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# kubectl describe node 节点名称(node,master)
kubectl describe node k8s-master

# Name: k8s-master1
# Roles: master
# Labels: beta.kubernetes.io/arch=amd64
# beta.kubernetes.io/os=linux
# kubernetes.io/arch=amd64
# kubernetes.io/hostname=k8s-master1
# kubernetes.io/os=linux
# node-role.kubernetes.io/master=
# Annotations: kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
# node.alpha.kubernetes.io/ttl: 0
# projectcalico.org/IPv4Address: 192.168.2.30/24
# projectcalico.org/IPv4IPIPTunnelAddr: 100.105.225.0
# volumes.kubernetes.io/controller-managed-attach-detach: true
# CreationTimestamp: Sun, 18 Apr 2021 13:49:56 -0400
# Taints: node-role.kubernetes.io/master:NoSchedule
# *******

污点(Taints)添加

1
2
# kubectl taint nodes 节点名称 key=value:effect
kubectl taint nodes k8s-node01 check=zhang:NoSchedule

污点(Taints)删除

1
2
3
4
# kubectl taint nodes 节点名称 key=value:effect-
kubectl taint nodes k8s-node01 check=zhang:NoSchedule-
# 或者kubectl taint nodes 节点名称 key:effect-
kubectl taint nodes k8s-node01 check:NoExecute-

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
apiVersion: apps/v1Beta1
kind: Deployment
metadata:
name: nginx-deploy
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
images: nginx:laste
ports:
- containerPort: 80
tolerations: #containers同级
- key: "key1" #能容忍的污点key
operator: "Equal" #Equal等于表示key=value , Exists不等于,表示当值不等于下面value正常
value: "value1" #值
effect: "NoExecute" #effect策略,见上面
tolerationSeconds: 3600 #原始的pod多久驱逐,注意只有effect: "NoExecute"才能设置,不然报错

3.Tolerations容忍

设置了污点的Node将根据taint的effect:NoSchedule、PreferNoSchedule、NoExecute和Pod之间产生互斥的关系,Pod将在一定程度上不会被调度到Node上。

但我们可以在Pod上设置容忍(Tolerations),意思是设置了容忍的Pod将可以容忍污点的存在,可以被调度到存在污点的Node上。

重要说明:

  • 其中key、value、effect要与Node上设置的taint保持一致
  • operator的值为Exists时,将会忽略value;只要有key和effect就行
  • tolerationSeconds:表示pod 能够容忍 effect 值为 NoExecute 的 taint;当指定了 tolerationSeconds【容忍时间】,则表示 pod 还能在这个节点上继续运行的时间长度。

当不指定key值时

当不指定key值和effect值时,且operator为Exists,表示容忍所有的污点【能匹配污点所有的keys,values和effects】

1
2
tolerations:
- operator: "Exists"

当不指定effect值时

当不指定effect值时,则能匹配污点key对应的所有effects情况

1
2
3
tolerations:
- key: "key"
operator: "Exists"

当有多个Master存在时

当有多个Master存在时,为了防止资源浪费,可以进行如下设置:

1
kubectl taint nodes Node-name node-role.kubernetes.io/master=:PreferNoSchedule
1
2
3
4
5
6
字段名              字段类型            描述
key string 此容忍针对的污点的 key。如果为空,则匹配所有的污点,此时operator 必须为 Exists。当 key 为空,operator 为 Exists 时,表示容忍匹配所有 key / value 的污点
operator string operator (操作符)表示 key 与 value 的关系。可选值为 Exists 和 Equal,默认为 Equal。 Exists 相当于 value 的通配符,此时 Pod 可以容忍包含该 key 的所有污点
value string 此容忍针对的污点的 value。如果 operator 为 Exists,value 应该为空,否则,value 为一个常规字符串
effect string 此容忍针对的污点的 effect。如果为空,则表示该容忍匹配污点的所有 effect。可选值为 NoSchedule、PreferNoSchedule、NoExecute
tolerationSeconds integer TolerationSeconds 代表了容忍的持续时间,当该字段被填写时,effect 必须为 NoExecute。默认情况下,该字段为空,代表 Pod 可以一直容忍该污点(不会被驱逐)。0 以及负数将被认为是 0 (立刻驱逐)。

4.多个Taints污点和多个Tolerations容忍怎么判断

可以在同一个node节点上设置多个污点(Taints),在同一个pod上设置多个容忍(Tolerations)。Kubernetes处理多个污点和容忍的方式就像一个过滤器:从节点的所有污点开始,然后忽略可以被Pod容忍匹配的污点;保留其余不可忽略的污点,污点的effect对Pod具有显示效果:特别是:

  • 如果有至少一个不可忽略污点,effect为NoSchedule,那么Kubernetes将不调度Pod到该节点
  • 如果没有effect为NoSchedule的不可忽视污点,但有至少一个不可忽视污点,effect为PreferNoSchedule,那么Kubernetes将尽量不调度Pod到该节点
  • 如果有至少一个不可忽视污点,effect为NoExecute,那么Pod将被从该节点驱逐(如果Pod已经在该节点运行),并且不会被调度到该节点(如果Pod还未在该节点运行)

5.污点和容忍的使用场景

污点和容忍使用起来非常灵活,可以用于:

  • 避免 Pod 被调度到某些特定的节点
  • 从节点上驱逐本不应该在该节点运行的 Pod

具体使用场景可能有:

  • 专属的节点: 如果想将一组节点专门用于特定的场景,可以为这些节点添加污点(例如 kubectl taint nodes nodename dedicated=groupName:NoSchedule)然后向对应的 Pod 添加容忍。带有这些容忍的 Pod 将可以使用这一组专属节点,同时也可以使用集群中的其他节点。如果想进一步限制这些 Pod 只能使用这一组节点,那么应该为这一组节点添加一个标签(例如 dedicated=groupName),并为这一组 Pod 添加 node affinity(或 node selector)以限制这些 Pod 只能调度到这一组节点上。
  • 带有特殊硬件的节点:集群中,如果某一组节点具备特殊的硬件(例如 GPU),此时非常有必要将那些不需要这类硬件的 Pod 从这组节点上排除掉,以便需要这类硬件的 Pod 可以得到资源。此时可以为这类节点添加污点(例如:kubectl taint nodes nodename special=true:NoSchedule 或者 kubectl taint nodes nodename special=true:PreferNoSchedule)并为需要这类硬件的 Pod 添加匹配的容忍。
  • 基于污点的驱逐 当节点出现问题时,可以使用污点以 Pod 为单位从节点上驱逐 Pod。
 评论