当前位置: 首页 > news >正文

K8S(七)—污点、容忍

目录

  • 污点、容忍
      • 污点(Taints):
      • 容忍(Tolerations):
      • 如何一起使用污点和容忍:
      • 操作符(Equal、Exists)
      • 例子
      • 基于污点的驱逐
      • 基于节点状态添加污点

污点、容忍

官网地址:https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration/

Kubernetes(通常简称为K8s)是一个用于容器编排和管理的开源平台。在Kubernetes中,污点(Taints)和容忍(Tolerations)是用于控制Pod调度的重要概念,它们允许您指定哪些节点可以接受哪些Pod。以下是有关污点和容忍的详细解释:

污点(Taints):

  1. 什么是污点
    污点是一种节点级别的属性,它告诉Kubernetes哪些节点不适合运行特定类型的Pod。节点上的污点可以阻止Pod被调度到不适合的节点上。

  2. 如何定义污点
    污点由节点的管理员定义,它们是键值对的形式,包括:

    • key:污点的名称,通常是一个字符串。
    • value:污点的值,通常为空字符串。
    • effect:污点的效果,可以是NoSchedulePreferNoScheduleNoExecute
      • NoSchedule:Pod将不会被调度到带有该污点的节点上。
      • PreferNoSchedule:Kubernetes会尽量避免将Pod调度到带有该污点的节点上,但如果没有其他可用节点,仍然可以调度。
      • NoExecute:对于已经运行在该节点上的Pod,如果它们不符合污点的要求,将被驱逐。

    设置污点

    [root@k8smaster taint_toleration]# kubectl describe node k8snode1|grep -i NoExecute
    Taints:             cf=tencent:NoExecute

取消污点

[root@k8smaster taint_toleration]# kubectl taint node k8snode1 cf=tencent:NoExecute-node/k8snode1 untainted
[root@k8smaster taint_toleration]# kubectl describe node k8snode1|grep -i NoExecute
[root@k8smaster taint_toleration]# 

容忍(Tolerations):

  1. 什么是容忍
    容忍是Pod级别的属性,它告诉Kubernetes该Pod可以容忍哪些节点上的污点。容忍允许Pod被调度到具有特定污点的节点上。

  2. 如何定义容忍
    容忍是在Pod的规范(Spec)中定义的,包括:

    • key:与污点的key匹配。
    • value:与污点的value匹配。
    • operator:匹配操作符,可以是Equal(等于)、Exists(存在)等。
    • effect:与污点的effect匹配。
  3. 示例
    假设您有一个Pod,它希望容忍名为gpu的污点,您可以使用以下方式定义容忍:

    tolerations:
    - key: gpuoperator: Equalvalue: nvidiaeffect: NoSchedule
    

如何一起使用污点和容忍:

  • 通过在节点上定义污点,您可以将一组节点标记为特定类型(例如GPU节点),然后通过在Pod规范中定义容忍,您可以确保只有需要GPU的Pod才会被调度到这些节点上。

  • 污点和容忍的结合可以为您提供更高的灵活性,以满足特定的部署需求。您可以根据需要在节点和Pod级别上定义多个污点和容忍。

总之,污点和容忍是Kubernetes中用于控制Pod调度的强大机制,它们使得您可以更精确地管理Pod在集群中的位置,以满足特定的硬件或软件要求。这对于在多样化的硬件和环境条件下运行容器化应用程序非常有用。

操作符(Equal、Exists)

你可以在 Pod 规约中为 Pod 设置容忍度。 下面两个容忍度均与上面例子中使用 kubectl taint 命令创建的污点相匹配, 因此如果一个 Pod 拥有其中的任何一个容忍度,都能够被调度到 node1

tolerations:
- key: "key1"operator: "Equal"value: "value1"effect: "NoSchedule"
tolerations:
- key: "key1"operator: "Exists"effect: "NoSchedule"

这里是一个使用了容忍度的 Pod:

pods/pod-with-toleration.yaml

apiVersion: v1
kind: Pod
metadata:name: nginxlabels:env: test
spec:containers:- name: nginximage: nginximagePullPolicy: IfNotPresenttolerations:- key: "example-key"operator: "Exists"effect: "NoSchedule"

operator 的默认值是 Equal

一个容忍度和一个污点相“匹配”是指它们有一样的键名和效果,并且:

  • 如果 operatorExists(此时容忍度不能指定 value),或者
  • 如果 operatorEqual,则它们的 value 应该相等。

