K8s集群中的Pod调度约束:污点、容忍与驱逐

目录

一、污点(Taint)

1.1.什么是污点

1.2.taint effect 支持的选项

1.3.污点相关操作

1.3.1.设置污点

1.3.2 去除污点

二、容忍(Tolerations)

2.1.什么是容忍

2.2. 设置 Pod 容忍

2.3. 其它注意事项

三、驱逐(cordon 和 drain)

3.1. 维护操作

3.2.cordon(隔离)

3.3.Drain(排空)

3.4.phase 的可能状态有 

四、故障排除步骤 


一、污点(Taint)

1.1.什么是污点

节点亲和性让 Pod 倾向或强制部署在特定节点上,而 Taint 则是节点用来拒绝不兼容 Pod 的机制。每个节点可设多个 Taint,拒绝不容忍这些 Taint 的 Pod 接入。通过 kubectl taint 命令可以给 Node 添加污点限制,Node 被设置上污点之后就和 Pod 之间存在了一种相斥的关系,可以让 Node 拒绝 Pod 的调度执行,甚至将 Node 已经存在的 Pod 驱逐出去。

污点的组成格式为:key=value:effect。每个污点有一个 key 和 value 作为污点的标签,其中 value 可以为空,effect 描述污点的作用。

1.2.taint effect 支持的选项

NoSchedule:表示 k8s 不会将 Pod 调度到具有该污点的 Node 上;

PreferNoSchedule:表示 k8s 将尽量避免将 Pod 调度到具有该污点的 Node 上;

NoExecute:表示 k8s 将不会将 Pod 调度到具有该污点的 Node 上,同时会将 Node 上已经存在的 Pod 驱逐出去。

master 就是因为有 NoSchedule 污点,k8s 才不会将 Pod 调度到 master 节点上:

[root@master01 ~]# kubectl describe node master | grep -i taints
Taints:             node-role.kubernetes.io/master:NoSchedule

1.3.污点相关操作

1.3.1.设置污点

格式:
kubectl taint node node名字 key1=value1:NoSchedule 

① 创建副本 yaml 文件

[root@master01 data]#vim pod01.yaml  
apiVersion: apps/v1  
kind: Deployment  
metadata:
  name: pod-nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      pod: nginx
  template:
    metadata:
      labels:
        pod: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14
        ports:
        - containerPort: 80

② 给 node01 设置污点

[root@master01 data]# kubectl taint node node01 w=d:NoSchedule
node/node01 tainted

③ 启动 pod,并查看 pod 详情信息

[root@master01 data]# kubectl apply -f pod1.yaml 
deployment.apps/pod-nginx created
[root@master01 data]# kubectl get pod -o wide
NAME                        READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
pod-nginx-76c6c5b65-296dl   1/1     Running   0          69s   10.244.2.18   node02   <none>           <none>
pod-nginx-76c6c5b65-jhqt2   1/1     Running   0          69s   10.244.2.20   node02   <none>           <none>
pod-nginx-76c6c5b65-kqbc2   1/1     Running   0          69s   10.244.2.19   node02   <none>           <none>
 

由于 node01 节点设置了污点,所以 k8s 不会将 Pod 调度到该节点上。

④ 节点说明,查找 Taints 字段

格式:
kubectl describe node node名字
 
[root@master01 data]# kubectl describe node node01 | grep -i taints
Taints:             w=d:NoSchedule

1.3.2 去除污点

格式:
kubectl taint node node名字 key1:NoSchedule-

① 去除 node01 节点污点

[root@master01 data]# kubectl taint node node01 w:NoSchedule-
node/node01 untainted
[root@master01 data]# kubectl describe node node01 | grep -i taint
Taints:             <none>

② 查看 pod 详情信息

[root@master01 data]# kubectl get pod -o wide
NAME                        READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
pod-nginx-76c6c5b65-296dl   1/1     Running   0          10m   10.244.2.18   node02   <none>           <none>
pod-nginx-76c6c5b65-jhqt2   1/1     Running   0          10m   10.244.2.20   node02   <none>           <none>
pod-nginx-76c6c5b65-kqbc2   1/1     Running   0          10m   10.244.2.19   node02   <none>           <none>

③ 设置 node02 节点污点,添加 NoExecute 选项

[root@master01 data]# kubectl taint node node02 fql=b:NoExecute
node/node02 tainted

④ 持续查看 pod 详情信息


                
### Kubernetes中污点和亲和性的适用场景 #### 污点 (Taints) 污点用于标记某些节点,使得只有特定的 Pod 才能被调度到这些节点上。通过这种方式,可以实现更精细的调度控制。 - **NoSchedule**: 这种效果意味着 Kubernetes 不会将新创建的 Pod 调度到带有此污点的节点上,但如果该节点上有已经存在的 Pod,则不会受到影响[^4]。 - **PreferNoSchedule**: 类似于 `NoSchedule`,但它是一个较弱的约束条件。即使没有配置容忍项,Kubernetes 可能仍然会选择将 Pod 调度到这样的节点上。 - **NoExecute**: 如果一个现有的 Pod 缺少对该污点的容忍声明,那么当这个污点被添加到节点时,Pod 将会被驱逐出去。同时,任何新的 Pod 都无法被调度到此类节点上。 ##### 使用案例 1. **专用资源分配** - 当集群中有特殊硬件需求(如 GPU 或者 SSD),可以通过给拥有这类设备的节点打上相应的污点来防止其他不需要这种资源的工作负载占用它们。 2. **隔离敏感工作负载** - 对于一些安全性较高的应用或者服务,可能希望将其其他常规业务隔离开来运行在一个独立的安全环境中。此时就可以利用 `NoExecute` 效果达到目的。 3. **维护期间保护重要组件** - 在执行计划内的升级或者其他操作之前先为主机增加临时性质的 `NoExecute` 污点以确保所有非必要的进程都被清理掉从而减少干扰因素。 ```bash kubectl taint nodes node-name key=value:NoExecute ``` --- #### 亲和性 (Affinity) 污点相反的是亲和性和反亲和性机制允许管理员定义偏好规则让 K8S 更倾向于把某个类型的 Pods 放置在一起或者是分开部署。 - **Node Affinity** 定义了一组规则决定哪些 Nodes 是候选目标供 Pod 的放置考虑; - **Pod Affinity/Anti-Affinity** 则关注如何基于现有 Pods 来影响未来 Pods 的位置选择。 ##### Node Affinity 示例 下面的例子展示了怎样指定只允许某类标签匹配成功的机器才能承载我们的应用程序实例: ```yaml affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: disktype operator: In values: - ssd ``` 这里我们告诉系统仅限那些携带了 `"disktype"` 属性等于 `"ssd"` 的计算单元才适合作为目标主机接纳请求中的容器镜像启动过程[^1]。 ##### Pod Anti-Affinity 实例 为了提高系统的可靠性并降低单点故障风险,在设计分布式架构的时候往往还需要考虑到跨区域分布的问题。比如我们可以规定同一个 StatefulSet 下的不同副本之间应该尽量分散开来避免集中失败情况发生: ```yaml affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - myapp topologyKey: failure-domain.beta.kubernetes.io/zone ``` 上述 YAML 文件片段设置了对于名为 `myapp` 的应用而言其各个实例间应当尽可能分布在不同的可用区之中。 --- ### 总结 无论是采用 Taint/Toleration 组合还是各种形式下的 Affinities 设置都能够帮助运维人员更好地掌控整个平台内部各组成部分之间的关系进而优化整体性能表现以及提升稳定性水平。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值