当前位置: 首页 > news >正文

Kubernetes Pod 一直 Pending 排查全流程:从 describe events 到资源、污点、PVC 逐层定位

Kubernetes Pod 一直 Pending 排查全流程:从 describe events 到资源、污点、PVC 逐层定位

上线时kubectl apply一把梭,结果kubectl get pods看到 Pod 卡在Pending十分钟不动。Pending 意味着调度器(scheduler)还没给这个 Pod 找到能落脚的节点,或者找到了节点但容器还没起来。它和CrashLoopBackOff(起来了又崩)是两码事——Pending 是根本没被调度上去

这篇按「怎么定位 → 五类常见原因 → 每类怎么修」的顺序,给一套能照着敲的排查流程。

第一步:永远先看 describe 的 Events

九成 Pending 问题的答案就写在kubectl describe最底下的 Events 里,别急着改 YAML。

kubectl describe pod<pod-name>-n<namespace>

翻到最下面的Events:段,重点看FailedScheduling这行。scheduler 会明确告诉你为什么调度不上去,比如:

Events: Type Reason Message ---- ------ ------- Warning FailedScheduling 0/3 nodes are available: 3 Insufficient cpu.

这行0/3 nodes are available后面的原因,直接决定你往哪个方向查。下面按最常见的几类 Message 分别讲。

原因一:资源不够(Insufficient cpu/memory)

Message 长这样:0/3 nodes are available: 3 Insufficient cpu.Insufficient memory。意思是所有节点的可分配剩余资源都小于你 Pod 的requests

注意关键点:调度看的是requests 之和 vs 节点 allocatable,不是节点当前真实使用率。哪怕节点 CPU 实际只用了 10%,只要已调度 Pod 的 requests 加起来占满了,新 Pod 照样调度不上。

先看节点到底还剩多少:

kubectl describenode<node-name>|grep-A6"Allocated resources"

输出里Requests那列就是已被预定的量:

Allocated resources: Resource Requests Limits cpu 3800m (95%) 6 (150%) memory 7Gi (90%) 10Gi

CPU requests 已经占到 95%,新 Pod 要 500m 自然塞不下。三种修法:

# 修法1:调低 Pod 的 requests(前提是真的用不了那么多)resources:requests:cpu:200m# 从 500m 降下来memory:256Mi
# 修法2:扩容节点(手动加节点或让 Cluster Autoscaler 自动加)kubectl get nodes# 确认加成功# 修法3:清理占着 requests 却闲置的 Podkubectltoppods-A--sort-by=cpu# 找出「requests 高但实际使用低」的

最容易被忽略的坑:某个 Pod 把requests.cpu写成了4(4 核),自己占满一台节点。写 requests 要按实际稳态用量估,不要照着 limits 抄。

原因二:节点有污点(Taints),Pod 没配容忍(Tolerations)

Message:node(s) had untolerated taint {key: value}。节点被打了污点(比如 master 节点默认带node-role.kubernetes.io/control-plane:NoSchedule),普通 Pod 不配 toleration 就被排斥。

看节点污点:

kubectl describenode<node-name>|grepTaints# Taints: node-role.kubernetes.io/control-plane:NoSchedule

两种修法。如果这个污点确实该被这个 Pod 容忍(比如 DaemonSet 要跑在所有节点上),给 Pod 加 toleration:

tolerations:-key:"node-role.kubernetes.io/control-plane"operator:"Exists"effect:"NoSchedule"

如果是节点被误打了污点(比如之前 drain 后忘了恢复),把污点去掉:

# 注意 key 后面加个减号表示删除kubectl taint nodes<node-name>node-role.kubernetes.io/control-plane:NoSchedule-

还有一种自动加的污点要小心:节点 NotReady 或磁盘压力大时,K8s 会自动打node.kubernetes.io/not-ready等污点,这时候要去修节点本身,而不是加 toleration 硬塞。

原因三:nodeSelector / affinity 把自己框死了

Message:node(s) didn't match Pod's node affinity/selector。你给 Pod 加了nodeSelectornodeAffinity,但没有节点带对应的 label。

# 比如要求节点有 disktype=ssd 标签nodeSelector:disktype:ssd

排查:看有没有节点真带这个 label。

kubectl get nodes --show-labels|grepdisktype# 空 → 没有任何节点带这个标签,自然调度不上

修法二选一:给目标节点打上 label,

kubectl label nodes<node-name>disktype=ssd

或者放宽约束。硬亲和(requiredDuringScheduling)调不上就直接 Pending,如果只是「优先」而非「必须」,改成软亲和preferredDuringSchedulingIgnoredDuringExecution,匹配不到时也能退而求其次调到别的节点。

原因四:PVC 没绑上(pod has unbound immediate PersistentVolumeClaims)

Message:pod has unbound immediate PersistentVolumeClaims。Pod 挂了个 PVC,但这个 PVC 没找到能绑定的 PV,Pod 就跟着一起 Pending。

先看 PVC 自己的状态:

kubectl get pvc-n<namespace># NAME STATUS VOLUME CAPACITY STORAGECLASS# data Pending (空)

