K8S OOM killer机制

当kubelet没来得及触发pod驱逐,使得节点内存耗尽时,将触发节点上的OOM killer机制;

Linux上有个机制叫OOM killer(Out Of Memory killer),这个机制会在系统内存耗尽的情况下发挥作用,即根据一定的算法规则,选择性的杀死一些进程,以释放部分内存,让系统继续稳定运行。

如何选择杀死哪个进程

当发生oomkill时,OOM killer给进程打分,得到oom_score,然后优先把oom_score最大的进程先杀死;

oom_score怎么计算获得呢?oom_score=oom_score_adj+进程内存占用大小;

而oom_score_adj则是可以人工给每个进程设置的,从而让用户通过设置进程的oom_score_adj值来影响OOM killer杀死进程的选择;

当oom_score_adj的值设置为-1000时,表示该进程将不会被OOM killer杀死,但如果设置的值不是-1000,那这个进程还是会参与打分,会受oom_score_adj以及进程内存占用大小的影响,需要注意的是,即使oom_score_adj的值设置的很小,比如-999,但当你的进程占用内存很大时,该进程同样有很大的概率会被杀死;

pod中容器进程的oom_score_adj

  • 对于Guaranteed级别的pod,其oom_score_adj的值被设置为-998
  • 对于Best-Effort级别的pod,其oom_score_adj的值被设置为1000
  • 对于Burstable级别的pod,其oom_score_adj的取值为2到999

怎么避免OOM Killer杀死某个业务进程?

  1. 将进程oom_score_adj的值设置为-1000;
  2. 关闭OOM killer机制;
设置oom_score_adj

在Linux系统中,oom_score_adj是一个文件,其路径通常位于/proc/[pid]/oom_score_adj,其中[pid]是进程的ID。通过修改这个文件,可以调整特定进程的OOM(Out of Memory)killer评分。这个评分影响OOM killer在选择哪个进程杀死时的决策。oom_score_adj的值范围从-1000到1000,负值会降低进程被OOM killer选中的概率,而正值则会增加。

在Kubernetes环境中,通常不需要手动设置oom_score_adj,因为kubelet会自动为容器设置适当的值,基于Pod的QoS(服务质量)等级。但是,如果你需要手动设置或调整容器内进程的oom_score_adj值,可以通过以下方法:

1. 直接在容器内设置

如果你有权限访问容器内部,可以直接在容器内修改oom_score_adj文件。例如,要为容器内的某个进程设置oom_score_adj值为500,可以执行以下命令:

复制代码
echo 500 > /proc/[pid]/oom_score_adj

替换[pid]为实际的进程ID。

2. 使用Security Context设置

在Kubernetes中,可以通过Pod的Security Context来设置特定的安全选项,包括oom_score_adj。以下是一个示例,展示如何在Pod定义中设置oom_score_adj

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  securityContext:
    oomScoreAdj: 500
  containers:
  - name: mycontainer
    image: myimage

在这个示例中,oomScoreAdj设置为500,这将应用于Pod内的所有容器。

3. 使用Node Feature Discovery

对于更复杂的场景,比如需要根据节点特性动态设置oom_score_adj,可以使用Node Feature Discovery项目。这个项目可以帮助你根据节点的硬件特性来设置特定的参数。

注意事项

  • 修改oom_score_adj可能会影响系统的稳定性,因为过高的值会增加进程被OOM killer选中的风险。
  • 在生产环境中,建议谨慎使用,并充分测试以确保不会对系统稳定性造成负面影响。
  • Kubernetes的自动oom_score_adj设置是基于Pod的QoS等级的,通常不需要手动干预。
关闭OOM killer机制

在Linux系统中,OOM(Out of Memory)killer是一个保护机制,用于在系统内存不足时自动选择并终止消耗内存最多的进程,以防止系统因内存耗尽而完全崩溃。尽管在某些情况下,您可能想要关闭这个机制,但请注意,这样做会增加系统因内存不足而变得不稳定或崩溃的风险。

如果您确实需要临时或永久地关闭OOM killer,可以通过以下方法:

1. 临时关闭OOM killer

可以通过向/proc/sys/vm/panic_on_oom文件写入值0来临时关闭OOM killer:

复制代码
echo 0 > /proc/sys/vm/panic_on_oom

这个设置在系统重启后会恢复默认值。

2. 永久关闭OOM killer

要永久关闭OOM killer,您需要编辑/etc/sysctl.conf文件(或对应的发行版配置文件),并添加或修改以下行:

复制代码
vm.panic_on_oom = 0

然后,应用更改:

复制代码
sysctl -p

这将使更改永久生效,即使在系统重启后。

3. 通过启动参数关闭

也可以在Linux内核启动参数中添加panic_on_oom=0来关闭OOM killer。这通常在/etc/default/grub(对于使用GRUB的系统)或相应的启动配置文件中设置。修改后,需要更新GRUB配置并重启系统:

复制代码
echo 'kernel_param="panic_on_oom=0"' >> /etc/default/grub
update-grub
reboot

注意事项

  • 关闭OOM killer可能会导致系统在内存不足时变得不稳定或无法预测,因为没有任何机制来自动终止进程以释放内存。
  • 在某些情况下,如实时或嵌入式系统,可能需要关闭OOM killer以避免意外的进程终止。
  • 在大多数服务器和桌面环境中,建议保持OOM killer启用,因为它是保护系统免受内存耗尽影响的重要机制。
相关推荐
chuanauc7 小时前
Kubernets K8s 学习
java·学习·kubernetes
小张是铁粉7 小时前
docker学习二天之镜像操作与容器操作
学习·docker·容器
烟雨书信7 小时前
Docker文件操作、数据卷、挂载
运维·docker·容器
IT成长日记7 小时前
【Docker基础】Docker数据卷管理:docker volume prune及其参数详解
运维·docker·容器·volume·prune
这儿有一堆花7 小时前
Docker编译环境搭建与开发实战指南
运维·docker·容器
LuckyLay7 小时前
Compose 高级用法详解——AI教你学Docker
运维·docker·容器
Uluoyu8 小时前
redisSearch docker安装
运维·redis·docker·容器
IT成长日记12 小时前
【Docker基础】Docker数据持久化与卷(Volume)介绍
运维·docker·容器·数据持久化·volume·
疯子的模样16 小时前
Docker 安装 Neo4j 保姆级教程
docker·容器·neo4j
虚伪的空想家17 小时前
rook-ceph配置dashboard代理无法访问
ceph·云原生·k8s·存储·rook