问题背景:某客户反馈ECS服务器上服务访问不到,导致业务异常,业务是通过单机Docker 部署的,但是目前发现docker 容器没有启动,start拉不起来,异常截图如下
问题排查:
1 从错误里面看是docker-shim去调用runc出现了异常,看起来是runc没有初始化成功,这个地方我想大家会有疑问,runc这个东西是干什么的,他在docker里面起到什么作用?
runc作为容器的运行时,现在作为独立的项目来进行发展,runc提供一套简单的容器运行环境,包括进程的命名空间、cgroups和文件系统权限等管理的功能,runc是基于oci标准的产物,可以让大家都通过统一的接口来进行运行时的操作。其本质的管理工作也是最主要的几个重要的函数clone,unshare和setns等重要的操作函数。
2 第二步就是验证下猜想runc没有拉起来,先把docker debug日志开启下,方法是:修改/etc/docker/daemon.json中增加"debug": true, 然后systemctl reload docker,完毕后执行 docker run -it --rm ubuntu echo OK 发现问题复现,并且看日志以及ps -aux |grep runc 看是为空的,证明runc没拉起来
3 继续过滤message日志,看下debug里面的输出,过滤runc的动作,并且搭配dmesg 打印内核级别的日志看,发现是run panic了
从提示的dumpd core里面看是libsystem.so这个库引发的, 其实我这个时候有点懵逼的,完全陷入知识盲区了,对于完全模式的组件没办法用原始最笨的方法 strace -e trace 去做追踪对比,其实这里之前得到一个非常有效的信息,就是用户机器被入侵了,虽然心理大概率敢肯定lib库被改了,让用户初始化,不过作为技术人员来说不拿出点证据总觉得缺点是什么!
问题总结:
经过多次strace 追踪对比,发现libsystem 库应用的不对,怎么去找ld.so.perload了!这个地方其实有点经验的意思了,之前处理过多次挖矿的问题,这个目录一般都是挖矿入侵创建的,找到异常库后,先注释,然后为了保险,先把ld.so.cache备份改名,ldconfig重新生成
动态库注释后,重启docker 相关容器已经拉起来了,重新捞日志发现panic现象消失,不过被入侵的机器里面很多库还是被改了,推荐考虑做好数据备份,重新初始化环境,然后做下安全加固