PVC 也是 Pending,再 describe 它:

kubectl describe pvc data-n<namespace>

常见两种根因:一是storageClassName写错或不存在,动态供应器根本没被触发;二是集群没装 provisioner(比如裸机集群没配 storage class)。

kubectl get storageclass# 确认 class 名字存在、且有 default 标记

修法:PVC 的storageClassName对上真实存在的 class;裸机环境要么手动创建 PV 静态绑定,要么装个 provisioner(如 local-path-provisioner)。

原因五:调度上了但容器起不来(ContainerCreating 卡住)

有时 Pod 不是纯 Pending,而是ContainerCreating长时间不动——已经调度到节点了,但 kubelet 在拉镜像或挂卷时卡住。还是 describe 看 Events:

  • Failed to pull image ... ImagePullBackOff:镜像名/tag 写错,或私有仓库缺imagePullSecrets
  • MountVolume.SetUp failed:卷挂载失败,常是 PV 后端(NFS/云盘)不可达。

镜像拉取失败最常见,先手动在节点上验证镜像能不能拉:

# 私有仓库要给 Pod 配 imagePullSecretskubectl create secret docker-registry regcred\--docker-server=<你的仓库>--docker-username=<user>--docker-password=<pwd>

然后在 Pod spec 里引用:

spec:imagePullSecrets:-name:regcred

一条命令快速缩小范围

排查前先用这条把「所有异常 Pod + 事件」一次性捞出来,比逐个 describe 快:

# 按最近事件排序,直接看到 FailedScheduling 原因kubectl get events-n<namespace>--sort-by='.lastTimestamp'|grep-i-E"fail|pending|insufficient"

小结

Pod Pending 的排查心法是「先问 scheduler 为什么调不上去」,而不是瞎改 YAML:

  • 第一步永远是kubectl describe pod看 Events 里的FailedScheduling,原因都写在那。
  • Insufficient cpu/memory:比的是 requests 之和 vs 节点 allocatable,不是真实使用率 → 降 requests、扩节点或清闲置 Pod。
  • untolerated taint:节点有污点 → 加 toleration 或删污点,自动打的污点要修节点本身。
  • didn’t match node selector/affinity:约束太死没节点匹配 → 打 label 或把硬亲和改软亲和。
  • unbound PVC:存储没绑上 → 查 storageClass 是否存在、有没有 provisioner。
  • ContainerCreating 卡住:已调度但拉镜像/挂卷失败 → 查镜像名和 imagePullSecrets。

一句话记忆点:Pending 看 scheduler,CrashLoop 看容器日志——describe 的 Events 段是这两类问题共同的第一现场。

http://www.jsqmd.com/news/1281095/

相关文章:

  • Nginx安全防护与HTTPS部署实战:从基础配置到纵深防御
  • Citra 3DS模拟器:在电脑上玩转任天堂3DS游戏的终极指南 [特殊字符]
  • 5分钟快速上手:GoldHEN金手指管理器终极使用指南
  • 3分钟极速上手!免费网盘直链下载助手完整指南:一键获取9大平台真实下载地址
  • 如何快速设计完美农场:3步掌握星露谷物语农场规划器终极指南
  • 物联网设备低功耗电源管理方案与优化实践
  • 实战指南:Spek音频频谱分析器的深度解析与完整部署方案
  • SNN在无人机编队控制中的MATLAB实现与优化
  • 工作流平台的开放生态建设:插件市场、开发者文档与社区运营策略
  • TPIC7710EVM评估板实战指南:快速验证汽车电子电机驱动方案
  • 手写“堆排序”
  • 工业信号干扰防护与光耦隔离技术实战
  • VS Code Git 工作树:多分支并行开发,让效率提升 300%
  • 虚拟化技术核心解析与实战应用指南
  • 物联网设备安全芯片SE050与PIC18F46K42集成方案
  • WASM 跨语言互操作的坑:字符串编码、内存管理和异步调用的三座大山
  • 如何免费获取网易云QQ音乐歌词:163MusicLyrics完整使用指南
  • 2026 年天津新能源库存车新能源资源车新能源汽车采购经验分享 - LYL仔仔
  • Spring @Async 不生效排查:自调用失效、默认线程池坑与异步方法里的异常去哪了
  • 2026 年浔阳区马桶疏通 菜盆疏通 抽粪,九江本地管道维修真实体验 - LYL仔仔
  • 如何用Marketch插件实现Sketch设计稿到前端代码的无缝转换
  • OpenClaw智能体框架四大安全漏洞剖析与企业级加固指南
  • Magpie:Windows平台终极窗口超分辨率工具完整指南
  • Langchain中间件-LLM工具模拟器设计与实践
  • 时间序列反事实必要性分析:从特征相关到因果推断的实践指南
  • C++多维数组:从内存布局到现代容器与性能优化实践
  • 物联网设备初级电池寿命优化方案与STM32低功耗设计
  • [WesternCTF2018]shrine-学习笔记
  • 大跨度柔性电动挡烟垂壁 消防3C认证防火防烟分区隔断
  • Hadoop+Spark+Hive构建小红书评论情感分析系统