Eu corro um contêiner em segundo plano usando
docker run -d --name hadoop h_Service
sai rapidamente. Mas se eu correr em primeiro plano, funciona bem. Eu verifiquei logs usando
docker logs hadoop
não houve erro. Alguma ideia?
DOCKERFILE
FROM java_ubuntu_new
RUN wget http://archive.cloudera.com/cdh4/one-click-install/precise/amd64/cdh4-repository_1.0_all.deb
RUN dpkg -i cdh4-repository_1.0_all.deb
RUN curl -s http://archive.cloudera.com/cdh4/ubuntu/precise/amd64/cdh/archive.key | apt-key add -
RUN apt-get update
RUN apt-get install -y hadoop-0.20-conf-pseudo
RUN dpkg -L hadoop-0.20-conf-pseudo
USER hdfs
RUN hdfs namenode -format
USER root
RUN apt-get install -y sudo
ADD . /usr/local/
RUN chmod 777 /usr/local/start-all.sh
CMD ["/usr/local/start-all.sh"]
start-all.sh
#!/usr/bin/env bash
/etc/init.d/hadoop-hdfs-namenode start
/etc/init.d/hadoop-hdfs-datanode start
/etc/init.d/hadoop-hdfs-secondarynamenode start
/etc/init.d/hadoop-0.20-mapreduce-tasktracker start
sudo -u hdfs hadoop fs -chmod 777 /
/etc/init.d/hadoop-0.20-mapreduce-jobtracker start
/bin/bash
chmod 777
é insegura e errado. Você deve reverter para permissões sãs (provavelmente 755 neste caso).Respostas:
Um contêiner de docker sai quando o processo principal é concluído.
Nesse caso, ele será encerrado quando o
start-all.sh
script terminar. Eu não sei o suficiente sobre o hadoop para dizer como fazê-lo nesse caso, mas você precisa deixar algo em execução em primeiro plano ou usar um gerenciador de processos como runit ou supervisord para executar os processos.Eu acho que você deve estar enganado sobre isso funcionando se você não especificar
-d
; deve ter exatamente o mesmo efeito. Eu suspeito que você o lançou com um comando ou uso ligeiramente diferente, o-it
que mudará as coisas.Uma solução simples pode ser adicionar algo como:
while true; do sleep 1000; done
até o final do script. No entanto, não gosto disso, pois o script deve realmente monitorar os processos que ele iniciou.
(Devo dizer que eu roubei esse código de https://github.com/sequenceiq/hadoop-docker/blob/master/bootstrap.sh )
fonte
Isso fez o truque para mim:
Depois disso, verifiquei os processos em execução usando:
Para prender novamente o contêiner
DICA: Para sair sem parar o tipo de contêiner:
^P^Q
fonte
-dit
é apenas uma abreviação #-di
é o mínimo necessário, a-t
opção é redundante quando usado com-d
se eu entendi corretamente-t
habilitar ... mas como eu costumo fazerexec
uma nova festança toda vez que não percebo. Eu tive problemas destacando a partir de um Mac, mas talvez eu estou fazendo isso errado ..Gostaria de estender ou ousar dizer, melhorar a resposta mencionada por camposer
Quando você corre
você está basicamente executando o contêiner em segundo plano no modo interativo.
Quando você anexa e sai do contêiner por CTRL + D (maneira mais comum de fazer isso), você para o contêiner porque acabou de interromper o processo principal no qual iniciou o contêiner com o comando acima.
Tirando proveito de um contêiner já em execução, eu apenas bifurcaria outro processo de bash e obteria um pseudo TTY executando:
fonte
sempre que eu quiser que um contêiner fique acordado depois de terminar a execução do script, eu adiciono
no final do comando. Então deve ser:
fonte
Se você deseja forçar a imagem a ficar por aí (para depurar algo ou examinar o estado do sistema de arquivos), você pode substituir o ponto de entrada para alterá-lo para um shell:
fonte
Uma boa abordagem seria iniciar seus processos e serviços executando-os em segundo plano e usar o
wait [n ...]
comando no final do seu script. No bash, o comando wait força o processo atual a:Eu peguei essa idéia no script inicial de Sébastien Pujadas para a construção de seu alce .
Partindo da pergunta original, seu start-all.sh ficaria assim:
fonte
Adicione isso ao final do Dockerfile:
Arquivo Docker de amostra:
Referência
fonte
CMD tail -f /dev/null
executa issosh -c "..."
. Emexec
vez disso, podemos usar o formulário? Ou sejaCMD ["tail", "-f", "/dev/null"]
Minha prática é que no Dockerfile inicie um shell que não saia imediatamente
CMD [ "sh", "-c", "service ssh start; bash"]
e executedocker run -dit image_name
. Dessa forma, o serviço (ssh) e o contêiner estão em execução.fonte
Eu adicionei a
read
declaração do shell no final. Isso mantém o processo principal do contêiner - script do shell de inicialização - em execução.fonte
Adicionando
no final do meu script de shell foi a minha correção!
fonte
Se você verificar o Dockerfile a partir de contêineres, por exemplo, fballiano / magento2-apache-php
você verá que no final de seu arquivo ele adiciona o seguinte comando: while true; dorme 1; feito
Agora, o que eu recomendo é que você faça isso
Em seguida, você verá se a imagem do docker teve um erro, se sair com 0, provavelmente precisará de um desses comandos que durará para sempre.
fonte
Existem muitas maneiras possíveis de fazer com que uma janela de encaixe saia imediatamente. Para mim, foi o problema com o meu
Dockerfile
. Houve um erro nesse arquivo. Eu tinha emENTRYPOINT ["dotnet", "M4Movie_Api.dll]
vez deENTRYPOINT ["dotnet", "M4Movie_Api.dll"]
. Como você pode ver, perdi uma citação (") no final.Para analisar o problema, iniciei meu contêiner e rapidamente o anexei para que eu pudesse ver qual era o problema exato.
Onde 4ea373efa21b é o meu ID de contêiner. Isso me leva ao problema real.
Depois de encontrar o problema, tive que criar, restaurar, publicar meu contêiner novamente.
fonte
Vindo de duplicatas, não vejo nenhuma resposta aqui que lide com o antipadrão muito comum de executar sua carga de trabalho principal como um trabalho em segundo plano, e depois me pergunto por que o Docker sai.
Em termos simples, se você tiver
em seguida, retire o
&
para executar o trabalho em primeiro plano ou adicioneno final do script, para aguardar todos os trabalhos em segundo plano.
Ele ainda será encerrado se a carga de trabalho principal terminar, portanto, talvez execute isso em
while true
loop para forçá-lo a reiniciar para sempre:(Observe também como escrever
while true
. É comum ver coisas tolas comowhile [ true ]
ouwhile [ 1 ]
que por acaso funcionam, mas não significa o que o autor provavelmente imaginou que deveria significar.)fonte
Você precisa executá-lo com o sinalizador -d para deixá-lo em execução como daemon em segundo plano.
fonte
Você pode executar o contêiner usando este sinalizador de reinicialização.
fonte
Como a imagem é linux, é preciso verificar se os scripts de shell usados no contêiner possuem finais de linha unix. Se eles tiverem um ^ M no final, serão finais de linha do Windows. Uma maneira de corrigi-los é com o dos2unix em /usr/local/start-all.sh para convertê-los do Windows para o Unix. A execução da janela de encaixe no modo interativo pode ajudar a descobrir outros problemas. Você pode ter um erro de digitação do nome do arquivo ou algo assim. consulte https://en.wikipedia.org/wiki/Newline
fonte