k8s之pod的调度之污点与容忍污点,什么是污点? 如何容忍污点

在 Kubernetes 中,污点(Taint)容忍(Toleration) 是用于控制 Pod 调度到特定节点的重要机制。污点允许节点拒绝某些 Pod 的调度,而容忍则允许 Pod 忽略节点的污点,从而调度到特定节点上。


1. 污点(Taint)

1.1.污点的作用

污点是节点上的一个标记,用于限制哪些 Pod 可以调度到该节点。通常用于以下场景:

  • 专用节点:某些节点专门用于运行特定类型的 Pod(如 GPU 节点)。
  • 节点维护:标记节点为不可调度状态,以便进行维护。
  • 故障隔离:将故障节点标记为不可调度,避免 Pod 调度到该节点。

1.2.污点的组成

每个污点由以下三部分组成:

  • Key: 污点的键(必填)。
  • Value: 污点的值(可选)。
  • Effect : 污点的效果(必填),有以下三种:
    • NoSchedule: 禁止调度新的 Pod 到该节点(已运行的 Pod 不受影响)。
    • PreferNoSchedule: 尽量不调度新的 Pod 到该节点(非强制)。
    • NoExecute: 禁止调度新的 Pod 到该节点,并且驱逐已运行但不满足容忍的 Pod。
1.3.污点的配置

通过 kubectl taint 命令为节点添加污点。

查看帮助文档

bash 复制代码
[root@master ~]# kubectl taint --help

语法:

bash 复制代码
kubectl taint nodes <节点名称> <key>=<value>:<effect>

示例:

  1. 为节点 node-1 添加一个污点带有值的,禁止调度新的 Pod:

    bash 复制代码
    [root@master ~]# kubectl taint nodes node-1 dedicated=special:NoSchedule
    node/node-1 tainted
    
    [root@master ~]# kubectl describe node node-1 | grep Taint
    Taints:             dedicated=special:NoSchedule
  2. 为节点 node-2 添加一个污点,尽量不调度新的 Pod:

    bash 复制代码
    [root@master ~]# kubectl taint nodes node-2 gpu:PreferNoSchedule
    node/node-2 tainted
    [root@master ~]# kubectl describe node node-2 | grep Taint
    Taints:             gpu:PreferNoSchedule
  3. 为节点 node-3 添加一个污点,禁止调度并驱逐不满足容忍的 Pod:

    bash 复制代码
    [root@master ~]# kubectl get pod -o wide 
    NAME                           READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
    web-server-1-79776bf47-h9zvh   1/1     Running   0          20m   10.244.3.14    node-3   <none>           <none>
    
    [root@master ~]# kubectl taint nodes node-3 maintenance=true:NoExecute
    node/node-3 tainted
    [root@master ~]# kubectl describe node node-3 | grep Taint
    Taints:             maintenance=true:NoExecute
    [root@master ~]# kubectl get pod -o wide  #node-3的pod已经被驱离,会被重新调度到其它节点

删除污点:

语法:

bash 复制代码
kubectl taint nodes <节点名称> <key>[:<effect>]-

示例 :

删除节点 node-1与node-2 上的污点:

bash 复制代码
[root@master ~]# kubectl taint nodes node-1 dedicated-
node/node-1 untainted
[root@master ~]# kubectl describe node node-1 | grep Taint
Taints:             <none>
bash 复制代码
[root@master ~]# kubectl taint nodes node-2 gpu-
node/node-2 untainted
[root@master ~]# kubectl describe node node-2 | grep Taint
Taints:             <none>

2. 容忍(Toleration)

2.1.容忍的作用

容忍是 Pod 的一个属性,允许 Pod 调度到带有特定污点的节点上。通过容忍,Pod 可以忽略节点的污点限制。

2.2.容忍的配置

容忍可以在 Pod 的 YAML 文件中通过 tolerations 字段配置。

示例:

bash 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: nginx
    image: nginx
  tolerations:
  - key: "dedicated"
    operator: "Equal"
    value: "special"
    effect: "NoSchedule"

字段说明:

  • key: 污点的键。
  • operator: 匹配操作符,可以是 Equal(精确匹配)或 Exists(存在即可)。
  • value: 污点的值(当 operatorEqual 时必填)。
  • effect: 污点的效果(如 NoScheduleNoExecute 等)。

示例场景:

  1. 允许 Pod 调度到带有 dedicated=special:NoSchedule 污点的节点:

    bash 复制代码
    tolerations:
    - key: "dedicated"
      operator: "Equal"
      value: "special"
      effect: "NoSchedule"
  2. 允许 Pod 调度到带有任意 gpu=true 污点的节点:

    此时operator为Exists,可以不指定污点的值

    bash 复制代码
    tolerations:
    - key: "gpu"
      operator: "Exists"
      effect: "NoSchedule"
  3. 允许 Pod 调度到带有任意 NoExecute 污点的节点:

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

2.3. 污点与容忍的常见使用场景

