J'ai construit une image de base à partir de Dockerfile nommée centos + ssh. Dans Dockerfile de centos + ssh, j'utilise CMD pour exécuter le service ssh.
Ensuite, je veux créer une image et exécuter un autre service nommé rabbitmq, le Dockerfile:
FROM centos+ssh
EXPOSE 22
EXPOSE 4149
CMD /opt/mq/sbin/rabbitmq-server start
Pour démarrer rabbitmq container , run :
docker run -d -p 222:22 -p 4149:4149 rabbitmq
mais le service ssh ne fonctionne pas, il semble que le Dockerfile CMD de rabbitmq écrase le CMD de centos.
- Comment CMD fonctionne-t-il dans l'image Docker?
- Si je veux exécuter plusieurs services, comment faire? Vous utilisez un superviseur?
Vous avez raison, le deuxième Dockerfile écrasera la
CMD
commande du premier. Docker exécutera toujours une seule commande, pas plus. Donc à la fin de votre Dockerfile, vous pouvez en spécifier un commande à exécuter. Pas plus.Mais vous pouvez exécuter les deux commandes sur une seule ligne:
Ce que vous pouvez également faire pour rendre votre Dockerfile un peu plus propre, vous pouvez placer vos commandes CMD dans un fichier supplémentaire:
Et un fichier comme celui-ci:
la source
&&
technique ne fonctionnera qu'avec des services non interactifs (qui peuvent démarrer en arrière-plan) sinon seul le premier fonctionnera.Bien que je respecte la réponse de qkrijger expliquant comment vous pouvez contourner ce problème, je pense que nous pouvons en apprendre beaucoup plus sur ce qui se passe ici ...
Pour répondre réellement à votre question de " pourquoi " ... Je pense qu'il serait utile pour vous de comprendre comment fonctionne la
docker stop
commande et que tous les processus doivent être arrêtés proprement pour éviter les problèmes lorsque vous essayez de les redémarrer (corruption de fichier, etc.).Problème: si docker a fait SSH début de la commande de ce et a commencé RabbitMQ de votre fichier Docker? " La commande docker stop tente d'abord d'arrêter un conteneur en cours d'exécution en envoyant un signal SIGTERM au processus racine (PID 1) dans le conteneur. " Quel processus est le suivi de docker en tant que PID 1 qui obtiendra le SIGTERM? Sera-ce SSH ou Rabbit ?? "Selon le modèle de processus Unix, le processus d'initialisation - PID 1 - hérite de tous les processus enfants orphelins et doit les récolter. La plupart des conteneurs Docker n'ont pas de processus d'initialisation qui le fait correctement, et par conséquent, leurs conteneurs se remplissent de processus zombies au fil du temps. "
Réponse: Docker prend simplement ce dernier CMD comme celui qui sera lancé en tant que processus racine avec le PID 1 et qui obtiendra le SIGTERM
docker stop
.Solution suggérée: vous devez utiliser (ou créer) une image de base spécialement conçue pour exécuter plus d'un service, tel que phusion / baseimage
Il devrait être important de noter que tini existe exactement pour cette raison, et à partir de Docker 1.13 et plus, tini fait officiellement partie de Docker, ce qui nous dit que l'exécution de plus d'un processus dans Docker EST VALIDE .. donc même si quelqu'un prétend être plus habile en ce qui concerne Docker, et insiste sur le fait que vous êtes absurde de penser à faire cela, sachez que vous ne l'êtes pas. Il existe des situations parfaitement valables pour cela.
Bon à savoir:
la source
La réponse officielle du docker à Exécuter plusieurs services dans un conteneur .
Il explique comment vous pouvez le faire avec un système init (systemd, sysvinit, upstart), un script (
CMD ./my_wrapper_script.sh
) ou un superviseur commesupervisord
.La
&&
solution de contournement ne peut fonctionner que pour les services qui démarrent en arrière-plan (démons) ou qui s'exécutent rapidement sans interaction et libèrent l'invite. Faire cela avec un service interactif (qui garde l'invite) et seul le premier service démarrera.la source
Pour expliquer pourquoi CMD est conçu pour n'exécuter qu'un seul service par conteneur, réalisons simplement ce qui se passerait si les serveurs secondaires exécutés dans le même conteneur ne sont pas triviaux / auxiliaires mais «majeurs» (par exemple, le stockage fourni avec l'application frontend). Pour commencer, cela décomposerait plusieurs fonctionnalités de conteneurisation importantes telles que la mise à l'échelle horizontale (automatique) et la replanification entre les nœuds, qui supposent toutes deux qu'il n'y a qu'une seule application (source de charge du processeur) par conteneur. Ensuite, il y a le problème des vulnérabilités - plus de serveurs exposés dans un conteneur signifie des correctifs plus fréquents des CVE ...
Admettons donc qu'il s'agit d'un `` coup de pouce '' des concepteurs de Docker (et Kubernetes / Openshift) vers les bonnes pratiques et nous ne devons pas réinventer les solutions de contournement (SSH n'est pas nécessaire - nous avons
docker exec / kubectl exec / oc rsh
conçu pour le remplacer)./devops/447/why-it-is-recommended-to-run-only-one-process-in-a-container
la source