kubectl taint nodes node1 k1=v1:NoSchedule
给节点node1增加一个taint,它的key是k1,value是v1,effect是NoSchedule。
这表示只有拥有和这个taint相匹配的toleration的pod才能够被分配到node1这个节点。
tolerations:
- key: "k1"
operator: "Equal"
value: "v1"
effect: "NoSchedule"
tolerations:
- key: "k1"
operator: "Exists"
effect: "NoSchedule"
上面两个容忍标签都与2.1.1创建的污点"匹配", 因此具有任一容忍标签的Pod都可以将其调度到node1上
一个toleration和一个taint相"匹配"是指它们有一样的key和effect
tolerations:
- key: "key"
operator: "Exists"
Kubernetes处理多个taint和toleration的过程就像一个过滤器,假设存在一个pod(A),存在一个节点(node1),A调度到node1的过程如下
给node1节点添加了如下的taint
kubectltaintnodes node1 k1=v1:NoSchedule
kubectltaintnodes node1 k1=v1:NoExecute
kubectltaintnodes node1 k2=v2:NoSchedule
然后存在一个pod(A),它有两个toleration:
tolerations:
- key: "k1"
operator: "Equal"
value: "v1"
effect: "NoSchedule"
- key: "k1"
operator: "Equal"
value: "v1"
effect: "NoExecute"
在这个例子中,A不会被分配到node1节点,因为其没有toleration和第3个taint相匹配。
但是如果在给节点添加上述taint之前,该pod已经在上述节点运行,那么它还可以继续运行在该节点上,因为第三个taint是三个taint中唯一不能被这个pod容忍的。
通常情况下,如果给一个节点添加了一个effect值为 NoExecute 的taint,则任何不能忍受这个taint的pod都会马上被驱逐,任何可以忍受这个taint的pod都不会被驱逐。
但是,如果pod存在一个effect值为 NoExecute 的toleration指定了可选属性 tolerationSeconds 的值,则表示在给节点添加了上述taint之后,pod 还能继续在节点上运行的时间。例如,
tolerations:
- key: "k1"
operator: "Equal"
value: "v1"
effect: "NoExecute"
tolerationSeconds: 3600
这表示如果这个pod正在运行,然后一个匹配的taint被添加到其所在的节点,那么pod还将继续在节点上运行 3600 秒,然后被驱逐。如果在此之前上述taint被删除了,则pod不会被驱逐。
将某些节点专门分配给特定的一组用户使用
kubectl taint nodes nodename dedicated=groupName:NoSchedule
通过编写一个自定义的 admission controller
在部分节点配备了特殊硬件(比如 GPU)的集群中,我们希望如下
kubectl taint nodes nodename special=true:NoSchedule
# 或者
# kubectl taint nodes nodename special=true:PreferNoSchedule
和专用节点的例子类似,添加这个toleration的最简单的方法是使用自定义 admission controller。比如
1. 我们推荐使用 Extended Resources 来表示特殊硬件,给配置了特殊硬件的节点添加taint时包含 extended resource 名称
2. 然后运行一个 ExtendedResourceToleration admission controller。
此时,因为节点已经被打上taint了,没有对应toleration的pod会被调度到这些节点。但当你创建一个使用了 extended resource 的pod时,ExtendedResourceToleration admission controller 会自动给pod加上正确的toleration,这样pod就会被自动调度到这些配置了特殊硬件件的节点上。
这样就能够确保这些配置了特殊硬件的节点专门用于运行 需要使用这些硬件的 Pod,并且你无需手动给这些pod添加 toleration。
当节点出现问题,pod就不会被驱逐
当前内置的taint如下
节点磁盘耗尽。
节点存在内存压力。
节点存在磁盘压力。
节点网络不可用。
节点不可调度。
如果kubelet启动时指定了一个 “外部” cloud provider,它将给当前节点添加一个taint将其标志为不可用。
在cloud-controller-manager的一个controller初始化这个节点后,kubelet将删除这个taint。
一个pod在网络断开时,仍然希望停留在当前节点上运行一段较长的时间,愿意等待网络恢复以避免被驱逐。在这种情况下,pod的toleration可能是下面这样的:
tolerations:
-key: "node.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 6000
给pod自动添加如下tolerations
tolerations:
-key: "node.kubernetes.io/not-ready"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300
tolerations:
-key: "node.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300
Node生命周期控制器会自动创建与Node条件相对应的带有NoSchedule效应的污点。同样,调度器不检查节点条件,而是检查节点污点。
这确保了节点条件不会影响调度到节点上的内容。用户可以通过添加适当的pod容忍度来选择忽略某些Node的问题(表示为Node的调度条件)。
自Kubernetes1.8起,DaemonSet控制器自动为所有守护进程添加如下NoSchedule toleration以防DaemonSet崩溃
node.kubernetes.io/memory-pressure
node.kubernetes.io/disk-pressure
node.kubernetes.io/out-of-disk (只适合 criticalpod)
node.kubernetes.io/unschedulable (1.10 或更高版本)
node.kubernetes.io/network-unavailable (只适合 host network)
添加上述toleration确保了向后兼容,你也可以选择自由的向DaemonSet添加toleration。
kubectltaintnodes node1 k1=v1:NoSchedule
在node1上添加了污点. 这个污点的key是k1,value是v1, 污点的effect是NoSchedule
如果pod没有定义容忍度的话就不会调度到拥有这个污点的节点上
kubectl taint nodes node1 k1=v1:NoSchedule-
spec:
tolerations: #设置容忍性
- key: "test"
operator: "Equal" # 如果操作符为Exists,那么value属性可省略,如果不指定operator,则默认为Equal
value: "16"
effect: "NoSchedule"
一般不要玩
kubectltaintnodes node1 k1=v1:NoExecute
其中的key、value、effect与Node的Taint设置需保持一致,还有以下几点说明
验证effect是NoSchedule情况
kubectl taint nodes node1 k1=v1:NoSchedule
vi /root/test2/tolerations-no.yaml
内容
apiVersion: v1
kind: Pod
metadata:
name: tolerations-no
spec:
containers:
- name: nginx
image: nginx
kubectl apply -f /root/test2/tolerations-no.yaml
kubectl get pods
kubectl describe pods tolerations-no
显示pod不能容忍节点污点,不能完成调度
vi /root/test2/tolerations-yes.yaml
内容
apiVersion: v1
kind: Pod
metadata:
name: tolerations-yes
spec:
containers:
- name: nginx
image: nginx
tolerations:
- key: k1
value: v1
effect: NoSchedule
kubectl apply -f /root/test2/tolerations-yes.yaml
kubectl get pods -o wide
可以看到tolerations-yes已经完成调度了,可以调度到node1节点上