run - docker-compose
Uso de Supervisor en Docker (2)
No estoy preguntando sobre el uso de supervisor con estibadores, pero solo quiero validar mi comprensión.
Entiendo que Docker ejecuta un solo proceso cuando se ejecuta. Además, el supervisor se usa cuando necesitamos ejecutar múltiples procesos dentro del contenedor.
He visto varios ejemplos en los que se inicia un contenedor desde la imagen base y se instalan varios servicios y el contenedor se compromete a formar una nueva imagen, todo sin supervisor.
Entonces, mi duda básica era cuál es la diferencia entre ambos enfoques.
Tengo entendido que cuando se detiene el contenedor Docker, envía una señal de interrupción al proceso con PID 1, el PID 1 administra el proceso secundario y detiene a todos los elementos secundarios, que es exactamente lo que hace el supervisor, mientras que podemos instalar varios procesos sin un solo supervisor. El proceso se puede ejecutar cuando se ejecuta la ejecución de
docker run
y cuando se detiene el contenedor, solo se enviarán señales al PID 1 y no se detendrá el otro proceso en ejecución correctamente.
Confirme cuánto es correcto mi entendimiento sobre el uso de
supervisord
.
Si bien podemos instalar varios procesos sin supervisor, solo se puede ejecutar un proceso cuando se ejecuta la ejecución de Docker y cuando se detiene el contenedor, solo se enviarán señales al PID 1 y no se detendrá con gracia el otro proceso en ejecución.
Sí, aunque depende de cómo se ejecute su proceso principal (en primer plano o en segundo plano), y cómo recopila los procesos secundarios.
Eso es lo que se detalla en " Señales de captura en contenedores Docker "
docker stop
detiene un contenedor en ejecución enviándole una señalSIGTERM
, deja que el proceso principal lo procese y, después de un período de gracia, usaSIGKILL
para finalizar la aplicación.La señal enviada al contenedor es manejada por el proceso principal que se está ejecutando (PID 1).
Si la aplicación está en primer plano, lo que significa que la aplicación es el proceso principal en un contenedor (PID1), podría manejar señales directamente.
Pero:
El proceso a señalar puede ser el de fondo y no puede enviar ninguna señal directamente. En este caso, una solución es configurar un shell-script como punto de entrada y organizar todo el procesamiento de la señal en ese script.
El problema se detalla más en " Docker y el problema de cosecha de zombis PID 1 "
Unix está diseñado de tal manera que los procesos primarios deben "esperar" explícitamente la finalización del proceso secundario, para recopilar su estado de salida. El proceso zombie existe hasta que el proceso padre haya realizado esta acción, utilizando la familia
waitpid()
de llamadas al sistema.La acción de llamar a waitpid () en un proceso hijo para eliminar a su zombie se llama "cosecha".
El proceso de
init
(PID 1) tiene una tarea especial. Su tarea es "adoptar" procesos secundarios huérfanos.
El sistema operativo espera que el proceso de inicio también coseche a los niños adoptados.
Problema con Docker:
Vemos que muchas personas ejecutan solo un proceso en su contenedor, y piensan que cuando ejecutan este único proceso, terminan.
Pero lo más probable es que este proceso no esté escrito para comportarse como un proceso de inicio adecuado.
Es decir, en lugar de cosechar adecuadamente los procesos adoptados, probablemente espera que otro proceso deinit
haga ese trabajo, y con razón.
El uso de una imagen como
phusion/baseimage-docker
ayuda a administrar uno (o varios) procesos mientras se mantiene un proceso principal compatible con init.
Utiliza
runit
lugar de
supervisord
, para la gestión multiproceso:
Runit no está allí para resolver el problema de la cosecha. Más bien, es para soportar múltiples procesos. Se recomiendan múltiples procesos por seguridad (a través del proceso y el aislamiento del usuario).
Runit usa menos memoria que Supervisord porque Runit está escrito en C y Supervisord en Python.
Y en algunos casos de uso, los reinicios del proceso en el contenedor son preferibles a los reinicios del contenedor completo.
Esa imagen incluye un
script
my_init
que se ocupa del problema de la "cosecha".
En baseimage-docker, alentamos a ejecutar múltiples procesos en un solo contenedor. Sin embargo, no necesariamente múltiples servicios.
Un servicio lógico puede consistir en múltiples procesos del sistema operativo, y proporcionamos las facilidades para hacerlo fácilmente.
Actualización de septiembre de 2016 para docker 1.12 (cuarto trimestre de 2016 / primer trimestre de 2017)
Arnaud Porterie simplemente twitted :
[🐳] Acaba de fusionarse: con
docker run --init
, Rick Grimes se encargará de todos tus zombies.
( cometer eabae09 )
Ver PR 26061 : " Agregar proceso de inicio para la lucha de zombies y manejo de señales " (y PR 26736 )
Esto agrega un pequeño binario en C para combatir zombies. Se monta bajo / dev / init y se antepone a los argumentos especificados por el usuario. Lo habilita a través de un indicador de demonio, dockerd --init, ya que está deshabilitado de forma predeterminada para la compatibilidad con versiones anteriores.
También puede anular la opción de daemon o especificar esto por contenedor con
docker run --init=true|false
.Puede probar esto ejecutando un proceso como este como el pid 1 en un contenedor y ver el zombie extra que aparece en el contenedor mientras se ejecuta.
int main(int argc, char ** argv) {
pid_t pid = fork();
if (pid == 0) {
pid = fork();
if (pid == 0) {
exit(0);
}
sleep(3);
exit(0);
}
printf("got pid %d and exited/n", pid);
sleep(20);
}
El Docker Daemon ahora tiene la opción
--init
Ejecute un init dentro de contenedores para reenviar señales y cosechar procesos