Kubernetes Pod调度进阶:Taints(污点)和Tolerations(容忍)
2018-05-23
污点(Taint)和容忍(Toleration)是从Kubernetes 1.6开始提供的高级调度功能。 在Kubernetes的文档中Taints and Tolerations的介绍已经十分详细。 本文将从简单理解的角度看一下Taint和Toleration。
污点(Taint) #
污点(Taint)的组成 #
使用kubectl taint
命令可以给某个Node节点设置污点,Node被设置上污点之后就和Pod之间存在了一种相斥的关系,可以让Node拒绝Pod的调度执行,甚至将Node已经存在的Pod驱逐出去。
每个污点的组成如下:
1key=value:effect
每个污点有一个key和value作为污点的标签,其中value可以为空,effect描述污点的作用。当前taint effect支持如下三个选项:
NoSchedule
:表示k8s将不会将Pod调度到具有该污点的Node上PreferNoSchedule
:表示k8s将尽量避免将Pod调度到具有该污点的Node上NoExecute
:表示k8s将不会将Pod调度到具有该污点的Node上,同时会将Node上已经存在的Pod驱逐出去
污点的设置和去除 #
使用kubectl设置和去除污点的命令示例如下:
1# 设置污点
2kubectl taint nodes node1 key1=value1:NoSchedule
3
4# 去除污点
5kubectl taint nodes node1 key1:NoSchedule-
接下来看一个具体的例子,使用kubeadm部署和初始化的Kubernetes集群,master节点被设置了一个node-role.kubernetes.io/master:NoSchedule
的污点,可以使用kubectl describe node <node-name>
命令查看。这个污点表示默认情况下master节点将不会调度运行Pod,即不运行工作负载。对于使用二进制手动部署的集群设置和移除这个污点的命令如下:
1kubectl taint nodes <node-name> node-role.kubernetes.io/master=:NoSchedule
2
3kubectl taint nodes <node-name> node-role.kubernetes.io/master:NoSchedule-
注意:kubeadm初始化的Kubernetes集群,master节点也被打上了一个
node-role.kubernetes.io/master=
的label,标识这个节点的角色为master。给Node设置Label和设置污点是两个不同的操作。设置Label和移除Label的操作命令如下
1# 设置Label
2kubectl label node node1 node-role.kubernetes.io/master=
3# 移除Label
4kubectl label node node1 node-role.kubernetes.io/master-
5
6kubectl get node
7NAME STATUS ROLES AGE VERSION
8node1 Ready master 10d v1.9.8
9node2 Ready master 10d v1.9.8
10node3 Ready master 10d v1.9.8
11node4 Ready <none> 10d v1.9.8
12node5 Ready <none> 10d v1.9.8
容忍(Tolerations) #
设置了污点的Node将根据taint的effect:NoSchedule、PreferNoSchedule、NoExecute和Pod之间产生互斥的关系,Pod将在一定程度上不会被调度到Node上。 但我们可以在Pod上设置容忍(Toleration),意思是设置了容忍的Pod将可以容忍污点的存在,可以被调度到存在污点的Node上。
通过在Pod的spec中设置tolerations字段,给Pod设置上容忍点Toleration:
1tolerations:
2- key: "key1"
3 operator: "Equal"
4 value: "value1"
5 effect: "NoSchedule"
6 tolerationSeconds: 3600
7- key: "key1"
8 operator: "Equal"
9 value: "value1"
10 effect: "NoExecute"
11- key: "key2"
12 operator: "Exists"
13 effect: "NoSchedule"
- 其中key, vaule, effect要与Node上设置的taint保持一致
- operator的值为Exists将会忽略value值
- tolerationSeconds用于描述当Pod需要被驱逐时可以在Pod上继续保留运行的时间
下面看一下在Pod上设置容忍的两个特例:
示例1: 当不指定key值时,表示容忍所有的污点key:
1tolerations:
2- operator: "Exists"
示例2:当不指定effect值时,表示容忍所有的污点作用:
1tolerations:
2- key: "key"
3 operator: "Exists"
实践:Kubernetes master节点不运行工作负载 #
Kubernetes集群的Master节点是十分重要的,一个高可用的Kubernetes集群一般会存在3个以上的master节点,为了保证master节点的稳定性,一般不推荐将业务的Pod调度到master节点上。 下面将介绍一下我们使用Kubernetes调度的Taints和和Tolerations特性确保Kubernetes的Master节点不执行工作负载的实践。
我们的Kubernetes集群中总共有3个master节点,节点的名称分别为k8s-01
、k8s-02
、k8s-03
。
为了保证集群的稳定性,同时提高master节点的利用率,我们将其中一个节点设置为node-role.kubernetes.io/master:NoSchedule
,另外两个节点设置为node-role.kubernetes.io/master:PreferNoSchedule
,这样保证3个节点中的1个无论在任何情况下都将不运行业务Pod,而另外2个载集群资源充足的情况下尽量不运行业务Pod。
1kubectl taint nodes k8s-01 node-role.kubernetes.io/master=:NoSchedule
2
3kubectl taint nodes k8s-02 node-role.kubernetes.io/master=:PreferNoSchedule
4
5kubectl taint nodes k8s-03 node-role.kubernetes.io/master=:PreferNoSchedule
另外对于我们部署在集群中的一些非业务组件,例如Kubernetes Dashboard
、jaeger-collector
、jaeger-query
、Prometheus
、kube-state-metrics
等组件,通过设置Tolerations和Pod Affinity(亲和性)将这些组件运行在master节点上,而其他的业务Pod运行在普通的Node节点上。