上一篇已讲解 PriorityClass 基础配置与核心原理,本文依托四阶段全流程可复现实验,完整验证 Pod 调度优先级、资源竞争排队、高优先级抢占三大核心机制,深度剖析 Kubernetes 资源紧缺场景下的调度决策逻辑与生产落地规范。
目录
实验前置条件
实验阶段一:部署系统基础服务
实验阶段二:部署关键业务应用
实验阶段三:触发资源竞争
实验阶段四:模拟紧急抢占场景
实验收尾:资源清理规范
生产级核心问答题
实验核心总结
实验前置条件
Kubernetes 集群 1.14 及以上版本,集群默认自带 Pod 抢占机制,无需额外开启;至少包含一个工作节点,推荐配置 2 核 CPU、2Gi 内存,保证实验现象标准可复现。提前预定义三级 PriorityClass,划分系统、业务、后台任务调度优先级。
优先级配置文件 priorityclasses.yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: sys-essential
value: 10000000
globalDefault: false
description: "系统核心组件,最高调度优先级,禁止被抢占"
—
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: business-critical
value: 8000000
globalDefault: false
description: "核心业务应用,中高优先级,仅低于系统组件"
—
apiVersion: scheduling.k8s.io/v1
kind: best-effort
value: 100000
globalDefault: false
description: "后台非核心任务,最低优先级,资源不足时优先被驱逐"
执行创建命令:
kubectl apply -f priorityclasses.yaml
实验阶段一:部署系统基础服务
实验目标是以 DaemonSet 方式部署最高优先级系统核心组件,集群每个节点固定运行一个实例,抢占底层资源作为实验资源基线,同时保障系统组件永不被低优先级服务抢占。
配置文件 essential-system.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-essential
spec:
selector:
matchLabels:
app: node-essential
template:
metadata:
labels:
app: node-essential
spec:
priorityClassName: sys-essential
containers:
– name: essential
image: busybox
command: ["sleep", "3600"]
resources:
requests:
cpu: 300m
memory: 200Mi
limits:
cpu: 300m
memory: 200Mi
部署与验证命令
kubectl apply -f essential-system.yaml
kubectl get pods -l app=node-essential -o wide
实验预期:集群每个节点自动调度运行 1 个 Pod,状态均为 Running;单节点固定占用 300m CPU、200Mi 内存;该级别系统核心组件,不会被任何中低优先级 Pod 抢占驱逐。
实验阶段二:部署关键业务应用
实验目标是部署中高优先级核心业务订单服务,进一步消耗节点资源,让集群整体资源达到饱和临界状态,为后续资源竞争、抢占机制测试铺垫环境。
配置文件 business-critical-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
replicas: 1
selector:
matchLabels:
app: order-service
template:
metadata:
labels:
app: order-service
spec:
priorityClassName: business-critical
containers:
– name: order
image: busybox
command: ["sleep", "3600"]
resources:
requests:
cpu: 800m
memory: 500Mi
部署与资源核查命令
kubectl apply -f business-critical-app.yaml
kubectl get pods -l app=order-service -o wide
kubectl describe nodes | grep -A 5 "Allocated"
节点资源占用状态:系统基础 Pod 占用 300m CPU,核心业务 Pod 占用 800m CPU,单节点合计占用 1100m CPU;节点剩余可用 CPU 不足 900m,集群资源临近饱和,无充足资源调度新 Pod。
实验阶段三:触发资源竞争
实验目标为部署最低优先级后台批处理任务,故意设置多副本超出现有剩余资源,验证资源不足时,低优先级 Pod 无法正常调度、进入 Pending 排队状态,且高优先级业务服务完全不受影响。
配置文件 background-tasks.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: background-task
spec:
replicas: 3
selector:
matchLabels:
app: background-task
template:
metadata:
labels:
app: background-task
spec:
priorityClassName: best-effort
containers:
– name: task
image: busybox
command: ["sleep", "3600"]
resources:
requests:
cpu: 500m
memory: 300Mi
部署与状态观察命令
kubectl apply -f background-tasks.yaml
kubectl get pods –sort-by='.spec.priority' -o wide
实验现象与结论:3 个低优先级后台任务仅部分调度成功,其余大量处于 Pending 状态;Pod 事件提示 Insufficient CPU、Insufficient Memory 资源不足;已运行的系统组件、核心业务 Pod 状态稳定无波动。由此可证,资源紧缺时高优先级 Pod 拥有绝对调度优先权,低优先级 Pod 只能排队等待集群释放空闲资源。
实验阶段四:模拟紧急抢占场景
实验目标是部署最高优先级紧急任务,申请 1 核 CPU 资源,刻意超出节点剩余可用资源,强制触发 Kubernetes 原生抢占机制,验证高优先级任务可驱逐低优先级 Pod、抢占资源完成调度。
配置文件 emergency-scenario.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: emergency-scaler
spec:
replicas: 1
selector:
matchLabels:
app: emergency-scaler
template:
metadata:
labels:
app: emergency-scaler
spec:
priorityClassName: sys-essential
containers:
– name: emergency-handler
image: busybox
command: ["sh", "-c", "echo 'EMERGENCY TASK RUNNING'; sleep 600"]
resources:
requests:
cpu: 1000m
memory: 400Mi
部署与观察抢占行为命令
kubectl apply -f emergency-scenario.yaml
kubectl get events –field-selector involvedObject.kind=Pod –sort-by=.metadata.creationTimestamp
kubectl get pods –sort-by='.spec.priority' -o wide
抢占现象:高优先级紧急任务创建后因资源不足调度失败,集群自动触发抢占机制;调度器优先选择最低优先级后台 Pod 进行驱逐,被驱逐 Pod 进入 Terminating 状态并销毁;资源释放后紧急任务立刻完成调度变为 Running;系统组件、核心业务等高优先级 Pod 全程不受任何影响。
抢占驱逐顺序:第一顺位优先驱逐最低优先级 best-effort 类型 Pod;第二顺位驱逐同优先级中资源实际使用超请求配额的 Pod;同优先级同资源占用情况下,优先驱逐启动时间更晚的 Pod;调度器永远不会驱逐同级或更高优先级的系统、核心业务 Pod。
实验收尾:资源清理规范
按照优先级从低到高顺序清理资源,避免清理过程中再次触发抢占调度,保证集群环境干净无残留。
kubectl delete -f emergency-scenario.yaml
kubectl delete -f background-tasks.yaml
kubectl delete -f business-critical-app.yaml
kubectl delete -f essential-system.yaml
kubectl delete priorityclass sys-essential business-critical best-effort
验证清理完成
kubectl get pods
kubectl get priorityclass
终端无任何实验相关 Pod 与 PriorityClass 资源输出,即代表清理完毕。
生产级核心问答题
Q1:K8s 抢占机制发生的前提条件是什么?
A1:需同时满足三个条件:集群 CPU、内存等核心资源已耗尽,无法满足新 Pod 的资源请求;新高优先级 Pod 无法正常调度且无可用空闲节点;集群已开启 Pod 抢占功能(1.14 + 版本默认开启)。满足条件后,调度器会主动驱逐低优先级 Pod,为高优先级应用腾出资源。
Q2:集群资源不足时,Pod 被驱逐的先后顺序是什么?
A2:遵循固定调度规则:优先级数值越低,越优先被驱逐;同一优先级下,资源实际占用超过声明请求的 Pod 优先驱逐;同优先级、同资源占用场景,创建启动时间更晚的 Pod 优先被驱逐;高优先级系统、核心业务 Pod 永远不会被低优先级服务抢占驱逐。
Q3:哪些工作负载适合配置高 / 低 PriorityClass?
A3:高优先级适合集群核心组件、监控告警、日志服务、CoreDNS、数据库、服务发现等基础组件;中高优先级适合订单、支付、用户中心、核心网关、核心 API 接口等关键业务;低优先级适合离线批处理、定时任务、数据同步、测试环境服务、非核心后台 Job 等可容忍延迟的任务。
Q4:被抢占驱逐的低优先级 Pod 后续会怎样?
A4:被驱逐 Pod 立即进入 Terminating 状态,执行优雅终止逻辑后被删除;若 Pod 由 Deployment、StatefulSet、Job 等控制器管理,控制器会自动重建新 Pod;新 Pod 重新进入调度队列,等待集群出现空闲资源后再完成调度;被驱逐 Pod 不会自动原地迁移,也无法保留原节点运行环境。
实验核心总结
PriorityClass 优先级数值越大,调度优先级越高;资源充足环境下,所有优先级 Pod 均可正常调度运行;资源紧缺时,高优先级应用拥有天然调度优先权,低优先级只能排队等待;高优先级任务无法调度时,会自动触发抢占机制,仅驱逐更低优先级 Pod;抢占机制不会跨级别驱逐高优先级服务,保障核心业务稳定性;生产环境需按业务重要性分级配置 PriorityClass,从调度层面杜绝核心业务被后台低优先级任务挤垮。



