He creado una imagen base de Dockerfile llamada centos + ssh. En el Dockerfile de centos + ssh, uso CMD para ejecutar el servicio ssh.
Luego, quiero crear una imagen para ejecutar otro servicio llamado rabbitmq, el Dockerfile:
FROM centos+ssh
EXPOSE 22
EXPOSE 4149
CMD /opt/mq/sbin/rabbitmq-server start
Para iniciar el contenedor rabbitmq, ejecute :
docker run -d -p 222:22 -p 4149:4149 rabbitmq
pero el servicio ssh no funciona, parece que el CMD de Dockerfile de rabbitmq anula el CMD de centos.
- ¿Cómo funciona CMD dentro de la imagen de la ventana acoplable?
- Si quiero ejecutar varios servicios, ¿cómo? ¿Usando supervisor?
Tiene razón, el segundo Dockerfile sobrescribirá el
CMD
comando del primero. Docker siempre ejecutará un solo comando, no más. Entonces, al final de su Dockerfile, puede especificar uno comando para ejecutar. No mas.Pero puede ejecutar ambos comandos en una línea:
Lo que también puede hacer para hacer que su Dockerfile sea un poco más limpio, puede poner sus comandos CMD en un archivo adicional:
Y un archivo como este:
fuente
&&
La técnica funcionará solo con servicios no interactivos (que pueden comenzar en segundo plano); de lo contrario, solo se ejecutará el primero.Si bien respeto la respuesta de qkrijger explicando cómo puede solucionar este problema, creo que podemos aprender mucho más sobre lo que está sucediendo aquí ...
Para responder realmente a su pregunta de " por qué " ... creo que sería útil para usted comprender cómo funciona el
docker stop
comando y que todos los procesos deben cerrarse limpiamente para evitar problemas cuando intente reiniciarlos (corrupción de archivos, etc.).Problema: ¿Qué pasa si Docker hizo SSH inicio de ella de mando y comenzó RabbitMQ de su archivo estibador? " El comando de parada de la ventana acoplable intenta detener un contenedor en ejecución primero enviando una señal SIGTERM al proceso raíz (PID 1) en el contenedor " . ¿Qué proceso está siguiendo la ventana acoplable como PID 1 que obtendrá el SIGTERM? ¿Será SSH o Rabbit?"De acuerdo con el modelo de proceso Unix, el proceso init - PID 1 - hereda todos los procesos hijo huérfanos y debe cosecharlos. La mayoría de los contenedores Docker no tienen un proceso init que lo haga correctamente y, como resultado, sus contenedores se llenan con procesos zombies a lo largo del tiempo ".
Respuesta: Docker simplemente detiene última CMD como uno que conseguirá en marcha como el proceso de raíz con el PID 1 y obtener el SIGTERM de
docker stop
.Solución sugerida: debe usar (o crear) una imagen base creada específicamente para ejecutar más de un servicio, como phusion / baseimage
Debe ser importante tener en cuenta que tini existe exactamente por esta razón, y a partir de Docker 1.13 y versiones posteriores, tini es oficialmente parte de Docker, lo que nos dice que ejecutar más de un proceso en Docker ES VÁLIDO ... así que incluso si alguien afirma Ser más hábil con respecto a Docker, e insiste en que es absurdo pensar en hacer esto, sabe que no lo es. Hay situaciones perfectamente válidas para hacerlo.
Bueno saber:
fuente
La respuesta oficial de Docker para ejecutar múltiples servicios en un contenedor .
Explica cómo puede hacerlo con un sistema de inicio (systemd, sysvinit, upstart), un script (
CMD ./my_wrapper_script.sh
) o un supervisor comosupervisord
.La
&&
solución alternativa puede funcionar solo para los servicios que se inician en segundo plano (demonios) o que se ejecutarán rápidamente sin interacción y liberarán el mensaje. Haciendo esto con un servicio interactivo (que mantiene el mensaje) y solo se iniciará el primer servicio.fuente
Para abordar por qué CMD está diseñado para ejecutar solo un servicio por contenedor, vamos a darnos cuenta de lo que sucedería si los servidores secundarios que se ejecutan en el mismo contenedor no son triviales / auxiliares sino "principales" (por ejemplo, almacenamiento incluido con la aplicación frontend). Para empezar, desglosaría varias características importantes de contenedorización, como el escalado horizontal (auto) y la reprogramación entre nodos, que asumen que solo hay una aplicación (fuente de carga de CPU) por contenedor. Luego está el problema de las vulnerabilidades: más servidores expuestos en un contenedor significan parches más frecuentes de CVE ...
Así que admitamos que es un 'empujón' de los diseñadores de Docker (y Kubernetes / Openshift) hacia las buenas prácticas y no deberíamos reinventar las soluciones alternativas (SSH no es necesario, hemos
docker exec / kubectl exec / oc rsh
diseñado para reemplazarlo)./devops/447/why-it-is-recommended-to-run-only-one-process-in-a-container
fuente