最近碰到一个棘手的问题,一台CentOS云主机的ip地址在运行一段时间后,总是莫名奇妙的消失,导致主机无法登录和访问,只能通过vnc控制台恢复,经过调查后发现,该主机的dhclient服务被杀掉,进一步研究ifup-eth代码发现,如果不设置PERSISTENT_DHCLIENT参数,那么dhclient服务启动的时候会默认采用-1参数,导致dhclient服务被杀死后,ip地址也随后被释放。
if [ -n "${DYNCONFIG}" ] && [ -x /sbin/dhclient ]; then
if is_true "${PERSISTENT_DHCLIENT}"; then
ONESHOT="";
else
ONESHOT="-1";
fi;
generate_config_file_name
generate_lease_file_name
# Initialize the dhclient args and obtain the hostname options if needed:
DHCLIENTARGS="${DHCLIENTARGS} ${ONESHOT} -q ${DHCLIENTCONF} -lf ${LEASEFILE} -pf /var/run/dhclient-${DEVICE}.pid"
为了解决这个问题,我们修改了ifcfg-eth0文件,添加了PERSISTENT_DHCLIENT参数。同时,我一直很好奇到底dhclient是如何被杀死的,但是却一直找不到简单有效的工具来跟踪系统信号,特别是SIGKILL。
killsnoop
killsnoop是Netflix大神Brendan Gregg写的perf-tools工具中的一个子工具,可以用来trace系统中的各种kill事件,对低版本的Linux支持也比较好,使用起来也非常简单。
安装
wget https://raw.githubusercontent.com/brendangregg/perf-tools/master/killsnoop
chmod +x killsnoop
试用
打开终端1,执行killsnoop, 默认它会跟踪系统所有的kill事件:
./killsnoop
打开终端2,执行一个长任务,比如sleep
sleep 120
打开终端3, 用SIGKILL杀死终端2上的 sleep
[root@hluo ~]# ps -ef|grep sleep
root 15318 15284 0 23:20 pts/1 00:00:00 sleep 120
root 15358 15328 0 23:20 pts/2 00:00:00 grep --color=auto sleep
[root@hluo ~]# kill -9 15318
然后我们在killsnoop所在的终端1上会看到如下输出,说明sleep进程被bash进程15328杀死了。
[root@hluo ~]# ./killsnoop
Tracing kill()s. Ctrl-C to end.
COMM PID TPID SIGNAL RETURN
bash 15328 15318 9 0
把killsnoop跑在后台,用-p参数指定需要跟踪的进程,比如dhclient, 用-t指定显示时间戳,就可以知道到底是谁在什么时候杀死了dhclient了。
killsnoop -t -p pidof(dhclient)