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.

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

相关推荐
Zhu7582 小时前
【软件部署】用docker部署Apache Kafka 集群架构isolated模式带SSL
docker·kafka·apache
海鸥812 小时前
Kubernetes 集群中缺少 kagent.dev/v1alpha2
云原生·容器·kubernetes
qq_396153452 小时前
docker ddns-go 忘记密码
docker·容器·golang
Zhu7582 小时前
【软件部署】用docker部署Apache Kafka 集群架构的isolated模式
docker·kafka·apache
AAA_搬砖达人小郝2 小时前
Docker常用命令(2026最新)
开发语言·docker
Zhu7582 小时前
【数据迁移】k8s平台本地数据迁移整改
云原生·容器·kubernetes
无效的名字2 小时前
windows下,怎么压缩Docker Desktop占用的磁盘空间
windows·docker·容器
不是书本的小明2 小时前
多套小规格k8s集群 集成到统一k8s集群
云原生·容器·kubernetes