2015-01-29 18 views
92

Ich betreibe einen Container in derWarum Behälter Docker verlässt sofort

docker run -d --name hadoop h_Service 

es schnell verlässt mit Hintergrund. Aber wenn ich in den Vordergrund renne, funktioniert es gut. Ich überprüfte Protokolle mit

docker logs hadoop 

gab es keinen Fehler. Irgendwelche Ideen?

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 
+0

können Sie uns Ihre Dockerfile und den kompletten Laufbefehl zeigen? – user2915097

+0

Ich werde bearbeiten und zeigen Sie Docker-Datei. Ich habe Ihnen bereits Befehl –

+0

zur Verfügung gestellt Die goldene Regel ist, dass Sie Ihre dockerized Server von Daemonizing verhindern sollten. Die meisten Server-Pakete haben Optionen, um sie in den Vordergrund zu zwingen, da die Daemonisierung der Normalfall ist. –

Antwort

51

A Andockfensters Ausfahrten Behälter, wenn sein Hauptprozess beendet. In diesem Fall wird es beendet, wenn Ihr start-all.sh Skript endet. Ich weiß nicht genug über hadoop, um Ihnen zu sagen, wie es in diesem Fall geht, aber Sie müssen entweder etwas im Vordergrund laufen lassen oder einen Prozessmanager wie runit oder supervisord verwenden, um die Prozesse auszuführen.

Ich denke, Sie müssen sich irren, wenn es funktioniert, wenn Sie nicht angeben -d; Es sollte genau den gleichen Effekt haben. Ich vermute, dass Sie es mit einem etwas anderen Befehl gestartet haben oder -it verwenden, was die Dinge ändern wird.

while true; do sleep 1000; done

bis zum Ende des Skripts:

Eine einfache Lösung kann so etwas hinzuzufügen sein. Ich mag das jedoch nicht, da das Skript die Prozesse, die es ausgelöst hat, wirklich überwachen sollte.

(Ich sollte sagen, dass ich diesen Code aus https://github.com/sequenceiq/hadoop-docker/blob/master/bootstrap.sh stahl)

93

Dies hat den Trick für mich:

docker run -dit ubuntu 

Nachdem es kann ich sah, wie die Prozesse laufen:

docker ps -a 

Zum erneuten Anbringen des Behälters

docker attach CONTAINER_NAME 

TIPP: ohne Verlassen des Containertyp zu stoppen: ^P^Q

+0

Ja, es ist leicht zu vergessen die "-it" -Flaggen – nachocab

+0

Vielen Dank für den Tipp (: – artemn

+0

Was macht 'dit'? Ich dachte' i' war interaktiv ..? – Tommy

30

Ich mag würde ich sagen, zu verlängern oder zu wagen, zu verbessern, indem camposer

erwähnt Antwort Wenn Sie

docker run -dit ubuntu 

laufen Sie im Grunde laufen der Container im Hintergrund im interaktiven Modus.

Wenn Sie den Container mit STRG + D anhängen und beenden (am häufigsten), stoppen Sie den Container, weil Sie gerade den Hauptprozess beendet haben, den Sie mit dem obigen Befehl gestartet haben.

Herstellung Vorteil eines bereits laufenden Container, ich würde nur einen weiteren Prozess der bash Gabel und ein Pseudo-TTY durch Laufen bringen:

docker exec -it <container ID> /bin/bash 
-4

Da das Bild ist ein Linux, eine Sache zu prüfen ist, um sicherzustellen, Alle im Container verwendeten Shell-Skripte haben Unix-Zeilenendungen. Wenn sie am Ende ein^M haben, dann sind sie Fensterzeilenenden. Eine Möglichkeit, sie zu beheben, ist dos2unix auf /usr/local/start-all.sh, um sie von Windows in Unix zu konvertieren. Wenn Sie das Andockfenster im interaktiven Modus ausführen, können Sie andere Probleme erkennen. Sie könnten einen Dateinamen Tippfehler oder etwas haben. Siehe https://en.wikipedia.org/wiki/Newline

5

Ein guter Ansatz wäre, Ihre Prozesse und Dienste im Hintergrund zu starten und den Befehl wait [n ...] am Ende des Skripts zu verwenden. In bash erzwingt der Befehl wait den aktuellen Prozess wie folgt:

Warten Sie auf jeden angegebenen Prozess und geben Sie den Beendigungsstatus zurück. Wenn n nicht angegeben wird, wird auf alle derzeit aktiven untergeordneten Prozesse gewartet, und der Rückkehrstatus ist Null.

Ich habe diese Idee von Sébastien Pujadas 'start script for his elk build.

von der ursprünglichen Frage nehmen, sind Sie start-all.sh etwa so aussehen würde ...

#!/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 & 
wait 
1

Mein pracitce ist in der Dockerfile eine Shell starten, die nicht sofort CMD [ "sh", "-c", "service ssh start; bash"] verlassen wird, dann Führen Sie docker run -dit image_name. Auf diese Weise läuft der (ssh) Service und Container.

2

, wenn ich ein Container will nach aufbleiben der Skriptausführung beenden füge ich

&& tail -f /dev/null 

am Ende des Befehls. So soll es sein:

/usr/local/start-all.sh && tail -f /dev/null 
0

exec "$ @"

am Ende meiner Shell-Skript Hinzufügen war mein fix!

Verwandte Themen