24.污点和容忍度深入研究

24.污点和容忍度深入研究

Taint(污点)和Toleration(容忍度)可以作用于node和pod上,其目的是优化pod在集群间的调度,这跟节点亲和性类似;

只不过它们作用的方式相反,其用作确保pod不会被调度在指定的节点上。

1.概念引入

在这里插入图片描述

为了可以让大家更简单、更直观的了解到污点和容忍度的意思,我这里画了个趣图。

如图所示,node节点上分别有云、五角星、十字架这三个不同组合的污点;Pod-A上有云和五角星的污点容忍度,Pod—B上则没有容忍度。

最终调度结果为:
1.Pod-A:调度至node-1和node-3
2.Pod-B:只会调度至node-3

注意:Taints(污点)存在于node,Tolerations(容忍度)存在于pod

再举个例子,3d的射击类游戏一般会让人有头晕目眩的感觉(这就是污点),如果你是长期射击类游戏的玩家(这就是容忍度),就不会有问题,且愿意尝试这块游戏(这就是完成匹配,准备调度)

此时,你对污点和容忍度应该有了较基础的了解了。

2.污点和容忍度配置

污点的容忍度配置主要有三个字段:key、value和effect,其中:

1>key:表示字段名,如图形
2>value:表示字段值,如云、五角星、十字架
3>effect:表示调度规则,其又细分:Noschedule、PreferNoSchedule和NoExecute三种

具体描述可参考下面的表格:

参数 描述
key string类型,最大长度253个字符,必须小写或数字开头
value string类型,最大长度63个字符,必须小写或数字开头
effect:Noschedule 1.不允许非法pod调度上来。2.taints变更后,不会驱离非法的pod
effect:PreferNoSchedule 1.最好不要把非法pod调度上来。2.taints变更后,不会驱离非法的pod
effect:NoExecute 1.不允许非法pod调度上来。2.taints变更后,会驱离非法的pod,驱离时间为tolerationSeconds

3.怎么配置?

就如我上面所说,无论是Taints还是Tolerations(污点和容忍度),都有三个字段:key、value和effect,那么他们是如何匹配工作的呢?

此时会用到一个判断控制器operator,具体匹配规则如下:

operator 描述
Equal (默认) key、value和effect必须都相同
Exists key和effect必须相同
需要注意operator没指定的话,默认是Equal。

另外,这里还有两个特殊用法:

tolerations:
- operator: "Exists"

1>Exists:空字段key,会匹配所有的keys, values and effects,意味着容忍所有

tolerations:
- key: "key"
  operator: "Exists"

2>Exists:空effect,会匹配所有的键为"key"的effect

4.内置污点

从K8S1.6开始支持了很多封装好的驱离式effect,node controller会根据实际情况,自动给node节点打上对应污点,保证了Pod调度的合理性和安全性,从而对生产环境保驾护航。

具体如下所示:

taint effect 描述
node.kubernetes.io/not-ready 节点未就绪
node.kubernetes.io/unreachable 节点不可达
node.kubernetes.io/out-of-disk 节点地盘耗尽
node.kubernetes.io/memory-pressure 内存存在压力
node.kubernetes.io/disk-pressure 磁盘存在压力
node.kubernetes.io/network-unavailable 网络不可用
node.kubernetes.io/unschedulable 节点不可调度
node.cloudprovider.kubernetes.io/uninitialized 节点未初始化,不可用

试想一下,如果没有这些内置的effect帮助会怎么样呢?

如果节点还未就绪,就有pod调度上来,又比如节点的硬盘资源已经满了,pod再调度上来?等等;
这是不是很不合理,也很可怕呢?

5.常用命令补充

命令 说明
kubectl taint -h taint的帮助命令
kubectl taint nodes foo dedicated=special-user:NoSchedule 给node打污点,修改时需要使用–overwrite=true进行覆盖
kubectl taint nodes foo dedicated:NoSchedule- 移除taint污点

6.实战:Taints and Tolerations

1)首先给centos-3这个节点打上污点,其key=department,value=ops,effect=NoSchedule

kubectl taint nodes centos-3.shared department=ops:NoSchedule

我们再来回顾一下NoSchedule的策略:
1.不允许非法pod调度上来。
2.taints变更后,不会驱离非法的pod。

2)接着,我们编辑filebeat-ds,并apply

注意:这时候的ds应该不会调度至我们打了污点的centos-3.shared节点上。

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: filebeat-ds
  labels:
    app: filebeat
spec:
  selector:
    matchLabels:
      app: filebeat
  template:
    metadata:
      labels:
        app: filebeat
    spec:
      containers:
      - name: filebeat
        image:  prima/filebeat:6.4.2
        env:
        - name: REDIS_HOST
          value: db.ikubernetes.is:6379
        - name: LOG_LEVEL
          value: info

3)发现ds并没有部署到centos-3节点,污点配置生效,且和预期一致

[root@centos-1 dingqishi]# kubectl get pod -o wide
NAME                     READY   STATUS              RESTARTS   AGE    IP           NODE              NOMINATED NODE   READINESS GATES
filebeat-ds-tg7gf        0/1     ContainerCreating   0          3m2s          centos-2.shared              

4)接着,我们delete之前的yaml,重新编辑file-ds-tolerations.yaml(增加相关容忍度,希望能容忍centos-3.shared节点的污点),并apply

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: filebeat-ds
  labels:
    app: filebeat
spec:
  selector:
    matchLabels:
      app: filebeat
  template:
    metadata:
      labels:
        app: filebeat
    spec:
      containers:
      - name: filebeat
        image:  prima/filebeat:6.4.2
        env:
        - name: REDIS_HOST
          value: test.db:6379
        - name: LOG_LEVEL
          value: info
      tolerations:
      - key: "department"
        operator: "Equal"
        value: "ops"
        effect: "NoSchedule"

5)观察pod,发现centos-3.shared已经运行pod,新增的容忍度功能成功

[root@centos-1 dingqishi]# kubectl get pod -o wide
NAME                     READY   STATUS              RESTARTS   AGE     IP           NODE              NOMINATED NODE   READINESS GATES
filebeat-ds-l2png        0/1     ContainerCreating   0          2m43s          centos-2.shared              
filebeat-ds-qq2nc        0/1     ContainerCreating   0          2m43s          centos-3.shared              

6)接下来我们修改node3污点,测试Noschedule策略是否如期一致,是否会在taints变更后,不会驱离非法的pod?

kubectl taint nodes centos-3.shared department=test:NoSchedule --overwrite=true

7)我们发现pod还是在运行,并不会驱离,和预期一致

[root@centos-1 dingqishi]# kubectl get pod -o wide
NAME                     READY   STATUS              RESTARTS   AGE     IP           NODE              NOMINATED NODE   READINESS GATES
filebeat-ds-l2png        0/1     ContainerCreating   0          5m18s          centos-2.shared              
filebeat-ds-qq2nc        0/1     ContainerCreating   0          5m18s          centos-3.shared              

8)最后,我们将node3的污点effect修改为NoExecute,观察pod是否被驱离

如果没指定tolerationSeconds,就会马上驱离

kubectl taint nodes centos-3.shared department=test:NoExecute --overwrite=true

9)发现centos-3.shared上已经没有pod了,和预期一致

[root@centos-1 dingqishi]# kubectl get pod -o wide
NAME                     READY   STATUS             RESTARTS   AGE     IP           NODE              NOMINATED NODE   READINESS GATES
filebeat-ds-l2png        0/1     ImagePullBackOff   0          7m37s   10.244.1.7   centos-2.shared              

你可能感兴趣的:(kubernetes)