K8S中Pod驱逐介绍

K8s 触发 Pod 驱逐分为 API 驱逐(主动) 和 节点驱逐(自动) 两种。节点驱逐只监控内存、磁盘、PID等不可压缩资源,CPU 使用率不会触发驱逐。

关于为什么CPU是使用率不会触发驱逐下文会详细介绍

一、驱逐类型

驱逐类型 触发者 触发条件 是否可控制
API 驱逐 用户/控制器 节点维护、缩容、升级 可控制
节点驱逐 Kubelet 资源压力(内存/磁盘/PID) 自动触发

二、节点驱逐触发条件(核心)

1. 官方支持的驱逐信号

Kubelet 只监控以下不可压缩资源:

驱逐信号 说明 阈值示例 是否触发
不可压缩资源
memory.available 可用内存不足 < 100Mi 会
nodefs.available 节点根磁盘不足 < 5% 会
imagefs.available 镜像存储不足 < 10% 会
nodefs.inodesFree 文件节点不足 < 2% 会
pid.available 可用 PID 不足 < 10 会
可压缩资源
cpu.usage CPU 使用率 任意值 不会

2.可压缩资源和不可压缩资源

可压缩资源(Compressible Resources)

  • ‌代表资源 ‌:‌CPU‌
  • ‌特点 ‌:
    • 当资源不足时,Pod 不会被终止,只会因时间片减少而"变慢"或"饥饿"。
    • 系统通过 cgroups 限流(throttling)机制控制 CPU 使用,不超过设定的 limits。
  • ‌示例场景‌:多个 Pod 同时高负载使用 CPU,kubelet 会按请求比例分配时间片,但所有 Pod 仍可运行。

因为CPU是可压缩资源,所以在CPU不在驱逐条件里面

不可压缩资源(Incompressible Resources)

  • ‌代表资源 ‌:‌内存(Memory) ‌、‌**磁盘空间(Storage)**‌
  • ‌特点 ‌:
    • 一旦耗尽,无法通过简单限流回收,必须通过 ‌驱逐(Eviction) ‌ 或 ‌OOM Kill‌ 终止进程来释放资源。
    • 内存超限会触发内核 OOM Killer,优先杀死得分最高的容器(通常 QoS 低的 Pod)。
  • ‌示例场景‌:节点内存不足时,kubelet 会按 QoS 优先级驱逐 Pod;若来不及处理,内核直接 OOM Kill。

3.阈值配置

Kubelet 配置 (/var/lib/kubelet/config.yaml):

bash 复制代码
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration

# 软阈值(超过后等待宽限期再驱逐)
evictionSoft:
  memory.available: "500Mi"
  nodefs.available: "10%"
  imagefs.available: "15%"
  nodefs.inodesFree: "5%"

# 软阈值宽限期
evictionSoftGracePeriod:
  memory.available: "1m30s"
  nodefs.available: "1m30s"

# 硬阈值(超过后立即驱逐)
evictionHard:
  memory.available: "100Mi"
  nodefs.available: "5%"
  imagefs.available: "10%"
  nodefs.inodesFree: "2%"

4. 软阈值和硬阈值

阈值类型 行为 宽限期 使用场景
软阈值 超过后等待宽限期,再驱逐 有(如 90 秒) 临时压力,给恢复时间
硬阈值 超过后立即驱逐 无 严重压力,快速保护节点

5.触发流程

当node资源超限时会进入压力状态,然后根据软硬阈值对QoS低优先级pod进行驱逐,具体流程如下:

三、API 驱逐触发条件

1. 触发场景

场景 命令/操作 说明
节点维护 kubectl drain <node> 节点下线维护
节点缩容 集群自动缩容 (CA) 节省成本
版本升级 kubeadm upgrade 升级 K8s 版本
手动删除 kubectl delete pod 手动删除 Pod

2. 驱逐流程

3. PDB介绍

参考我另外一篇博客:https://blog.csdn.net/weixin_43866248/article/details/160023860?spm=1011.2124.3001.6209

PDB 可阻止 API 驱逐:

bash 复制代码
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: nginx-pdb
spec:
  minAvailable: 2        # 最少可用 Pod 数
  selector:
    matchLabels:
      app: nginx

四、驱逐优先级(QoS 等级)

