现象

k8s pod一直在重启,调度不起来

排查

1. 首先看状态

这个比较简单,我直接在页面上的(rancher查看api、查看/编辑yaml等都能看)
在这里插入图片描述

如图,找到containerStatuses,里面有个exitCode:137
网上搜了下错误码的意思:

  • 退出代码 0:一般为容器正常退出
  • 退出代码 1:由于容器中 pid 为 1 的进程错误而失败
  • 退出代码 137:由于容器收到 SIGKILL 信号而失败(手动执行或“oom-killer” [OUT-OF-MEMORY])
    = 退出代码 139:由于容器收到 SIGSEGV 信号而失败
  • 退出代码 143:由于容器收到 SIGTERM 信号而失败

网上对137的解释:一般为pod容器内存达到资源限制(resources.limits)或者宿主机本身内存不够了。

我们知道,oom被kill是可以在系统日志里看到的:
ubuntu 的系统日志在 /var/log/syslog,centos 的系统日志在 /var/log/messages

2. 登录机器排查

大致判断可能是OOM导致之后,需要进机器看下真实情况

  1. 首先看下pod所在的node
[superuser@server2558 ~]$ sudo kubectl get pod -n mynamespace -o wide
NAME                                           READY   STATUS             RESTARTS   AGE   IP               NODE               NOMINATED NODE   READINESS GATES
elasticsearch-568889b5f-h482t   0/1     CrashLoopBackOff   8          23m   10.x.x.x    a2617              <none>           <none>          <none>           <none>

如图,这个异常的pod被调度到了a2617节点

  1. 找到节点ip
[superuser@server2558 ~]$ sudo kubectl describe node a2617
Name:               a2617
Roles:              <none>
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    jindi.com/group=xxx
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=s2678-daben
                    kubernetes.io/os=linux
Annotations:        kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
                    node.alpha.kubernetes.io/ttl: 0
                    projectcalico.org/IPv4Address: 172.x.x.5/16
......

如图,ip为172.x.x.5
3. 查看节点剩余内存

[superuser@server2558 ~]$ sudo kubectl top nodes
NAME               CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%   
a2617              194m         4%     19869Mi         62%  
......

32G的机器,内存还剩10来个G…

  1. 登录节点机器,查看日志
[superuser@server2558 ~]$ sudo tail -n 100 /var/log/messages
Feb 10 16:07:47 a2617 kernel: [17948]  1000 17948  3990899  3029423    5957        0           802 java
Feb 10 16:07:47 a2617 kernel: Out of memory: Kill process 17948 (java) score 1184 or sacrifice child
Feb 10 16:07:47 a2617 kernel: Killed process 17948 (java), UID 1000, total-vm:15963596kB, anon-rss:12117692kB, file-rss:0kB, shmem-rss:0kB
Feb 10 16:07:47 a2617 kernel: calico-node invoked oom-killer: gfp_mask=0x201da, order=0, oom_score_adj=-998
Feb 10 16:07:47 a2617 kernel: calico-node cpuset=docker-70e0f5934f06de65ae596cc16b1b467b14fc9842796a01e8ae9eda42fe1b6431.scope mems_allowed=0

比较关键都信息Killed process 17948 (java), UID 1000, total-vm:15963596kB, anon-rss:12117692kB, file-rss:0kB, shmem-rss:0kB

  • total-vm 进程总共使用的虚拟内存;
  • anon-rss:虚拟内存实际占用的物理内存;

所以,可以看到,这个应用一下子申请了12G的无力内存,而节点内存没有那么多了,所以oom。

3. 处理

要么调度到其他节点上,要么给内存做下限制。

我是给pod加了资源限制, 再重启就好了。

resources:
  limits:
    cpu: "1"
    memory: 6Gi
  requests:
    cpu: 100m
    memory: 6Gi

问题:咨询我们运维,他表示pod的limit不会影响服务申请多少内存,只会在服务申请大于limit的内存时,直接异常。如果程序真的需要12G的内存,这么配置应该是无效的,可能是我改了参数,调度到了其他正常的节点,所以启动成功了。

但,观察两次调度的节点,第二次的节点内存比第一次的节点内存更小。如果还申请了12G内存,肯定会启动不成功。所以我感觉可能跟配置还是有点关系。大致是考虑服务可以申请12G内存,也可以申请更小的内存,如果我们没限制,他会申请更大的内存,导致oom, 限制了,申请小的内存,也能保证正常启动。

知道的朋友请帮忙解答下,谢谢


[1] https://www.bookstack.cn/read/kubernetes-practice-guide/troubleshooting-trick-analysis-exitcode.md
[2] https://www.xtplayer.cn/kubernetes/pod-container-restart-reason-check/#%E6%A3%80%E6%9F%A5%E5%AE%B9%E5%99%A8%E9%80%80%E5%87%BA%E5%8E%9F%E5%9B%A0%EF%BC%88reason%EF%BC%89%E5%92%8C%E7%8A%B6%E6%80%81%E7%A0%81

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