运维攻坚之kubernetes pod无故重启问题排查

wls1036
English

背景

某项目kubernetes环境某个应用每隔20分钟左右就会重启一次,时间不固定,但在容器事件里面没有任何记录。

排查

首先怀疑是健康检查没过导致容器自动重启,以下是健康检查的配置

按照该配置,检查间隔30s,不健康阈值60,也就是1800s=30分钟后会标记为不健康,但很快就排除该猜测,理由是

  • 手动调用健康检查是ok的
  • 后台有健康检查的记录,记录显示也都是通过的
  • 如果是健康检查不过的话,事件里面会有记录,这里找不到记录

正常情况下如果kubernetes重启pod那会在事件里记录重启的原因,但事件里面没有任何记录,所以可能不是kubernetes重启的,那么很容易想到一个可能性就是OOM,也就是进程因为内存使用超过限制触发OOM操作系统将其kill掉,查看操作系统日志/var/log/messages发现以下日志

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呢,此时操作系统的剩余内存还是很充足,注意到容器应用的启动参数配置的内存是4096M

JAVA_OPTS="$JAVA_OPTS -server -Xms4096M -Xmx4096M -Xss512k ..."

而容器给的内存限额是4500M,也就是说一台4500M的主机运行了一台需要4096M的程序,程序占了大比例主机内存,当然很容易被系统kill掉

OOM killer是Linux内核的一个特性,会检查占用内存过大的进程将其杀掉,操作系统会根据进程的内存使用情况打分,分数保存在/proc/{进程PID}/oom_score中,分数越大越容易被kill掉

解决

因为在启动命令里限制了内存,就没必要在kubernetes上再对内存进行限制,因此去掉kubernetes的内存限制问题解决。

经验总结

问题虽小,但造成的影响非常大,因为该客户为跨国集团,业务涉及多个国家,因此全天的交易量都非常大,从该问题可以总结以下经验

  • 如果kubernetes没有事件记录,很可能是操作系统级别的问题,应该从操作系统入手排查
  • 实践才是检验真理的唯一标准,在出事之前,所有人都觉得这么配置很合理,都没想到会被OOM,出了问题才焕然大悟
阅读 2.9k

yaya平台
记录yaya平台技术细节

幸福是奋斗出来的

254 声望
72 粉丝
0 条评论
你知道吗?

幸福是奋斗出来的

254 声望
72 粉丝
文章目录
宣传栏