说明:

存在两种特殊情况:

如果一个容忍度的 key 为空且 operatorExists, 表示这个容忍度与任意的 key、value 和 effect 都匹配,即这个容忍度能容忍任何污点。

如果 effect 为空,则可以与所有键名 key1 的效果相匹配。

下面的例子表示任何污点都可以接受

tolerations:- key:""operator: "Exists"value:""effect:"" 

上述例子中 effect 使用的值为 NoSchedule,你也可以使用另外一个值 PreferNoSchedule。 这是“优化”或“软”版本的 NoSchedule —— 系统会 尽量 避免将 Pod 调度到存在其不能容忍污点的节点上, 但这不是强制的。effect 的值还可以设置为 NoExecute,下文会详细描述这个值。

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

  • 如果未被忽略的污点中存在至少一个 effect 值为 NoSchedule 的污点, 则 Kubernetes 不会将 Pod 调度到该节点。
  • 如果未被忽略的污点中不存在 effect 值为 NoSchedule 的污点, 但是存在至少一个 effect 值为 PreferNoSchedule 的污点, 则 Kubernetes 会 尝试 不将 Pod 调度到该节点。
  • 如果未被忽略的污点中存在至少一个 effect 值为 NoExecute 的污点, 则 Kubernetes 不会将 Pod 调度到该节点(如果 Pod 还未在节点上运行), 并且会将 Pod 从该节点驱逐(如果 Pod 已经在节点上运行)。

例如,假设你给一个节点添加了如下污点:

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

假定某个 Pod 有两个容忍度:

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

在这种情况下,上述 Pod 不会被调度到上述节点,因为其没有容忍度和第三个污点相匹配。 但是如果在给节点添加上述污点之前,该 Pod 已经在上述节点运行, 那么它还可以继续运行在该节点上,因为第三个污点是三个污点中唯一不能被这个 Pod 容忍的。

通常情况下,如果给一个节点添加了一个 effect 值为 NoExecute 的污点, 则任何不能忍受这个污点的 Pod 都会马上被驱逐,任何可以忍受这个污点的 Pod 都不会被驱逐。 但是,如果 Pod 存在一个 effect 值为 NoExecute 的容忍度指定了可选属性 tolerationSeconds 的值,则表示在给节点添加了上述污点之后, Pod 还能继续在节点上运行的时间。例如,

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

这表示如果这个 Pod 正在运行,同时一个匹配的污点被添加到其所在的节点, 那么 Pod 还将继续在节点上运行 3600 秒,然后被驱逐。 如果在此之前上述污点被删除了,则 Pod 不会被驱逐。

例子

使用yaml启动pod

[root@k8smaster taint_toleration]# cat pod.yaml 
apiVersion: v1
kind: Pod
metadata:name: demo-podnamespace: defaultlabels:app: myappenv: dev
spec:nodeName: k8snode1containers:- name: busyboximage: busybox:latestimagePullPolicy: IfNotPresentcommand:- "/bin/sh"- "-c"- "sleep 3600"

此时,k8snode1和k8snode2都没有污点,都可以正常被调度,但是在yaml文件在指定了要运行在那个节点上。

[root@k8smaster taint_toleration]# kubectl get pod -o wide
NAME                                READY   STATUS    RESTARTS   AGE    IP               NODE       NOMINATED NODE   READINESS GATES
demo-pod                            1/1     Running   0          20s    10.244.249.24    k8snode1   <none>           <none>
nginx-deployment-559d658b74-75fpp   1/1     Running   0          100m   10.244.249.21    k8snode1   <none>           <none>
nginx-deployment-559d658b74-j6rdd   1/1     Running   0          101m   10.244.249.20    k8snode1   <none>           <none>
nginx-deployment-559d658b74-kh8jb   1/1     Running   0          101m   10.244.185.250   k8snode2   <none>           <none>

设置污点

[root@k8smaster taint_toleration]# kubectl describe node k8smaster|grep -i taint
Taints:             node-role.kubernetes.io/master:NoSchedule
[root@k8smaster taint_toleration]# kubectl  taint nodes k8snode1 cf=tencent:NoExecutenode/k8snode1 tainted[root@k8smaster taint_toleration]# kubectl describe node k8snode1|grep -i taint 
Taints:             cf=tencent:NoExecute

