Skip to content

rke1-k8s1.16.3 exception 节点 Pod 分布不均排查文档

问题现象

三台带有 node-type=exception:NoSchedule 污点的节点 Pod 数量分布不均:

节点max-podscurrent-podsCPU内存
szb1203311036160核756G
szb1303415086160核1T
szb1401711075160核756G

排查思路

Pod 分布不均通常不是单一原因造成的,需要从节点状态、资源余量、调度约束、调度器行为四个维度排查。

一、确认节点状态与可调度性

bash
kubectl get nodes -l node-type=exception -o wide
kubectl describe node szb12033 szb13034 szb14017

重点检查:

  • ConditionsReady 是否为 True
  • 是否存在 SchedulingDisabled(不可调度)
  • 是否存在额外的 Taints(如 NoExecute)导致 Pod 被驱逐
  • Capacity / Allocatable 资源是否一致

二、检查实际资源分配(requests 才是调度依据)

bash
kubectl top node szb12033 szb13034 szb14017
kubectl describe node szb12033 | grep -A 20 "Allocated resources"
kubectl describe node szb13034 | grep -A 20 "Allocated resources"
kubectl describe node szb14017 | grep -A 20 "Allocated resources"

调度器看的是 requests,不是 limits,也不是实际使用率。要对比:

  • CPU requests 占比
  • Memory requests 占比
  • Pod 数量占比

如果某节点 CPU/Memory requests 已经很高,即使 current-pods 少,新 Pod 也不会再调度过去。

三、查看节点上运行的 Pod 规格分布

bash
kubectl get pods --all-namespaces --field-selector spec.nodeName=szb12033 -o custom-columns=NAME:.metadata.name,NS:.metadata.namespace,CPU_REQUEST:.spec.containers[*].resources.requests.cpu,MEM_REQUEST:.spec.containers[*].resources.requests.memory

将三个节点分别导出后对比:

  • 大规格 Pod(高 CPU/内存请求)是否集中在了某些节点
  • DaemonSet Pod 数量是否一致
  • 业务 Pod 是否被反亲和性打散

四、检查 Pod 调度约束

4.1 NodeSelector / Affinity / Tolerations

bash
# 查看无法调度到 szb12033 的 Pod 是否有节点亲和性约束
kubectl get pods --all-namespaces -o json | jq '
  .items[]
  | select(.spec.nodeName == null)
  | {name: .metadata.name, ns: .metadata.namespace, affinity: .spec.affinity, nodeSelector: .spec.nodeSelector}
'

4.2 Pod 反亲和性(Pod Anti-Affinity)

如果业务 Deployment 配置了 requiredDuringSchedulingIgnoredDuringExecution 的 Pod 反亲和性,当某个节点已有一个副本后,其他副本不会调度到同一节点,导致分布看起来"不均匀",但这是预期行为。

bash
kubectl get deployments --all-namespaces -o yaml | grep -B5 -A20 podAntiAffinity

五、查看调度事件与日志

5.1 调度事件

bash
kubectl get events --all-namespaces --field-selector reason=FailedScheduling
kubectl get events --all-namespaces --field-selector reason=Scheduled | grep -E "szb12033|szb13034|szb14017"

5.2 调度器日志

RKE1 1.16.3 默认使用 kube-scheduler:

bash
# 找到 kube-scheduler Pod
kubectl -n kube-system get pods -l component=kube-scheduler

# 查看日志
kubectl -n kube-system logs <kube-scheduler-pod-name> | grep -E "szb12033|szb13034|szb14017"

如果集群启用了自定义调度策略(scheduler policy),检查:

bash
kubectl -n kube-system get configmap scheduler-policy -o yaml

六、检查 kubelet max-pods 与资源限制

三台节点 max-pods 不一致(110 vs 150),说明 kubelet 的 --max-pods 参数配置不同。需要确认:

bash
# 在节点上执行
ps aux | grep kubelet | grep max-pods
cat /etc/kubernetes/kubelet.yaml 2>/dev/null | grep maxPods

RKE1 中 kubelet 配置通常在 cluster.ymlservices.kubelet.extra_args 或节点级别 extra_args 中。

七、快速排查脚本

已提供 check_exception_node_distribution.sh 脚本,可一键收集以下信息:

  1. 节点状态与污点
  2. 各节点 Allocatable / Allocated 资源
  3. 各节点 Pod 数量与资源请求汇总
  4. 最近 FailedScheduling 事件

运行:

bash
./check_exception_node_distribution.sh

八、常见原因总结

现象可能原因
某节点 current-pods 明显偏低节点有额外 taint、NotReady、SchedulingDisabled、资源 requests 已耗尽
三节点 Pod 数差异大但资源差异小存在 Pod 反亲和性、大规格 Pod 集中、max-pods 不一致
新 Pod 持续不调度到某节点节点资源不足、污点不匹配、亲和性约束
调度结果无规律调度器自定义策略、优先级/抢占、Descheduler 干预

九、建议

  1. 统一 max-pods:三台节点规格接近,建议统一为 110 或 150,避免调度上限不一致造成理解偏差。
  2. 使用 Descheduler:如果希望 Pod 分布更均衡,可以部署 Kubernetes Descheduler 并配置 RemoveDuplicatesLowNodeUtilization 策略。
  3. 监控 requests 而非 limits:调度瓶颈通常是 requests 资源,而不是 limits 或实际使用率。
  4. 检查业务亲和性:确认业务是否有意通过反亲和性打散,避免误判为"不均"。