导读:本期聚焦于清原小日向创作的《Kubernetes Pod 长期 Pending 是什么原因,如何从资源和亲和性角度排查?》,敬请观看详情。集群里某个服务始终起不来,调度器一直把Pod挂在Pending状态,这种状况往往不是程序崩溃,而是节点资源或亲和规则卡住了。先确认kubectl describe看到的FailedScheduling事件,里面会列出CPU内存缺口以及无法满足的节点亲和、Pod反亲和条件。资源层面要核对requests是否超过节点可分配量,是否存在被大块资源占满导致碎片无法容纳。亲和性方面,nodeSelector、nodeAffinity和podAntiAffinity如果设置过严,会让调度器找不到匹配节点。把资源请求调小、放宽拓扑约束或增加节点,通常能让Pod被正常调度。

当我们在Kubernetes集群中部署应用后,偶尔会遇到Pod长时间处于Pending状态,执行kubectl get pod看到STATUS一直是Pending,且READY为0/1。这种情况说明Pod已经被API Server接收,但调度器始终没有把它绑定到某个节点上。最常见的原因可以归为两大类:一是集群资源无法满足Pod的requests要求,二是各种亲和性与反亲和性规则把可用节点全部排除了。理解这两类问题的形成机制,才能快速定位并解决调度失败。

Kubernetes Pod 长期 Pending 是什么原因,如何从资源和亲和性角度排查?

从资源维度排查 Pending 的根因

Kubernetes调度器在做决策时,首先会过滤掉那些剩余可分配资源小于Pod中容器requests总和的节点。如果一个节点总共有4核CPU、8Gi内存,已经被其他Pod申请走了3.8核与7Gi,而新Pod请求0.5核、1Gi,那么该节点在过滤阶段就会被淘汰。当所有节点都过不了这道资源门槛,Pod就会长期Pending,并在describe事件里出现类似“0/5 nodes are available: 5 Insufficient cpu”的提示。

除了总量不足,资源碎片也是容易被忽视的问题。假设集群有三个节点,每个节点剩0.6核CPU,而待调度Pod请求1核CPU,虽然整体剩余1.8核,但没有任何单节点能满足,也会调度失败。此时单纯看集群总资源会误判为资源够用。我们可以用kubectl describe node来逐个检查Allocatable与Allocated resources,重点关注cpu、memory、ephemeral-storage三项的Requests分配比例。

解决资源类Pending通常有三种思路。第一是压缩Pod的requests,例如把不必要的容器资源请求调低;第二是清理或缩容长期占用资源却低利用率的负载;第三是向集群添加新节点或扩容节点规格。下面是一段查看节点资源分配的命令示例,能帮助快速定位瓶颈节点:

kubectl get nodes -o custom-columns=NODE:.metadata.name,CPU_ALLOC:.status.allocatable.cpu,MEM_ALLOC:.status.allocatable.memory
kubectl describe node worker-1 | grep -A 10 "Allocated resources"

亲和性与反亲和性规则导致的调度阻塞

Kubernetes提供了nodeSelector、nodeAffinity、podAffinity和podAntiAffinity等机制来控制Pod应该或不应该落在哪些节点上。这些规则在调度流程中属于“亲和性过滤”。如果规则写得过于严格,例如要求节点必须带有disktype=ssd标签,但集群中没有任何节点打这个标签,那么调度器找不到匹配项,Pod就会Pending。podAntiAffinity若设置成硬性要求(requiredDuringSchedulingIgnoredDuringExecution),并且规定同一Deployment的多个副本不能在同一可用区,但可用区数量少于副本数,同样会无法调度。

很多人会把preferred和required混淆。required类型是强制条件,不满足就绝对不调度;preferred是倾向性条件,不满足也会退而求其次。在排查时,应先把yaml里的affinity段摘出来,检查是否有required条款指向了不存在的拓扑域。比如下列配置要求Pod必须调度到zone=cn-east-1的节点,若集群实际zone标签是cn-east,就会直接卡死:

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: zone
          operator: In
          values:
          - cn-east-1

对于podAntiAffinity引起的Pending,可以通过kubectl describe pod看到“node(s) had volume node affinity conflict”或“node(s) didn't match pod anti-affinity rules”之类事件。放宽策略的方式包括把required改为preferred,或者减少topologyKey的约束粒度。例如把topologyKey从kubernetes.io/hostname改为topology.kubernetes.io/zone,允许同可用区内不同主机部署,能显著降低冲突概率。

综合排查流程与最小化复现方法

面对长期Pending的Pod,推荐采用标准排查顺序:先用kubectl describe pod <pod-name>查看Events,定位是资源不足还是亲和失败;再执行kubectl get events --sort-by=.lastTimestamp观察集群级事件;最后用kubectl get node -o wide与kubectl describe node核对标签和资源。这个流程能覆盖九成以上的调度问题,避免盲目重启或删Pod。

为了方便验证,我们可以构建一个最小化测试用例:创建一个明确请求超大资源、并指定不存在标签的Pod,观察其Pending原因,从而确认集群当前调度逻辑。以下示例yaml故意设置2核请求与不存在的node标签,用于复现典型的双重阻塞:

apiVersion: v1
kind: Pod
metadata:
  name: debug-pending
spec:
  containers:
  - name: app
    image: nginx
    resources:
      requests:
        cpu: "2"
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: nonexistent-label
            operator: In
            values:
            - "true"

通过对比真实业务Pod与这个调试Pod的事件输出,可以判断问题是出在资源侧还是亲和侧。如果是资源侧,就参考前面节点扩容或缩容请求;如果是亲和侧,就修正yaml里的标签匹配。把调度约束设计成“尽量满足而非必须满足”,并配合合理的资源request,才能保障Pod在节点波动时仍可被调度,减少莫名其妙的Pending积压。

KubernetesPod_Pendingaffinity修改时间:2026-08-19 02:58:26

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。