Evictions

本文简单介绍以下一下 evictions 机制。

1. Eviction Signal

在 evictions 机制下,kubelet 会动态计算以下 Eviction Signal 是否小于用户配置的值,并触发 pod evictions 以及 GC 操作:

Eviction Signal Description(kubelet 计算 signal 的公式)
memory.available memory.available := node.status.capacity[memory] - node.stats.memory.workingSet
nodefs.available nodefs.available := node.stats.fs.available
nodefs.inodesFree nodefs.inodesFree := node.stats.fs.inodesFree
imagefs.available imagefs.available := node.stats.runtime.imagefs.available
imagefs.inodesFree imagefs.inodesFree := node.stats.runtime.imagefs.inodesFree
pid.available pid.available := node.stats.rlimit.maxpid - node.stats.rlimit.curproc

需要注意:kubelet 内部会自动判断 CRI 存放镜像文件的 device 。当有存放目录不是根目录时,imagefs.available/imagefs.inodesFree 配置才会独立生效。

evictions 机制包括以下两种类型:

  • hard eviction:Eviction Signal 到达后立即驱逐容器并执行GC,该模式下容器驱逐时会强制终止容器,无视 TerminationGracePeriodSeconds 配置。
  • soft eviction:Eviction Signal 到达后等待指定时间,指定时间内 Eviction Signal 消失则不会触发 GC 和 pod evictions,该模式驱逐容器时,支持 TerminationGracePeriodSeconds 配置,但是时常不能超过 evictionMaxPodGracePeriod 设置的指定值。

kubelet 默认每隔 10s 计算一次 ,该配置通过 kubelet 的命令行参数 –housekeeping-interval 进行调整。

2. Node conditions

Eviction Signal 同时也会影响 Kubernetes 的Node conditions,它们的映射关系如下:

Node Condition Eviction Signal Description
MemoryPressure memory.available Available memory on the node has satisfied an eviction threshold
DiskPressure nodefs.available, nodefs.inodesFree, imagefs.available, or imagefs.inodesFree Available disk space and inodes on either the node’s root filesystem or image filesystem has satisfied an eviction threshold
PIDPressure pid.available Available processes identifiers on the (Linux) node has fallen below an eviction threshold

默认情况下,node 状态的更新周期为 10s,通过 –node-status-update-frequency 参数可以配置。

当配置 soft evictions 时,Node conditions 会存在波动 –eviction-pressure-transition-period,该参数控制 kubelet 在将 Node conditions 转换前必须等待的时间,改配置默认值为 5m。

3. Pod eviction

当 Kubelet 资源回收无法使 eviction signal 回到设定的阈值之下时,Kubelet 将开始对 Pod 执行驱逐操作。

1. MemoryPressure

当 Node 出现 MemoryPressure 状态时,Kubernetes 主要根据 Pod 的 Qos 决定驱逐顺序。

Kubernetes 根据 Pod 的 resource 将 pod 分为以下三种 Qos 类型:

  • BestEffort:Pod 中的容器不得有任何 memory 或 CPU 的 request 或 limit 配置。
  • Burstable:Pod 中至少有一个 Container 有memory 或 CPU 的 request 或 limit 配置,且不满足 Guaranteed 的条件。
  • Guaranteed:Pod 的 request 和 limit 满足以下条件。
    • Pod 中的每个 Container 都必须有 memory 和 CPU 的 request 和 limit 配置。
    • Pod 中的每个 Container,memory 和 CPU 的 request 和 limit 相同。

需要注意:当定义 Pod 的 memory 和 CPU limit 配置时,如果省略 request 的相关配置,那么 Kubernetes 默认会使用同样的配置填充 request 的值,此时 Pod 的 Qos 是 Guaranteed。

以下配置决定 pod 是否会成为被驱逐对象:

  • Pod 使用的资源(包括 CPU/内存)是否超过 request,以及资源超出的使用量。
  • Pod Priority
  • Pod 的 Qos 级别

驱逐是参考一下顺序:

  • BestEffort 和 Burstable 类型的 pod 优先被驱逐,驱逐的先后依照以下指标:
    • Priority 的低的先被驱逐
    • Pod 使用的对应资源超出 request 配置值(BestEffort 的 request 视为 0),超出多的先被驱逐
  • Burstable 类型的 Pod 如果使用的资源在 request 指标之下,那么会和 Guaranteed 类型的 Pod 一同处理,驱逐的先后依照以下指标:
    • Priority 的低的先被驱逐
    • 资源使用越接近 request 的先被驱逐

需要注意:Kubernetes 的 Qos 设计并没有考虑 EphemeralStorage requests 的使用场景,因此这里描述的 Pod 驱逐顺序不适用于 DiskPressure 场景。

2. DiskPressure

1. 资源回收

当 node 出现DiskPressure 时,Kubelet 会在驱赶 Pod 之前触发资源回收,即回收磁盘空间。假设 Kubelet 回收磁盘空间后 DiskPressure 消失,那么 Kubelet 不会执行 pod eviction 操作。

