解决K8S组件被内核OOM_KILL

解决K8S组件被内核OOM_KILL

Deng YongJie's blog 1,573 2023-06-11

背景:

为达到高性能、高承载、灵活性,故使用二进制K8S集群,但增加维护复杂度,其核心组件常被内核OOM_KILL,引发节点失联,导致POD大批量Unkwon,触发POD驱逐,调度到其它节点,其它节点又因突发的CPU、内存,导致组件和POD被KILL,以此循环,引发雪崩。

解决方案:

因自定义可调优的地方较多,需根据实际问题不断调优并解决根因,以下为故障自愈重启、设置OOM得分规避组件被KILL的方法。

一、流程讲解

  1. 调优操作系统内核OOM参数
  2. 调优K8S组件kubelet资源预留参数,调优system.service参数
  3. 计算统计POD资源,更精细化控制资源并预留

二、调优内核OOM参数

新增内核参数,有则修改,无则新增

vim /etc/sysctl.conf
vm.overcommit_memory = 0
vm.admin_reserve_kbytes = 1048576
vm.oom_kill_allocating_task = 1

sysctl -p

参数解释:

vm.overcommit_memory为0时,视情况允许overcommit。系统在为进程分配虚拟地址空间时,会判断当前申请的虚拟地址空间大小是否超过剩余内存大小,如果超过剩余内存会被拒绝。
vm.overcommit_memory为0时,受系统内存以及admin_reserve_kbytes限制。
vm.admin_reserve_kbytes给有cap_sys_admin权限的用户保留的内存,以便用于系统紧急恢复。
vm.oom_kill_allocating_task,此参数默认是0,内核会杀死内存占用过多的进程,通常杀死内存占用最多的进程。非0时,只杀掉导致触发OOM的进程,可以避免遍历进程列表(因为遍历进程列表代价比较大)。

三、调优kubelet参数

修改参数

vim  /lib/systemd/system/kubelet.service
--max-pods=100
--eviction-max-pod-grace-period=60
--eviction-pressure-transition-period=60s
--eviction-hard=imagefs.available<15%,memory.available<6G,nodefs.available<10%,nodefs.inodesFree<5%
--kube-reserved=cpu=4000m,memory=8G
--system-reserved=cpu=4000m,memory=8G
--eviction-soft=imagefs.available<20%,memory.available<8G,nodefs.available<15%
--eviction-soft-grace-period=memory.available=1m,nodefs.available=1m,imagefs.available=1m
--eviction-minimum-reclaim=memory.available=2G,nodefs.available=500Mi,imagefs.available=2G



#systemd参数设置:
OOMScoreAdjust=-1000  #此参数要4.20以上的内核才能生效


systemctl daemon-reload
systemctl restart kubelet.service


#手动执行命令设置:
  echo "-1000" > /proc/${KUBELET_PID}/oom_score_adj
  echo "-1000" > /proc/${KUBE_PROXY_PID}/oom_score_adj
  echo "-1000" > /proc/${FLANNELD_PID}/oom_score_adj

参数解释:

max-pods=100,最大pod数量。
eviction-max-pod-grace-period,驱逐pod前最大等待时间。
eviction-pressure-transition-period,kubelet上报节点的状态时间,超过阈值时,节点会被设置为memory pressure或者disk pressure,然后开启pod eviction。
eviction-hard,节点级别的预留内存,当节点上的可用内存降至预留值以下时,kubelet将尝试硬驱逐Pod。
  imagefs:可选文件系统,供容器运行时存储容器镜像和容器可写层,kubelet通过删除所有未使用的镜像来释放磁盘空间。
  memory: 总使用的内存大于该值,触发kubelet硬驱逐pod。
  nodefs: 节点的主要文件系统,用于本地磁盘卷、emptyDir、日志存储等,kubelet通过驱逐 pod 及其容器来释放磁盘空间。
  nodefs.inodesFree:索引节点内存状态的信号,kubelet驱逐pod释放空间。
kube-reserved,为Kubernetes组件守护程序预留资源。
system-reserved,为操作系统守护进程记述其资源预留值。
eviction-soft,软驱逐条件与指定的宽限期配对,超过宽限期则驱逐。如宽限期内,总使用内存如果改善到低于阈值就不进行驱逐。必须与宽限期配合使用,否则kubelet会在启动时返回错误。如果达到硬驱逐阈值,kubelet将立即开始回收资源,而没有任何宽限期,故软驱逐的值要比硬驱逐大。
eviction-soft-grace-period,定义软驱逐宽限期,持续多久才进行驱逐。
eviction-minimum-reclaim,每次至少回收的资源量。

system.service解释:

https://www.freedesktop.org/software/systemd/man/systemd.exec.html#

image-20230615170142712

https://www.freedesktop.org/software/systemd/man/systemd-oomd.html

image-20230615170618917