快速搞懂K8S的污点和容忍度(理论+实战)

本文主要快速讲解Kubernetes的污点和容忍度,一句话总结:如果Pod能容忍某个节点上的污点,那么Pod就可以调度到该节点。

在K8S中,如果Pod能容忍某个节点上的污点,那么Pod就可以调度到该节点。如果不能容忍,那就无法调度到该节点。污点和容忍度就像谈恋爱的小情侣,你情我愿,女生知道男生的缺点,却依然选择容忍,这样他们可以生活在一起。如果女生容忍不了男生的缺点,那就没法生活在一起。

1、理论

1.1、污点和容忍度的概念

  • 污点(Taints):定义在节点上,用于拒绝Pod调度到此节点,除非该Pod具有该节点上的污点容忍度。被标记有Taints的节点并不是故障节点。
  • 容忍度(Tolerations):定义在Pod上,用于配置Pod可容忍的节点污点,K8S调度器只能将Pod调度到该Pod能够容忍的污点的节点上。
  • 调度示例图:

1.2、排斥等级

Node对Pod对象的排斥等级有3种:

  • NoSchedule:没有配置此污点容忍度的新Pod不能调度到此节点,节点上现存的Pod不受影响。
  • PreferNoSchedule:没有配置此污点容忍度的新Pod尽量不要调度到此节点,如果找不到合适的节点,依然会调度到此节点。
  • NoExecute:没有配置此污点容忍度的新Pod对象不能调度到此节点,节点上现存的Pod会被驱逐。

1.3、容忍度操作符

在Pod上定义容忍度时,它支持两种操作符:Equal和Exists。

  • Equal:容忍度与污点必须在key、value和effect三者完全匹配。
  • Exists:容忍度与污点必须在key和effect二者完全匹配,容忍度中的value字段要使用空值。

1.4、用法

污点定义在节点的nodeSpec中,容忍度定义在Pod的podSpec中。

污点和容忍度都是键值对的数据格式,但是要增加一个排斥等级(effect)标记。

语法格式为:"key=value:effect"。

1.5、使用场景

1、独占节点

  • 如果想拿出部分节点给特定的Pod使用,可以通过给节点添加污点,然后特定的Pod加入对应的容忍度。
  • 在集群中有些机器设备可能比较特殊,比如CPU性能很好、内存很大等等,不希望普通Pod占用这部分特殊节点,可以通过污点和容忍度来解决。

2、驱逐Pod

上文中定义了Node对Pod的排斥等级有3种。Node如果定义的排斥等级是NoExecute,那么没有配置该污点容忍度的Pod会被驱逐。

K8S 也会使用污点自动标识有问题的节点,比如节点在内存不足的情况下,节点控制器会自动为该节点打上污点信息,并且使用 NoExecute作为排斥等级,此时没有设置此类污点容忍度的Pod 会被驱逐。

DaemonSet控制器会无视此类污点,以便能在节点上部署重要的Pod。

目前,内置的污点也比较多,比如以下几个:

2、实战

2.1、管理节点污点

给节点添加污点:

ini 复制代码
 kubectl taint nodes node01 key=value:effect

给节点删除污点,此处的effect可以没有

css 复制代码
 kubectl taint nodes node01 key[:effect]-

2.2、管理Pod的容忍度

上文中提到了,容忍度的操作符有2种:Equal和Exists,同时把排斥等级也要加上。

使用Equal的场景:

vbnet 复制代码
tolerations:
- key: "key"
  operator: "Equal"
  value: "value"
  effect: "NoExecute"

使用Exists的场景:

vbnet 复制代码
tolerations:
- key: "key"
  operator: "Exists"
  effect: "NoExecute"

如果Node上污点的排斥等级是NoExecute时,该Node上正在运行的Pod如果没有该污点的容忍度,就会被立刻驱逐。不过系统增加了tolerationSeconds字段,用来延迟驱逐Pod。

tolerationSeconds字段的意思是:如果 Pod 的容忍度配置里存在 排斥等级为 NoExecute ,并且指定了属性 tolerationSeconds 的值,那么Pod 还能继续在该节点上运行的时间(单位为秒):

vbnet 复制代码
tolerations:
- key: "key"
  operator: "Equal"
  value: "value"
  effect: "NoExecute"
  tolerationSeconds: 3600

2.3、具体操作

2.3.1、前置小知识

  • 查看看节点label,label是key-value的数据格式
sql 复制代码
kubectl get nodes --show-labels
  • 增加节点label,比如设置一个key是special-app,value是specialwebapp的label
ini 复制代码
kubectl label node k8s-worker-2 special-app=specialwebapp
  • 查看节点污点情况

查看某节点的污点情况,可以看到Taints这一栏是none,也可以看到label情况。

sql 复制代码
kubectl describe node k8s-worker-2

2.3.2、实战示例过程

步骤

  1. 给定某个K8S节点,比如k8s-worker-2,节点的有一个label,Pod根据label选择调度到k8s-worker-2,此时调度成功。
  2. k8s-worker-2增加污点,此时Pod调度失败。
  3. 给Pod配置此污点的容忍度,调度成功。
  4. 删除节点的污点,删除容忍度,部署成功。

操作过程

  • 设置污点
ini 复制代码
 kubectl taint nodes k8s-worker-2 question-node=broken-disk:NoSchedule
  • 部署Pod,可以看到没有配置容忍度的Pod一直处于Pending状态,查看Pod的描述,也给出了原因:调度失败,node有污点,Pod没有容忍度。
  • 给Pod配置容忍度,部署成功
  • 删除污点,删除容忍度,部署成功

    kubectl taint nodes k8s-worker-2 question-node-

完整的yaml文件

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: webapp
  namespace: demo
  labels:
    app: webapp
spec:
  nodeSelector:
    # 选择调度到具有这个label的节点
    "special-app": "specialwebapp"
#    kubernetes.io/hostname: k8s-worker-2
  tolerations:
    - key: "question-node"
      operator: "Equal"
      value: "broken-disk"
      effect: "NoSchedule"
  containers:
    - name: webapp
      image: nginx
      ports:
        - containerPort: 80

总结

在K8S中,如果Pod能容忍某个节点上的污点,那么Pod就可以调度到该节点。如果不能容忍,那就无法调度到该节点。

本篇完结!感谢你的阅读,欢迎点赞 关注 收藏 私信!!!

原文链接: www.mangod.top/articles/20...mp.weixin.qq.com/s/td6gTN49g...

相关推荐
devlei5 小时前
从源码泄露看AI Agent未来:深度对比Claude Code原生实现与OpenClaw开源方案
android·前端·后端
努力的小郑6 小时前
Canal 不难,难的是用好:从接入到治理
后端·mysql·性能优化
Victor3567 小时前
MongoDB(87)如何使用GridFS?
后端
Victor3567 小时前
MongoDB(88)如何进行数据迁移?
后端
小红的布丁7 小时前
单线程 Redis 的高性能之道
redis·后端
GetcharZp8 小时前
Go 语言只能写后端?这款 2D 游戏引擎刷新你的认知!
后端
宁瑶琴9 小时前
COBOL语言的云计算
开发语言·后端·golang
风向决定发型丶9 小时前
K8S CPU绑核详解
云原生·容器·kubernetes
普通网友9 小时前
阿里云国际版服务器,真的是学生党的性价比之选吗?
后端·python·阿里云·flask·云计算
IT_陈寒10 小时前
Vue的这个响应式问题,坑了我整整两小时
前端·人工智能·后端