kubernetes 的 taints 和 tolerations 的理解和实践

概述

taints 和 tolerations 是一个比较好理解的概念,taints 可以翻译为污点,给 node 打上 taints,就可以用来驱逐 pod,并防止 pod 调度到该节点上。就像是某个人有了一个坏习惯(taints),那么其他人的就会远离这个人。但是有些人可以容忍别人的坏习惯,那么就会不受影响。就像 pod 拥有了 tolerations,就可以免疫节点上对应的 taints。

taints 的官方说明为:

The node this Taint is attached to has the “effect” on any pod that does not tolerate the Taint.

也就是说,taint 会为所有不能忍受该 taint 的 pod 添加副作用(不调度,偏好不调度,不执行)

如果要让某些 pod 免疫这些 taints,可以使用 tolerations。

taints 的使用

在使用 taints 的时候很简单,我们只需要指定节点 taints 的 key 和 value 即可。比如:

$ kubectl taint nodes minikube onlyNginxPod=true:NoSchedule

其中,onlyNginxPod 是 taints 的 key,true 是 value,NoSchedule 是 effect。另外还有 PreferNoScheduler 和 NoExecute。这里顺便总结一下这三种 effect 的区别:

  • NoSchedule: 表示不要将 Pod 向该节点调度。如果 Pod 已经调度到该节点了,则不受影响。
  • PreferNoScheduler: 表示尽量不要往该节点调度,但是如果没有其他选择,还是会将 Pod 调度到该节点。
  • NoExecute: Pod 不仅不能往上调度,所有已经运行在该节点上的 Pod 将会被驱逐。

这个时候,我们尝试创建一个普通的 pod,看看调度情况。

pod.yaml

apiVersion: v1
kind: Pod
metadata:
    name: nginx
    namespace: default
    labels:
        app: nginx
spec:
    containers:
    - name: nginx
      image: nginx:latest
$ kubectl apply -f pod-nginx.yaml 
$ kubectl describe pods nginx

Warning  FailedScheduling  <unknown>  default-scheduler  0/1 nodes are available: 1 node(s) had taint {onlyNginxPod: true}, that the pod didn't tolerate.

会出现上面的警告信息。表示因为 pod 没有容忍该 taint,所以没有办法调度上去。

我们可以用以下语句来删除 taint

$ kubectl taint node minikube onlyNginxPod=true:NoSchedule-

tolerations 的使用

某些情况下,我们仍然希望 Pod 可以调度到有 taint 的节点上,这时候就可以为 Pod 指定 tolerations。比如将上面的 Pod 改写成如下:

pod.yaml

apiVersion: v1
kind: Pod
metadata:
    name: nginx
    namespace: default
    labels:
        app: nginx
spec:
    containers:
    - name: nginx
      image: nginx:latest
    tolerations:
      - key: onlyNginxPod
        operator: Equal
        value: "true"
        effect: NoSchedule

然后创建这个 Pod,

···yaml
$ kubectl apply -f pod.yaml
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx 0/1 ContainerCreating 0 4s
···

说明该 pod 调度成功,tolerations 生效了。tolerations 会匹配 key 和 effect,只有一样的时候才会生效。tolerations 的 operator 字段除了 Equal 之外,还有 Exists

  • Equal: 要求 value 也相同。
  • Exists: 不需要设置 value 字段。

kubernetes 中使用 taints 和 tolerations 的常用场景

taints 和 tolerations 不仅仅是提供给用户使用的特性,kubernetes 本身也大量使用了 taints 和 tolerations。比如:

  • node.kubernetes.io/not-ready: Node 还没准备好,对应的 NodeCondition 的 ReadyFalse。比如在创建集群时,还没有安装 CNI 的话,节点就会有该 taint。对应的 effect 为 NoSchedule。

  • node.kubernetes.io/unreachable: node controller 无法连接到 Node,此时 NodeCondition 的 ReadyUnknown。对应的 effect 为 NoSchedule。

  • node.kubernetes.io/out-of-disk: 磁盘用尽。对应的 effect 为 NoSchedule。

  • node.kubernetes.io/memory-pressure: 节点有内存的压力。对应的 effect 为 NoSchedule。

  • node.kubernetes.io/disk-pressure: 节点有磁盘压力。和四个参数有关:nodefs.available, nodefs.inodesFree, imagefs.available, imagefs.inodesFree。nodefs 是用来存储卷和 daemon 日志的,imagefs 是容器运行时用来存储镜像和容器可写层的。当这些值到达某个阈值,就会出现 disk-pressure。对应的 effect 为 NoSchedule。

  • node.kubernetes.io/network-unavailable: 节点的网络还不可用。对应的 effect 为 NoSchedule。

  • node.kubernetes.io/unschedulable: 节点是不可调度的。对应的 effect 为 NoSchedule。

  • node.kubernetes.io/pid-pressure: 节点上的进程太多。对应的 effect 为 NoSchedule。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据