demo-pod 会停止运行

[root@k8smaster taint_toleration]# cat pod.yaml 
apiVersion: v1
kind: Pod
metadata:name: demo-podnamespace: defaultlabels:app: myappenv: dev
spec:nodeName: k8snode1containers:- name: busyboximage: busybox:latestimagePullPolicy: IfNotPresentcommand:- "/bin/sh"- "-c"- "sleep 3600"tolerations:- key: "cf"operator: "Equal"value: "tencent"effect: "NoExecute"

将ymal文件进行修改,将容忍度也设置为k8snode1可以接受的程度,如下:

  tolerations:- key: "cf"operator: "Equal"value: "tencent"effect: "NoExecute"

可以看到demo-pod 重新运行了

[root@k8smaster taint_toleration]# kubectl get pod -o wide
NAME                                READY   STATUS    RESTARTS   AGE   IP              NODE       NOMINATED NODE   READINESS GATES
demo-pod                            1/1     Running   0          13h   10.244.249.25   k8snode1   <none>           <none>

基于污点的驱逐

特性状态: Kubernetes v1.18 [stable]

前文提到过污点的效果值 NoExecute 会影响已经在节点上运行的如下 Pod:

  • 如果 Pod 不能忍受这类污点,Pod 会马上被驱逐。
  • 如果 Pod 能够忍受这类污点,但是在容忍度定义中没有指定 tolerationSeconds, 则 Pod 还会一直在这个节点上运行。
  • 如果 Pod 能够忍受这类污点,而且指定了 tolerationSeconds, 则 Pod 还能在这个节点上继续运行这个指定的时间长度。

当某种条件为真时,节点控制器会自动给节点添加一个污点。当前内置的污点包括:

  • node.kubernetes.io/not-ready:节点未准备好。这相当于节点状况 Ready 的值为 “False”。
  • node.kubernetes.io/unreachable:节点控制器访问不到节点. 这相当于节点状况 Ready 的值为 “Unknown”。
  • node.kubernetes.io/memory-pressure:节点存在内存压力。
  • node.kubernetes.io/disk-pressure:节点存在磁盘压力。
  • node.kubernetes.io/pid-pressure: 节点的 PID 压力。
  • node.kubernetes.io/network-unavailable:节点网络不可用。
  • node.kubernetes.io/unschedulable: 节点不可调度。
  • node.cloudprovider.kubernetes.io/uninitialized:如果 kubelet 启动时指定了一个“外部”云平台驱动, 它将给当前节点添加一个污点将其标志为不可用。在 cloud-controller-manager 的一个控制器初始化这个节点后,kubelet 将删除这个污点。

在节点被排空时,节点控制器或者 kubelet 会添加带有 NoExecute 效果的相关污点。 如果异常状态恢复正常,kubelet 或节点控制器能够移除相关的污点。

在某些情况下,当节点不可达时,API 服务器无法与节点上的 kubelet 进行通信。 在与 API 服务器的通信被重新建立之前,删除 Pod 的决定无法传递到 kubelet。 同时,被调度进行删除的那些 Pod 可能会继续运行在分区后的节点上。

说明:

控制面会限制向节点添加新污点的速率。这一速率限制可以管理多个节点同时不可达时 (例如出现网络中断的情况),可能触发的驱逐的数量。

你可以为 Pod 设置 tolerationSeconds,以指定当节点失效或者不响应时, Pod 维系与该节点间绑定关系的时长。

比如,你可能希望在出现网络分裂事件时,对于一个与节点本地状态有着深度绑定的应用而言, 仍然停留在当前节点上运行一段较长的时间,以等待网络恢复以避免被驱逐。 你为这种 Pod 所设置的容忍度看起来可能是这样:

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

说明:

Kubernetes 会自动给 Pod 添加针对 node.kubernetes.io/not-readynode.kubernetes.io/unreachable 的容忍度,且配置 tolerationSeconds=300, 除非用户自身或者某控制器显式设置此容忍度。

这些自动添加的容忍度意味着 Pod 可以在检测到对应的问题之一时,在 5 分钟内保持绑定在该节点上。

DaemonSet 中的 Pod 被创建时, 针对以下污点自动添加的 NoExecute 的容忍度将不会指定 tolerationSeconds

  • node.kubernetes.io/unreachable
  • node.kubernetes.io/not-ready

