优先级类别
学习目标
- 理解 PriorityClass 的概念和作用
- 掌握如何创建和使用 PriorityClass
- 了解优先级对调度和驱逐的影响
核心概念
一句话解释
PriorityClass 定义 Pod 的调度优先级,高优先级 Pod 可以抢占低优先级 Pod。
工作原理
┌─────────────────────────────────────────────────────────┐
│ PriorityClass │
├─────────────────────────────────────────────────────────┤
│ │
│ 优先级范围:0 - 1,000,000,000 │
│ 值越大,优先级越高 │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ system-node-critical: 2,000,000,000 │ │
│ │ system-cluster-critical: 1,000,000,000 │ │
│ │ high-priority: 1,000,000 │ │
│ │ default-priority: 0 │ │
│ │ low-priority: -100 │ │
│ └─────────────────────────────────────────┘ │
│ │
│ 高优先级 Pod 可以抢占低优先级 Pod │
│ 当节点资源不足时: │
│ - 高优先级 Pod 优先调度 │
│ - 低优先级 Pod 可能被驱逐 │
│ │
└─────────────────────────────────────────────────────────┘
内置 PriorityClass
# 系统组件使用,不应修改
system-node-critical: 2,000,000,000
# - kubelet
# - kube-proxy
# - 系统守护进程
system-cluster-critical: 1,000,000,000
# - kube-dns
# - metrics-server
# - 集群关键组件
创建 PriorityClass
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000000 # 优先级值
globalDefault: false # 是否为默认优先级
preemptionPolicy: PreemptLowerPriority # 抢占策略
description: "High priority class for critical workloads"
抢占策略
┌─────────────────────────────────────────────────────────┐
│ 抢占策略 │
├─────────────────────────────────────────────────────────┤
│ │
│ PreemptLowerPriority(默认) │
│ ┌─────────────────────────────────────────┐ │
│ │ 可以抢占低优先级 Pod │ │
│ │ 当节点资源不足时: │ │
│ │ - 驱逐低优先级 Pod │ │
│ │ - 调度高优先级 Pod │ │
│ └─────────────────────────────────────────┘ │
│ │
│ Never │
│ ┌─────────────────────────────────────────┐ │
│ │ 不抢占其他 Pod │ │
│ │ 当节点资源不足时: │ │
│ │ - 等待资源释放 │ │
│ │ - 不驱逐其他 Pod │ │
│ └─────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
使用 PriorityClass
apiVersion: v1
kind: Pod
metadata:
name: high-priority-pod
spec:
priorityClassName: high-priority # 指定优先级类别
containers:
- name: app
image: nginx
抢占流程
┌─────────────────────────────────────────────────────────┐
│ 抢占流程 │
├─────────────────────────────────────────────────────────┤
│ │
│ 场景:高优先级 Pod 需要调度,但节点资源不足 │
│ │
│ 1. 调度器尝试调度高优先级 Pod │
│ │ │
│ v │
│ 2. 检查节点资源 │
│ └─ 资源不足 │
│ │ │
│ v │
│ 3. 查找可抢占的低优先级 Pod │
│ └─ 找到低优先级 Pod │
│ │ │
│ v │
│ 4. 驱逐低优先级 Pod │
│ └─ 发送 SIGTERM,等待优雅终止 │
│ │ │
│ v │
│ 5. 调度高优先级 Pod │
│ └─ 完成调度 │
│ │
└─────────────────────────────────────────────────────────┘
优先级与 QoS 的关系
┌─────────────────────────────────────────────────────────┐
│ 优先级决定顺序 │
├─────────────────────────────────────────────────────────┤
│ │
│ 1. PriorityClass(主要因素) │
│ └─ 高优先级 Pod 先调度,后驱逐 │
│ │
│ 2. QoS 类别(次要因素) │
│ └─ 同优先级时,BestEffort 先驱逐 │
│ │
│ 3. requests 比例(最后因素) │
│ └─ 同 QoS 时,requests 比例高的后驱逐 │
│ │
│ 优先级比较: │
│ PriorityClass > QoS > requests 比例 │
│ │
└─────────────────────────────────────────────────────────┘
调度器抢占过程
┌─────────────────────────────────────────────────────────┐
│ 调度器抢占逻辑 │
├─────────────────────────────────────────────────────────┤
│ │
│ 1. 尝试正常调度 │
│ ├─ 成功 → 结束 │
│ └─ 失败 → 进入抢占流程 │
│ │
│ 2. 检查 Pod 是否可以抢占 │
│ ├─ preemptionPolicy=Never → 等待 │
│ └─ preemptionPolicy=PreemptLowerPriority → 继续 │
│ │
│ 3. 查找候选节点 │
│ └─ 有低优先级 Pod 的节点 │
│ │
│ 4. 计算抢占收益 │
│ └─ 评估驱逐后是否能调度成功 │
│ │
│ 5. 执行抢占 │
│ └─ 驱逐最低优先级的 Pod │
│ │
│ 6. 调度高优先级 Pod │
│ │
└─────────────────────────────────────────────────────────┘
实践练习
练习 1:创建 PriorityClass
# priority-classes.yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000000
globalDefault: false
preemptionPolicy: PreemptLowerPriority
description: "High priority for critical workloads"
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: low-priority
value: 100
globalDefault: false
preemptionPolicy: Never
description: "Low priority for batch jobs"
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: default-priority
value: 0
globalDefault: true
description: "Default priority class"
kubectl apply -f priority-classes.yaml
# 查看所有 PriorityClass
kubectl get priorityclasses
练习 2:使用 PriorityClass
# high-priority-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: high-priority-pod
spec:
priorityClassName: high-priority
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: "500m"
memory: "256Mi"
---
# low-priority-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: low-priority-pod
spec:
priorityClassName: low-priority
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: "500m"
memory: "256Mi"
kubectl apply -f high-priority-pod.yaml
kubectl apply -f low-priority-pod.yaml
# 查看 Pod 优先级
kubectl get pods -o custom-columns=NAME:.metadata.name,PRIORITY:.spec.priority
练习 3:观察抢占行为
# 填满节点资源
apiVersion: apps/v1
kind: Deployment
metadata:
name: low-priority-deploy
spec:
replicas: 5
selector:
matchLabels:
app: low
template:
metadata:
labels:
app: low
spec:
priorityClassName: low-priority
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: "500m"
memory: "256Mi"
kubectl apply -f low-priority-deploy.yaml
# 等待 Pod 运行
kubectl get pods -w
# 创建高优先级 Pod
kubectl apply -f high-priority-pod.yaml
# 观察低优先级 Pod 被驱逐
kubectl get pods -w
练习 4:查看抢占事件
# 查看 Pod 事件
kubectl describe pod high-priority-pod | grep -A 10 Events
# 查看节点事件
kubectl describe node <node-name> | grep -A 10 Events
# 查看调度器日志
kubectl logs -n kube-system -l component=kube-scheduler | grep -i preempt
练习 5:设置默认优先级
# default-priority.yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: my-default
value: 500
globalDefault: true
description: "My default priority"
kubectl apply -f default-priority.yaml
# 创建不指定 priorityClassName 的 Pod
kubectl run default-pod --image=nginx
# 查看 Pod 优先级
kubectl get pod default-pod -o yaml | grep priority
最佳实践
1. 合理设置优先级值
- 为不同级别的工作负载设置不同优先级
- 预留足够的间隔
2. 限制高优先级 Pod 数量
- 使用 ResourceQuota 限制
- 防止滥用高优先级
3. 谨慎使用抢占
- 抢占会导致服务中断
- 考议使用 preemptionPolicy: Never
4. 使用命名约定
- high-priority: 关键业务
- medium-priority: 普通业务
- low-priority: 批处理任务
5. 监控抢占事件
- 跟踪抢占频率
- 调整优先级策略
常见问题
1. Pod 一直 Pending
# 检查 Pod 优先级
kubectl get pod <pod-name> -o yaml | grep priorityClassName
# 检查是否有可抢占的 Pod
kubectl get pods --sort-by=.spec.priority
# 检查调度事件
kubectl describe pod <pod-name> | grep -A 10 Events
2. 如何限制高优先级 Pod
# 使用 ResourceQuota 限制
apiVersion: v1
kind: ResourceQuota
metadata:
name: priority-quota
spec:
hard:
pods: "10"
# 限制高优先级 Pod 数量
count/pods.high-priority: "2"
3. 抢占会导致什么问题?
抢占会导致:
- 低优先级 Pod 被驱逐
- 服务中断(直到新 Pod 启动)
- 可能的级联抢占
建议:
- 关键服务使用 preemptionPolicy: Never
- 设置合理的优先级间隔
- 监控抢占频率
小结
| 要点 | 说明 |
|---|---|
| PriorityClass | 定义 Pod 的调度优先级 |
| 优先级范围 | 0 - 1,000,000,000,值越大越高 |
| 抢占策略 | PreemptLowerPriority(默认)或 Never |
| 内置类别 | system-node-critical, system-cluster-critical |
| 抢占流程 | 驱逐低优先级 Pod,调度高优先级 Pod |
| 使用场景 | 区分关键业务和普通任务 |
练习编辑器
bash
Loading...