美文网首页
kubernetes 容忍及污点

kubernetes 容忍及污点

作者: Joening | 来源:发表于2023-10-22 10:40 被阅读0次

    Pod 中存在属性 Node selector / Node affinity,用于将 Pod 指定到合适的节点。

    相对的,节点中存在属性 污点 taints,使得节点可以排斥某些 Pod。

    污点和容忍(taints and tolerations)成对工作,以确保 Pod 不会被调度到不合适的节点上。

    • 可以为节点增加污点(taints,一个节点可以有 0-N 个污点)
    • 可以为 Pod 增加容忍(toleration,一个 Pod 可以有 0-N 个容忍)
    • 如果节点上存在污点,则该节点不会接受任何不能容忍(tolerate)该污点的 Pod

    向节点添加/删除污点

    # 向节点添加污点
    kubectl taint nodes node1 key=value:NoSchedule
    # 删除污点
    kubectl taint nodes node1 key:NoSchedule-
    

    上述命令为节点 node1 添加了一个污点。污点是一个键值对,在上面的添加指令中,污点的键为 key,值为 value,污点效果为 NoSchedule。此污点意味着 Kubernetes 不会向该节点调度任何 Pod,除非该 Pod 有一个匹配的容忍(toleration)。

    向pod添加容忍

    # 示例1
    tolerations:
    - key: "key"
      operator: "Equal"
      value: "value"
      effect: "NoSchedule"
    
    # 示例2
    tolerations:
    - key: "key"
      operator: "Exists"
      effect: "NoSchedule"
    
    # 向pod中添加容忍,以便可以匹配到上面添加的节点污点
        spec:
          containers:
          - image: nginx:latest
            imagePullPolicy: IfNotPresent
            name: nginx
          tolerations:
          - effect: NoSchedule
            key: key
            operator: Exists
    # tolerations用于向pod添加容忍。
    

    污点与容忍的匹配

    当满足以下条件时,k8s认为污点和容忍匹配:

    • 键(key)相同;
    • 效果(effect)相同;
    • 污点的operator为:
      • Exists (此时污点中不应该指定 value)
      • 或者 Equal (此时容忍的 value 应与污点的 value 相同)

    特殊情况

    存在以下两种特殊情况:

    • 容忍中未定义 key 但是定义了 operator 为 Exists,Kubernetes 认为此容忍匹配所有的污点,如下所示:
    tolerations:
    - operator: "Exists"
    
    • 容忍中未定义 effect 但是定义了 key,Kubernetes 认为此容忍匹配所有 effect,如下所示:
    tolerations:
    - key: "key"
      operator: "Exists"
    

    支持的effect有:

    • NoSchedule
    • PreferNoSchedule 比 NoSchedule 更宽容一些,Kubernetes 将尽量避免将没有匹配容忍的 Pod 调度到该节点上,但是并不是不可以
    • NoExecute 不能在节点上运行(如果已经运行,将被驱逐)

    一个节点上可以有多个污点,同时一个 Pod 上可以有多个容忍。K8s 使用一种类似于过滤器的方法来处理多个节点和容忍:

    • 对于节点的所有污点,检查 Pod 上是否有匹配的容忍,如果存在匹配的容忍,则忽略该污点;
    • 剩下的不可忽略的污点将对该 Pod 起作用

    pod容忍配置总结

    字段名 字段类型 描述
    key string 此容忍针对的污点的 key。如果为空,则匹配所有的污点,此时operator 必须为 Exists。当 key 为空,operator 为 Exists 时,表示容忍匹配所有 key / value 的污点
    operator string operator (操作符)表示 key 与 value 的关系。可选值为 Exists 和 Equal,默认为 Equal。 Exists 相当于 value 的通配符,此时 Pod 可以容忍包含该 key 的所有污点
    value string 此容忍针对的污点的 value。如果 operator 为 Exists,value 应该为空,否则,value 为一个常规字符串
    effect string 此容忍针对的污点的 effect。如果为空,则表示该容忍匹配污点的所有 effect。可选值为 NoSchedule、PreferNoSchedule、NoExecute
    tolerationSeconds integer TolerationSeconds 代表了容忍的持续时间,当该字段被填写时,effect 必须为 NoExecute。默认情况下,该字段为空,代表 Pod 可以一直容忍该污点(不会被驱逐)。0 以及负数将被认为是 0 (立刻驱逐)。

    举个栗子:

    • 如果存在至少一个不可忽略的污点带有效果 NoSchedule,则 Kubernetes 不会将 Pod 调度到该节点上
    • 如果没有不可忽略的污点带有效果 NoSchedule,但是至少存在一个不可忽略的污点带有效果 PreferNoSchedule,则 Kubernetes 将尽量避免将该 Pod 调度到此节点
    • 如果存在至少一个忽略的污点带有效果 NoExecute,则:
      • 假设 Pod 已经在该节点上运行,Kubernetes 将从该节点上驱逐(evict)该 Pod
      • 假设 Pod 尚未在该节点上运行,Kubernetes 将不会把 Pod 调度到该节点

    假设我们给一个节点添加了三个污点

    kubectl taint nodes node01 key1=value1:NoSchedule
    kubectl taint nodes node01 key1=value1:NoExecute
    kubectl taint nodes node01 key2=value2:NoSchedule
    

    同时,有一个pod带有两个容忍:

    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      annotations:
        deployment.kubernetes.io/revision: '1'
        k8s.kuboard.cn/ingress: 'false'
        k8s.kuboard.cn/service: none
        k8s.kuboard.cn/workload: web-nginx
      labels:
        k8s.kuboard.cn/layer: web
        k8s.kuboard.cn/name: web-nginx
      name: web-nginx
      namespace: default
    spec:
      replicas: 2
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          k8s.kuboard.cn/layer: web
          k8s.kuboard.cn/name: web-nginx
      strategy:
        rollingUpdate:
          maxSurge: 25%
          maxUnavailable: 25%
        type: RollingUpdate
      template:
        metadata:
          labels:
            k8s.kuboard.cn/layer: web
            k8s.kuboard.cn/name: web-nginx
        spec:
          containers:
            - image: 'nginx:latest'
              imagePullPolicy: IfNotPresent
              name: nginx
          dnsPolicy: ClusterFirst
          restartPolicy: Always
          tolerations:
            - effect: NoSchedule
              key: key1
              operator: Equal
              value: value1
            - effect: NoExecute
              key: key1
              operator: Equal
              value: value1
    

    在上面的栗子中,pod有两个容忍,匹配了节点的前两个污点,只有第三个污点对pod来说不可忽略,该污点的效果为NoSchedule:

    • Kubernetes 不会将此 Pod 调度到该节点上
    • 如果 Kubernetes 先将 Pod 调度到了该节点,后向该节点添加了第三个污点,则 Pod 将继续在该节点上运行而不会被驱逐(节点上带有 NoExecute 效果的污点已被 Pod 上的第二个容忍匹配,因此被忽略)

    通常,在带有效果 NoExecute 的污点被添加到节点时,节点上任何不容忍该污点的 Pod 将被立刻驱逐,而容忍该污点的 Pod 则不会被驱逐。

    此外,带有效果 NoExecute 的污点还可以指定一个可选字段 tolerationSeconds,该字段指定了 Pod 在多长时间后被驱逐,例如:

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

    此例子中,如果 Pod 已经运行在节点上,再向节点增加此污点时,Pod 将在该节点上继续运行 3600 秒,然后才被驱逐。如果污点在此之间被移除,则 Pod 将不会被驱逐。

    NoExecute 的污点效果,该效果将对已经运行在节点上的 Pod 施加如下影响:

    • 不容忍该污点的 Pod 将立刻被驱逐
    • 容忍该污点的 Pod 在未指定 tolerationSeconds 的情况下,将继续在该节点上运行
    • 容忍该污点的 Pod 在指定了 tolerationSeconds 的情况下,将在指定时间超过时从节点上驱逐

    注:

    tolerationSeconds 字段可以理解为 Pod 容忍该污点的耐心:

    • 超过指定的时间,则达到 Pod 忍耐的极限,Pod 离开所在节点
    • 不指定 tolerationSeconds,则认为 Pod 对该污点的容忍是无期限的

    此外,自 k8s 1.6 以来,k8s 的节点控制器在碰到某些特定的条件时,将自动为节点添加污点。这类污点有:

    • node.kubernetes.io/not-ready: 节点未就绪。对应着 NodeCondition Ready 为 False 的情况
    • node.kubernetes.io/unreachable: 节点不可触达。对应着 NodeCondition Ready 为 Unknown 的情况
    • 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:如果 kubelet 是由 “外部” 云服务商启动的,该污点用来标识某个节点当前为不可用的状态。在“云控制器”(cloud-controller-manager)初始化这个节点以后,kubelet将此污点移除

    如果某一个包含了大量本地状态的应用,在网络断开时,可能仍然想要在节点上停留比较长的时间,以等待网络能够恢复,而避免从节点上驱逐。此时,该 Pod 的容忍可能如下所示:

    tolerations:
    - key: "node.kubernetes.io/unreachable"
      operator: "Exists"
      effect: "NoExecute"
      tolerationSeconds: 6000
    

    如果 Pod 没有 node.kubernetes.io/not-ready 容忍, Kubernetes 将自动为 Pod 添加一个 tolerationSeconds=300 的 node.kubernetes.io/not-ready 容忍。同样的,如果 Pod 没有 node.kubernetes.io/unreachable 容忍,Kubernetes 将自动为 Pod 添加一个 tolerationSeconds=300 的 node.kubernetes.io/unreachable 容忍

    这类自动添加的容忍确保了 Pod 在节点发生 not-ready 和 unreachable 问题时,仍然在节点上保留 5 分钟。

    DaemonSet Pod 相对特殊一些,他们在创建时就添加了不带 tolerationSeconds 的 NoExecute 效果的容忍,适用的污点有:

    • node.kubernetes.io/unreachable
    • node.kubernetes.io/not-ready
      这将确保 DaemonSet Pod 始终不会被驱逐。

    污点和容忍的使用场景

    污点和容忍使用起来非常灵活,可以用于:

    • 避免 Pod 被调度到某些特定的节点
    • 从节点上驱逐本不应该在该节点运行的 Pod

    具体使用场景可能有:

    • 专属的节点: 如果想将一组节点专门用于特定的场景,可以为这些节点添加污点(例如 kubectl taint nodes nodename dedicated=groupName:NoSchedule)然后向对应的 Pod 添加容忍。带有这些容忍的 Pod 将可以使用这一组专属节点,同时也可以使用集群中的其他节点。如果想进一步限制这些 Pod 只能使用这一组节点,那么应该为这一组节点添加一个标签(例如 dedicated=groupName),并为这一组 Pod 添加 node affinity(或 node selector)以限制这些 Pod 只能调度到这一组节点上。
    • 带有特殊硬件的节点:集群中,如果某一组节点具备特殊的硬件(例如 GPU),此时非常有必要将那些不需要这类硬件的 Pod 从这组节点上排除掉,以便需要这类硬件的 Pod 可以得到资源。此时可以为这类节点添加污点(例如:kubectl taint nodes nodename special=true:NoSchedule 或者 kubectl taint nodes nodename special=true:PreferNoSchedule)并为需要这类硬件的 Pod 添加匹配的容忍。
    • 基于污点的驱逐 当节点出现问题时,可以使用污点以 Pod 为单位从节点上驱逐 Pod。

    相关文章

      网友评论

          本文标题:kubernetes 容忍及污点

          本文链接:https://www.haomeiwen.com/subject/mocivdtx.html