导读:本期聚焦于冷风创作的《Kubernetes 优先级类 PriorityClass 该怎么配置才合理》,敬请观看详情。当集群节点资源紧张时,低优先级 Pod 被大量驱逐导致核心服务抖动,这种情况往往源于优先级类设置不当。PriorityClass 是 Kubernetes 中用于定义 Pod 调度与抢占优先级的集群级资源,通过数值大小控制谁先被调度、谁后被驱逐。合理配置需要将业务划分为关键链路、普通服务与批处理任务三层,并为每层绑定不同 priorityClass。非优先级类 Pod 默认值为零,容易被高优先级抢占。本文梳理了创建优先级类、在 Pod 中引用、以及避免优先级反转的实操要点,帮助集群在资源争抢时保留重要负载。

在 Kubernetes 集群运行过程中,节点可用资源并不是无限供应的。当多个工作负载同时申请 CPU 与内存,调度器必须决定先安排谁、驱逐谁。PriorityClass 作为集群级别的优先级定义对象,给 Pod 赋予一个整数值,数值越大代表优先级越高。高优先级 Pod 在资源不足时可以通过抢占机制驱逐低优先级 Pod 从而获得运行机会,而节点资源回收时也是低优先级先行退出。理解这套机制,是配置出稳定集群的第一步。

Kubernetes 优先级类 PriorityClass 该怎么配置才合理

PriorityClass 的基础结构与创建方式

PriorityClass 是一个集群作用域的资源,不需要绑定命名空间。它的核心字段包括 valueglobalDefaultpreemptionPolicy。其中 value 是一个三十二位整数,系统预留了最高优先级 1000000000 给关键系统组件,用户自定义通常落在几到几十万之间。globalDefault 设为 true 时,任何没有显式声明 priorityClassName 的 Pod 都会采用该类的数值,这在统一兜底策略时非常有用,但要小心覆盖导致预期外的抢占。

下面是一个典型的高、中、低三层优先级类定义。我们将核心交易服务设为九十万,普通 API 服务设为五十万,离线批处理设为十万,并且把中等级别设为全局默认,避免遗留 Pod 落入零值被随意驱逐。

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: critical-priority
value: 900000
preemptionPolicy: PreemptLowerPriority
globalDefault: false
description: "核心链路业务使用"
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: normal-priority
value: 500000
preemptionPolicy: PreemptLowerPriority
globalDefault: true
description: "普通在线服务默认"
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: batch-priority
value: 100000
preemptionPolicy: Never
globalDefault: false
description: "离线任务不抢占"

需要注意 preemptionPolicy 字段。默认值是 PreemptLowerPriority,表示允许抢占。若设为 Never,则该优先级类只影响调度排序,不会主动驱逐他人,适合对时延不敏感但又不希望被误杀的批处理作业。很多团队忽略这个字段,结果批处理任务在高峰时段反过来挤掉在线服务,根源就在于这里配置成了允许抢占。

在 Pod 与控制器中引用优先级类

定义好 PriorityClass 之后,必须在工作负载中通过 priorityClassName 引用才会生效。对于 Deployment、StatefulSet 等控制器,应该写在 template 的 spec 里,而不是外层,否则不会传递给真正的 Pod。如果只改了 Deployment 元数据而没进 pod template,调度器依然按照全局默认或零值处理。

以下示例展示了一个核心服务的 Deployment 片段,它明确使用了前面定义的 critical-priority。这样当节点内存水位超过阈值,调度器会优先保留该 Pod,把同节点上的 batch-priority 任务驱逐掉以腾出空间。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: order
    spec:
      priorityClassName: critical-priority
      containers:
      - name: main
        image: ipipp.com/order:1.2
        resources:
          requests:
            cpu: "500m"
            memory: "512Mi"
          limits:
            cpu: "1"
            memory: "1Gi"

对于已经运行且没设优先级的存量 Pod,直接修改 Deployment 并滚动更新即可,新建 Pod 会带上新类名。但如果某些第三方 Operator 生成的 Pod 不支持注入字段,就需要通过修改其上层 CRD 或 webhook 来补。另外,当 globalDefault 从 false 改为 true,存量未声明类名的 Pod 不会立刻变更优先级,只有重建后才生效,这一点在排障时经常被遗漏。

避免优先级反转与资源碎片的实践策略

优先级配置最典型的陷阱是优先级反转:低优先级 Pod 占着资源不释放,高优先级 Pod 反而 pending。造成这种现象往往不是因为 PriorityClass 数值写错,而是低优先级 Pod 设置了过高的资源 request,或者使用了 Never 抢占策略却长期占用大块内存。解决思路是给批处理任务加上合理的 resources.limits,并配合 Cluster Autoscaler 在抢占无效时扩容节点。

另一个容易被忽视的问题是资源碎片。假设节点剩余两核,但一个需要四核的高优先级 Pod 想调度进来,调度器会尝试驱逐几个一核的低优先级 Pod。如果低优先级 Pod 分布在不同节点且每节点只剩一核,就可能发生跨节点驱逐风暴。此时应在 PriorityClass 设计阶段就把大规格任务和中小规格任务分层,让批处理尽量以小而多的形式存在,降低单次抢占成本。

# 查看当前集群所有优先级类及数值
kubectl get priorityclasses.scheduling.k8s.io -o custom-columns=NAME:.metadata.name,VALUE:.value,GLOBAL:.globalDefault

# 找出因为优先级原因处于 Pending 的 Pod
kubectl get pods -A --field-selector=status.phase=Pending -o wide

最后建议在测试环境用混沌工具模拟节点压力,观察不同 PriorityClass 下的驱逐顺序是否符合设计。只有把关键链路、普通服务、离线任务三层的数值差距拉开,并且严格控制 globalDefault 的适用范围,集群才能在真实流量高峰中稳住核心业务,而不是盲目抢占导致雪崩。配置完成之后,还应把优先级类清单纳入版本库评审,避免后续有人随意新建更高数值的类破坏原有秩序。

KubernetesPriorityClass优先级调度修改时间:2026-08-16 18:44:28

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