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 可能无法调度到指定节点。

相关推荐
Yuanymoon6 小时前
【由技及道】模块化战争与和平-论项目结构的哲学思辨【人工智智障AI2077的开发日志】
java·开发语言·spring boot·spring·容器
沈二到不行7 小时前
wsl2&centos实践
windows·容器
i1yo_kiki8 小时前
实现dify与docker下载安装
运维·docker·容器
Karoku0668 小时前
【CI/CD】Jenkins + Docker +SpringCloud微服务项目持续集成
运维·ci/cd·docker·微服务·容器·kubernetes·jenkins
赴前尘9 小时前
docker compose 搭建 redis 主从复制集
redis·docker·容器
Biehmltym11 小时前
【Java企业生态系统的演进】从单体J2EE到云原生微服务
java·云原生·java-ee
不务专业的程序员--阿飞12 小时前
【Eureka 缓存机制】
java·缓存·云原生·eureka
咖啡の猫12 小时前
kubernetes 部署项目
云原生·容器·kubernetes
还没入门的大菜狗13 小时前
【go】以Kubernetes中的 kubelet 为引思考go语言中共享状态的选择
kubernetes
陵易居士15 小时前
黑马头条启动文章微服务时报错Error creating bean with name ‘buildMinioClient‘的原因及解决方案
微服务·云原生·架构