Taint/Toleration pod调度策略

一  Taint/Toleration介绍:

1  一个例子:

我这里测试了一个rc,内容如下:

[root@k8s-master-01 practice]# cat my-nginx-rc.yaml 
apiVersion: v1
kind: ReplicationController
metadata:
  name: my-nginx
spec:
  replicas: 3
  selector:
    app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
      restartPolicy: Always
[root@k8s-master-01 practice]# cat my-nginx-service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: my-nginx
spec:
  selector:
    app: nginx
  ports:
  - name: http
    port: 80
    targetPort: 80
    protocol: TCP
[root@k8s-master-01 practice]# kubectl create -f my-nginx-rc.yaml 
replicationcontroller/my-nginx created

[root@k8s-master-01 practice]# kubectl get pod
NAME                    READY   STATUS    RESTARTS   AGE
my-nginx-7dkgz          1/1     Running   0          60s
my-nginx-mq8rs          1/1     Running   0          60s
my-nginx-rj67n          1/1     Running   0          60s

[root@k8s-master-01 practice]# kubectl create -f my-nginx-service.yaml 
service/my-nginx created
[root@k8s-master-01 practice]# kubectl get svc
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
my-nginx       NodePort    10.103.32.111    <none>        80:30965/TCP   9s

[root@k8s-master-01 practice]# kubectl describe pod my-nginx-7dkgz|grep -i node:
Node:               k8s-node-02/10.10.0.135
[root@k8s-master-01 practice]# kubectl describe pod my-nginx-mq8rs|grep -i node:              
Node:               k8s-node-01/10.10.0.190
[root@k8s-master-01 practice]# kubectl describe pod my-nginx-rj67n|grep -i node:     
Node:               k8s-node-02/10.10.0.135

说明:整个集群有三个master node和两个slave node,当运行三个nginx pod的时候,发现所有的容器都都跑在了slave node上,而三个master上却没有容器,这就是本课的内容了。

2  Taint/Toleration说明:

[root@k8s-master-01 practice]# kubectl describe node k8s-master-01|grep -i taints
Taints:             node-role.kubernetes.io/master:NoSchedule

在master节点上都能看到这个信息,这就是默认情况下master节点不能运行pod的原因。这正是Taint/Toleration机制。

taint:污点的意思。如果一个节点被打上了污点,那么pod是不允许运行在这个节点上面的,当然如果你可以容忍(Toleration),那可以运行。

为k8s-master-01打一个污点:

[root@k8s-master-01 practice]# kubectl taint nodes k8s-master-01 env=joint:NoSchedule
node/k8s-master-01 tainted
[root@k8s-master-01 practice]# kubectl describe node k8s-master-01|grep -i taints
Taints:             env=joint:NoSchedule
                    node-role.kubernetes.io/master:NoSchedule

上面这条污点规则意味着:当有新的pod需要调度时(不影响已经在k8s-master-01上运行的pod),k8s-master-01不参与。

如果有需求,当我调度新的pod时,想让它运行在这个节点上,就要设置容忍了:

还拿上面的例子:

kubectl taint nodes k8s-master-01 node-role.kubernetes.io/master-
node/k8s-master-01 untainted

注意后面有一个“-”,这条命令是指:移除所有以node-role.kubernetes.io/master为键的Taint.

