来源:马哥Linux运维 | 发布日期:2026-05-28
Pod Pending 排障指南
Pod 卡在 Pending 意味着 Scheduler 找不到合适的节点分配,或 Kubelet 在创建容器阶段卡住。核心排查工具:
kubectl describe pod的 Events 段直接告诉你原因。
调度链路概述
用户创建 Pod → API Server 写入 etcd
→ Scheduler 监听到未绑定 Pod → 过滤/打分 → 选定节点
→ 目标节点 Kubelet → 拉镜像 → 创建容器 → 启动
卡在 Pending,问题一定出在调度阶段或容器创建前置阶段。
排查前核心命令速查
# ① 最关键:Events 段直接告诉你调度失败原因
kubectl describe pod <pod-name> -n <namespace> | tail -20
# ② 全局事件时间线
kubectl get events -n <namespace> --sort-by='.lastTimestamp'
# ③ 节点资源(需 Metrics Server)
kubectl top nodes
kubectl top pods -n <namespace>
# ④ 节点详情(Taints / Conditions / Allocated resources)
kubectl describe node <node-name>
# ⑤ Pod YAML(定位调度配置)
kubectl get pod <pod-name> -n <namespace> -o yaml
# 重点看:spec.nodeName, spec.nodeSelector, spec.affinity,
# spec.tolerations, spec.containers[].resources, status.conditions
7 个排查方向
方向一:节点资源不足
Events 关键词: Insufficient cpu / Insufficient memory / Insufficient ephemeral-storage
Scheduler 预选机制: 检查每个节点的 requests 总和是否满足新 Pod,不是看实时使用率。节点负载很低但 request 满了,Pod 一样调度不上去。
# 确认线索
kubectl describe pod <pod-name> -n <namespace> | grep -A5 FailedScheduling
# 0/5 nodes are available: 3 Insufficient memory.
# 确认各节点资源分配
kubectl describe node <node> | grep -A5 "Allocated resources"
# 查看节点可分配量
kubectl describe node <node> | grep -A3 "Capacity"
# 查看节点实际使用
kubectl top nodes
修复方案:
- 扩容节点或调整 Pod requests(降低 request 到符合实际基线的更优值)
- 使用节点自动扩缩容(Cluster Autoscaler / Karpenter)
- 驱逐低优先级 Pod 释放资源
方向二:污点与容忍(Taints/Tolerations)
Events 关键词: node(s) had taint
原理: 节点打了 Taint,Pod 必须在 spec.tolerations 中声明容忍才能调度上去。
# 查看节点污点
kubectl describe node <node> | grep -i taint
# 或
kubectl get node <node> -o jsonpath='{.spec.taints}'
# 查看 Pod 是否声明了 tolerations
kubectl get pod <pod-name> -n <namespace> -o yaml | grep -A10 tolerations
系统常见污点:
| 污点 | 含义 | 影响 |
|------|------|------|
| node.kubernetes.io/not-ready | 节点未就绪 | 默认 effect NoExecute |
| node.kubernetes.io/unreachable | 节点不可达 | 默认 NoExecute |
| node.kubernetes.io/disk-pressure | 磁盘压力 | 默认 NoSchedule |
| node.kubernetes.io/memory-pressure | 内存压力 | 默认 NoSchedule |
| node-role.kubernetes.io/master | Master 节点 | 控制面不调度业务 Pod |
方向三:节点亲和性与反亲和(Affinity)
Events 关键词: didn't match node selector / didn't match pod affinity/anti-affinity
# 查看 Pod 的亲和性配置
kubectl get pod <pod-name> -n <namespace> -o yaml | grep -A20 affinity
# 查看节点标签
kubectl get nodes --show-labels
常见问题: nodeSelectorTerms 之间是 OR 关系,但 matchExpressions 之间是 AND 关系,多条件组合容易导致无匹配节点。
方向四:存储卷问题(PVC Pending)
Events 关键词: waiting for volume to be created, either by external provisioner or by manual creation
整个链路都可能阻塞:
- StorageClass 不存在或未安装 CSI 驱动
- PV 自动供给失败
- PVC 的 accessModes 不匹配
- 节点与 PV 不在同一个可用区
# 检查 PVC 状态
kubectl get pvc -n <namespace>
kubectl describe pvc <pvc-name> -n <namespace>
# 检查 StorageClass
kubectl get sc
kubectl describe sc <storage-class>
# 如果 Pod 中有 Volume 挂载,在 describe pod 中能看到
kubectl describe pod <pod-name> -n <namespace> | grep -A5 Volume
方向五:配额限制(ResourceQuota / LimitRange)
Events 关键词: exceeded quota
# 查看 Namespace 配额
kubectl get resourcequota -n <namespace>
kubectl describe resourcequota <quota-name> -n <namespace>
# 查看 LimitRange
kubectl get limitrange -n <namespace>
kubectl describe limitrange <range-name> -n <namespace>
两个典型场景:
- Namespace 的 ResourceQuota 已耗尽 → 增加配额或清理资源
- LimitRange 设置了默认 request/limit,Pod 未显式声明 → Scheduler 自动套用默认值,可能导致资源不足
方向六:节点选择器(nodeSelector)
Events 关键词: didn't match node selector
# 查看 Pod 的 nodeSelector
kubectl get pod <pod-name> -n <namespace> -o yaml | grep -A5 nodeSelector
# 查看可用节点标签
kubectl get nodes --show-labels | grep <expected-label>
方向七:端口冲突(hostPort)
Events 关键词: node(s) didn't have free ports for the requested pod ports
# 查看 Pod 的端口配置
kubectl get pod <pod-name> -n <namespace> -o yaml | grep -A5 ports
原理: 使用 hostPort 意味着在该节点上只能运行一个该 Pod 副本。如果节点数少于副本数,多余的 Pod 就会 Pending。大多数应用应避免使用 hostPort,改用 ClusterIP + Service。
排障流程图
Pod Pending
│
├─ kubectl describe pod → Events
│ │
│ ├─ FailedScheduling → Scheduler 问题
│ │ ├─ Insufficient cpu/memory → 方向一
│ │ ├─ node(s) had taint → 方向二
│ │ ├─ didn't match node selector → 方向三/六
│ │ ├─ waiting for volume → 方向四
│ │ ├─ exceeded quota → 方向五
│ │ └─ didn't have free ports → 方向七
│ │
│ └─ 无 FailedScheduling → Scheduler 已完成
│ └─ 检查节点 Kubelet / 容器运行时 / 镜像拉取
│
└─ kubectl get events -n <ns> --sort-by=.lastTimestamp
→ 全局时间线排查
关联页面
| 页面 | 关联点 |
|---|---|
| pod-troubleshooting | Pod 排障总纲(CrashLoopBackOff/OOM/探针/Pending 基本排查) |
| k8s-scheduling-strategy-guide | Pod 调度策略六大机制 |
| resource-rbac-scheduling-troubleshooting | 调度失败/Taint/OOMKill 排障 |
| storage-troubleshooting | 存储排障(PVC Pending) |
| k8s-resource-limits-configuration | 资源限制与 QoS 配置 |
| k8s-top10-troubleshooting-checklist | 十大高频排障清单 |