节点驱逐时,Pod 按 QoS 等级 决定驱逐顺序:

QoS 等级 配置要求 优先级 驱逐顺序
BestEffort 无 requests/limits 低 最先被驱逐
Burstable 有 requests,无 limits 或不等于 中 其次被驱逐
Guaranteed requests = limits 高 最后被驱逐

五、驱逐情况查看

1. 查看驱逐事件

bash 复制代码
# 查看所有驱逐事件
kubectl get events --field-selector reason=Eviction --all-namespaces

# 查看特定节点的驱逐事件
kubectl get events --field-selector involvedObject.kind=Node

# 查看驱逐详情
kubectl describe event <event-name>

2. 查看节点压力状态

bash 复制代码
# 查看节点条件
kubectl describe node <node-name> | grep -A 5 "Conditions"

# 输出示例
Conditions:
  Type             Status  Reason                       Message
  ----             ------  ------                       -------
  MemoryPressure   True    KubeletHasInsufficientMemory  内存压力
  DiskPressure     False   KubeletHasNoDiskPressure
  PIDPressure      False   KubeletHasSufficientPID
  Ready            True    KubeletReady

3. 查看 Kubelet 配置

bash 复制代码
# 查看驱逐阈值配置
cat /var/lib/kubelet/config.yaml | grep -A 10 "eviction"

# 查看 Kubelet 启动参数
ps -ef | grep kubelet | grep eviction

4. 查看 Pod QoS 等级

bash 复制代码
# 查看 Pod 的 QoS 等级
kubectl get pod <pod-name> -o jsonpath='{.status.qosClass}'

# 输出:BestEffort / Burstable / Guaranteed

六、场景问题

问题 1: CPU 使用率打满会触发驱逐吗?

答案当然是不会。其实这篇博客就是因为这个问题而写的,相信看到这里已经可以明白为什么CPU使用率打满不会触发驱逐,原因就是:CPU是可压缩资源。但是pod会运行的很慢。

问题 2: 排查为什么 Pod 被驱逐了?

bash 复制代码
# 排查步骤
# 1. 查看驱逐事件
kubectl get events --field-selector reason=Eviction

# 2. 查看节点压力
kubectl describe node <node> | grep Conditions

# 3. 查看 Pod QoS 等级
kubectl get pod <pod> -o jsonpath='{.status.qosClass}'

# 4. 查看 Kubelet 日志
journalctl -u kubelet | grep -i eviction

# 5.查看pod yaml,查看pod重建原因
kubectl get pod <pod-name> -n <namespace> -o yaml

# 5.查看pod event
kubectl describe pod <pod-name> -n <namespace>
Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  5m    default-scheduler  0/3 nodes are available: 3 Insufficient cpu.
  Warning  Evicted           2m    kubelet            The node was low on resource: ephemeral-storage. Container runtime evicted some of its containers.

水平有限,有问题可评论或者私信

相关推荐
DarkAthena4 小时前
wslc ps 卡死的排查:一次「停容器不停 VM」引发的连环故障
docker
小沈同学呀6 小时前
【Agent开发第十五期】部署上线:把 Alex 搬进浏览器,15 期全栈串联收官
docker·agent·从零搭建ai助手
lwx9148526 小时前
Docker-安装SSH服务
docker·容器·ssh
艾伦_耶格宇10 小时前
【kubernetes - 1.28版本】-11 K8S核心组件
java·容器·kubernetes
时间售卖铺11 小时前
Docker实战:一键部署轻量级容器
运维·docker·云原生
月落汀兰11 小时前
拒绝配置写死镜像!K8s 存储卷与配置管理,PV/PVC、ConfigMap、Secret 实战避坑指南
运维·kubernetes
艾伦_耶格宇12 小时前
【kubernetes - 1.28版本】-10 K8S命名空间
云原生·容器·kubernetes
tedcloud12314 小时前
Docker Compose 部署 Uptime Kuma:配置 HTTPS、QQ 邮箱告警与数据备份
服务器·网络协议·ui·docker·容器·https·开源
syntaxsage15 小时前
Dive:Docker 镜像层可视化分析工具
运维·其他·docker·容器
java_logo15 小时前
Docker 部署 Samba:轻松搭建局域网文件共享
运维·docker·容器·文件共享·samba·smb·轩辕镜像