Właściwy sposób na uruchomienie kontenera dokowanego, gdy jest używany do zadań okresowych

41

Mam kontener dokera z zainstalowanym i skonfigurowanym oprogramowaniem.

Nie ma żadnego programu, który powinien być uruchamiany / uruchamiany przez cały czas.

Co chcę - jego zdolność do uruchamiania niektórych poleceń w zależności od zdarzeń zewnętrznych. lubić:

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

i

docker exec mysupercont /path/to/myothercommand 

Ale „exec” jest niemożliwe, gdy kontener jest zatrzymany, a także w tym kontenerze znajdują się pewne „działające” dane, które były używane dla tych poleceń, więc nie mogę

docker run ...

za każdym razem, ponieważ odtwarza pojemnik z obrazu i niszczy moje dane.

Jaki jest „właściwy” i „najlepszy” sposób na utrzymanie takiego kontenera w ruchu? Które polecenie mogę uruchomić w środku?

Korjavin Ivan
źródło
To bardzo dobrze wyjaśnione pytanie. Zobacz inny podobny post tutaj .
Grant Li
1
docker run -d --name=name container tail -f /dev/null
steampowered 17.07.17

Odpowiedzi:

46

Nie musisz wykonywać za każdym razem docker run.

docker run jest właściwie sekwencją dwóch poleceń: „utwórz” i „uruchom”.

Po uruchomieniu kontenera musisz określić „ -it”:

-i, --interactive = false Utrzymuj STDIN otwarty, nawet jeśli nie jest dołączony
-t, --tty = false Przydziel pseudo-TTY

Przykład:

docker run -it debian:stable bash

Po zakończeniu pracy polecenie określone podczas uruchamiania (w moim przykładzie bash). Na przykład wykonujesz „wyjście”. Zatrzymuje się pojemnik:

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

Teraz możesz zacząć od nowa

docker start 1329c99a831b

Kontener jest uruchamiany i ponownie wykonuje polecenie „bash”.
Połącz się z tą sesją „bash” za pomocą polecenia

docker attach 1329c99a831b

Podsumowując : musisz zrozumieć różnicę między pojemnikiem runa startpojemnikiem.
Poza tym poszukaj w dokumentacji roli parametrów „ -i t” i „ -d” dla „Uruchom”

MSemochkin
źródło
1
aha, rozumiem to. Pytanie brzmiało: nie mam nic do uruchomienia w kontenerze, ale muszę utrzymać go w stanie „uruchomionym”. Twoja odpowiedź brzmi - użyj bash, aby utrzymać kontener w stanie uruchomionym?
Korjavin Ivan
Tak. Proces określony w czasie wykonywania musi być uruchomiony do kontenera, aby kontynuować. Najprostszym przykładem jest bash. Być może będziesz najłatwiejszym sposobem, aby uruchomić kontener za pomocą „-d” i połączyć się z nim w razie potrzeby za pomocą docker attach ID. Wyjdź z tej sesji bez końca bash, możesz użyćCTRL-p CTRL-q
MSemochkin
Proces określony podczas uruchamiania kontenera otrzymuje PID 1. W związku z tym kontener po prostu nie może bez niego pracować ☺
MSemochkin
Moje doświadczenie z uruchamianiem i dołączaniem (lub uruchamianiem z -ai) jest to, że nie wyświetla się monit i interaktywna edycja wiersza poleceń. EG tty nie renderuje ani nie echa.
dlamblin,
1
To jest fajne. Pamiętaj, że jeśli chcesz uruchomić kontener w tle bez konieczności ręcznego uruchamiania go ponownie (np. Jeśli prowadzisz usługę sieci web), użyj parametrów „-itd” i CTRL-p CTRL-q, aby odłączyć bez zatrzymywania pojemnik.
taranaki
6

Cała sprawa, czy można uruchomić zatrzymany kontener, zależy od tego, jak kontener został pierwotnie utworzony, tj. Uruchomić. Jeśli uruchomiłeś polecenie, które się zakończyło lub wyjdziesz z polecenia interaktywnego, np. Bash, nie możesz uruchomić, zrestartować ani wykonać zatrzymanego kontenera. Wszystko, co możesz zrobić, to usunąć. To śmieci.

Ale ostatni komentarz taranaki, użycie „-itd”, wydaje się być tym, co zamówił doker.

Kontener działa, a Ty możesz wykonać cokolwiek zechcesz, możesz zatrzymać, uruchomić lub zrestartować kontener. Oczywiście jest to tylko wstępne ustalenie oparte na alpejskim obrazie. Uwaga: jeśli podłączysz się do kontenera, zatrzyma się on po wyjściu, ale możesz go uruchomić ponownie.

Sue Parker
źródło
2
+1 „wydaje się być tym, co zamówił doker” :-)
Matt Alexander
5

Ponieważ wspomniałeś o okresowych zadaniach i prawdopodobnie używasz czegoś takiego jak cron ze względu na sposób, w jaki chcesz używać docker exec, mam dla ciebie tylko lekarstwo. Przynajmniej skończyłem robić coś takiego.

  1. Plik Docker

    FROM <some base>
    CMD tail -f /dev/null
    
  2. Uruchom ze zwykłym docker run -d ....(użyłem docker-compose)

  3. Skonfiguruj plik crontab hostów, na przykład:

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

Uważam to rozwiązanie za przyjemne, ponieważ możemy polegać na starożytnym i sprawdzonym crontabie w dość domyślnym środowisku Linux, podczas gdy Docker obsługuje bardziej egzotyczne zależności logiki biznesowej i zmienne środowiskowe. Możesz także ustawić pewne limity, jeśli zadania okresowe utkną i będą miały wycieki pamięci lub cokolwiek innego.

Elnygren
źródło
0

Od czasu do czasu Tail nadal powoduje niektóre operacje na plikach.

Oto moje rozwiązanie, by spać wiecznie, bez żadnych skutków ubocznych.

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

Jak to działa

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
źródło
1
trudno zrozumieć, co robi. dlaczego nie spać 3650d
Pieter
1
Masz rację, sen prawdopodobnie działałby tak dobrze, jak moje rozwiązanie, jednak sen w końcu się skończy :-D PS: Dodam kilka komentarzy, aby moje rozwiązanie było łatwe do zrozumienia.
qoomon