某项目kubernetes环境某个应用每隔20分钟左右就会重启一次,时间不固定,但在容器事件里面没有任何记录。java
首先怀疑是健康检查没过致使容器自动重启,如下是健康检查的配置node
按照该配置,检查间隔30s,不健康阈值60,也就是1800s=30分钟后会标记为不健康,但很快就排除该猜想,理由是bash
正常状况下若是kubernetes重启pod那会在事件里记录重启的缘由,但事件里面没有任何记录,因此可能不是kubernetes重启的,那么很容易想到一个可能性就是OOM,也就是进程由于内存使用超过限制触发OOM操做系统将其kill掉,查看操做系统日志/var/log/messages
发现如下日志ui
May 11 15:01:36 k8s-node-prod-3 kernel: [17094.020710] oom_kill_process.cold.30+0xb/0x1cf May 11 15:01:36 k8s-node-prod-3 kernel: [17094.020788] [ pid ] uid tgid total_vm rss pgtables_bytes swapents oom_score_adj name May 11 15:01:36 k8s-node-prod-3 kernel: [17094.109707] oom_reaper: reaped process 25929 (java), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB May 11 15:29:12 k8s-node-prod-3 kernel: [18750.337581] java invoked oom-killer: gfp_mask=0x6000c0(GFP_KERNEL), nodemask=(null), order=0, oom_score_adj=969 May 11 15:29:12 k8s-node-prod-3 kernel: [18750.337621] oom_kill_process.cold.30+0xb/0x1cf May 11 15:29:12 k8s-node-prod-3 kernel: [18750.337709] [ pid ] uid tgid total_
果真有OOM的记录,并且几回kill的事件也正符合应用重启的时间,再查看其余java进程的oom_score,居然高达1000多有很大风险会被再次kill掉,所以罪魁祸首就是OOM,那为何会致使OOM呢,此时操做系统的剩余内存仍是很充足,注意到容器应用的启动参数配置的内存是4096Mspa
JAVA_OPTS="$JAVA_OPTS -server -Xms4096M -Xmx4096M -Xss512k ..."
而容器给的内存限额是4500M,也就是说一台4500M的主机运行了一台须要4096M的程序,程序占了大比例主机内存,固然很容易被系统kill掉操作系统
OOM killer是Linux内核的一个特性,会检查占用内存过大的进程将其杀掉,操做系统会根据进程的内存使用状况打分,分数保存在/proc/{进程PID}/oom_score中,分数越大越容易被kill掉
由于在启动命令里限制了内存,就不必在kubernetes上再对内存进行限制,所以去掉kubernetes的内存限制问题解决。日志
问题虽小,但形成的影响很是大,由于该客户为跨国集团,业务涉及多个国家,所以全天的交易量都很是大,从该问题能够总结如下经验code