在 Kubernetes 集群中,Pod 调度失败是常见问题之一。当出现类似 0/5 nodes are available: 2 Insufficient cpu, 2 Insufficient memory, 3 node(s) had untolerated taint... 的错误时,我们需要从 资源分配、污点(Taint)与容忍(Toleration)、抢占(Preemption)机制 等多个维度进行分析。本文将详细解析这类问题的成因,并提供完整的解决方案,同时结合代码示例帮助读者深入理解。
在 Kubernetes 中,调度器(Scheduler)负责将 Pod 分配到合适的节点上运行。当 Pod 无法调度时,通常会返回类似如下的错误:
0/5 nodes are available:
2 Insufficient cpu,
2 Insufficient memory,
3 node(s) had untolerated taint {vci.vke.volcengine.com/node-type: vci}.
preemption: 0/5 nodes are available:
2 No preemption victims found for incoming pod,
3 Preemption is not helpful for scheduling.这个错误信息告诉我们:
接下来,我们将逐一分析这些问题的原因和解决方案。
Kubernetes 调度器在分配 Pod 时,会检查节点的 可分配资源(Allocatable Resources) 是否满足 Pod 的 requests 需求。如果节点资源不足,Pod 就无法调度。
我们可以使用以下命令查看节点资源使用情况:
kubectl top nodes输出示例:
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
node-1 500m 50% 2Gi 40%
node-2 800m 80% 3Gi 60%如果发现某些节点的 CPU 或内存使用率接近 100%,说明资源紧张。
在 Pod 的 YAML 中,可以调整 requests 以减少资源占用:
resources:
requests:
cpu: "500m" # 0.5 核
memory: "1Gi" # 1GB 内存但要注意,requests 不能设置过低,否则可能导致 Pod 因资源不足被 OOMKilled。
删除不再需要的 Pod 或 Deployment:
kubectl delete pod <pod-name>
kubectl delete deployment <deployment-name>污点是 Kubernetes 的一种机制,用于 限制 Pod 调度到某些节点。例如:
运行以下命令查看节点污点:
kubectl describe node <node-name>输出示例:
Taints: vci.vke.volcengine.com/node-type=vci:NoSchedule这表明该节点有一个污点 vci.vke.volcengine.com/node-type=vci,并且效果是 NoSchedule(不允许新 Pod 调度)。
在 Pod 的 YAML 中添加 tolerations:
tolerations:
- key: "vci.vke.volcengine.com/node-type"
operator: "Equal"
value: "vci"
effect: "NoSchedule"这样 Pod 就可以调度到带有该污点的节点。
如果确定该污点不再需要,可以移除:
kubectl taint nodes <node-name> vci.vke.volcengine.com/node-type:NoSchedule-Kubernetes 允许 高优先级 Pod 抢占低优先级 Pod 的资源,以便完成调度。但如果:
No preemption victims found)。Preemption is not helpful)。查看集群中的优先级类:
kubectl get priorityclass示例输出:
NAME VALUE
high-priority 1000000
low-priority 100在 Pod 的 YAML 中指定更高的 PriorityClass:
apiVersion: v1
kind: Pod
metadata:
name: high-priority-pod
spec:
priorityClassName: high-priority
containers:
- name: nginx
image: nginx如果某些低优先级 Pod 占用了资源,可以手动删除或调整其优先级:
kubectl delete pod <low-priority-pod>如果 Pod 配置了 nodeSelector 或 affinity,但没有任何节点匹配,也会导致调度失败:
spec:
nodeSelector:
gpu: "true"检查节点标签:
kubectl get nodes --show-labels确保所有节点处于 Ready 状态:
kubectl get nodes如果节点状态异常(如 NotReady),需要排查节点问题(如 kubelet 是否正常运行)。
检查节点资源:
kubectl top nodes
kubectl describe nodes检查污点:
kubectl describe node <node-name>检查优先级和抢占:
kubectl get priorityclass
kubectl get pods --sort-by='.spec.priority'检查 Pod 配置:
kubectl describe pod <pod-name>requests、tolerations、nodeSelector 等配置。当 Kubernetes Pod 调度失败时,主要从以下几个方面排查:
requests。tolerations 或移除污点。nodeSelector、节点状态等。通过合理的资源规划、污点管理和优先级设置,可以有效避免 Pod 调度失败问题,提高集群稳定性。
命令 | 作用 |
|---|---|
kubectl top nodes | 查看节点资源使用情况 |
kubectl describe node <node> | 查看节点详情(包括污点) |
kubectl taint nodes <node> key=value:NoSchedule- | 移除污点 |
kubectl get priorityclass | 查看优先级类 |
kubectl get pods --sort-by='.spec.priority' | 按优先级查看 Pod |
通过本文的分析,相信读者能够更好地理解和解决 Kubernetes 调度失败问题。如果有进一步的问题,欢迎在评论区讨论! 🚀