写点什么

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

作者:程序员欣宸
  • 2022 年 8 月 31 日
    广东
  • 本文字数:3347 字

    阅读完需:约 11 分钟

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

欢迎访问我的 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/log dmesg|grep memory 命令查看 OOM Killer 日志,确认是否存在进程被杀的情况;

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

问题复盘

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

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


[admin@dev ~]$ docker psCONTAINER ID        IMAGE                                                 COMMAND                  CREATED             STATUS              PORTS                     NAMESfbbcd0d7d57c        eshead                                                "/bin/sh -c 'cd ~/..."   10 hours ago        Up 10 hours         0.0.0.0:10300->9100/tcp   es-headef23574c0afe        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/bashrpc 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



  • 看来可能是内存系统内存不足,导致 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 ~]$ toptop - 09:24:40 up 3 days, 12:30,  6 users,  load average: 2.02, 1.83, 1.79Tasks: 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 stKiB Mem : 13174000+total, 13239316 free, 11658065+used,  1920036 buff/cacheKiB Swap:  4194300 total,  2515328 free,  1678972 used. 14449396 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND19816 admin 20 0 41.774g 0.012t 6396 S 1.0 9.5 159:22.23 java19389 admin 20 0 40.963g 0.010t 6360 S 1.0 8.6 96:36.80 java18464 admin 20 0 41.804g 8.216g 6460 S 0.7 6.5 157:01.02 java18751 admin 20 0 41.829g 7.692g 6364 S 1.3 6.1 98:26.24 java24233 admin 20 0 37.290g 7.543g 6616 S 0.7 6.0 22:41.94 java19671 admin 20 0 32.509g 7.314g 6392 S 0.7 5.8 58:14.12 java9466 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 内存,就是最耗内存的那个,所以次次都是它了:



  • 以上就是整个问题的复盘过程,如果您也遇到类似问题,希望本文能给您提供一些参考;

欢迎关注 InfoQ:程序员欣宸

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


发布于: 刚刚阅读数: 3
用户头像

搜索"程序员欣宸",一起畅游Java宇宙 2018.04.19 加入

前腾讯、前阿里员工,从事Java后台工作,对Docker和Kubernetes充满热爱,所有文章均为作者原创,个人Github:https://github.com/zq2599/blog_demos

评论

发布
暂无评论
Docker杀掉了容器?问题分析与解决过程全面复盘_Docker_程序员欣宸_InfoQ写作社区