6

Docker杀掉了容器?问题分析与解决过程全面复盘

 2 years ago
source link: https://blog.51cto.com/zq2599/5635338
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码): https://github.com/zq2599/blog_demos

  • 在执行docker exec命令时,报错信息为:rpc error: code = 2 desc = containerd: container not found

先抛出结果

  • 如果您是通过搜索错误信息看到了此文,直接参考以下三点即可:

  • 在执行docker exec命令时报错,报错信息为:rpc error: code = 2 desc = containerd: container not found

  • 以上错误是因为系统内存不足,导致OOM Killer杀掉elasticsearch进程,该进程就是上一步中docker exec命令想作用到的容器;

  • 请检查您的系统内存情况,建议使用egrep -i -r ‘killed process’ /var/logdmesg|grep memory命令查看OOM Killer日志,确认是否存在进程被杀的情况;

  • 接下来的内容,是我对整个问题过程的复盘;

  • 收到同事反馈,说后台服务出现异常,定位后发现是应用连接elasticsearch server失败,于是用eshead去连接,还是失败;

  • 我们的elasticsearch是运行在docker环境中的,用docker ps查看,看起来没什么问题,信息如下:

[admin@dev ~]$ docker ps
CONTAINER ID        IMAGE                                                 COMMAND                  CREATED             STATUS              PORTS                     NAMES
fbbcd0d7d57c        eshead                                                "/bin/sh -c 'cd ~/..."   10 hours ago        Up 10 hours         0.0.0.0:10300->9100/tcp   es-head
ef23574c0afe        docker.elastic.co/elasticsearch/elasticsearch:6.1.1   "/usr/local/bin/do..."   10 hours ago        Up 10 hours                                   elasticsearch
  • 用命令docker logs -f elasticsearch,没有发现什么异常,只是最后一条日志是17:35打印的,而此时已经22:00了,也就是说四个小时es没有输出日志到控制台了;

  • 此时打算去容器内部看看有没有什么错误信息,执行命令docker exec -it elasticsearch /bin/bash,控制台显示如下错误信息:

[admin@dev ~]$ docker exec -it ef23574c0afe /bin/bash
rpc error: code = 2 desc = containerd: container not found
  • 提示信息的大意是找不到容器,当时并没有什么好思路,由于使用了数据卷,容器挂了不怕数据丢失,就想删除容器再创建一个试试;

  • docker rm -f elasticsearch删除容器,提示删除成功;

  • docker run --name elasticsearch重建一个容器,此时控制台提示"名为elasticsearch的容器已经存在"(不好意思忘了把当时的错误信息存下来了,大致是这个意思吧)

  • 此时没辙了,就用命令systemctl restart docker重启了docker服务;

  • 再用docker run --name elasticsearch命令,创建es容器成功;

  • 打开eshead,连接es成功;

  • 测试业务,操作成功,连接es正常;

  • 此时是23:00左右;

  • 至此,觉得问题已经解决了,在群里给大家说了下就回家了;

大写的尴尬

  • 刚刚坐上回家的车,收到同事消息说问题又出现了,es再次连接不上,状况和之前一样,这就尴尬了…

  • 带着郁闷回到家,在梦中问题再次解决,还是那熟悉的systemctl restart docker命令。。。

  • 以上就是问题的出现和第一轮处理的过程;

  • 第二天再次面对此问题;
  • 去google搜索的rpc error: code = 2 desc = containerd: container not found,发现有不少人遇到了类似问题;
  • 搜到的结果中,有的说重启docker解决,有的说升级docker,也有不少是抛出问题没有解决的;
  • 这个文章提供了有价值的信息,如下图,地址是: https://forums.docker.com/t/container-not-found-error/32303/4
Docker杀掉了容器?问题分析与解决过程全面复盘_java
  • 看来可能是内存系统内存不足,导致OOM Killer将elasticsearch进程杀掉,但是docker服务没有同步到这个信息,因此尽管进程不在了,但是docker ps可以看到,不过docker exec不会起作用,因为进程已经没了;

  • 执行命令egrep -i -r ‘killed process’ /var/log看看OOM Killer日志,有新发现,两次OOM导致进程被系统杀掉,时间上和es问题也吻合:

