k8s 污点(Taint) 和容忍度(Toleration)使用

Kubernetes 的污点 (Taint) 容忍度 (Toleration) 是强大的机制,用于控制 Pod 在节点上的调度。它们允许对节点进行标记,并指定哪些 Pod 可以忽略这些标记并仍然被调度到这些节点上。 这对于实现节点隔离、资源专用以及处理节点维护非常有用,Kubernetes 污点和容忍度还可以与其他调度功能(如节点亲和性)结合使用。

污点 (Taint):

污点应用于节点,表示节点的一些特性或限制。 它本质上是一个标记,告诉 Kubernetes 调度程序避免将某些 Pod 调度到该节点。 一个污点包含三个部分:

  • key: 污点的键,一个字符串,用于标识污点的类型。

  • value: 污点的值,一个字符串,提供关于污点类型的更多信息。可以为空字符串。

  • effect: 污点的效果,决定污点如何影响 Pod 的调度。 有三种效果:

    • NoSchedule:阻止 Pod 调度到该节点,除非 Pod 有匹配的容忍度。

    • PreferNoSchedule:调度程序会尽量避免将 Pod 调度到该节点,但如果必要,仍然可以调度。

    • NoExecute:驱逐节点上已经存在的、没有匹配容忍度的 Pod。 这通常用于维护。

容忍度 (Toleration):

容忍度应用于 Pod,表示 Pod 可以容忍某些节点上的污点。 它允许 Pod 被调度到具有匹配污点的节点上。 一个容忍度包含四个部分:

  • key: 容忍度的键,必须与节点污点的键匹配。

  • operator: 运算符,指定如何匹配污点的值。 可以是:

    • Equal:污点的值必须与容忍度的值完全匹配。

    • Exists:只要污点的键存在即可,忽略污点的值。

  • value: 容忍度的值,如果 operator 为 Equal,则必须与污点的值匹配。

  • effect: 容忍度的效果,必须与节点污点的效果匹配。

使用场景:

  • 专用节点: 将节点标记为仅用于特定类型的应用程序。 例如,将节点标记为 gpu=true:NoSchedule,只有具有 gpu=true:NoSchedule 容忍度的 Pod 才能调度到该节点。

  • 节点维护: 在节点进行维护之前,使用 NoExecute 效果的污点驱逐节点上的 Pod,然后进行维护。

  • 隔离敏感数据: 将节点标记为仅用于处理敏感数据的应用程序。

  • 资源隔离: 将节点标记为仅用于高内存或高 CPU 应用程序。

示例:

1. 添加污点:

kubectl taint nodes <node-name> key1=value1:NoSchedule

这将为名为 <node-name> 的节点添加一个污点,键为 key1,值为 value1,效果为 NoSchedule

2. 定义容忍度 (在 Pod 的 YAML 文件中):

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: nginx:latest
  tolerations:
  - key: "key1"
    operator: "Equal"
    value: "value1"
    effect: "NoSchedule"

这将允许名为 my-pod 的 Pod 调度到具有 key1=value1:NoSchedule 污点的节点上。

3. 使用 Exists 运算符:

如果只想检查键的存在性,而忽略值:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: nginx:latest
  tolerations:
  - key: "key1"
    operator: "Exists"
    effect: "NoSchedule"

这将允许 my-pod 调度到任何具有 key1 键的污点的节点上,无论其值是什么。

注意事项:

  • 匹配: 污点和容忍度必须完全匹配才能生效(除非使用 Exists 运算符,否则 keyvalue 和 effect 必须完全匹配)。

  • 顺序: 先添加污点,再创建具有匹配容忍度的 Pod,容忍度的顺序无关紧要

  • 移除污点: 使用 kubectl taint nodes <node-name> <key>-命令移除污点。

  • 谨慎操作: 不正确的污点和容忍度配置可能会导致 Pod 无法调度或被意外驱逐。

如果一个节点同时存在多个污点,Pod 的容忍度必须能够满足所有这些污点才能成功调度到该节点。 这意味着需要为每个污点在 Pod 的 tolerations 列表中添加一个对应的容忍度。

Kubernetes 处理多个污点和容忍度的方式就像一个过滤器:从节点的所有污点开始,然后忽略 pod 具有匹配容忍度的污点;其余未被忽略的污点对 pod 具有的效果如下:

  • 如果至少有一个未被忽略的污点具有 NoSchedule 效果, 那么 Kubernetes 将不会将 pod 调度到该节点上。

  • 如果没有未忽略的污点 NoSchedule ,但至少有一个未忽略的污点 PreferNoSchedule,则 Kubernetes 将尝试不将 pod 调度到节点上。

  • 如果至少有一个未被忽略的污点 NoExecute,那么该 pod 将被从节点中逐出(如果它已经在节点上运行),并且不会被调度到节点上(如果它尚未在节点上运行)。

1.例如,假设我们的一个节点上有以下三个污点

  • 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 容忍的污点。

通常情况下,如果将具有效果的污点 NoExecute 添加到节点,则任何不容忍该污点的 Pod 都会被立即驱逐,而容忍该污点的 Pod 则永远不会被驱逐。但是,具有 NoExecute 效果的容忍可以指定一个可选 tolerationSeconds 字段,该字段表示在添加污点后 Pod 将与节点保持绑定多长时间。例如:

tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoExecute"
  tolerationSeconds: 3600
这个配置表示如果此 pod 正在运行,并且节点上添加了匹配的污点,则 pod 将保持与节点的绑定状态 3600 秒,然后被驱逐。如果在此时间之前删除污点,则 pod 将不会被驱逐。

2.假设一个节点存在以下三个污点:

  • key=env,value=prod,effect=NoSchedule

  • key=disktype,value=ssd,effect=NoSchedule

  • key=zone,value=us-east-1,effect=NoSchedule

那么,Pod 的 tolerations 部分应该如下配置:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: nginx:latest
  tolerations:
  - key: "env"
    operator: "Equal"
    value: "prod"
    effect: "NoSchedule"
  - key: "disktype"
    operator: "Equal"
    value: "ssd"
    effect: "NoSchedule"
  - key: "zone"
    operator: "Equal"
    value: "us-east-1"
    effect: "NoSchedule"

这个配置确保了 my-pod 可以容忍这三个污点,从而能够被调度到该节点。


参考:

anzhihe 安志合个人博客,版权所有 丨 如未注明,均为原创 丨 转载请注明转自:https://chegva.com/6232.html | ☆★★每天进步一点点,加油!★★☆ | 

您可能还感兴趣的文章!

发表评论

电子邮件地址不会被公开。 必填项已用*标注