运行命令变成僵尸后,Docker容器拒绝被杀死

首先是第一件事。 我的系统信息和版本:

$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 13.04 Release: 13.04 Codename: raring $ sudo docker version Client version: 0.9.0 Go version (client): go1.2.1 Git commit (client): 2b3fdf2 Server version: 0.9.0 Git commit (server): 2b3fdf2 Go version (server): go1.2.1 $ lxc-version lxc version: 0.9.0 $ uname -a Linux ip-10-0-2-86 3.8.0-19-generic #29-Ubuntu SMP Wed Apr 17 18:16:28 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux 

里面的过程变成僵尸后,我无法阻止一个容器。 升级到docker 0.9.0后,我的服务器上出现了大量的僵尸。 例:

 $ ps axo stat,ppid,pid,comm | grep -w defunct Zl 25327 25332 node <defunct> $ pstree -p init(1)─┬ ├─sh(819)───docker(831)─┬ ├─lxc-start(25327)───node(25332)───{node}(25378) 

我可以看到lxc-start(25327)没有调用节点进程25332上的wait()以保持僵尸活着。 所以我查了一下strace在干什么,好像是被epoll_wait卡住了。 stract实际上被卡住了,只是显示了这一点:

 $sudo strace -ir -ttt -T -v -p 25327 Process 25327 attached - interrupt to quit (when asked to kill) 0.000103 [ 7fe59b9d34b3] epoll_wait(8, 

但是在我运行sudo docker kill 3da5764b7bc9358后,我得到了更多的输出:

  0.000103 [ 7fe59b9d34b3] epoll_wait(8, {{EPOLLIN, {u32=21673408, u64=21673408}}}, 10, 4294967295) = 1 <8.935002> 8.935097 [ 7fe59bcaff60] accept(4, 0, NULL) = 9 <0.000035> 0.000095 [ 7fe59bcafeb3] fcntl(9, F_SETFD, FD_CLOEXEC) = 0 <0.000027> 0.000083 [ 7fe59b9d401a] setsockopt(9, SOL_SOCKET, SO_PASSCRED, [1], 4) = 0 <0.000027> 0.000089 [ 7fe59b9d347a] epoll_ctl(8, EPOLL_CTL_ADD, 9, {EPOLLIN, {u32=21673472, u64=21673472}}) = 0 <0.000023> 0.000087 [ 7fe59b9d34b3] epoll_wait(8, {{EPOLLIN, {u32=21673472, u64=21673472}}}, 10, 4294967295) = 1 <0.000026> 0.000090 [ 7fe59bcb0130] recvmsg(9, {msg_name(0)=NULL, msg_iov(1)=[{"\3\0\0\0\0\0\0\0", 8}], msg_controllen=32, {cmsg_len=28, cmsg_level=SOL_SOCKET, cmsg_type=SCM_CREDENTIALS{pid=773, uid=0, gid=0}}, msg_flags=0}, 0) = 8 <0.000034> 0.000128 [ 7fe59bcb019d] sendto(9, "\0\0\0\0\0\0\0\0\364b\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 24, 0, NULL, 0) = 24 <0.000029> 0.000090 [ 7fe59b9d34b3] epoll_wait(8, {{EPOLLIN|EPOLLHUP, {u32=21673472, u64=21673472}}}, 10, 4294967295) = 1 <0.000018> 0.000091 [ 7fe59bcb0130] recvmsg(9, {msg_name(0)=NULL, msg_iov(1)=[{"\3\0\0\0\0\0\0\0", 8}], msg_controllen=32, {cmsg_len=28, cmsg_level=SOL_SOCKET, cmsg_type=SCM_CREDENTIALS{pid=0, uid=0, gid=0}}, msg_flags=0}, 0) = 0 <0.000026> 0.000122 [ 7fe59b9d347a] epoll_ctl(8, EPOLL_CTL_DEL, 9, NULL) = 0 <0.000037> 0.000084 [ 7fe59bcafd00] close(9) = 0 <0.000048> 0.000103 [ 7fe59b9d34b3] epoll_wait(8, {{EPOLLIN, {u32=21673408, u64=21673408}}}, 10, 4294967295) = 1 <1.091839> 1.091916 [ 7fe59bcaff60] accept(4, 0, NULL) = 9 <0.000035> 0.000093 [ 7fe59bcafeb3] fcntl(9, F_SETFD, FD_CLOEXEC) = 0 <0.000027> 0.000083 [ 7fe59b9d401a] setsockopt(9, SOL_SOCKET, SO_PASSCRED, [1], 4) = 0 <0.000026> 0.000090 [ 7fe59b9d347a] epoll_ctl(8, EPOLL_CTL_ADD, 9, {EPOLLIN, {u32=21673504, u64=21673504}}) = 0 <0.000032> 0.000100 [ 7fe59b9d34b3] epoll_wait(8, {{EPOLLIN, {u32=21673504, u64=21673504}}}, 10, 4294967295) = 1 <0.000028> 0.000088 [ 7fe59bcb0130] recvmsg(9, {msg_name(0)=NULL, msg_iov(1)=[{"\3\0\0\0\0\0\0\0", 8}], msg_controllen=32, {cmsg_len=28, cmsg_level=SOL_SOCKET, cmsg_type=SCM_CREDENTIALS{pid=774, uid=0, gid=0}}, msg_flags=0}, 0) = 8 <0.000030> 0.000125 [ 7fe59bcb019d] sendto(9, "\0\0\0\0\0\0\0\0\364b\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 24, 0, NULL, 0) = 24 <0.000032> 0.000119 [ 7fe59b9d34b3] epoll_wait(8, {{EPOLLIN|EPOLLHUP, {u32=21673504, u64=21673504}}}, 10, 4294967295) = 1 <0.000071> 0.000139 [ 7fe59bcb0130] recvmsg(9, {msg_name(0)=NULL, msg_iov(1)=[{"\3\0\0\0\0\0\0\0", 8}], msg_controllen=32, {cmsg_len=28, cmsg_level=SOL_SOCKET, cmsg_type=SCM_CREDENTIALS{pid=0, uid=0, gid=0}}, msg_flags=0}, 0) = 0 <0.000018> 0.000112 [ 7fe59b9d347a] epoll_ctl(8, EPOLL_CTL_DEL, 9, NULL) = 0 <0.000028> 0.000076 [ 7fe59bcafd00] close(9) = 0 <0.000027> 0.000096 [ 7fe59b9d34b3] epoll_wait(8, 

然后我看着epoll_wait在等待什么样的文件8(我从epoll_wait(8, {{EPOLLIN, {u32=21673408, u64=21673408}}}, 10, 4294967295) = 1 <8.935002> int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

 $ cat /proc/25327/fdinfo/8 pos: 0 flags: 02000002 tfd: 7 events: 19 data: 14ab830 tfd: 4 events: 19 data: 14ab5c0 

还要根据上面的tfd添加7和4(不确定tfd的真正含义)

 $ cat /proc/25327/fdinfo/4 pos: 0 flags: 02000002 $ cat /proc/25327/fdinfo/7 pos: 0 flags: 02000002 sigmask: fffffffe7ffbfab7 $ cd /proc/25327/fd $ ls -al lr-x------ 1 root root 64 Mar 13 22:28 0 -> /dev/null lrwx------ 1 root root 64 Mar 13 22:28 1 -> /dev/pts/17 lrwx------ 1 root root 64 Mar 13 22:28 2 -> /dev/pts/17 l-wx------ 1 root root 64 Mar 13 22:28 3 -> /var/log/lxc/3da5764b7bc935896a72abc9371ce68d4d658d8c70b56e1090aacb631080ec0e.log lrwx------ 1 root root 64 Mar 13 22:28 4 -> socket:[48415] lrwx------ 1 root root 64 Mar 14 00:03 5 -> /dev/ptmx lrwx------ 1 root root 64 Mar 14 00:03 6 -> /dev/pts/18 lrwx------ 1 root root 64 Mar 14 00:03 7 -> anon_inode:[signalfd] lrwx------ 1 root root 64 Mar 14 00:03 8 -> anon_inode:[eventpoll] 

有关socket的信息:

 $ sudo netstat -anp | grep 48415 Proto RefCnt Flags Type State I-Node PID/Program name Path unix 2 [ ACC ] STREAM LISTENING 48415 25327/lxc-start @/var/lib/lxc/3da5764b7bc935896a72abc9371ce68d4d658d8c70b56e1090aacb631080ec0e/command 

在docker.log中似乎有一个共同的模式,所有不停止的容器都有这个签名:

 2014/03/16 16:33:15 Container beb71548b3b23ba3337ca30c6c2efcbfcaf19d4638cf3d5ec5b8a3e4c5f1059a failed to exit within 0 seconds of SIGTERM - using the force 2014/03/16 16:33:25 Container SIGKILL failed to exit within 10 seconds of lxc-kill beb71548b3b2 - trying direct SIGKILL 

此时我不知道下一步该怎么做。 任何build议如何我可以找出是什么导致这些容器不能退出? 我应该收集的任何其他数据? 我也向这个过程发送了一个SIGCHLD,但没有成功。

更多的数据:添加日志到节点进程结束,我们开始使用容器中的start命令:

 Mon Mar 17 2014 20:52:52 GMT+0000 (UTC) process: main process = exit code: 0 

这里是docker的日志:

 2014/03/17 20:52:52 Container f8a3d55e0f... failed to exit within 0 seconds of SIGTERM - using the force 2014/03/17 20:53:02 Container SIGKILL failed to exit within 10 seconds of lxc-kill f8a3d55e0fd8 - trying direct SIGKILL 

时间戳显示进程已退出@ 20:52:52

这使用本地和lxc泊坞窗驱动程序。

编辑:复制步骤!

把它变成一个bash脚本并运行,看几乎50%的容器变成僵尸!

 CNT=0 while true do echo $CNT DOCK=$(sudo docker run -d -t anandkumarpatel/zombie_bug ./node index.js) sleep 60 && sudo docker stop $DOCK > out.log & sleep 1 CNT=$(($CNT+1)) if [[ "$CNT" == "50" ]]; then exit fi done 

Solutions Collecting From Web of "运行命令变成僵尸后,Docker容器拒绝被杀死"

更改为最新的内核修复了这个问题

发现确切的内核差异:
REPRO:linux-image-3.8.0-31-generic
NO REPRO:linux-image-3.8.0-32-generic

我认为这是修复:

 +++ linux-3.8.0/kernel/pid_namespace.c @@ -181,6 +181,7 @@ int nr; int rc; struct task_struct *task, *me = current; + int init_pids = thread_group_leader(me) ? 1 : 2; /* Don't allow any more processes into the pid namespace */ disable_pid_allocation(pid_ns); @@ -230,7 +231,7 @@ */ for (;;) { set_current_state(TASK_UNINTERRUPTIBLE); - if (pid_ns->nr_hashed == 1) + if (pid_ns->nr_hashed == init_pids) break; schedule(); } 

来自https://groups.google.com/forum/#!msg/fa.linux.kernel/u4b3n4oYDQ4/GuLrXfDIYggJ

去升级所有我们的服务器,这些服务器会重现这一点,看看它是否仍然存在。

在SLES 12 SP 1上观察不到Killable Docker容器(从3周开始运行)

docker exec -it命令下面的错误信息:

rpc error:code = 13 desc =无效的头字段值“oci运行时错误:exec失败:container_linux.go:247:启动容器进程导致\”process_linux.go:83:正在执行setns进程导致\\“退出状态16 \\ “\” \ n”

Linux内核:3.12.62-60.64.8-默认

Docker版本1.12.2,编译8eab29e