4. Pod 驱逐机制:kubelet 节点压力驱逐、API 驱逐与优先级抢占
在多租户集群中,Pod 驱逐是保障节点稳定性和租户隔离的关键手段。当节点资源紧张或需要维护时,Kubernetes 通过三种核心机制决定哪些 Pod 被终止以及何时终止:kubelet 节点压力驱逐、API 驱逐(Eviction API)和优先级与抢占(Priority & Preemption)。理解这三者的协同关系,是设计多租户故障域策略的基础。
4.1 kubelet 节点压力驱逐
kubelet 持续监控节点资源(内存、磁盘、PID 等)。当资源使用超过预设阈值时,kubelet 主动驱逐 Pod 以回收资源,保障节点整体健康。
核心驱逐信号与阈值
| 驱逐信号 | 描述 | 默认硬驱逐阈值 | 默认软驱逐阈值 |
|---|---|---|---|
memory.available |
节点可用内存 | 100Mi |
200Mi |
nodefs.available |
节点根文件系统可用空间 | 10% |
15% |
nodefs.inodesFree |
节点根文件系统可用 inode | 5% |
10% |
imagefs.available |
容器镜像存储文件系统可用空间 | 15% |
20% |
pid.available |
节点可用 PID 数量 | 100 |
200 |
priorityClassName 以避免被软驱逐优先选中。
驱逐顺序与 QoS 类
kubelet 根据 Pod 的 QoS 类决定驱逐顺序:
- BestEffort(无资源限制)—— 最先被驱逐
- Burstable(部分资源限制)—— 其次被驱逐
- Guaranteed(所有资源限制且相等)—— 最后被驱逐
同一 QoS 类内,kubelet 按 Pod 使用资源与请求量的比例排序,使用比例最高的 Pod 优先被驱逐。
4.2 API 驱逐(Eviction API)
API 驱逐提供了一种编程化的驱逐方式,允许集群管理员或控制器通过 Kubernetes API 主动驱逐 Pod,而无需等待 kubelet 节点压力触发。这在多租户场景中尤为重要,例如租户资源超限、节点维护或安全隔离时。
Eviction API 工作原理
客户端向 PodEviction 子资源提交驱逐请求,kube-controller-manager 中的 驱逐控制器 处理该请求:
- 检查 Pod 是否受 PodDisruptionBudget(PDB) 保护
- 如果 PDB 允许(即驱逐后不会低于最小可用副本数),则执行驱逐
- 如果 PDB 不允许,请求被拒绝,返回
429 Too Many Requests或409 Conflict
API 驱逐与节点压力驱逐对比
| 特性 | kubelet 节点压力驱逐 | API 驱逐(Eviction API) |
|---|---|---|
| 触发方式 | 节点资源阈值自动触发 | 用户/控制器主动调用 API |
| 遵守 PDB | 否 | 是 |
| 优雅终止 | 软驱逐支持,硬驱逐不支持 | 始终支持(受 terminationGracePeriodSeconds 控制) |
| 适用场景 | 节点资源紧急回收 | 计划内维护、租户隔离、资源配额管理 |
| 优先级影响 | 按 QoS 和资源使用比例 | 不直接考虑优先级,但受 PDB 约束 |
使用 Eviction API 驱逐 Pod
# 创建驱逐请求(YAML 格式)
cat <<EOF | kubectl create -f -
apiVersion: policy/v1
kind: Eviction
metadata:
name: my-pod
namespace: tenant-a
spec:
deleteOptions:
gracePeriodSeconds: 30
EOF
# 或直接使用 kubectl drain(底层调用 Eviction API)
kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data
4.3 优先级与抢占(Priority & Preemption)
优先级与抢占机制确保高优先级 Pod 在资源竞争时能够获得调度机会。当调度器无法为高优先级 Pod 找到可用节点时,它会抢占(驱逐)低优先级 Pod 以释放资源。
优先级类定义
通过 PriorityClass 定义全局优先级,值越大优先级越高:
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: tenant-critical
value: 1000000
globalDefault: false
description: "用于关键租户业务 Pod,抢占非关键 Pod"
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: tenant-batch
value: 100
globalDefault: false
description: "用于批处理任务,可被抢占"
抢占流程
抢占的租户隔离影响
在多租户集群中,抢占可能导致一个租户的 Pod 被另一个租户的 Pod 驱逐,引发公平性问题。建议采取以下策略:
- 租户优先级分层:为不同租户分配不同的优先级范围,关键租户使用高优先级,普通租户使用低优先级
- 设置抢占策略:通过
PreemptionPolicy控制是否允许抢占(PreemptLowerPriority或Never) - 结合资源配额:即使高优先级 Pod 也不能超过租户的资源配额,避免一个租户抢占整个集群
4.4 三种驱逐机制的协同与选择
| 场景 | 推荐机制 | 说明 |
|---|---|---|
| 节点内存/磁盘紧急不足 | kubelet 节点压力驱逐 | 自动触发,快速回收资源,不遵守 PDB |
| 计划内节点维护 | API 驱逐(kubectl drain) | 遵守 PDB,优雅迁移 Pod,避免服务中断 |
| 租户超配额或违规 | API 驱逐(控制器调用) | 可编程控制,结合租户策略自动驱逐 |
| 高优先级 Pod 等待调度 | 优先级与抢占 | 调度时触发,抢占低优先级 Pod 释放资源 |
| 节点资源碎片化 | API 驱逐 + 重调度 | 主动驱逐 Pod 以优化节点资源分布 |
在实际多租户集群中,这三种机制通常组合使用。例如:为关键租户设置高优先级和 Guaranteed QoS,使其在节点压力驱逐中处于最后被驱逐的位置;同时设置 PDB 保护,确保 API 驱逐不会导致服务不可用;最后通过优先级抢占确保关键任务在资源竞争时能够获得调度机会。