Pod 中存在属性 Node selector / Node affinity,用于将 Pod 指定到合适的节点。
相对的,节点中存在属性 污点 taints
,使得节点可以排斥某些 Pod。
污点和容忍(taints and tolerations)成对工作,以确保 Pod 不会被调度到不合适的节点上。
执行 kubectl taint
命令,可向节点添加污点,如下所示:
kubectl taint nodes node1 key=value:NoSchedule
该命令为节点 node1
添加了一个污点。污点是一个键值对,在本例中,污点的键为 key
,值为 value
,污点效果为 NoSchedule
。此污点意味着 Kubernetes 不会向该节点调度任何 Pod,除非该 Pod 有一个匹配的容忍(toleration)
执行如下命令可以将本例中的污点移除:
kubectl taint nodes node1 key:NoSchedule-
PodSpec 中有一个 tolerations
字段,可用于向 Pod 添加容忍。下面的两个例子中定义的容忍都可以匹配上例中的污点,包含这些容忍的 Pod 也都可以被调度到 node1
节点上:
容忍1:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
容忍2:
tolerations:
- key: "key"
operator: "Exists"
effect: "NoSchedule"
下面这个 Pod 的例子中,使用了容忍:
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
tolerations:
- key: "example-key"
operator: "Exists"
effect: "NoSchedule"
当满足如下条件时,Kubernetes 认为容忍和污点匹配:
键(key)相同
效果(effect)相同
污点的
operator
为:
Exists
(此时污点中不应该指定 value
)Equal
(此时容忍的 value
应与污点的 value
相同)如果不指定 operator
,则其默认为 Equal
特殊情况
存在如下两种特殊情况:
容忍中未定义 key
但是定义了 operator 为 Exists
,Kubernetes 认为此容忍匹配所有的污点,如下所示:
tolerations:
- operator: "Exists"
容忍中未定义 effect
但是定义了 key
,Kubernetes 认为此容忍匹配所有 effect
,如下所示:
tolerations:
- key: "key"
operator: "Exists"
支持的效果 effect
有:
NoSchedule
更宽容一些,Kubernetes 将尽量避免将没有匹配容忍的 Pod 调度到该节点上,但是并不是不可以一个节点上可以有多个污点,同时一个 Pod 上可以有多个容忍。Kubernetes 使用一种类似于过滤器的方法来处理多个节点和容忍:
例如:
如果存在至少一个不可忽略的污点带有效果 NoSchedule
,则 Kubernetes 不会将 Pod 调度到该节点上
如果没有不可忽略的污点带有效果 NoSchedule
,但是至少存在一个不可忽略的污点带有效果 PreferNoSchedule
,则 Kubernetes 将尽量避免将该 Pod 调度到此节点
如果存在至少一个忽略的污点带有效果
NoExecute
,则:
例如,假设您给一个节点添加了三个污点:
kubectl taint nodes node1 key1=value1:NoSchedule
kubectl taint nodes node1 key1=value1:NoExecute
kubectl taint nodes node1 key2=value2:NoSchedule
同时,有一个 Pod 带有两个容忍:
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
在这个案例中,Pod 上有两个容忍,匹配了节点的前两个污点,只有节点的第三个污点对该 Pod 来说不可忽略,该污点的效果为 NoSchedule
:
NoExecute
效果的污点已被 Pod 上的第二个容忍匹配,因此被忽略)通常,在带有效果 NoExecute
的污点被添加到节点时,节点上任何不容忍该污点的 Pod 将被立刻驱逐,而容忍该污点的 Pod 则不会被驱逐。
此外,带有效果 NoExecute
的污点还可以指定一个可选字段 tolerationSeconds
,该字段指定了 Pod 在多长时间后被驱逐,例如:
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
tolerationSeconds: 3600
此例子中,如果 Pod 已经运行在节点上,再向节点增加此污点时,Pod 将在该节点上继续运行 3600 秒,然后才被驱逐。如果污点在此之间被移除,则 Pod 将不会被驱逐。
污点和容忍使用起来非常灵活,可以用于:
避免 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。
原文:https://www.cnblogs.com/sanduzxcvbnm/p/13073837.html