[admin@dev ~]$ sudo egrep -i -r 'killed process' /var/log
/var/log/messages:Mar 25 17:08:42 dev kernel: Killed process 12385 (controller) total-vm:72068kB, anon-rss:644kB, file-rss:0kB
/var/log/messages:Mar 25 17:08:42 dev kernel: Killed process 11887 (java) total-vm:44440740kB, anon-rss:10786220kB, file-rss:0kB
/var/log/messages:Mar 25 23:13:05 dev kernel: Killed process 43011 (controller) total-vm:72068kB, anon-rss:640kB, file-rss:0kB
/var/log/messages:Mar 25 23:13:12 dev kernel: Killed process 36316 (java) total-vm:44448156kB, anon-rss:11088004kB, file-rss:0kB
/var/log/secure:Mar 26 08:48:49 dev sudo:   admin : TTY=pts/9 ; PWD=/home/admin ; USER=root ; COMMAND=/bin/egrep -i -r killed process /var/log
  • 执行命令dmesg|grep memory看也有记录,进程ID和egrep查到的是同一个,如下:
[   17.644157] Freeing initrd memory: 19872k freed
[   17.749669] Non-volatile memory driver v1.3
[   17.749834] crash memory driver: version 1.1
[   18.833237] Freeing unused kernel memory: 1620k freed
[   19.279518] [TTM] Zone  kernel: Available graphics memory: 65870004 kiB
[   19.279520] [TTM] Zone   dma32: Available graphics memory: 2097152 kiB
[245831.555024]  [<ffffffff8116d616>] out_of_memory+0x4b6/0x4f0
[245831.555827] Out of memory: Kill process 11887 (java) score 99 or sacrifice child
[245831.560069]  [<ffffffff8116d616>] out_of_memory+0x4b6/0x4f0
[245831.560791] Out of memory: Kill process 20406 (java) score 99 or sacrifice child
[267649.159340]  [<ffffffff8116d616>] out_of_memory+0x4b6/0x4f0
[267649.160478] Out of memory: Kill process 36316 (java) score 97 or sacrifice child
[267651.140770]  [<ffffffff8116d616>] out_of_memory+0x4b6/0x4f0
[267651.142104] Out of memory: Kill process 36316 (java) score 97 or sacrifice child
  • 所以可以基本确定是内存不足导致OOM Killer杀掉了elasticsearch进程,用top看看当前内存情况,发现128G内存几乎已经耗尽:
[admin@dev ~]$ top
top - 09:24:40 up 3 days, 12:30,  6 users,  load average: 2.02, 1.83, 1.79
Tasks: 814 total,   1 running, 812 sleeping,   0 stopped,   1 zombie
%Cpu(s):  1.0 us,  0.7 sy,  0.0 ni, 98.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 13174000+total, 13239316 free, 11658065+used,  1920036 buff/cache
KiB Swap:  4194300 total,  2515328 free,  1678972 used. 14449396 avail Mem


  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
19816 admin     20   0 41.774g 0.012t   6396 S   1.0  9.5 159:22.23 java
19389 admin     20   0 40.963g 0.010t   6360 S   1.0  8.6  96:36.80 java
18464 admin     20   0 41.804g 8.216g   6460 S   0.7  6.5 157:01.02 java
18751 admin     20   0 41.829g 7.692g   6364 S   1.3  6.1  98:26.24 java
24233 admin     20   0 37.290g 7.543g   6616 S   0.7  6.0  22:41.94 java
19671 admin     20   0 32.509g 7.314g   6392 S   0.7  5.8  58:14.12 java
9466 admin     20   0 32.105g 7.300g   6628 S   1.0  5.8  18:41.46 java
  • 接下来的事情就简单了,根据进程ID检查耗内存大的进程的身份,最终确定有5个java进程的启动参数配置不当,都是10G,一下子用掉了50G内存,导致系统内存不足,于是调整它们的启动内存再依次重启,然后重启docker,重建es容器,运行了一天时间,一切正常;

  • 至此,问题已经修复,为什么系统内存耗尽后OOM Killer杀掉的是elasticsearch进程(连续两次都是),可以参考内核的源码linux/mm/oom_kill.c,里面的oom_badness方法,方法注释中说了,调出最耗内存的进程杀掉,如下图,我们的机器上elasticsearch占用了32G内存,就是最耗内存的那个,所以次次都是它了:

Docker杀掉了容器?问题分析与解决过程全面复盘_java_02
  • 以上就是整个问题的复盘过程,如果您也遇到类似问题,希望本文能给您提供一些参考;

欢迎关注51CTO博客:程序员欣宸

 学习路上,你不孤单,欣宸原创一路相伴…


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK