linux - que - El contenedor Docker se niega a morir cuando el comando de ejecución se convierte en un zombi
que es docker (2)
primero lo primero. Información y versiones de mi sistema:
$ 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
No puedo detener un contenedor después de que el proceso en su interior se convierta en un zombie. Después de actualizar a docker 0.9.0, estaba viendo toneladas de zombies en mi servidor. ejemplo:
$ 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)
Puedo ver que lxc-start(25327)
no llama a wait () en el proceso del nodo 25332 manteniendo vivo al zombi. Así que comprobé lo que estaba haciendo con strace y parecía estar atascado en un epoll_wait
. Stract realmente se atasca al principio y solo muestra esto:
$sudo strace -ir -ttt -T -v -p 25327
Process 25327 attached - interrupt to quit (when asked to kill)
0.000103 [ 7fe59b9d34b3] epoll_wait(8,
pero después de ejecutar un sudo docker kill 3da5764b7bc9358 obtengo más salida:
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,
luego miré lo que esperaba epoll_wait que parece el archivo 8 (estoy adivinando esto de epoll_wait(8, {{EPOLLIN, {u32=21673408, u64=21673408}}}, 10, 4294967295) = 1 <8.935002>
que es de la forma 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
también agregando 7 y 4 basados en tfd arriba (no estoy seguro de lo que realmente significa 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]
información sobre el zócalo:
$ 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
Parece que hay un patrón común en el docker.log. Todos los contenedores que no se detienen tienen esta firma:
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
En este punto no tengo idea de qué hacer a continuación. ¿Alguna sugerencia sobre cómo puedo averiguar qué está causando que estos contenedores no salgan? ¿Algún otro dato que deba recopilar? También envié un SIGCHLD a este proceso sin ningún resultado.
más datos: registro agregado al final del proceso del nodo, comenzamos a usar el comando de inicio en el contenedor:
Mon Mar 17 2014 20:52:52 GMT+0000 (UTC) process: main process = exit code: 0
y aquí están los registros de la ventana acoplable:
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
Las marcas de tiempo muestran el proceso salido @ 20:52:52
Esto sucede utilizando controladores de docker nativos y lxc.
EDITAR: REPRO PASOS!
¡Convierta esto en un script de bash y ejecute y vea cómo casi el 50% de los contenedores se convierten en zombies!
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
Observando el contenedor Docker no killable en SLES 12 SP 1 (estuvo funcionando desde 3 semanas)
En el comando docker exec -it
siguiente mensaje de error:
error de rpc: código = 13 desc = valor de campo de encabezado no válido "oci runtime error: exec error: container_linux.go: 247: se inició el proceso de contenedor /" process_linux.go: 83: se ejecutó el proceso setns // "salir del estado 16 // "/"/norte"
Kernel de Linux: 3.12.62-60.64.8-predeterminado
Docker versión 1.12.2, compilación 8eab29e
cambiando a las últimas correcciones del kernel el problema
encontró la diferencia exacta del núcleo:
REPRO: linux-image-3.8.0-31-generic
NO REPRO: linux-image-3.8.0-32-generic
Creo que esta es la solución:
+++ 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();
}
que vino de aquí: https://groups.google.com/forum/#!msg/fa.linux.kernel/u4b3n4oYDQ4/GuLrXfDIYggJ
Vamos a actualizar todos nuestros servidores que reprodifican esto y ver si todavía ocurre.