是否配置 imagefs 阈值,影响了 kubelet 回收磁盘空间的行为:

  • 配置 imagefs 时,磁盘回收顺序如下:
    • nodefs 触发 Eviction Signal –> kubelet 删除退出容器
    • imagefs 触发 Eviction Signal –> kubelet 删除所有不再使用中的镜像
  • 没有配置 imagefs ,只设置了nodefs时:
    • kubelet 删除退出容器以及所有不再使用中的镜像

2. Pod eviction

当上述资源回收无法起作用时,Kubelet 考虑删除节点中正在运行的 Pod ,通过删除本地卷、容器日志、write layer 来释放磁盘空间。

是否配置 imagefs 阈值,pod eviction 优先级:

  • 配置 imagefs 时,pod eviction 顺序如下:
    • nodefs 触发 Eviction Signal –> 根据 pod 占用的 local volumes + logs of all containers 空间
    • imagefs 触发 Eviction Signal –> 根据 pod 占用的 write layer 空间
  • 没有配置 imagefs ,只设置了nodefs时:
    • 根据 pod 占用的 local volumes + logs of all containers + write layer 空间

3. 其他 Eviction 场景

其他 Eviction Signal 引发的 eviction 场景主要是 inode 和 PID ,由于这两种资源没有 Qos 概念,主要根据 Pod Priority 决定驱逐顺序。

4. Node 资源耗尽

如果 Kubelet 并没有收到任意 Eviction Signal,但此时 Node 节点存在 OOM ,此时 Kubelet 依赖系统自带的 oom_killer 回收内存。

Kubelet 默认情况下为不同 Qos 规格的容器设置不同的 oom_score_adj 参数:

Quality of Service oom_score_adj
Guaranteed -997
BestEffort 1000
Burstable min(max(2, 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)

kubelet 还为 Pod 中具有 system-node-critical 优先级的容器设置 oom_score_adj 值 -997

5. 配置项

eviction 相关配置包括以下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
nodeStatusUpdateFrequency: 5s
evictionHard:                           # 资源高水线(hard)
  memory.available: 100Mi
  nodefs.available: 10%
  imagefs.available: 5%
evictionSoft:                            # 资源高水线(soft)
  memory.available: 500Mi
  nodefs.available: 15%
  imagefs.available: 15%
evictionSoftGracePeriod:                 # 资源高水线(soft),宽限时间
  memory.available: 5m
  nodefs.available: 5m
  imagefs.available: 5m
evictionMinimumReclaim:                   # 资源低水线
  memory.available: 500Mi
  nodefs.available: 1Gi
  imagefs.available: 500Gi
evictionMaxPodGracePeriod: 0               # soft 模式下,TerminationGracePeriodSeconds 最大值
evictionPressureTransitionPeriod: 5m       # NodeConditions 更新时间

上述配置中,evictionMinimumReclaim 表示最小资源回收额度,表示当 eviction 发生时,资源的使用率必须在用户配置的水线之下,额外回收的量。

6. 其他

  • Node 预留内存:kubelet 支持通过 –kube-reserved–system-reserved 参数为系统预留内存。
  • active_file Memory:参考

Kubelet GC

Kubelet 支持对 images 和 containers 进行定期清理,但这个机制官方已经标记为废弃状态,涉及到以下 kubelet 配置:

  • image-gc-high-threshold:触发 images 清理磁盘空间阈值
  • image-gc-low-threshold:images 磁盘清理的目标阈值

上述配置的默认值为 85% 和 80% ,即当磁盘使用容量达到 85% 时 kubelet 将根据 images 的使用频率删除节点上的镜像,当磁盘容量下降到 80% 时停止。

  • maximum-dead-containers:当前节点能够保留旧实例的最大数量,默认为 -1,即没有限制
  • maximum-dead-containers-per-container:每个 container 要保留的旧实例的数量,默认为 1
  • minimum-container-ttl-duration:旧实例可以被回收的最小时间,默认为 0

按照 kubelet 的默认配置,pod 反复重启时只保留最近一次的重启实例。

通过 docker ps -a 查看 container 实例时,容器名称格式为 k8s_<container名称><pod名称><命名空间名称><pod uid><重启次数>

关闭 ImageGC

在一些环境中,容器使用的 Images 是通过 docker load 等方式从文件导入到节点上的,这种情况下可能需要关闭 Kubernetes ImageGC 功能。

在 1.21.14 版本中,以下两个机制都会触发 ImageGC:

  • ImageGCManager(已经废弃)
  • Evictions 机制中的资源回收过程

上述机制中,ImageGCManager 在高版本 Kubernetes 中已经被标记为废弃,通在 Kubelet 启动配置中间 –image-gc-high-threshold 的值设置为 100 可以完全关闭 ImageGCManager 。

Evictions 机制中 Kubelet 会定时检查系统盘使用率并在超出阈值时,触发磁盘清理操作,磁盘清理操作包括删除退出容器以及无用镜像。

浏览 Kubelet 中 eviction-manager 的代码,发现并不能单独关闭删除进行逻辑,并使 evictions 机制在磁盘空间不足时正常工作。

用户只能在移除 eviction 中的 nodefs.available 、imagefs.available 的配置以禁用 evictions 带来的 ImageGC,但副作用是节点磁盘空间不足时,Kubelet 无法感知不会触发 Pod 迁移。

参考