上一篇文章里面提了一个新的知识点:调度。默认情况下master节点是不调度普通pod的。我们上节课通过<kubectl taint xx > 这条命令让master节点允许被调度,即允许普通pod在master节点上创建。
# 查看master节点是否允许调度,如果出现下面就说明不允许调度
# kubectl describe nodes k8s-master | grep Taint
Taints: node-role.kubernetes.io/control-plane:NoSchedule
# 设置master允许调度节点
# kubectl taint nodes k8s-master node-role.kubernetes.io/control-plane:NoSchedule-
node/k8s-master untainted
本章节来了解下K8S中的污点(Taint),
一、污点(Taint)的作用与类型
1. 污点的作用
污点是定义在节点(Node)上的属性,用于 排斥不符合条件的 Pod 调度到该节点。通过污点可以实现:
- 资源隔离:如限制 GPU 节点仅运行特定 Pod。
- 节点维护:在节点维护期间禁止新 Pod 调度。
- 故障处理:自动标记故障节点并驱逐 Pod(如内存不足、磁盘压力等场景)。
2. 污点的三种效果(Effect)
类型 | 说明 |
---|---|
NoSchedule | 新 Pod 无法调度到该节点(已运行的 Pod 不受影响) |
PreferNoSchedule | 尽量不调度新 Pod 到该节点,但不强制 |
NoExecute | 新 Pod 无法调度到该节点,且已运行的 Pod 若不容忍污点会被驱逐(可设置驱逐延迟时间) |
3. 污点的配置命令
# 添加污点(示例:禁止调度到带有 SSD 磁盘的节点)
kubectl taint nodes k8s-master disktype=ssd:NoSchedule
# 删除污点
kubectl taint nodes node01 disktype=ssd:NoSchedule-
4. 分别举例
1. NoSchedule(禁止调度新 Pod)
场景: 禁止新 Pod 调度到该节点,但已运行的 Pod 不受影响。
典型用途:标记维护节点或专用节点(如 GPU 节点)。
节点添加污点,这里给node01节点添加gpu=ture:NoSchedule
# 节点添加污点(通过命令行操作)
kubectl taint nodes k8s-node01 gpu=ture:NoSchedule
查看node节点的taints,由于指给k8s-node01这一个节点打了污点,所以第一个master的值为null
# kubectl get nodes -o json | jq '.items[].spec.taints'
null
[
{
"effect": "NoSchedule",
"key": "gpu",
"value": "ture"
}
]
配置yaml文件创建pod
# Pod 配置容忍度(YAML)
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
tolerations:
- key: "gpu" # 匹配污点的键
operator: "Equal" # 需键值精确匹配
value: "ture" # 污点的值
effect: "NoSchedule" # 效果必须一致
containers:
- name: nginx
image: m.daocloud.io/docker.io/nginx
查看结果验证,不出意外创建的pod的去了master服务器
取消污点,就是在污点命令后面加一个<->。 再次查看污点,都为null了
root@k8s-master:~# kubectl taint nodes k8s-node01 gpu=ture:NoSchedule-
node/k8s-node01 untainted
root@k8s-master:~# kubectl get nodes -o json | jq '.items[].spec.taints'
null
null
2. PreferNoSchedule(尽量不调度新 Pod)
场景: 调度器尽量避免调度新 Pod 到该节点,但允许降级。
典型用途:非关键节点资源不足时的弹性调度。
节点添加污点,这里给k8s-master节点添加disk=slow:PreferNoSchedule
# 节点添加污点(通过命令行操作)
kubectl taint nodes k8s-master disk=slow:PreferNoSchedule
查看node节点的taints,由于指给k8s-node01这一个节点打了污点,所以第2个node的值为null
# kubectl get nodes -o json | jq '.items[].spec.taints'
[
{
"effect": "PreferNoSchedule",
"key": "disk",
"value": "slow"
}
]
null
配置yaml文件创建pod,
# cat tainted.yaml
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: nginx
image: m.daocloud.io/docker.io/nginx
查看结果验证,不出意外创建的pod的去了node01服务器
3. NoExecute(驱逐现有 Pod)
场景:禁止新 Pod 调度,且驱逐已运行的不容忍该污点的 Pod(可设置驱逐延迟时间)。
典型用途:一般用于替换node节点或者升级node节点的时候。节点故障恢复、紧急维护。
节点添加污点,这里给k8s-node01节点添加maintenance=true:NoExecute
# 节点添加污点
kubectl taint nodes k8s-node01 maintenance=true:NoExecute
查看node节点的taints,由于指给k8s-node01这一个节点打了污点,所以第1个master的值为null
# kubectl get nodes -o json | jq '.items[].spec.taints'
null
[
{
"effect": "NoExecute",
"key": "maintenance",
"value": "true"
}
]
配置yaml文件创建pod,
# cat tainted.yaml
apiVersion: v1
kind: Pod
metadata:
name: critical-pod
spec:
tolerations:
- key: "maintenance"
operator: "Exists" # 仅需键存在,无需值匹配
effect: "NoExecute"
tolerationSeconds: 30 # 允许在节点存活 30s
containers:
- name: nginx
image: m.daocloud.io/docker.io/nginx
查看结果验证,一开始这个pod被分配到了node01节点,但是30S后就销毁了。和上面预设的一致。由于pod没有设置重启策略,所以销毁后就不再存在了。
二、容忍度(Toleration)的配置与匹配规则
1. 容忍度的作用
上面的例子里面看到一半taint是和Toleration进行配合,互相选择,接下来讲解下Toleration的属性,其实上面的yaml例子已经有所展示。
容忍度是定义在 Pod 上的属性,允许 Pod 忽略节点的污点,从而被调度到该节点。
2. 容忍度的配置示例
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
tolerations:
- key: "disktype" # 匹配污点的键
operator: "Equal" # 操作符(Equal/Exists)
value: "ssd" # 匹配污点的值(operator=Equal时需指定)
effect: "NoSchedule" # 匹配污点的效果
tolerationSeconds: 3600 # 仅对 NoExecute 有效,设置驱逐延迟时间[6,12](@ref)
containers:
- name: nginx
image: nginx
3. 关键参数解析
参数 | 说明 |
---|---|
operator | - Equal :需匹配键和值;- Exists :仅需键存在,无需指定值 |
effect | 需与节点污点的效果一致(空值表示匹配所有效果) |
tolerationSeconds | 仅对 NoExecute 有效,定义 Pod 在节点上的存活时间(单位:秒) |
三、典型应用场景
1. 专用节点管理
- 场景:将节点标记为专用(如 GPU 节点),仅允许特定 Pod 调度。
- 配置:
# 节点添加污点
kubectl taint nodes gpu-node hardware=gpu:NoSchedule
2. 节点维护与驱逐
- 场景:节点维护时添加
NoExecute
污点,驱逐现有 Pod 并禁止新调度。 - 配置:
kubectl taint nodes node01 maintenance=true:NoExecute
3. 自动处理节点故障
Kubernetes 内置污点自动标记异常节点:
node.kubernetes.io/not-ready
:节点未就绪node.kubernetes.io/unreachable
:节点不可达node.kubernetes.io/disk-pressure
:磁盘压力过高
四、调试与验证
- 查看节点污点:
kubectl describe node <node-name> | grep Taints
2.检查 Pod 容忍度:
kubectl describe pod <pod-name> | grep -A 5 Tolerations
3.模拟调度测试:
kubectl apply --dry-run=client -f pod.yaml
总结
机制 | 作用对象 | 核心能力 |
---|---|---|
污点 | 节点 | 限制 Pod 调度,实现资源隔离与节点维护 |
容忍度 | Pod | 允许 Pod 忽略污点,灵活调度到特定节点 |
通过合理使用污点与容忍度,可以实现精细化的 Pod 调度策略,提升集群资源利用率与稳定性。