K8s Taints 与 Tolerations:节点隔离与 Pod 驱逐控制

好嘞!既然你诚心诚意地发问了,那我就大发慈悲地告诉你,咳咳,我是说,我就来跟你好好聊聊 Kubernetes 里的“傲娇” Taints 和“百搭” Tolerations!准备好了吗?这是一场关于节点隔离与 Pod 驱逐控制的奇幻旅程,系好安全带,老司机要发车啦! 🚀

大家好,我是你们的 Kubernetes 诗人兼段子手,今天的主题是:K8s Taints 与 Tolerations:节点隔离与 Pod 驱逐控制。

想象一下,你正在经营一家豪华酒店,里面住满了各种各样的旅客(Pod)。有些旅客是 VIP 客户,必须住最好的套房(特定节点),享受专属服务;有些旅客比较随意,只要有个地方睡觉就行。而有些房间(节点)呢,可能因为装修、维护或者其他原因,暂时不想接待普通旅客。

那么,问题来了:如何才能让 VIP 客户住进专属套房,让普通旅客避开正在装修的房间,并且在房间需要维护时,礼貌地“请”走里面的旅客呢?

答案就是:Taints 和 Tolerations! 这对“欢喜冤家” 就像酒店里的“入住规则”和“入住许可”,它们共同控制着 Pod 能不能在一个节点上“安家落户”。

一、Taints:节点的“生人勿近”结界

Taints 就像节点上贴的一张“禁止入内”的告示,或者说,是节点释放的一种“傲娇”气息,它宣告:“我不是谁都能住的,想要住我这里,先看看你有没有资格!”

1. Taints 的构成:Key、Value、Effect

一个 Taint 由三个部分组成:

  • Key: Taint 的名字,相当于“禁止入内”的原因,比如 node.kubernetes.io/disk-pressure(磁盘压力过大)。
  • Value: Taint 的值,相当于对“禁止入内”原因的补充说明,可以为空。
  • Effect: Taint 的效果,决定了 Pod 如何应对这个 Taint,这是最重要的一部分!

Effect 的三种取值:

Effect 含义 形象比喻
NoSchedule 除非 Pod 明确声明可以容忍(Tolerate)这个 Taint,否则禁止调度到该节点。 “谢绝入住”,直接拦在门外,除非你有通行证。
PreferNoSchedule 尽量不要调度到该节点,但如果实在没有其他合适的节点,还是可以勉强入住。这是一种“软性”的拒绝。 “尽量别住”,但如果没得选,凑合一下也行。
NoExecute 不但禁止新的 Pod 调度到该节点,而且会驱逐已经运行在该节点上的、没有对应 Toleration 的 Pod。这是一种非常强硬的拒绝。 “立即退房”,不仅不让新旅客入住,还要把已经住在这里的“不速之客”赶走!

2. Taints 的应用场景:

  • 节点维护: 当节点需要进行维护、升级时,可以添加 NoExecute Taint,驱逐上面的 Pod,防止维护期间出现问题。
  • 资源不足: 当节点资源(CPU、内存、磁盘)不足时,可以添加 NoSchedulePreferNoSchedule Taint,避免新的 Pod 调度上来,加剧资源压力。
  • 专用节点: 某些节点可能专门用于运行特定类型的 Pod,可以添加 Taint,防止其他 Pod 误入。例如,GPU 节点可以添加 nvidia.com/gpu=true:NoSchedule Taint。

3. 举个栗子:

假设我们要给一个节点添加一个 Taint,表示该节点磁盘压力过大,不适合运行新的 Pod,并且要驱逐已经运行在该节点上的、不容忍该 Taint 的 Pod:

kubectl taint nodes <node-name> node.kubernetes.io/disk-pressure=true:NoExecute

这条命令的意思是:给 <node-name> 节点添加一个 Taint,Key 是 node.kubernetes.io/disk-pressure,Value 是 true,Effect 是 NoExecute

二、Tolerations:Pod 的“免死金牌”通行证

Tolerations 就像 Pod 携带的“免死金牌”或者“通行证”,它告诉 Kubernetes:“我知道这个节点有点‘傲娇’,但我有能力容忍它的‘傲娇’,请允许我住在这里!”

1. Tolerations 的构成:Key、Operator、Value、Effect、TolerationSeconds

一个 Toleration 由五个部分组成:

  • Key: 容忍的 Taint 的 Key,必须与 Taint 的 Key 对应。
  • Operator: 操作符,用于匹配 Taint 的 Value。
    • Equal(默认值):要求 Toleration 的 Value 必须与 Taint 的 Value 相等。
    • Exists:只要存在具有相同 Key 的 Taint,就表示容忍。
  • Value: 容忍的 Taint 的 Value,只有当 Operator 为 Equal 时才需要指定。
  • Effect: 容忍的 Taint 的 Effect,必须与 Taint 的 Effect 对应。
  • TolerationSeconds: 仅当 effect=NoExecute 时有效,表示 Pod 在节点 Taint 生效后,还能在该节点上存活的时间(秒)。如果未设置,Pod 将立即被驱逐。

2. Tolerations 的应用场景:

  • 容忍节点维护: 某些对中断不敏感的 Pod,可以添加 Toleration,容忍节点维护期间的 Taint,避免被驱逐。
  • 容忍资源不足: 某些对资源要求不高的 Pod,可以添加 Toleration,容忍资源不足的 Taint,充分利用集群资源。
  • 运行在专用节点: 某些需要运行在特定节点上的 Pod,必须添加 Toleration,才能被调度到这些节点上。