[root@k8s-master-01 practice]# kubectl describe node k8s-master-01|grep -i taint
Taints:             env=joint:NoSchedule
(只剩下这一条taint。)
[root@k8s-master-01 practice]# kubectl create -f my-nginx-rc.yaml                           
[root@k8s-master-01 practice]# kubectl get pod|grep my-nginx                    
my-nginx-4xq2c          1/1     Running   0          55s
my-nginx-979nf          1/1     Running   0          55s
my-nginx-l2zv4          1/1     Running   0          55s
my-nginx-qfkgk          1/1     Running   0          55s
my-nginx-wj8qj          1/1     Running   0          55s
my-nginx-zthhf          1/1     Running   0          55s
[root@k8s-master-01 practice]# kubectl describe pod my-nginx-4xq2c|grep -i node:     
Node:               k8s-node-02/10.10.0.135
[root@k8s-master-01 practice]# kubectl describe pod my-nginx-979nf|grep -i node:     
Node:               k8s-node-01/10.10.0.190
[root@k8s-master-01 practice]# kubectl describe pod my-nginx-l2zv4|grep -i node:     
Node:               k8s-master-01/10.10.0.170
[root@k8s-master-01 practice]# kubectl describe pod my-nginx-qfkgk|grep -i node:     
Node:               k8s-node-02/10.10.0.135
[root@k8s-master-01 practice]# kubectl describe pod my-nginx-wj8qj|grep -i node:     
Node:               k8s-node-01/10.10.0.190
[root@k8s-master-01 practice]# kubectl describe pod my-nginx-zthhf|grep -i node:     
Node:               k8s-master-01/10.10.0.170

我们看见新的pod在toleration这个污点后就可以运行在了这台master node上了。

3  调度策略:

3.1  可以在同一个 node 上使用多个 taints ,也可以在同一个 pod 上使用多个 tolerations。

3.2  taints and tolerations 时类似一个过滤器:
对比一个 node 上所有的 taints
忽略掉和 pod 中 toleration 匹配的 taints
遗留下来未被忽略掉的所有taints将对pod产生effect,具体见下:

3.2.1 至少有 1 个未被忽略的 taint 且 effect 是 NoSchedule 时,则 k8s 不会将该 pod 调度到这个 node 上

3.2.2 至少有 1 个未被忽略的 taint 且 effect 是 PreferNoSchedule 时,则 k8s 将尝试不把该 pod 调度到这个 node 上

3.2.3 至少有 1 个未被忽略的 taint 且 effect 是 NoExecute 时,则 k8s 会立即将该 pod 从该 node 上驱逐(如果已经在该 node 上运行),

或着不会将该 pod 调度到这个 node 上(如果还没在这个 node 上运行)

3.4 我们上面使用的策略是:NoSchedule,其他的策略:

PreferNoSchedule:这意味着不是一个强制必须的调度策略(尽量不去满足不合要求的 pod 调度到 node 上来)

NoExecute:立刻移除已经运行的pod且新pod不会被调度到该节点上。

3.5 常见的写法:

3.5.1 下面两种写法等价:

tolerations:
- key: "demo.test.com/app"
  operator: "Equal"
  value: "whoami"
  effect: "NoSchedule"
 tolerations:
- key: "demo.test.com/app"
  operator: "Exists"
  effect: "NoSchedule"

operator 默认值是 Equal 如果不指定的话

3.5.2:

key 为空且 operator 是 Exists 时,将匹配所有的 keys, values 和 effects ,这表明可以 tolerate 所有的 taint

3.6具体场景使用:

有下列三个taint:

kubectl taint nodes tvm-04 key1=value1:NoSchedule
kubectl taint nodes tvm-04 key1=value1:NoExecute
kubectl taint nodes tvm-04 key2=value2:NoSchedule

tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoSchedule"
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoExecute"

上述场景中,

该 pod 不会调度到 node 上,因为第 3 个 taint 不满足
如果该 pod 已经在该 node 上运行,则不会被驱逐

通常而言,不能 tolerate 一个 effect 是 NoExecute 的 pod 将被立即驱逐,但是,通过指定可选的字段 tolerationSeconds 则可以规定该 pod 延迟到一个时间段后再被驱逐,例如:
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
tolerationSeconds: 3600
也就是说,在 3600 秒后将被驱逐。但是,如果在这个时间点前移除了相关的 taint 则也不会被驱逐
注3:关于被驱逐,如果该 pod 没有其他地方可以被调度,也不会被驱逐出去(个人实验结果,请自行验证)

posted @ 2018-12-21 16:48  fengzhihai  阅读(957)  评论(0编辑  收藏  举报