- A+
摘要: 大家好,今天跟大家分享一例有趣的问题。问题的有趣之处,在于它稍微有点曲折。处理这类问题,我们需要不断的提出一个个小的问题,然后通过解决这些小问题,最后解决原本的问题。
问题现象
服务器的CPU总是被init用掉30%左右,而且可以看到整个系统的sy占比相当之高。
问题处理过程
init进程在做什么?
首先,init进程作为Linux系统所有进程的父进程,负责系统的启动过程。这个进程使用CPU资源,我们第一个需要问自己的问题是,这个进程到底在做什么。
使用strace可以挂到正在运行的进程上,追踪进程的系统调用。通过阅读进程的系统调用,我们大概可以估计一下进程的行为。具体到这个问题,在strace日志中,会发现大量的进程退出的记录。下边是用SIGCHLD信号过滤过的strace日志。在这个截图里,我们可以看到,在一秒时间内,就有大量的进程退出。CLD_EXITED说明子进程退出。这绝对是一个非常不正常的状况。如此行为必然消耗大量CPU资源。
这些进程到底是什么?
知道init在不断的启停大量进程之后,我们自然而然的会问自己,这些进程到底是什么。找出这个问题的答案的方法可能有很多种,但是这里我用到了一种比较简单的方法,叫做auditing,简单点说,就是审计和记录系统一些关键操作。
我们开启audit之后,会在/var/log/audit/目录里快速生成很多日志文件,通过分析和过滤,发现大量被启停的进程是atd。syscall=2对应fork系统调用。
另外用ls命令不断的刷新/proc目录,我们也可以看到进程短时间被大量启停的迹象。
atd被不断的启停导致init使用CPU高?
目前我们知道了,init进程在不断的atd进程,基本上我们已经有了一个阶段性的结论。我们简单验证一下这个结论。
把/usr/bin/atd重命名为/usr/bin/atd.backup,重启系统,问题不再发生。
为什么atd被不断的启停?
init启动atd的基本方式是,如果atd退出,那么atd会被重启。这个可以在atd.conf文件中看到。所以开始猜测的情况是,因为atd不正常退出,所以被init重复启动。所以方向放在了调试atd非正常退出上。结果用strace追踪,并没有发现太多有用的信息。最后我把方向转向了ltrace。用ltrace追踪atd的启动过程,我发现这个进程会fork一个子进程,然后这个子进程又会重复父进程的行为,直到无穷。这是一个非常有趣的现象。
atd的bug?
这个时候,很自然的,我会认为这是atd的一个bug,而这个bug在客户机器环境中被触发出来。
但是这个时候我发现另外一个不和逻辑的地方,我明明把atd重命名为atd.backup,但是机器重启之后,依然有atd这个进程存在,而且CPU问题不在了!
顺手用which命令查了一下atd,发现这次正在运行的atd命令是usr/sbin/atd,而不是/usr/bin/atd。这两个文件大小完全不同。
root@iZ2ze322qa55cmibwpd2zeZ:~# ls -al /usr/bin/atd.backup -rwx--x--x 1 root root 2443616 Feb 20 2017 /usr/bin/atd.backup root@iZ2ze322qa55cmibwpd2zeZ:~# ls -al /usr/sbin/atd -rwxr-xr-x 1 root root 22544 Oct 21 2013 /usr/sbin/atd
而且/usr/bin/atd这个文件,并属于at这个package。
root@iZ2ze322qa55cmibwpd2zeZ:~# dpkg -L at /. /lib /lib/systemd /lib/systemd/system /lib/systemd/system/atd.service /usr /usr/share /usr/share/man /usr/share/man/man8 /usr/share/man/man8/atd.8.gz /usr/share/man/man5 /usr/share/man/man5/at.allow.5.gz /usr/share/man/man1 /usr/share/man/man1/at.1.gz /usr/share/doc /usr/share/doc/at /usr/share/doc/at/README /usr/share/doc/at/copyright /usr/share/doc/at/Problems /usr/share/doc/at/changelog.Debian.gz /usr/share/doc/at/timespec /usr/sbin /usr/sbin/atd /usr/bin /usr/bin/at /usr/bin/batch /etc /etc/init.d /etc/init.d/atd /etc/at.deny /etc/pam.d /etc/pam.d/atd /etc/init /etc/init/atd.conf /var /var/spool /var/spool/cron /var/spool/cron/atjobs /var/spool/cron/atspool /usr/share/man/man5/at.deny.5.gz /usr/share/man/man1/atrm.1.gz /usr/share/man/man1/batch.1.gz /usr/share/man/man1/atq.1.gz /usr/bin/atq /usr/bin/atrm
结论&建议
目前这种状况,建议重新安装系统,同时可以请安全团队进一步核实这个文件的来源。
- 安卓客户端下载
- 微信扫一扫
- 微信公众号
- 微信公众号扫一扫