79·调度与资源高级

优先级类别

kubernetesschedulingpriority-classes

优先级类别

学习目标

  1. 理解 PriorityClass 的概念和作用
  2. 掌握如何创建和使用 PriorityClass
  3. 了解优先级对调度和驱逐的影响

核心概念

一句话解释

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...

继续学习

完成本课后,建议继续学习下一课「调度器配置」 以巩固所学知识。