k8s调度: 污点与容忍

大番茄 2020年12月19日 2,218次浏览

https://kubernetes.io/zh/docs/concepts/scheduling-eviction/taint-and-toleration/

污点设置到节点上,用来排斥一些pod。 只有可以容忍这些污点的pod可以调度到节点上。


注意: nodeName 是不经过调度器的, 所以污点对nodeName是无效的。

    spec:
      nodeName: k8snode1    # 就是这个nodeName配置
      containers:
      - image: harbor.atest.pub/system/centos:7
        name: centos

一、污点

一个污点包含: 键(key),值(value),效果(effect)。
键值都是自定义的,可以用来表述功能, 也用来做容忍设置的匹配。
一个节点可以设置多个污点,一个pod同样可以设置多个容忍。

effect有三种:

NoSchedule

不能容忍的pod不会调度到上面,但已经存在的不能容忍pod没有影响。

NoExecute

不能容忍的pod不会调度到上面,并且已经存在的不能容忍的pod也会移走。

PreferNoSchedule

NoSchedule功能差不多。 不能容忍的pod一般不会调度到上面,已存在的没有影响。 只是在其它节点都有NoScheduleNoExecute污点时, 就会调度到PreferNoSchedule上面。 老好人一个。


设置污点

注意: 如果value不提供,则value表示为空。keyeffect必须提供,并且不能为''。

两种方式,一种是命令行, 一种是使用kubectl edit修改节点信息。
命令行设置

[root@k8smaster1 ~]# kubectl taint node k8snode1 status=break:NoSchedule
node/k8snode1 tainted

可以为同一个key, value添加多个效果。

[root@k8smaster1 ~]# kubectl taint node k8snode1 status=break:NoExecute
node/k8snode1 tainted

省略value的情况下

[root@k8smaster1 ~]# kubectl taint node k8snode1 test:NoExecute
node/k8snode1 tainted



查看node的详细状态可以看到设置的污点,在yaml文件里添加,也是这样。

  taints:
  - effect: NoExecute
    key: test
  - effect: NoExecute
    key: status
    value: break
  - effect: NoSchedule
    key: status
    value: break

删除污点

两种方式,一种是命令行, 一种是kubectl edit修改节点信息。

命令行删除污点只要在后面加一个-减号就行。
删除key为status的所有污点:

[root@k8smaster1 ~]# kubectl taint node k8snode1 status-
node/k8snode1 untainted

只删除key为status, 效果为NoExecute的污点:

[root@k8smaster1 ~]#  kubectl taint node k8snode1 status:NoExecute-
node/k8snode1 untainted

二、容忍

容忍的设置主要根据operator,它决定了如何匹配污点。
两个值:EqualExists, 默认: Equal

Equal:

最基本的就是需要keyvalue与污点一样,会对这俩个值做匹配。
value如果不写,相当于value为空, 只匹配同样value为空的节点。
effect可选。effect如果不写,就是匹配所有effect。 如果写了,只匹配指定的effect

例子1:

如,污点这样的设置:

  taints:
  - effect: NoSchedule
    key: host
    value: k8snode2
  - effect: NoExecute
    key: host
    value: k8snode2

容忍的配置有两种:
1、不指定effect。

      tolerations:
      - operator: Equal
        key: host
#        effect: NoExecute
        value: k8snode2

2、把两个effect都加上。

      tolerations:
      - operator: Equal
        key: host
        effect: NoExecute
        value: k8snode2
      - operator: Equal
        key: host
        effect: NoSchedule
        value: k8snode2

例子2:

没有value。
污点:

  taints:
  - effect: NoSchedule
    key: host
    value: k8snode2
  - effect: NoExecute
    key: host
    value: k8snode2
  - effect: NoSchedule
    key: test

容忍:

      tolerations:
      - operator: Equal
        key: host
#        effect: NoExecute
        value: k8snode2
      - operator: Equal
        key: test

Exists

这个oprator不能写valuekeyeffect都是可选的。
如, 只有operator, 可以匹配所有。

      tolerations:
      - operator: Exists

添加key就匹配key, 添加effect就匹配effect。如果都加上了,就必须都匹配才能容忍对应污点。

如,可以容忍所有effectNoExecute的污点。

      - operator: Exists
        effect: NoExecute

同样的,如果只写了Key, 就可以容忍所有keystatus的污点。

      tolerations:
      - operator: Exists
        key: status


过滤规则

您可以给一个节点添加多个污点,也可以给一个 Pod 添加多个容忍度设置。
Kubernetes 处理多个污点和容忍度的过程就像一个过滤器:从一个节点的所有污点开始遍历, 过滤掉那些 Pod 中存在与之相匹配的容忍度的污点。
余下未被过滤的污点的 effect 值决定了 Pod 是否会被分配到该节点,特别是以下情况:

如果未被过滤的污点中存在至少一个 effect 值为 NoSchedule 的污点, 则 Kubernetes 不会将 Pod 分配到该节点。

如果未被过滤的污点中不存在 effect 值为 NoSchedule 的污点, 但是存在 effect 值为 PreferNoSchedule 的污点, 则 Kubernetes 会 尝试 将 Pod 分配到该节点。

如果未被过滤的污点中存在至少一个 effect 值为 NoExecute 的污点, 则 Kubernetes 不会将 Pod 分配到该节点(如果 Pod 还未在节点上运行), 或者将 Pod 从该节点驱逐(如果 Pod 已经在节点上运行)。

当然,如果节点没有余下的污点,pod会尝试分配到对应节点。

三、延伸

容忍的配置里effectNoExecute时还有一个属性tolerationSeconds
正常情况下容忍了污点,就会一直存在, 但是加上这个参数以后,会在指定的事件以后被驱逐。
前提是没有其它的容忍代替这条容忍, 如果其它的容忍都已经匹配所有污点了,这个就不管用了。

注意: 这个参数只是触发一下驱逐,并不是不能在当前节点待了, 如果没有其它节点可用,pod会在节点上重新启动。 然后到一定时间以后再次被驱逐。 周而复始。

节点会因为一些状况,自动添加污点。
https://kubernetes.io/zh/docs/concepts/scheduling-eviction/taint-and-toleration/#taint-based-evictions