Kubernetes运维:Evictions 机制
文章目录
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 相关配置包括以下:
|
|
上述配置中,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 迁移。
参考
文章作者 yoaz
上次更新 2022-07-01
许可协议 MIT