• k8s 亲和、反亲和、污点、容忍


    目录

    一、K8s调度

    二、亲和与反亲和

    2.1、Pod和Node

    2.2、硬亲和和软亲和

    三、污点与容忍

    3.1  污点(Taint)

    3.1.1  污点的组成 

    3.1.2  污点的设置和去除

    3.2  容忍(Tolerations)

    3.2.1  Toleration 基本用法

    3.2.2  Toleration案例

    3.3   多污点与多容忍配置


    一、K8s调度

    1. 调度器通过kubernetes的list-watch机制来发现集群中新创建且尚未被调度到Node上的Pod。调度器会将发现的每一个未调度的Pod调度到一个合适的Node上来运行。
    2. kube-scheduler是Kubernetes集群的默认调度器,并且是集群控制面的一部分。如果你真的希望或者有这方面的需求,kube-scheduler在设计上是允许你自己写一个调度组件并替换原有的kube-scheduler。
    3. 在做调度决定时需要考虑的因素包括:单独和整体的资源请求、硬件/软件/策略限制、亲和以及反亲和要求、数据局域性、负载间的干扰等等。
       

    二、亲和与反亲和

    亲和性的原理其实很简单,主要利用label标签结合nodeSelector选择器来实现

    2.1、Pod和Node

    • 从pod出发,可以分成亲和性和反亲和性,分别对应podAffinity和podAntiAffinity
    • 从node出发,也可以分成亲和性和反亲和性,分别对应nodeAffinity和nodeAntiAffinity。
    • 从操作指令来讲,可以有ln、Notln、Exists、DoesNotExist等等。
    1. 针对亲和性来讲,in代表我要调度到有这个标签的位置
    2. 针对反亲和性来讲,in代表我不要调度到有这个标签的位置

    2.2、硬亲和和软亲和

    preferredDuringSchedulingIgnoredDuringExecution    软亲和

    软策略:结合下面的 “operator: NotIn”,意思就是尽量不要将 pod 调度到匹配到的节点,但是如果没有不匹配的节点的话,也可以调度到匹配到的节点。

    requiredDuringSchedulingIgnoredDuringExecution 硬亲和

    硬策略:结合下面的 “operator: In”,意思就是必须调度到满足条件的节点上,否则就等着 Pending。

    不管哪种方式,最终还是要依赖 label 标签。

    1. kubectl get pods -n company ai-action-statistic-gray-86465f9c4b-hdfk4 -oyaml | grep nodeSelector -B 5 -A 5
    2. uid: ed47f094-f70a-45ed-b7dd-d46f2d01986f
    3. spec:
    4. affinity:
    5. nodeAffinity:
    6. requiredDuringSchedulingIgnoredDuringExecution: #硬策略
    7. nodeSelectorTerms:
    8. - matchExpressions:
    9. - key: node-role.kubernetes.io/gray
    10. operator: In
    11. values:
    12. - gray
    13. preferredDuringSchedulingIgnoredDuringExecution: #软策略
    14. - weight: 1
    15. preference:
    16. matchExpressions:
    17. - key: pc-app
    18. operator: NotIn
    19. values:
    20. - luna

    三、污点与容忍

    K8s 每个节点上都可以应用一个或多个 taint ,这表示对于那些不能容忍这些 taint 的 pod,是不会被该节点接受的。如果将 toleration 应用于 pod 上,则表示这些 pod 可以(但不要求)被调度到具有相应 taint 的节点上。

    3.1  污点(Taint)

    • 如果一个节点被标记为有污点,那么意味着不允许pod调度到该节点,除非pod也被标记为可以容忍污点节点。
    • 在使用kubeadm部署的k8s集群的时候应该会发现,通常情况下,应用是不会调度到master节点的。因为kubeadm部署的k8s集群默认给master节点加了Taints(污点)

    3.1.1  污点的组成 

    使用kubectl taint命令可以给某个Node节点设置污点,Node被设置上污点之后就和Pod之间存在了一种相斥的关系,可以让Node拒绝Pod的调度执行,甚至将Node已经存在的Pod驱逐出去。

    每个污点的组成如下:

    key=value:effect
    

    每个污点有一个key和value作为污点的标签,其中value可以为空,effect描述污点的作用。

    污点有三种策略:

    • PreferNoSchedule:NoSchedule的软策略版本,表示尽量不调度到污点节点上去。
    • NoExecute:该选项意味着一旦Taint生效,如该节点内正在运行的Pod没有对应容忍(Tolerate)设置,则会直接被逐出。
    • NoSchedule:表示k8s将不会将Pod调度到具有该污点的Node上

    NoExecute和NoSchedule的区别:

    • NoSchedule只是不调度,但并不影响已经调度好的容器,即使给宿主机新增了污点,这些Pod依然会正常运行。同样PreferNoSchedule也是。
    • NoExecute就不一样了,会将Pod驱逐到其他宿主,除非该Pod容忍。

    3.1.2  污点的设置和去除

    使用kubectl设置和去除污点的命令示例如下:

    1. # 设置污点
    2. kubectl taint nodes node1 key1=value1:NoSchedule
    3. # 去除污点
    4. kubectl taint nodes node1 key1:NoSchedule-

    接下来看一个具体的例子,使用kubeadm部署和初始化的Kubernetes集群,master节点被设置了一个node-role.kubernetes.io/master:NoSchedule的污点,可以使用kubectl describe node 命令查看。这个污点表示默认情况下master节点将不会调度运行Pod,即不运行工作负载。

    对于使用二进制手动部署的集群设置和移除这个污点的命令如下:

    1. kubectl taint nodes <node-name> node-role.kubernetes.io/master=:NoSchedule
    2. kubectl taint nodes <node-name> node-role.kubernetes.io/master:NoSchedule-

    3.2  容忍(Tolerations)

    设置了污点的Node将根据taint的effect:NoSchedule、PreferNoSchedule、NoExecute和Pod之间产生互斥的关系,Pod将在一定程度上不会被调度到Node上。 但我们可以在Pod上设置容忍(Toleration),意思是设置了容忍的Pod将可以容忍污点的存在,可以被调度到存在污点的Node上。

    3.2.1  Toleration 基本用法

    pod 的 Toleration 声明中的 key 和 effect 需要与 Taint 的设置保持一致,并且满足以下条件之一:

    1. operator 的值为 Exists,这时无需指定 value
    2. operator 的值为 Equal 并且 value 相等
    3. 如果不指定 operator,则默认值为 Equal。

    另外还有如下两个特例:

    1. 空的 key 配合 Exists 操作符能够匹配所有的键和值
    2. 空的 effect 匹配所有的 effect

    上面的例子中 effect 的取值为 NoSchedule,下面对 effect 的值作下简单说明:

    1. NoSchedule:如果一个 pod 没有声明容忍这个 Taint,则系统不会把该 Pod 调度到有这个 Taint 的 node 上
    2. PreferNoSchedule:NoSchedule 的软限制版本,如果一个 Pod 没有声明容忍这个Taint,则系统会尽量避免把这个 pod 调度到这一节点上去,但不是强制的。
    3. NoExecute:定义 pod 的驱逐行为,以应对节点故障。

    NoExecute 这个 Taint 效果对节点上正在运行的 pod 有以下影响:

    • 没有设置 Toleration 的 Pod 会被立刻驱逐
    • 配置了对应 Toleration 的 pod,如果没有为 tolerationSeconds 赋值,则会一直留在这一节点中
    • 配置了对应 Toleration 的 pod 且指定了 tolerationSeconds 值,则会在指定时间后驱逐
       

    3.2.2  Toleration案例

    1. tolerations:
    2. - key: "key1"
    3. operator: "Equal"
    4. value: "value1"
    5. effect: "NoSchedule"
    6. tolerationSeconds: 3600
    7. - key: "key1"
    8. operator: "Equal"
    9. value: "value1"
    10. effect: "NoExecute"
    11. - key: "key2"
    12. operator: "Exists"
    13. effect: "NoSchedule"
    • 其中key, vaule, effect要与Node上设置的taint保持一致
    • operator的值为Exists将会忽略value值
    • tolerationSeconds用于描述当Pod需要被驱逐时可以在Pod上继续保留运行的时间

    下面看一下在Pod上设置容忍的两个特例:

    示例1: 当不指定key值时,表示容忍所有的污点key:

    1. tolerations:
    2. - operator: "Exists"

    示例2:当不指定effect值时,表示容忍所有的污点作用:

    1. tolerations:
    2. - key: "key"
    3. operator: "Exists"

    注意:  在节点故障情况下,为了保持现存的 pod 驱逐的限速设置,系统将会以限速的模式逐步给 node 设置 Taint,这就能防止在一些特定情况下(比如 master 暂时失联)造成的大量 pod 被驱逐的后果。这一功能兼容于 tolerationSeconds,允许 pod 定义节点故障时持续多久才被逐出。

    3.3   多污点与多容忍配置

    **系统允许在同一个 node 上设置多个 taint,也可以在 pod 上设置多个 Toleration。**Kubernetes 调度器处理多个 Taint 和 Toleration 能够匹配的部分,剩下的没有忽略掉的 Taint 就是对 Pod 的效果了。下面是几种特殊情况:

    • 如果剩余的 Taint 中存在 effect=NoSchedule,则调度器不会把该 pod 调度到这一节点上。
    • 如果剩余的 Taint 中没有 NoSchedule 的效果,但是有 PreferNoSchedule 效果,则调度器会尝试不会 pod指派给这个节点
    • 如果剩余 Taint 的效果有 NoExecute 的,并且这个 pod已经在该节点运行,则会被驱逐;如果没有在该节点运行,也不会再被调度到该节点上。
    1. kubectltaint nodes node1 key1=value1:NoSchedule
    2. kubectl taint nodes node1 key1=value1:NoExecute
    3. kubectl taint nodes node1 key2=value2:NoSchedule

  • 相关阅读:
    小黑准备收拾东西领物资的日常积累:线程与进程
    Quectel EC200N-CN驱动移植记录
    macOS上制作arm64的jdk17镜像
    在强化学习rl中对于state value function和state action value function的理解
    HTML 学习笔记(基础)
    【JAVA版本】websocket获取B站直播弹幕——基于直播开放平台
    Git 查看当前分支是基于哪个分支拉取(源头分支)
    LLM 系列 | 21 : Code Llama实战(上篇) : 模型简介与评测
    计算机网络 | 数据链路层
    全志v853体验可能会遇到的问题
  • 原文地址:https://blog.csdn.net/WuDan_1112/article/details/126109254