这保证了出现上述问题时 DaemonSet 中的 Pod 永远不会被驱逐。

基于节点状态添加污点

控制平面使用节点控制器自动创建 与节点状况 对应的、效果为 NoSchedule 的污点。

调度器在进行调度时检查污点,而不是检查节点状况。这确保节点状况不会直接影响调度。 例如,如果 DiskPressure 节点状况处于活跃状态,则控制平面添加 node.kubernetes.io/disk-pressure 污点并且不会调度新的 Pod 到受影响的节点。 如果 MemoryPressure 节点状况处于活跃状态,则控制平面添加 node.kubernetes.io/memory-pressure 污点。

对于新创建的 Pod,可以通过添加相应的 Pod 容忍度来忽略节点状况。 控制平面还在具有除 BestEffort 之外的 QoS 类的 Pod 上添加 node.kubernetes.io/memory-pressure 容忍度。 这是因为 Kubernetes 将 GuaranteedBurstable QoS 类中的 Pod(甚至没有设置内存请求的 Pod) 视为能够应对内存压力,而新创建的 BestEffort Pod 不会被调度到受影响的节点上。

DaemonSet 控制器自动为所有守护进程添加如下 NoSchedule 容忍度,以防 DaemonSet 崩溃:

  • node.kubernetes.io/memory-pressure
  • node.kubernetes.io/disk-pressure
  • node.kubernetes.io/pid-pressure (1.14 或更高版本)
  • node.kubernetes.io/unschedulable (1.10 或更高版本)
  • node.kubernetes.io/network-unavailable (只适合主机网络配置)

添加上述容忍度确保了向后兼容,你也可以选择自由向 DaemonSet 添加容忍度。

相关文章:

  • mysql的BIT数值类型
  • 微信小程序scroll-view的scroll-into-view和vanUI的tabs标签结合使用
  • 智能优化算法应用:基于共生生物算法3D无线传感器网络(WSN)覆盖优化 - 附代码
  • Nginx的stream配置
  • [足式机器人]Part2 Dr. CAN学习笔记-数学基础Ch0-7欧拉公式的证明
  • 如何在Facebook Business Manager进行企业认证
  • 骨灰级程序员那些年曾经告诉我们的高效学习的态度
  • mysql 数据库
  • Re9 Attention is all you need
  • 2.4 C语言之运算符
  • 1、springboot项目运行报错
  • Spring Boot+FreeMarker=打造高效Web应用
  • 三层交换原理
  • <蓝桥杯软件赛>零基础备赛20周--第9周--前缀和与差分
  • 前端知识笔记(四)———JQuery 自动刷新页面但不闪烁的实现方法
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • HashMap ConcurrentHashMap
  • javascript面向对象之创建对象
  • JS学习笔记——闭包
  • python 学习笔记 - Queue Pipes,进程间通讯
  • Rancher如何对接Ceph-RBD块存储
  • Redash本地开发环境搭建
  • SAP云平台运行环境Cloud Foundry和Neo的区别
  • vue的全局变量和全局拦截请求器
  • Vue官网教程学习过程中值得记录的一些事情
  • 解析带emoji和链接的聊天系统消息
  • 使用SAX解析XML
  • 突破自己的技术思维
  • 源码安装memcached和php memcache扩展
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • 分布式关系型数据库服务 DRDS 支持显示的 Prepare 及逻辑库锁功能等多项能力 ...
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • ​​​​​​​​​​​​​​Γ函数
  • #、%和$符号在OGNL表达式中经常出现
  • #NOIP 2014#Day.2 T3 解方程
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • (1)(1.13) SiK无线电高级配置(六)
  • (C++20) consteval立即函数
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (补)B+树一些思想
  • (二开)Flink 修改源码拓展 SQL 语法
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (译) 理解 Elixir 中的宏 Macro, 第四部分:深入化
  • (转)一些感悟
  • .【机器学习】隐马尔可夫模型(Hidden Markov Model,HMM)
  • .bat批处理(七):PC端从手机内复制文件到本地
  • .NET 8.0 发布到 IIS
  • .NET 材料检测系统崩溃分析
  • .NET简谈设计模式之(单件模式)
  • .NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版)
  • .net生成的类,跨工程调用显示注释
  • .NET中 MVC 工厂模式浅析
  • @LoadBalanced 和 @RefreshScope 同时使用,负载均衡失效分析