k8s调度策略之优先级和抢占,驱逐详解
# k8s调度策略之优先级和抢占,驱逐详解
# 1. 调度
调度是指将pod分配到合适的节点上,Kube-scheduler通过watch机制监听kube-apiserver,查询已经新建但还未调度的pod,根据调度策略将pod调度至集群内最合适的node.
:::
# 1.1. 调度流程
用户提交创建pod的请求
api-server 处理用户请求,存储用户数据到ETCD
kube-schedule中的informer组件监听api-server,筛选出space.nodeName=''的pod列表,循环遍历的为每个pod尝试分配节点, kube-scheduler 给一个 Pod 做调度选择时包含两个步骤:
第一阶段
预选阶段,过滤节点,调度器通过Predicate算法过滤掉不满足条件的节点主要的预选算法包括资源相关算法PodFitsResources作用:检查节点是否有足够的资源(CPU、内存、GPU 等)满足 Pod 的 requests。
规则: 节点剩余资源 ≥ Pod 的 requests(需考虑已调度 Pod 的资源占用)。 如果 Pod 未指定 requests,默认按 limits 的 100% 计算(可能导致资源不足)。
CheckNodeMemoryPressure / CheckNodeDiskPressure / CheckNodePIDPressure作用:检查节点是否处于资源压力状态。 内存压力:节点剩余内存不足。 磁盘压力:节点磁盘空间或 inode 不足。 PID 压力:节点进程 ID 不足。
规则:若节点存在压力,则跳过该节点(除非 Pod 容忍 memoryPressure、diskPressure 等污点)。
选择器与标签算法MatchNodeSelector作用:检查节点是否匹配 Pod 的 nodeSelector 或 nodeAffinity 硬性规则。
规则: nodeSelector:节点必须包含所有指定标签。 nodeAffinity(requiredDuringScheduling):必须满足所有硬性匹配条件。
PodFitsHostPorts 作用:检查节点上是否有 Pod 声明的 hostPort 已被占用。
规则:若节点上已有 Pod 占用了相同的 hostPort,则排除该节点。
存储相关算法VolumeZonePredicate 作用:检查持久卷(PV)的可用区是否与节点匹配。
规则:若 Pod 使用特定可用区的 PV(如 topology.kubernetes.io/zone),则节点必须位于同一可用区。
VolumeBindingPredicate 作用:检查节点是否能绑定 Pod 所需的 PVC(Persistent Volume Claim)。
规则:若 PVC 是 WaitForFirstConsumer 模式,调度器会延迟绑定,直到选择节点。 节点必须满足 PVC 的存储类(StorageClass)、容量等要求。
亲和性/反亲和性算法InterPodAffinity作用:检查 Pod 的亲和性/反亲和性硬性规则(requiredDuringScheduling)。规则:Pod 亲和性:必须与指定 Pod 在同一个拓扑域(如节点、可用区)。 Pod 反亲和性:必须避免与指定 Pod 在同一个拓扑域。
污点与容忍算法作用:检查 Pod 是否容忍节点的污点(Taints)。 规则:若节点有污点且 Pod 未声明对应的容忍(Toleration),则排除该节点。 污点效果(Effect)为 NoSchedule 时,必须严格匹配容忍。
Predicate算法(预选算法)执行流程:
并行过滤:调度器并行执行所有 Predicate 算法,快速缩小候选节点范围。顺序无关性:各算法之间无依赖关系,最终结果取逻辑“与”(所有条件均需满足)。短路优化:若某算法过滤后无剩余节点,直接终止流程,Pod 进入 Pending 状态。
第二阶段
优选阶段(priorities):为上一阶段选出来的node进行打分,选出得分最高的主要的优选阶段算法包括资源均衡类的LeastRequestedPriority 最低请求优先算法
规则:选择(CPU 和 Memory)request最低的的宿主机
BalancedResourceAllocation 资源均衡分配
规则:优先选择 CPU 和内存利用率接近 的节点,避免单一资源过载
亲和性权重类算法NodeAffinityPriority(节点亲和性权重)
作用:为符合 nodeAffinity 软性规则(preferredDuringScheduling)的节点加分。
规则:根据 preference 中的 weight 值增加分数。
InterPodAffinityPriority(Pod 亲和性/反亲和性权重)
作用:根据 Pod 亲和性/反亲和性的软性规则(preferredDuringScheduling)调整分数。 规则:
Pod 亲和性:与目标 Pod 处于同一拓扑域的节点加分。 Pod 反亲和性:与目标 Pod 处于同一拓扑域的节点减分。
TaintTolerationPriority(污点容忍优先)
作用:为容忍更多污点的节点加分(需结合 PodToleratesNodeTaints Predicate 使用)。
规则:优先选择容忍度高的节点(如专用节点池)
NodeAffinityPriority、TaintTolerationPriority 和 InterPodAffinityPriority 这三种 Priority,一个 Node 满足上述规则的字段数目越多,它的得分就会越高
其他算法
ImageLocalityPriority(镜像本地性优先)
作用:优先选择已存在 Pod 所需镜像的节点,减少镜像拉取时间。
VolumeZonePredicate(存储卷可用区匹配)
作用:优先选择与持久卷(PV)处于同一可用区(Zone)的节点。
规则:减少跨可用区访问存储的延迟。
第三阶段
binding阶段(选定阶段):选择得分最高的Node节点和pod进行binding操作,将结果存储在etcd中,选择出来的node节点对应的kubelet会去执行创建pod的相关操作。 :::
# 3. 优先级机制/抢占机制(Priority)
# 3.1 概念:
作用于调度阶段,当资源不足时,决定哪些pod被优先调度或者抢占的机制。高优先级的pod被调度失败后,可以驱逐低优先级pod的方式抢占低优先级pod的资源完成调度。
# 3.2 如何使用优先级和抢占机制
- 新建一个PriorityClass对象,设置优先级数值
- 在Pod的spec的priorityClassName引用PriorityClas
- 当高优先级Pod无法调度时,调度器尝试驱逐低优先级Pod以释放资源
# 4. Qos服务质量等级机制(驱逐机制)
# 4.1 概念:
QoS 等级作用于运行阶段,是 Kubernetes 在 运行时(节点资源不足时) 决定哪些 Pod 会被优先驱逐的机制。
它根据 Pod 的资源请求(Requests)和限制(Limits)的配置,将 Pod 分为三个等级:
Guaranteed(最高):
- 所有容器的 CPU/Memory 均设置
requestslimits`。 - 最后被驱逐。
- 所有容器的 CPU/Memory 均设置
Burstable(中等):
- 至少一个容器设置了
requests,但未满足requestslimits`。 - 驱逐优先级低于 BestEffort。
- 至少一个容器设置了
BestEffort(最低):
- 所有容器均未设置
requests和limits。 - 最先被驱逐。
- 所有容器均未设置
# 5. 优先级和服务质量等级两者的关系
两者的核心区别
| 特性 | QoS 等级 | 优先级/抢占机制 |
|---|---|---|
| 作用阶段 | 运行时(节点资源不足时) | 调度阶段 |
| 目标 | 决定哪些 Pod 被优先驱逐 | 决定哪些 Pod 被优先调度或抢占 |
| 依赖配置 | 资源 requests/limits | PriorityClass |
| 触发条件 | 节点资源压力(如 OOM) | 调度器发现资源不足 |
尽管两者独立,但在实际场景中会共同影响 Pod 的生命周期:
# 场景 1:调度阶段的抢占
优先级决定抢占顺序:
- 高优先级 Pod 触发抢占时,只会驱逐 优先级更低 的 Pod。
- 与 QoS 等级无关:即使被抢占的 Pod 是
Guaranteed,只要其优先级更低,仍然会被驱逐。
QoS 影响抢占后的稳定性:
- 如果高优先级 Pod 的 QoS 为
BestEffort,虽然它被成功调度,但在节点资源不足时可能被优先驱逐。
- 如果高优先级 Pod 的 QoS 为
# 场景 2:运行时的驱逐
QoS 决定驱逐顺序:
- 当节点资源不足(如内存压力)时,
BestEffortPod 会被优先驱逐,无论其优先级如何。 - 优先级不直接影响运行时驱逐:即使一个
BestEffortPod 优先级很高,它仍可能被驱逐。
- 当节点资源不足(如内存压力)时,