bigywater.tech
Kubernetes · 110

临时存储:ephemeral-storage 请求与驱逐

容器往根文件系统写了很多东西会怎样?ephemeral-storage 的 limit 超了是 OOM 吗?emptyDir 和可写层是分开算还是合起来算?tmpfs 算不算?这篇各写 120 MiB 到三个地方,看哪个会被驱逐、多久被驱逐。

23 / 33 秒
可写层 / 磁盘型 emptyDir 超过 50Mi limit 后被驱逐所用的时间
Evicted
超限的结果是 kubelet 驱逐 Pod,不是 OOMKilled
Memory 不算
medium: Memory 的 emptyDir 写 120 MiB,100 秒后仍 Running

容量与调度

实测 · 本机执行输出
  节点 worker:capacity.ephemeral-storage=485473984512;allocatable.ephemeral-storage=485473984512(= capacity,没有预留)
  对照 df:节点上 /var 所在文件系统总大小 474095688 KiB(和 capacity 同一个来源:kubelet 的 imagefs/nodefs)
  requests.ephemeral-storage: 100Ti 的 Pod:phase=Pending;[('PodScheduled', 'Unschedulable', '0/3 nodes are available: 1 node(s) had untolerated taint(s), 2 Insufficient ephemeral-storage. preemption: 0/3 nodes are available: 3 Preemp')]

节点 worker 的 capacity.ephemeral-storage 是 485473984512 字节,allocatable 与它相同(没有预留),正好是节点上 /var 所在文件系统 df 显示的总大小(474095688 KiB)。requests.ephemeral-storage: 100Ti 的 Pod 一直 Pending,PodScheduled=False,0/3 nodes are available: … 2 Insufficient ephemeral-storage(控制面节点因污点被排除)。

可写层超限

实测 · 本机执行输出
  写 120 MiB 到容器根文件系统(limit 50Mi):23 秒后 phase=Failed,reason=Evicted;message='Pod ephemeral local storage usage exceeds the total limit of containers 50Mi. '
  事件:['3s Warning Evicted pod/layer Pod ephemeral local storage usage exceeds the total limit of containers 50Mi.']
  被驱逐的 Pod 对象还在(Failed),容器已被杀;kubectl get 的 STATUS=Error

limits.ephemeral-storage: 50Mi 的容器往自己的根文件系统写 120 MiB:23 秒后 Pod 被驱逐,phase=Failed、reason=Evicted、message=Pod ephemeral local storage usage exceeds the total limit of containers 50Mi.,事件同样是 Evicted。被驱逐的 Pod 对象还在(Failed),容器已被杀。它不是 OOM,没有 OOMKilled,是 kubelet 周期性检查后主动驱逐的,所以有十几秒到几十秒的延迟。

emptyDir 一起算

实测 · 本机执行输出
  写 120 MiB 到 emptyDir(Pod 总 limit 50Mi):33 秒后 phase=Failed,reason=Evicted;message='Pod ephemeral local storage usage exceeds the total limit of containers 50Mi. '

同样 limit 50Mi,往磁盘型 emptyDir 写 120 MiB:33 秒后同样 Failed / Evicted,message 也是 Pod ephemeral local storage usage exceeds the total limit of containers 50Mi.——kubelet 把容器可写层和磁盘型 emptyDir 合在一起,与 Pod 所有容器 limits 之和比较。

内存型不算

实测 · 本机执行输出
  写 120 MiB 到 medium: Memory 的 emptyDir(ephemeral-storage limit 50Mi):100 秒后 phase=Running(没有被驱逐;这部分算内存,不算 ephemeral-storage)
  对照 df:容器里 /data 的文件系统 tmpfs

medium: Memory 的 emptyDir 是 tmpfs:写 120 MiB 也不触发 ephemeral-storage 驱逐,100 秒后 Pod 仍是 Running——这部分算内存(计入容器内存),不算 ephemeral-storage(内存型 emptyDir 写超内存 limit 的后果见 k54)。

分步演示

临时存储
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / kind(Docker 里的单节点或多节点真实集群,节点是 Docker Desktop 虚拟机里的容器)/ kubectl;用空的 kubeconfig 之外的独立 kubeconfig,不碰用户自己的集群;计时用 date +%s%N / kubectl 事件时间戳,数字每次运行会有小幅抖动。三节点 kind 集群 kx-main(Kubernetes v1.37.0),节点是 Docker 容器,文件系统共享宿主机的虚拟磁盘,所以容量数字是宿主磁盘的大小;驱逐时间是 2 秒间隔轮询 Pod 状态得到,单次测量(kubelet 的检查周期决定了它在十几到几十秒之间波动);写入用 dd;每种情形各一次
    • 没有验证:容器日志大小计入 ephemeral-storage(日志轮转 containerLogMaxSize / containerLogMaxFiles);LocalStorageCapacityIsolation 特性关闭时的行为;节点级 nodefs / imagefs 压力驱逐(见 k31);limit 不设时的 Pod 优先级;ephemeral-storage 在 LimitRange / ResourceQuota 里的用法(本文只验证了 Pod 级)
    京ICP备2026067502号-1京公网安备11010502063487号