K8S-节点污点与POD容忍度
1、污点(taints)和容忍度(tolerations)概念
1.1、污点(taints)
用来标记节点的键值性数据,让节点有能力主动拒绝调度器将pod调度到节点上。除非该pod对象明确定义能够容忍该污点,节点spec.taints定义
给节点定义污点语法格式为:key=value:effect
key:value,通过键值保存污点数据
effect:效用标识,级别,如下:
NoSchedule:pod中没有定义该污点容忍度(pod中spec.tolerations)为NoSchedule的pod 将不会调度到该节点,为强制性约束,但是不影响已经调度到该节点上的pod
PreferNoSchedule:pod中没有定义该污点容忍度(pod中spec.tolerations)为PreferNoSchedule的pod 将尽量不调度到该节点,当没有满足条件的其他节点可调度时,也可以调度到该节点。为非强制性约束,不影响已经调度到该节点上的pod
NoExecute:pod中没有定义该污点容忍度(pod中spec.tolerations)为NoExecute的pod 将不调度到该节点,强制性约束。而且当前节点上的POD,如果因为节点污点变动或者pod污点容忍度不再满足匹配关系时,pod对象将会被立即驱逐
1.2、容忍度:
定义pod能够接受pod在有指定污点的节点上运行,在pod定义中:spec.tolerations定义,根据使用操作不同主要由一下两种形式:
Equal:与污点信息完全匹配的等值关系,key value和effect 和节点taint完全一致,pod才可以调度到节点运行
Exist:存在性匹配方式,会忽略value;只要有key和effect就行。
当不指定key值和effect值时,且operator为Exists,表示容忍所有的污点【能匹配污点所有的keys,values和effects】
当不指定effect值时,则能匹配污点key对应的所有effects
tolerations:
- key: "key"
operator: "Exists"
2、示例
环境
如环境图片中看到kube-node01到kube-node04均没有设置污点。
2.1、NoSchedule
给kube-node1增加check=aa:NoSchedule污点
[root@kube-master01 taints]# kubectl taint node kube-node01 check=aa:NoSchedule
部署pod

kind: Deployment
metadata:
name: test
spec:
replicas: 5
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
containers:
- name: test
image: redis:6.0-alpine
如下:可以看到,节点pod将不会被调度到kube-node01
给kube-node02也增加check=aa:NoSchedule污点
[root@kube-master01 taints]# kubectl taint node kube-node02 check=aa:NoSchedule
如下:pod仍然在kube-node02上运行,因为NoSchedule不会因为节点污点的变化而影响已经在节点上运行的pod,重新创建pod,pod将不会再调度到污点的pod上
如下:删除pod重建后pod将只会被调度到kube-node03和node-04上
在创建pod时增加容忍度,再重新创建pod,pod也会被调度到污点节点,但是定义时的key=value:effect需要和污点定义的一致

apiVersion: apps/v1 kind: Deployment metadata: name: test spec: replicas: 5 selector: matchLabels: app: test template: metadata: labels: app: test spec: tolerations: - key: "check" operator: "Equal" value: "aa" effect: "NoSchedule" tolerationSeconds: 120 containers: - name: test image: redis:6.0-alpine
如下,可以看到当pod配置了容忍度后,pod也可以被调度到kube-node01和kube-node02上
恢复:删除节点kube-node01和kube-node02节点上的污点:在新增污点语句后面增加一个"-",表示删除
[root@kube-master01 taints]# kubectl taint node kube-node01 check=aa:NoSchedule-
[root@kube-master01 taints]# kubectl taint node kube-node02 check=aa:NoSchedule-
2.2、PreferNoSchedule
尽量不调度到有该污点的节点,但是当没有符合taints要求的节点时也可以调度到设置了PreferNoSchedule污点的节点的
给kube-node01和kube-node02增加check=aa:PreferNoSchedule污点
[root@kube-master01 taints]# kubectl taint node kube-node01 check=aa:PreferNoSchedule
[root@kube-master01 taints]# kubectl taint node kube-node02 check=aa:PreferNoSchedule
当给kube-node03和kube-node04增加check=aa:PreferNoSchedule污点后再重建pod,就可以调度到有该污点的节点:
[root@kube-master01 taints]# kubectl taint node kube-node03 check=aa:PreferNoSchedule
[root@kube-master01 taints]# kubectl taint node kube-node04 check=aa:PreferNoSchedule
[root@kube-master01 taints]# kubectl delete pod `kubectl get pods|awk 'NR>1{print $1}'`
恢复,移除所有节点上的污点,删除pod
2.3、NoExecute
节点设置污点为NoExecute后,pod没有配置spec.tolerations为NoExcute的POD不能调度到该节点,已经运行在该节点的pod也会被驱逐

apiVersion: apps/v1
kind: Deployment
metadata:
name: test
spec:
replicas: 5
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
containers:
- name: test
image: redis:6.0-alpine
如下:节点无污点,每个节点都有pod运行
在kube-node03上增加check=aa:NoExecute
[root@kube-master01 taints]# kubectl taint node kube-node03 check=aa:NoExecute
可以看到,由于pod没有设置tolerations,位于kube-node03上的pod被驱逐到其他节点
为pod增加tolerations后:

apiVersion: apps/v1
kind: Deployment
metadata:
name: test
spec:
replicas: 5
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
tolerations:
- key: "check"
operator: "Equal"
value: "aa"
effect: "NoExecute"
containers:
- name: test
image: redis:6.0-alpine
增加后应用并删除原来的pod,可以看到,重建后的pod时可以调度到kube-node03上
3、问题节点标识
kubernetes从1.6开始,支持通过节点控制器在特定条件下自动为节点增加污点信息,都使用NoExecute效用标识
如:
node.kubernetes.io/not-ready :节点进入NotReady状态时自动添加污点
node.alpha.kubernetes.io/unreachable: 节点进入NotReachable自动添加
node.kubernetes.io/out-of-disk : OutOfDisk
node.kubernetes.io/memory-pressure :内存压力
node.kubernetes.io/disk-pressure :磁盘压力
node.kubernetes.io/network-unavailable :网络不用
node.cloudprovider.kubernetes.io/uninitialized :外部云环境程序启动时,自动添加此污点,待云控制管理器中的控制器初始化节点时再将污点删除
kubernetes的核心组件通常都要容忍上述污点以确保相应的Deamonset控制器能够在相应的节点上部署pod对象,如:kube-proxy,kube-flannel,calico等
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!