【问题标题】:Docker container refuses to get killed after run command turns into a zombieDocker容器在run命令变成僵尸后拒绝被杀死
【发布时间】:2014-04-20 05:59:39
【问题描述】:

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

$ 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 &lt;8.935002&gt; 猜测,其格式为 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]

关于套接字的信息:

$ 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

此时我不知道下一步该做什么。关于如何找出导致这些容器不退出的原因的任何建议?我应该收集任何其他数据吗?我还向这个进程发送了一个 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

timestamps show process exited @ 20:52:52

使用本机和 lxc docker 驱动程序都会发生这种情况。

编辑:重现步骤!

将其转换为 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

【问题讨论】:

  • 哇,这么多数据;感谢您收集这一切。我还有一个请求:您能添加您的内核版本吗?
  • 抱歉,错过了一件事:$ 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
  • 你能始终如一地重现这个吗?如果是,您能否提供一个展示该行为的 Dockerfile?
  • 这并不能持续重现,它在 370 次中发生了 55 次,并且仅在我们的生产系统上发生,这与我们的测试系统完全一样,只是缺少用户负载。
  • 但是日志中有一个共同的模式: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

标签: linux docker zombie-process lxc


【解决方案1】:

在 SLES 12 SP 1 上观察不可杀死的 Docker 容器(自 3 周以来一直在运行)

docker exec -it 命令出现以下错误消息:

rpc 错误:代码 = 13 desc = 无效的标头字段值“oci 运行时错误:执行失败:container_linux.go:247:启动容器进程 导致 \"process_linux.go:83: 执行 setns 进程导致 \\"exit 状态 16\\"\"\n"

Linux 内核:3.12.62-60.64.8-default

Docker 版本 1.12.2,构建 8eab29e

【讨论】:

  • 你能粘贴while exec命令吗?确保您已在映像上安装了您尝试创建的 shell。 (例如一些 docker 镜像没有 bash 因此不会启动
  • 很遗憾没有;我使用了 bash 并且在该图像中通常我运行 bash 脚本,这些脚本会运行,然后容器会被销毁(Jenkins 作业)。但是一旦移除容器就卡住了;不知道如何重现。我认为如果可能的话,最好有更多信息性错误消息语句给用户更多提示
【解决方案2】:

更换到最新的内核解决了这个问题

找到确切的内核差异:
REPRO:linux-image-3.8.0-31-generic
没有复制: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

将升级我们所有重现此问题的服务器,看看它是否仍然存在。

【讨论】:

  • 我在Linux ring-agent-7.labs.intellij.net 3.14.0-1.el6.elrepo.x86_64 #1 SMP Mon Mar 31 12:32:23 EDT 2014 x86_64 x86_64 x86_64 GNU/Linux 上重现问题,docker run 命令卡在 epoll_wait(4,...) 上
猜你喜欢
  • 2011-09-14
  • 1970-01-01
  • 1970-01-01
  • 2019-06-03
  • 2013-06-01
  • 2011-09-26
  • 2019-09-13
  • 2014-06-19
  • 1970-01-01
相关资源
最近更新 更多