16.6.5 优先级与抢占
优先级与抢占用于保证关键业务在资源紧张时获得调度机会。Kubernetes 通过 PriorityClass 定义全局优先级,数值越大优先级越高,Pod 通过 priorityClassName 引用;globalDefault 可设定默认优先级。调度器在筛选与打分后,会优先考虑高优先级 Pod,并在必要时触发抢占。
原理草图(调度与抢占路径):
安装/启用检查(PriorityClass 内置,无需额外安装):
# 确认集群版本支持(1.14+ 默认启用,1.8-1.13 需检查特性开关)
kubectl version --short
# 查看已存在的优先级类
kubectl get priorityclass
命令解释:
- kubectl version --short:确认 API Server 版本,评估是否需要启用特性门控。
- kubectl get priorityclass:列出现有优先级定义与数值。
PriorityClass 与 Pod 示例(含默认优先级):
# 文件:/opt/k8s/priority/high-priority.yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 100000
globalDefault: false
description: "关键业务优先级"
---
# 文件:/opt/k8s/priority/default-priority.yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: default-priority
value: 1000
globalDefault: true
description: "默认优先级"
# 文件:/opt/k8s/priority/app-high.yaml
apiVersion: v1
kind: Pod
metadata:
name: app-high
spec:
priorityClassName: high-priority
containers:
- name: nginx
image: nginx:1.25
resources:
requests:
cpu: "500m"
memory: "256Mi"
# 应用配置并观察效果
kubectl apply -f /opt/k8s/priority/high-priority.yaml
kubectl apply -f /opt/k8s/priority/default-priority.yaml
kubectl apply -f /opt/k8s/priority/app-high.yaml
# 查看 Pod 实际优先级数值
kubectl get pod app-high -o jsonpath='{.spec.priority}{"\n"}'
命令解释:
- kubectl apply -f:创建/更新 PriorityClass 与 Pod。
- jsonpath='{.spec.priority}':返回 Pod 实际解析后的数值优先级。
抢占场景演示(低优先级批任务被驱逐):
# 文件:/opt/k8s/priority/low-batch.yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: low-batch
value: 10
globalDefault: false
description: "低优先级批处理"
---
apiVersion: v1
kind: Pod
metadata:
name: batch-low
spec:
priorityClassName: low-batch
containers:
- name: busybox
image: busybox:1.36
command: ["sh","-c","sleep 3600"]
resources:
requests:
cpu: "1"
memory: "512Mi"
kubectl apply -f /opt/k8s/priority/low-batch.yaml
# 查看调度事件与抢占事件
kubectl describe pod app-high | sed -n '/Events/,$p'
kubectl describe pod batch-low | sed -n '/Events/,$p'
命令解释:
- kubectl describe pod:查看调度失败原因、抢占/驱逐事件。
- sed -n '/Events/,$p':聚焦事件字段,便于排查。
与 PDB 约束联动示例(限制可被驱逐的数量):
# 文件:/opt/k8s/priority/pdb-web.yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: web
kubectl apply -f /opt/k8s/priority/pdb-web.yaml
kubectl get pdb web-pdb
命令解释:
- minAvailable: 2:限制最少可用副本数,抢占时会尊重该约束。
- kubectl get pdb:查看 PDB 是否生效。
关键策略建议:
- 建立分层:系统关键(100000+)> 核心业务(10000)> 普通业务(1000)> 批处理(10)。
- 避免全量高优先级,防止饥饿与频繁驱逐。
- 配合 LimitRange/ResourceQuota 限制高优先级 Pod 的请求上限。
- 对核心业务设置合理 PDB,降低抢占抖动。
排错清单与命令:
# 1) 观察调度失败与抢占事件
kubectl describe pod <pod-name> | sed -n '/Events/,$p'
# 2) 确认 PriorityClass 是否正确
kubectl get priorityclass
kubectl get priorityclass high-priority -o yaml
# 3) 查看调度器日志(按实际集群组件名)
kubectl -n kube-system logs deploy/kube-scheduler | tail -n 200
# 4) 观察被驱逐 Pod 的状态
kubectl get pod -A | grep Evicted
命令解释:
- describe pod:定位调度失败具体原因。
- get priorityclass -o yaml:验证 value 与 globalDefault 是否冲突。
- logs deploy/kube-scheduler:分析抢占决策与资源瓶颈。
- grep Evicted:快速定位被抢占/驱逐的 Pod。
练习(可在测试集群完成):
1. 创建 high-priority 与 low-batch 两个优先级类,启动 3 个低优先级 Pod,占满节点资源;再创建 1 个高优先级 Pod,观察低优先级 Pod 是否被驱逐。
2. 给低优先级工作负载加 PDB(minAvailable: 2),再次触发抢占,观察高优先级 Pod 是否仍能成功调度。
3. 调整高优先级 Pod 的 resources.requests,记录调度结果变化,并总结“请求过大导致无法抢占”的现象。