Der richtige Weg, den Docker-Container bei regelmäßigen Aufgaben zu starten

41

Ich habe Docker-Container mit installierter und konfigurierter Software.

Es darf kein Programm ständig gestartet / ausgeführt werden.

Was ich will - seine Fähigkeit, einen Befehl abhängig von externen Ereignissen zu starten. mögen:

docker exec mysupercont /path/to/mycommand -bla -for

und

docker exec mysupercont /path/to/myothercommand 

Aber "exec" ist unmöglich, wenn der Container gestoppt ist, und auch dieser Container enthält einige "funktionierende" Daten, die für diese Befehle verwendet wurden, sodass ich sie nicht verwenden kann

docker run ...

jedes Mal, weil es Container von Bild neu erstellen und meine Daten zerstören.

Was ist der "richtige" und "beste" Weg, um einen solchen Container am Laufen zu halten? Welchen Befehl kann ich drinnen starten?

Korjavin Ivan
quelle
Dies ist eine sehr gut erläuterte Frage. Einen ähnlichen Beitrag finden Sie hier .
Grant Li
1
docker run -d --name=name container tail -f /dev/null
Steampowered

Antworten:

46

Sie müssen nicht jedes Mal durchführen docker run.

docker run ist eigentlich eine Folge von zwei Befehlen: "create" und "start".

Wenn Sie den Container ausführen, müssen Sie Folgendes angeben -it:

-i, --interactive = false Lässt STDIN offen, auch wenn es nicht angehängt ist.
-t, --tty = false Weist ein Pseudo-TTY zu

Beispiel:

docker run -it debian:stable bash

Nach Abschluss der Arbeit wurde der Befehl beim Start angegeben (in meinem Beispiel bash). Zum Beispiel führen Sie den "Exit" durch. Containerhaltestellen:

CONTAINER ID        IMAGE                      COMMAND                CREATED             STATUS                     PORTS               NAMES
1329c99a831b        debian:stable              "bash"                 51 seconds ago      Exited (0) 1 seconds ago                       goofy_bardeen

Jetzt können Sie es erneut starten

docker start 1329c99a831b

Der Container wird gestartet und führt den Befehl "bash" erneut aus.
Stellen Sie mit dem Befehl eine Verbindung zu dieser Sitzung "bash" her

docker attach 1329c99a831b

Fazit : Sie müssen den Unterschied zwischen runund startContainer verstehen .
Beachten Sie dabei die Dokumentation zur Rolle der Parameter " -i t" und " -d" für den "Run"

MSemochkin
quelle
1
aha, ich verstehe das. Die Frage war: Ich habe nichts im Container zu laufen, aber ich muss es im "Lauf" -Zustand halten. Also lautet Ihre Antwort: Verwende bash, um den Container im Laufzustand zu halten?
Korjavin Ivan
Ja. Der Prozess, den Sie zur Laufzeit angegeben haben, muss ausgeführt werden, damit der Container weiterhin funktioniert. Das einfachste Beispiel ist bash. Vielleicht ist es der einfachste Weg, den Container mit dem "-d" zu starten und bei Bedarf eine Verbindung mit dem herzustellen docker attach ID. Holen Sie sich aus dieser Sitzung, ohne Bash zu beenden, können Sie verwendenCTRL-p CTRL-q
MSemochkin
Der Prozess, den Sie während des Containerlaufs angeben, erhält die PID 1. Dementsprechend kann der Container einfach nicht ohne sie funktionieren. It
MSemochkin
Meine Erfahrung mit start and attach (oder start with -ai) ist, dass die Eingabeaufforderung und die interaktive Bearbeitung Ihrer Befehlszeile nicht angezeigt werden. ZB das tty wird nicht gerendert oder zurückgemeldet.
Dlamblin
1
Das ist schick. Wenn Sie den Container im Hintergrund starten möchten, ohne ihn erneut manuell starten zu müssen (z. B. wenn Sie einen Webdienst ausführen), verwenden Sie die Parameter '-itd' und STRG-p STRG-q, um die Verbindung zu trennen, ohne den Container anzuhalten Container.
Taranaki
6

Ob Sie einen gestoppten Container starten können oder nicht, hängt davon ab, wie der Container ursprünglich erstellt, dh ausgeführt wurde. Wenn Sie einen beendeten Befehl ausgeführt haben oder einen interaktiven Befehl beenden, z. B. bash, können Sie den gestoppten Container nicht starten, neu starten oder ausführen. Alles was Sie tun können, ist es zu entfernen. Es ist Müll.

Aber Taranakis letzter Kommentar, '-itd', scheint genau das zu sein, was der Hafenarbeiter befohlen hat.

Der Container läuft weiter und Sie können ausführen, was immer Sie wollen, und Sie können den Container stoppen, starten oder neu starten. Dies ist natürlich nur eine vorläufige Feststellung, die auf dem alpinen Image basiert. Wenn Sie eine Verbindung zum Container herstellen, wird dieser beim Beenden angehalten, Sie können ihn jedoch erneut starten.

Sue Parker
quelle
2
+1 "scheint das zu sein, was der Hafenarbeiter bestellt hat" :-)
Matt Alexander
5

Da Sie regelmäßige Aufgaben erwähnt haben und aufgrund der Art und Weise, wie Sie sie verwenden möchten, wahrscheinlich so etwas wie Cron verwenden docker exec, habe ich genau das richtige Medikament für Sie. Zumindest habe ich so etwas gemacht.

  1. Dockerfile

    FROM <some base>
    CMD tail -f /dev/null
    
  2. Laufe mit dem üblichen docker run -d ....(habe ich benutzt docker-compose)

  3. Richten Sie die Host-Maschine crontab ein, zum Beispiel:

    * * * * * docker exec mysupercont foo >> /var/log/foo.log 2>&1
    * * * * * docker exec mysupercont bar >> /var/log/bar.log 2>&1
    

Ich finde diese Lösung schön, da wir uns in einer ziemlich standardmäßigen Linux-Umgebung auf die alte und bewährte crontab verlassen können, während Docker die exotischeren Deps und Umgebungsvariablen Ihrer Geschäftslogik handhabt. Sie können auch einige Grenzwerte festlegen, wenn Ihre regelmäßigen Aufgaben hängen bleiben und Speicherlecks auftreten oder was auch immer.

Elnygren
quelle
0

Tail verursacht von Zeit zu Zeit noch einige Dateivorgänge.

Hier ist meine Lösung, um für immer ohne Nebenwirkungen zu schlafen.

# Ah, ha, ha, ha, stayin' alive...
while true; do :; done & kill -STOP $! && wait $!

Wie es funktioniert

while true; do :; done & # do nothing(:) in background, in an endless loop
kill -STOP $!            # stop the background process of doing nothing
wait $!                  # wait forever, because doing nothing process is stopped
qoomon
quelle
1
schwer zu verstehen, was es tut. warum nicht einfach schlafen 3650d
Pieter
1
Du hast recht, der Schlaf würde wahrscheinlich genauso gut funktionieren wie meine Lösung, aber der Schlaf wird irgendwann nachlassen :-D PS: Ich werde einige Kommentare hinzufügen, damit meine Lösung leicht verständlich wird.
Qoomon