可锐资源网

技术资源分享平台,提供编程学习、网站建设、脚本开发教程

k8s中pod频繁重启,oom处理(k8s pod一直重启)

java项目在k8s 中oom处理

oom情况发生一般都是因为内存使用过高导致,最好是走查代码分析出内存占用高的具体原因。 此篇文章说明什么情况下会出现oom,以及如何从运维层面暂缓oom发生。真正解决内存占用还是需要分析代码以及java 堆栈. 不想了解细节,参见最后的java内存配置

发生 oom 情况分类

  • oom
  • 一般说的是java堆内存不够,频繁GC释放不了足够内存来完成新的内存申请导致,这种情况就是jvm内存配置限制了内存申请,解决方式就是调整内存限制大小。
  • oom killer
  • oom killer是linux系统对内存管理的一种方式,当操作系统内存不够用 linux会启动一个oom进程根据在运行的进程的内存占用通过oom_scope和oom_scope_adj 决定杀死某个进程来释放内存(一般都是会干掉内存最高的,详细可以参见 oom_scope 和oom_scope_adj 参数)

java 中jvm内存配置

java 中一般通过配置java的启动参数配置jvm的内存使用情况例如-Xms2048m -Xmx2048m 不过在当前容器化环境一般都会配置POD的资源限制,而openjdk 新版本已经能够识别到容器的资源限制,所以可以不配置jvm。让jdk自动选择。但是jvm默认时使用总内存的一半,例如:k8s中内存限制为1024M,那么jvm只会使用约512M的内存,哪怕jvm已经放生oom,jvm也不会在申请,这样就导致通过k8s的配置和内存使用不统一,可以通过配置jvm参数解决此问题-XX:MaxRAMPercentage=90.0 -XX:MinRAMPercentage=60.0 最高使用k8s 限制内存的90%

oom killer 如何避免

配置POD 内存资源限制,如果不配置 jvm会按照宿主机的内存自动分配。当宿主机内存不够用,这种POD非常容易被kill掉

配置POD 内存的request和limit一样大,这样k8s会调整进程的oom_scope_adj和oom_adj值来保证操作系统不kill掉这种pod(不是绝对的). 如果内存使用超过 limit同样会被干掉

项目中java内存配置

  • 使用推荐的基础镜像
  • 推荐jdk
  • 列表中的镜像能自动发现k8s的资源限制
  • Dockerfile 中配置jvm默认分配比例
  • -XX:MaxRAMPercentage=70.0 -XX:MinRAMPercentage=50.0
  • 可以参见Wiki
  • 配置容器的内存限制
  • jenkins 使用cm-service2 chart包发布的时候配置
  • --set resources.limits.memory="2Gi" \
  • 默认就是2Gi, 如果需要修改则通过此配置修改

通过以上三项配置后无需配置jvm的参数,如果内存仍然不够用(java 发生oom)修改jenkins中的内存限制重新发布即可

特殊情况:如果服务的 可用性非常高,不像被操作系统oom killer那么配置request和limits为相同值

--set resources.limits.memory="2Gi" \ --set resources.requests.memory="2Gi" \


#2023年度创作挑战#

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言