3. 举个栗子:

假设我们要让一个 Pod 容忍 node.kubernetes.io/disk-pressure=true:NoExecute 这个 Taint,并且允许它在 Taint 生效后继续存活 300 秒:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: nginx
  tolerations:
  - key: "node.kubernetes.io/disk-pressure"
    operator: "Equal"
    value: "true"
    effect: "NoExecute"
    tolerationSeconds: 300

这个 YAML 文件定义了一个 Pod,它有一个 Toleration,Key 是 node.kubernetes.io/disk-pressure,Operator 是 Equal,Value 是 true,Effect 是 NoExecute,TolerationSeconds 是 300。

三、Taints 和 Tolerations 的“爱恨情仇”:如何正确“调情”

Taints 和 Tolerations 就像一对“傲娇”的情侣,想要让他们和谐相处,需要掌握一些“调情”技巧:

  • Key 必须匹配: Toleration 的 Key 必须与 Taint 的 Key 对应,否则 Toleration 就失去了意义。
  • Operator 和 Value 的选择:
    • 如果 Taint 的 Value 是固定的,可以使用 Equal 操作符,并指定对应的 Value。
    • 如果 Taint 的 Value 不重要,只需要 Key 存在即可,可以使用 Exists 操作符。
  • Effect 必须匹配: Toleration 的 Effect 必须与 Taint 的 Effect 对应,否则 Toleration 也无法生效。
  • TolerationSeconds 的使用: 只有当 Taint 的 Effect 为 NoExecute 时,TolerationSeconds 才有意义。它决定了 Pod 在 Taint 生效后还能存活多久。

表格总结:Taints 和 Tolerations 的关键属性

属性 Taint Toleration 说明
Key Taint 的名称 要容忍的 Taint 的 Key 必须匹配,否则 Toleration 无效。
Value Taint 的值 要容忍的 Taint 的 Value 只有当 Operator 为 Equal 时才需要指定,并且必须与 Taint 的 Value 相等。
Effect Taint 的效果 (NoSchedule, PreferNoSchedule, NoExecute) 要容忍的 Taint 的 Effect 必须匹配,否则 Toleration 无效。
Operator N/A 操作符 (Equal, Exists) 用于匹配 Taint 的 Value。
TolerationSeconds N/A Pod 在 Taint 生效后存活的时间(秒) 仅当 Effect 为 NoExecute 时有效。

四、实战演练:一个完整的例子

假设我们有一个 GPU 节点,专门用于运行深度学习任务。为了防止其他 Pod 误入,我们给该节点添加一个 Taint:

kubectl taint nodes gpu-node nvidia.com/gpu=true:NoSchedule

然后,我们创建一个 Pod,专门用于运行深度学习任务,并添加一个 Toleration,容忍该 Taint:

apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod
spec:
  containers:
  - name: gpu-container
    image: tensorflow/tensorflow:latest-gpu
  nodeSelector:
    gpu: "true"  # 确保调度到 GPU 节点
  tolerations:
  - key: "nvidia.com/gpu"
    operator: "Equal"
    value: "true"
    effect: "NoSchedule"

在这个例子中,我们首先给 gpu-node 添加了一个 Taint,Key 是 nvidia.com/gpu,Value 是 true,Effect 是 NoSchedule。然后,我们创建了一个 gpu-pod,它有一个 Toleration,Key 是 nvidia.com/gpu,Operator 是 Equal,Value 是 true,Effect 是 NoSchedule

由于 gpu-pod 的 Toleration 与 gpu-node 的 Taint 匹配,因此它可以被调度到 gpu-node 上运行。而其他没有对应 Toleration 的 Pod 则无法被调度到 gpu-node 上,从而实现了节点隔离的目的。

五、高级技巧:Taints 和 Tolerations 的“隐藏技能”

除了基本用法之外,Taints 和 Tolerations 还有一些“隐藏技能”,可以帮助我们更好地控制 Pod 的调度和驱逐:

  • Default Tolerations: 可以通过 Admission Controller 自动给所有 Pod 添加默认的 Tolerations,简化配置。
  • Node Affinity 和 Taints/Tolerations 的结合: 可以同时使用 Node Affinity 和 Taints/Tolerations,实现更精细的调度控制。
  • 动态 Taints: 可以使用 Node Controller 根据节点的状态(例如,资源使用率)动态地添加或删除 Taints。

六、总结:掌握 Taints 和 Tolerations,成为 K8s 调度大师

Taints 和 Tolerations 是 Kubernetes 中非常重要的概念,它们提供了强大的节点隔离和 Pod 驱逐控制能力。掌握了它们,你就可以:

  • 优化资源利用率: 将 Pod 调度到最合适的节点上,避免资源浪费。
  • 提高集群稳定性: 在节点维护期间,安全地驱逐 Pod,防止服务中断。
  • 实现精细化调度: 根据 Pod 的需求,将它们调度到特定的节点上。

总而言之,Taints 和 Tolerations 就像 Kubernetes 的“交通警察”,它们维护着集群的秩序,确保 Pod 能够安全、高效地运行。

希望今天的讲解对你有所帮助!如果你还有其他问题,欢迎随时提问。下次再见! 👋

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注