Eu construí uma imagem base do Dockerfile chamada centos + ssh. No Dockerfile do centos + ssh, eu uso o CMD para executar o serviço ssh.
Em seguida, quero criar uma imagem para executar outro serviço chamado rabbitmq, o Dockerfile:
FROM centos+ssh
EXPOSE 22
EXPOSE 4149
CMD /opt/mq/sbin/rabbitmq-server start
Para iniciar o contêiner rabbitmq, execute:
docker run -d -p 222:22 -p 4149:4149 rabbitmq
mas o serviço ssh não funciona, parece que o CMD do Dockerfile da rabbitmq substitui o CMD do centos.
- Como o CMD funciona dentro da imagem do docker?
- Se eu quiser executar vários serviços, como? Usando o supervisor?
Você está certo, o segundo Dockerfile irá sobrescrever o
CMD
comando do primeiro. O Docker sempre executará um único comando, não mais. Portanto, no final do seu Dockerfile, você pode especificar um comando a ser executado. Não mais.Mas você pode executar os dois comandos em uma linha:
O que você também pode fazer para tornar seu Dockerfile um pouco mais limpo, é colocar seus comandos CMD em um arquivo extra:
E um arquivo como este:
fonte
&&
A técnica funcionará apenas com serviços não interativos (que podem iniciar em segundo plano), caso contrário, apenas o primeiro será executado.Embora eu respeite a resposta do qkrijger explicando como você pode contornar esse problema, acho que podemos aprender muito mais sobre o que está acontecendo aqui ...
Para realmente responder à sua pergunta de " por que " ... acho que seria útil para você entender como o
docker stop
comando funciona e que todos os processos devem ser desligados de forma limpa para evitar problemas quando você tenta reiniciá-los (arquivo corrompido, etc.).Problema: E se estivador fez SSH início a partir dele do comando e começou RabbitMQ de seu arquivo Docker? " O comando docker stop tenta parar um contêiner em execução primeiro enviando um sinal SIGTERM para o processo raiz (PID 1) no contêiner. " Qual processo o docker está rastreando como PID 1 que obterá o SIGTERM? Será SSH ou Coelho ?? "De acordo com o modelo de processo Unix, o processo init - PID 1 - herda todos os processos filhos órfãos e deve colhê-los. A maioria dos contêineres Docker não tem um processo init que faz isso corretamente e, como resultado, seus contêineres ficam cheios de processos zumbis ao longo do tempo. "
Resposta: O Docker simplesmente pega o último CMD como aquele que será iniciado como o processo raiz com PID 1 e obterá o SIGTERM de
docker stop
.Solução sugerida: você deve usar (ou criar) uma imagem de base feita especificamente para executar mais de um serviço, como phusion / baseimage
Deve ser importante observar que o tini existe exatamente por esse motivo, e a partir do Docker 1.13 e superior, o tini é oficialmente parte do Docker, o que nos diz que a execução de mais de um processo no Docker É VÁLIDO .. então, mesmo que alguém afirme que seja mais habilidoso em relação ao Docker, e insista que você é absurdo por pensar em fazer isso, saiba que não é. Existem situações perfeitamente válidas para fazer isso.
Bom saber:
fonte
A resposta oficial do docker para Executar vários serviços em um contêiner .
Ele explica como você pode fazer isso com um sistema init (systemd, sysvinit, upstart), um script (
CMD ./my_wrapper_script.sh
) ou um supervisor semelhantesupervisord
.A
&&
solução alternativa pode funcionar apenas para serviços que começam em segundo plano (daemons) ou que serão executados rapidamente sem interação e liberarão o prompt. Fazendo isso com um serviço interativo (que mantém o prompt) e apenas o primeiro serviço será iniciado.fonte
Para entender por que o CMD foi projetado para executar apenas um serviço por contêiner, vamos apenas perceber o que aconteceria se os servidores secundários executados no mesmo contêiner não fossem triviais / auxiliares, mas "principais" (por exemplo, armazenamento empacotado com o aplicativo front-end). Para começar, ele quebraria vários recursos importantes de conteinerização, como escalonamento (auto) horizontal e reescalonamento entre nós, ambos assumindo que há apenas um aplicativo (fonte de carga da CPU) por contêiner. Depois, há a questão das vulnerabilidades - mais servidores expostos em um contêiner significa patching mais frequente de CVEs ...
Então, vamos admitir que é um 'empurrão' dos designers do Docker (e Kubernetes / Openshift) em direção às boas práticas e não devemos reinventar soluções alternativas (SSH não é necessário - nós
docker exec / kubectl exec / oc rsh
projetamos para substituí-lo)./devops/447/why-it-is-recommended-to-run-only-one-process-in-a-container
fonte