eviction-hard 是立即驱逐,无缓冲;eviction-soft 需同时满足持续超阈值和无可用宽限期,二者阈值须有梯度且不可重叠,memory.available 应基于内核 memavailable 字段设定,避免误用 free 输出或百分比,并需配合 system-reserved 配置。

eviction-hard 和 eviction-soft 的本质区别
--eviction-hard 是“立刻驱逐”,一旦触发,kubelet 会立即终止 Pod,不给缓冲时间;--eviction-soft 是“软驱逐”,需要同时满足两个条件:资源持续超阈值(靠 --eviction-soft-grace-period 控制),且没有可用 grace period(靠 --eviction-max-pod-grace-period 配合)。硬阈值是保底安全线,软阈值是主动干预窗口。
常见错误现象:NodeConditionReady 反复变 Unknown,或 Pod 被杀但日志里查不到 Evicted 状态——大概率是只配了 --eviction-soft 却没设 grace period,导致软策略永远不生效。
-
--eviction-hard推荐从memory.available、<code>nodefs.available 起步,不要设成 <code> 或 <code>,否则磁盘写满前 kubelet 已失联 -
--eviction-soft建议比 hard 早 1–2 Gi 或 5–8%,例如memory.available 对应 <code>memory.available - 两者不能共用同一指标却不设差异,比如
memory.available 同时出现在 soft 和 hard 里——soft 会因无 grace period 永远卡住
memory.available 阈值为什么不能只看 free + buffers/cached
Linux 的 memory.available 是内核 3.14+ 通过 MemAvailable 字段暴露的估算值,它剔除了无法快速回收的 slab、page cache dirty pages、tmpfs 等。直接用 free -h 的 available 列只是近似,但 kubelet 读的是 /proc/meminfo 里的原始值,受 cgroup v1/v2、kmem accounting 是否开启影响极大。
使用场景:在容器密度高、启用 memory.kmem.limit_in_bytes 的节点上,memory.available 可能比预期低 20% 以上,此时按 free 输出设阈值会导致过早驱逐。
- 确认内核版本:
uname -r,低于 3.14 的节点根本没MemAvailable,kubelet 会 fallback 到粗略估算,阈值需上浮 30% - cgroup v2 下若启用
memory.high,memory.available计算更保守,建议 hard 阈值至少留 1Gi 缓冲 - 避免用
nodefs.inodesFree做主驱逐指标——inode 耗尽往往发生在小文件暴增场景,但驱逐 Pod 并不能释放已分配的 inode
disk pressure 驱逐的实际生效顺序和陷阱
当 nodefs.available 或 imagefs.available 触发时,kubelet 先尝试清理镜像(pruneImages),再删容器日志、emptyDir,最后才驱逐 Pod。但这个顺序不可控,且 pruneImages 默认只清理最近 5 分钟没被引用的镜像——如果业务 Pod 频繁重启,镜像可能永远不被清理。
常见错误现象:磁盘显示 95% 使用率,但 kubectl describe node 里 Conditions 没出现 MemoryPressure 或 DiskPressure——大概率是 imagefs 和 nodefs 指向同一挂载点,而 kubelet 默认只监控 nodefs,除非显式配置 --imagefs-available-margin。
- 确认
imagefs路径:df -h | grep $(grep 'docker\|containerd' /proc/1/mountinfo | awk '{print $5}'),多数情况它和nodefs是同一个设备 - 若共用设备,必须同时配置
--eviction-hard=nodefs.available,否则 <code>imagefs阈值无效 -
--eviction-minimum-reclaim对 disk 无效,它只影响 memory 和 pid;磁盘清理量由 kubelet 内部策略决定,无法强制最小清理 GB 数
阈值调得太激进反而引发雪崩
硬阈值设太紧(如 memory.available)会让 kubelet 在内存真正吃紧前就驱逐大量 Pod,剩余 Pod 因竞争加剧更快耗尽资源,形成“驱逐→负载升高→再驱逐”循环。尤其在 burstable QoS 的 Pod 上,cgroup memory limit 往往高于 request,驱逐后调度器可能把新 Pod 分配到同样快撑爆的节点。
性能影响:每次驱逐会触发 syncLoop 全量状态比对,若节点有 200+ Pod,单次驱逐可导致 kubelet CPU 占用尖峰达 300%,进一步拖慢状态上报,让 master 误判节点失联。
- 生产环境
--eviction-hard最低建议不低于memory.available(小节点)或 <code>(32G+ 内存节点) - 避免用
allocatable百分比设阈值,比如memory.available——allocatable 本身随 kube-reserved 变化,百分比会漂移 - 所有阈值必须配合
--system-reserved=memory=1Gi类配置,否则 kubelet 自身内存开销会被计入可用量,导致误触发
最常被忽略的一点:--eviction-hard 阈值修改后,kubelet 不会自动 reload,必须重启进程才能生效;而 --eviction-soft 参数变更后,旧 grace timer 不会中断,新策略要等下一个监控周期才参与判断。