场景 1:专用节点
  • 为 GPU 节点添加污点:

    bash 复制代码
    [root@master ~]# kubectl taint nodes node-1 gpu=true:NoSchedule
    node/node-1 tainted
  • 在需要调度到 GPU 节点的 Pod 中添加容忍:

    bash 复制代码
    [root@master ~]# cat create_pod.yml 
    apiVersion: v1
    kind: Pod
    metadata:
     name: test-pod-1
     namespace: default
     labels:
      app: nginx
    spec:
     containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
         - containerPort: 80
     tolerations:
      - key: gpu
        operator: Exists
        effect: NoSchedule
        
    [root@master ~]# kubectl apply -f create_pod.yml 
    pod/test-pod-1 created  
    [root@master ~]# kubectl get pod -o wide 
    NAME                           READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
    test-pod-1                     1/1     Running   0          5s    10.244.2.85    node-1   <none>           <none>
场景 2:节点维护
  • 为维护节点添加污点:

    bash 复制代码
    [root@master ~]# kubectl taint nodes node-2 maintenance=true:NoExecute
    node/node-2 tainted
  • 在需要继续运行的 Pod 中添加容忍:

    需要注意:对已经运行在该节点的pod将会被驱离,自动调度到其他节点,除非在创建的时候提前指定容忍该污点的作用。

    bash 复制代码
    [root@master ~]# cat create_pod.yml 
    apiVersion: v1
    kind: Pod
    metadata:
     name: test-pod-1
     namespace: default
     labels:
      app: nginx
    spec:
     containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
         - containerPort: 80
     tolerations:
      - key: maintenance
        operator: Equal
        value: "true"
        effect: NoExecute
        
    [root@master ~]# kubectl apply -f create_pod.yml 
    pod/test-pod-1 created
    [root@master ~]# kubectl get pod -o wide 
    NAME                           READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
    test-pod-1                     1/1     Running   0          5s    10.244.1.135   node-2   <none>           <none>
场景 3:故障隔离
  • 为故障节点添加污点:

    bash 复制代码
    kubectl taint nodes node-2 failure=true:NoExecute
  • 在需要继续运行的 Pod 中添加容忍:

    bash 复制代码
    tolerations:
    - key: "failure"
      operator: "Equal"
      value: "true"
      effect: "NoExecute"

3. 总结

  • 污点:用于限制 Pod 调度到特定节点。
  • 容忍:允许 Pod 忽略节点的污点,调度到特定节点。
  • 通过污点和容忍,可以实现节点的专用化、维护和故障隔离等场景。

通过合理使用污点和容忍,可以更灵活地控制 Kubernetes 集群中 Pod 的调度行为,提升集群的稳定性和资源利用率。

4.污点的优先级

4.1. 污点的效果与 nodeName与nodeSelector 的关系

情况 1:污点效果为 NoSchedule
  • 如果节点上有 NoSchedule 污点,而 Pod 没有配置相应的容忍:
    • 即使 Pod 使用了 nodeName 指定了该节点,Pod 仍然不会被调度到该节点
    • Kubernetes 会忽略 nodeName 的指定,因为污点的优先级更高。
情况 2:污点效果为 NoExecute
  • 如果节点上有 NoExecute 污点,而 Pod 没有配置相应的容忍:
    • 如果 Pod 已经运行在该节点上,它会被驱逐
    • 如果 Pod 尚未调度到该节点,即使使用了 nodeName,Pod 也不会被调度到该节点。
情况 3:Pod 配置了容忍
  • 如果 Pod 配置了与节点污点匹配的容忍:
    • 无论污点的效果是 NoSchedule 还是 NoExecute,Pod 都可以正常调度到该节点。
    • nodeName 的指定会生效,Pod 会被调度到指定的节点。

4.2.总结

  • 污点的优先级高于 nodeName与nodeSelector :即使 Pod 使用了 nodeName或者nodeSelector 指定节点,污点仍然会生效。
  • 污点的效果决定行为
    • NoSchedule:阻止 Pod 调度到该节点。
    • NoExecute:驱逐已运行的 Pod 或阻止新 Pod 调度。
  • 容忍的作用:如果 Pod 配置了与污点匹配的容忍,则可以忽略污点的限制,正常调度到指定节点。

因此,在使用 nodeName或者nodeSelector 时,需要确保 Pod 配置了与节点污点匹配的容忍,否则 Pod 可能无法调度到指定节点。

相关推荐
無名之輩12 分钟前
Nvidia Device Plugin入门二之envvar策略
kubernetes
云和数据.ChenGuang2 小时前
微服务技术栈
微服务·云原生·架构
syty20202 小时前
K8s是什么
容器·kubernetes·dubbo
江团1io03 小时前
微服务雪崩问题与系统性防御方案
微服务·云原生·架构
Evan Wang4 小时前
使用Terraform管理阿里云基础设施
阿里云·云原生·terraform
向上的车轮4 小时前
基于go语言的云原生TodoList Demo 项目,验证云原生核心特性
开发语言·云原生·golang
灵犀物润5 小时前
Kubernetes 配置检查与发布安全清单
安全·容器·kubernetes
360智汇云6 小时前
k8s交互桥梁:走进Client-Go
golang·kubernetes·交互
xy_recording6 小时前
Day20 K8S学习
学习·容器·kubernetes
衍余未了6 小时前
k8s 内置的containerd配置阿里云个人镜像地址及认证
java·阿里云·kubernetes