Ich starte einen Container im Hintergrund mit
docker run -d --name hadoop h_Service
es geht schnell. Aber wenn ich im Vordergrund renne, funktioniert es gut. Ich habe die Protokolle mit überprüft
docker logs hadoop
Es gab 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
chmod 777
ist unsicher und falsch. Sie sollten zu normalen Berechtigungen zurückkehren (in diesem Fall wahrscheinlich 755).Antworten:
Ein Docker-Container wird beendet, wenn sein Hauptprozess abgeschlossen ist.
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 Sie nicht angeben
-d
; es sollte genau den gleichen Effekt haben. Ich vermute, Sie haben es mit einem etwas anderen Befehl gestartet oder mit einem Befehl,-it
der die Dinge ändert.Eine einfache Lösung könnte darin bestehen, Folgendes hinzuzufügen:
while true; do sleep 1000; done
bis zum Ende des Skripts. Ich mag das jedoch nicht, da das Skript wirklich die Prozesse überwachen sollte, die es gestartet hat.
(Ich sollte sagen, ich habe diesen Code von https://github.com/sequenceiq/hadoop-docker/blob/master/bootstrap.sh gestohlen. )
quelle
Das hat den Trick für mich getan:
Danach habe ich nach folgenden Prozessen gesucht:
Zum erneuten Anbringen des Behälters
TIPP: Zum Beenden ohne Anhalten des Containertyps:
^P^Q
quelle
-dit
-di
ist das erforderliche Minimum, die-t
Option ist redundant, wenn sie verwendet wird,-d
wenn ich das richtig verstehe-t
anbringen ... aber da ich normalerweiseexec
jedes Mal eine neue Bash bekomme, merke ich es nicht. Ich hatte Probleme, mich von einem Mac zu lösen, aber vielleicht mache ich das falsch.Ich möchte erweitern oder es wagen zu sagen, die von Camposer erwähnte Antwort zu verbessern
Wenn du rennst
Grundsätzlich führen Sie den Container im interaktiven Modus im Hintergrund aus.
Wenn Sie den Container mit STRG + D anhängen und verlassen (am häufigsten), stoppen Sie den Container, weil Sie gerade den Hauptprozess abgebrochen haben, den Sie mit dem obigen Befehl gestartet haben.
Wenn ich einen bereits laufenden Container ausnutzen würde, würde ich einfach einen weiteren Bash-Prozess abspalten und ein Pseudo-TTY erhalten, indem ich Folgendes ausführe:
quelle
Wann immer ich möchte, dass ein Container nach Abschluss der Skriptausführung, die ich hinzufüge, aktiv bleibt
am Ende des Befehls. So sollte es sein:
quelle
Wenn Sie das Image zum Herumhängen zwingen möchten (um etwas zu debuggen oder den Status des Dateisystems zu überprüfen), können Sie den Einstiegspunkt überschreiben, um ihn in eine Shell zu ändern:
quelle
Ein guter Ansatz wäre, Ihre Prozesse und Dienste zu starten, die sie im Hintergrund ausführen, und den
wait [n ...]
Befehl am Ende Ihres Skripts zu verwenden. In bash erzwingt der Befehl wait den aktuellen Prozess zu:Ich habe diese Idee von Sébastien Pujadas 'Startskript für seinen Elchbau bekommen .
Ausgehend von der ursprünglichen Frage würde Ihre start-all.sh ungefähr so aussehen ...
quelle
Fügen Sie dies am Ende von Dockerfile hinzu:
Beispiel-Docker-Datei:
Referenz
quelle
CMD tail -f /dev/null
läuft es durchsh -c "..."
. Können wirexec
stattdessen das Formular verwenden? DhCMD ["tail", "-f", "/dev/null"]
Meine Praxis ist, in der Docker-Datei eine Shell zu starten, die nicht sofort beendet wird
CMD [ "sh", "-c", "service ssh start; bash"]
, und dann auszuführendocker run -dit image_name
. Auf diese Weise werden der (ssh) -Dienst und der Container ausgeführt.quelle
Ich habe
read
am Ende eine Shell-Anweisung hinzugefügt . Dadurch bleibt der Hauptprozess des Containers - Start-Shell-Skript - ausgeführt.quelle
Hinzufügen
Am Ende meines Shell-Skripts war mein Fix!
quelle
Wenn Sie Dockerfile aus Containern überprüfen, z. B. fballiano / magento2-apache-php
Sie werden sehen, dass er am Ende seiner Datei den folgenden Befehl hinzufügt: while true; schlafe 1; getan
Was ich jetzt empfehle, ist, dass Sie dies tun
Dann werden Sie sehen, ob Ihr Docker-Image einen Fehler hatte. Wenn es mit 0 beendet wird, benötigt es wahrscheinlich einen dieser Befehle, der für immer schlafen wird.
quelle
Es gibt viele Möglichkeiten, einen Docker sofort zu beenden. Für mich war es das Problem mit meinem
Dockerfile
. Es gab einen Fehler in dieser Datei. Ich hatteENTRYPOINT ["dotnet", "M4Movie_Api.dll]
stattENTRYPOINT ["dotnet", "M4Movie_Api.dll"]
. Wie Sie sehen, hatte ich am Ende ein Zitat (") verpasst.Um das Problem zu analysieren, startete ich meinen Container und befestigte meinen Container schnell, damit ich sehen konnte, was genau das Problem war.
Wobei 4ea373efa21b meine Container-ID ist. Dies bringt mich zum eigentlichen Problem.
Nachdem ich das Problem gefunden hatte, musste ich meinen Container erneut erstellen, wiederherstellen und veröffentlichen.
quelle
Aufgrund von Duplikaten sehe ich hier keine Antwort, die sich mit dem sehr häufigen Antipattern befasst, Ihre Hauptarbeitslast als Hintergrundjob auszuführen und sich dann zu fragen, warum Docker beendet wird.
In einfachen Worten, wenn Sie haben
Nehmen Sie dann entweder das heraus
&
, um den Job im Vordergrund auszuführen, oder fügen Sie hinzuam Ende des Skripts, damit es auf alle Hintergrundjobs wartet.
Es wird dann immer noch beendet, wenn die Hauptarbeitslast beendet wird. Führen Sie dies also möglicherweise in a aus
while true
Schleife aus, um einen Neustart für immer zu erzwingen:(Beachten Sie auch, wie man schreibt
while true
. Es ist üblich, alberne Dinge zu sehen, wiewhile [ true ]
oderwhile [ 1 ]
die zufällig funktionieren, aber meinen Sie nicht, was der Autor wahrscheinlich gedacht hat, dass sie bedeuten sollten.)quelle
Sie müssen es mit dem Flag -d ausführen, damit es als Daemon im Hintergrund ausgeführt wird.
quelle
Sie können den Container mit diesem Neustart-Flag ausführen.
quelle
Da es sich bei dem Image um ein Linux handelt, müssen Sie überprüfen, ob alle im Container verwendeten Shell-Skripte Unix-Zeilenenden haben. Wenn sie am Ende ein ^ M haben, sind sie Windows-Zeilenenden. Eine Möglichkeit, sie zu beheben, besteht darin, sie mit dos2unix unter /usr/local/start-all.sh von Windows nach Unix zu konvertieren. Wenn Sie das Docker im interaktiven Modus ausführen, können Sie andere Probleme herausfinden. Sie könnten einen Dateinamen-Tippfehler haben oder so. Siehe https://en.wikipedia.org/wiki/Newline
quelle