run - docker-compose
¿Por qué no puedo usar Docker CMD varias veces para ejecutar múltiples servicios? (3)
Construí una imagen base de Dockerfile llamada centos + ssh. En el archivo Dockerfile de centos + ssh, uso CMD para ejecutar el servicio ssh.
Entonces quiero construir una imagen ejecute 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, ejecuta:
docker run -d -p 222:22 -p 4149:4149 rabbitmq
pero el servicio ssh no funciona, parece que el CMD Dockerfile de rabbitmq anula la CMD de centos.
- ¿Cómo funciona CMD dentro de la imagen del acoplador?
- Si quiero ejecutar un servicio múltiple, ¿cómo? ¿Usando el supervisor?
Aunque CMD está escrito en Dockerfile, realmente es información de tiempo de ejecución. Al igual que EXPOSE, pero al contrario de, por ejemplo, EJECUTAR y AGREGAR. Con esto, quiero decir que puedes anularlo más tarde, en un Dockerfile extendido, o simple en tu comando de ejecución, que es lo que estás experimentando. En todo momento, solo puede haber una CMD.
Si desea ejecutar múltiples servicios, de hecho usaría el supervisor. Puede crear un archivo de configuración de supervisor para cada servicio, AGREGAR estos en un directorio y ejecutar el supervisor con supervisord -c /etc/supervisor
para apuntar a un archivo de configuración de supervisor que carga todos sus servicios y se ve como
[supervisord]
nodaemon=true
[include]
files = /etc/supervisor/conf.d/*.conf
Si desea obtener más información, escribí un blog sobre este tema aquí: http://blog.trifork.com/2014/03/11/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance/
Si bien respeto la respuesta de qkrijger explicando cómo puede solucionar este problema, creo que hay mucho más que podemos aprender sobre lo que está sucediendo aquí ...
Para responder realmente a su pregunta de " por qué " ... creo que sería útil para usted entender cómo funciona el comando docker stop
y que todos los procesos deben cerrarse limpiamente para evitar problemas cuando intente reiniciarlos (corrupción de archivos, etc.) .
Problema: ¿Qué pasa si Docker inició SSH desde su comando e inició RabbitMQ desde su archivo Docker? " El comando docker stop intenta detener primero un contenedor en ejecución enviando una señal SIGTERM al proceso raíz (PID 1) en el contenedor " . ¿Qué proceso es el seguimiento del acoplador como PID 1 que obtendrá el SIGTERM? ¿Será SSH o Rabbit? "De acuerdo con el modelo de proceso de Unix, el proceso init - PID 1 - hereda todos los procesos secundarios huérfanos y debe cosecharlos. La mayoría de los contenedores Docker no tienen un proceso init que hace esto correctamente, y como resultado sus contenedores se llenan de zombie procesa con el tiempo ".
Respuesta: Docker simplemente toma la última CMD como la que se iniciará como el proceso raíz con PID 1 y obtendrá el SIGTERM de la 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
Bueno saber:
Tiene razón, el segundo archivo Docker sobrescribirá el comando CMD
del primero. Docker siempre ejecutará un solo comando, no más. Entonces, al final de su archivo Docker, puede especificar un comando para ejecutar. No mas.
Pero puedes ejecutar ambos comandos en una línea:
FROM centos+ssh
EXPOSE 22
EXPOSE 4149
CMD service sshd start && /opt/mq/sbin/rabbitmq-server start
Lo que también podrías hacer para que tu archivo Dockerfue un poco más limpio, podrías poner tus comandos CMD en un archivo adicional:
FROM centos+ssh
EXPOSE 22
EXPOSE 4149
CMD sh /home/centos/all_your_commands.sh
Y un archivo como este:
service sshd start &
/opt/mq/sbin/rabbitmq-server start