Korzystam z kontenera w tle, używając
docker run -d --name hadoop h_Service
wychodzi szybko. Ale jeśli uruchomię się na pierwszym planie, działa dobrze. Sprawdziłem dzienniki za pomocą
docker logs hadoop
nie było błędu. Jakieś pomysły?
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
jest niepewne i złe. Powinieneś powrócić do rozsądnych uprawnień (prawdopodobnie 755 w tym przypadku).Odpowiedzi:
Kontener dokera kończy pracę po zakończeniu głównego procesu.
W takim przypadku zakończy działanie po
start-all.sh
zakończeniu skryptu. Nie wiem wystarczająco dużo o hadoopie, aby powiedzieć ci, jak to zrobić w tym przypadku, ale musisz albo zostawić coś uruchomionego na pierwszym planie, albo użyć menedżera procesów, takiego jak runit lub supervisord, aby uruchomić procesy.Myślę, że musisz się mylić, że działa, jeśli nie określisz
-d
; powinien mieć dokładnie taki sam efekt. Podejrzewam, że uruchomiłeś go za pomocą nieco innej komendy lub użycia,-it
które zmieni rzeczy.Prostym rozwiązaniem może być dodanie czegoś takiego:
while true; do sleep 1000; done
do końca skryptu. Nie podoba mi się to, ponieważ skrypt powinien naprawdę monitorować procesy, które rozpoczął.
(Powinienem powiedzieć, że ukradłem ten kod z https://github.com/sequenceiq/hadoop-docker/blob/master/bootstrap.sh )
źródło
To załatwiło sprawę:
Następnie sprawdziłem, czy procesy działają, używając:
Do ponownego zamocowania pojemnika
WSKAZÓWKA: Aby wyjść bez zatrzymywania typu kontenera:
^P^Q
źródło
-dit
jest tylko skrótem-di
jest wymaganym minimum,-t
opcja jest zbędna, jeśli jest używana,-d
jeśli dobrze rozumiem-t
włączonego ... ale ponieważ zwykle jestemexec
nowy bash za każdym razem, gdy tego nie zauważam. Miałem problemy z odłączeniem się od komputera Mac, ale może robię to źle ...Chciałbym przedłużyć, czy ośmielę się powiedzieć, poprawić odpowiedź, o której wspomina Camposer
Kiedy biegniesz
w zasadzie uruchamiasz kontener w tle w trybie interaktywnym.
Po dołączeniu i zamknięciu kontenera za pomocą CTRL + D (najczęstszy sposób, aby to zrobić), zatrzymujesz kontener, ponieważ właśnie zabiłeś główny proces, który uruchomiłeś kontener za pomocą powyższego polecenia.
Korzystając z już działającego kontenera, po prostu rozwidlę kolejny proces bash i otrzymam pseudo TTY, uruchamiając:
źródło
za każdym razem, gdy chcę, aby kontener pozostał bezczynny po zakończeniu wykonywania skryptu, dodaję
na końcu polecenia. Tak powinno być:
źródło
Jeśli chcesz zmusić obraz do zawieszenia się (w celu debugowania lub sprawdzenia stanu systemu plików), możesz zastąpić punkt wejścia, aby zmienić go na powłokę:
źródło
Dobrym podejściem byłoby uruchomienie procesów i usług, uruchamiając je w tle i używając
wait [n ...]
polecenia na końcu skryptu. W bash polecenie czekania wymusza na bieżącym procesie:Wpadłem na ten pomysł ze skryptu startowego Sébastiena Pujadasa dla jego budowy łosi .
Biorąc z pierwotnego pytania, twoja strona start-all.sh wyglądałaby mniej więcej tak ...
źródło
Dodaj to na końcu Dockerfile:
Przykładowy plik Docker:
Odniesienie
źródło
CMD tail -f /dev/null
uruchamia tosh -c "..."
. Czyexec
zamiast tego możemy użyć formularza? To znaczyCMD ["tail", "-f", "/dev/null"]
Moja praktyka polega na tym, że w Dockerfile uruchom powłokę, która nie wyjdzie natychmiast
CMD [ "sh", "-c", "service ssh start; bash"]
, a następnie uruchomdocker run -dit image_name
. W ten sposób usługa (ssh) i kontener są uruchomione.źródło
Na końcu dodałem
read
instrukcję powłoki. Dzięki temu główny proces kontenera - skrypt powłoki startowej - działa.źródło
Dodawanie
na końcu mojego skryptu powłoki była moja poprawka!
źródło
Jeśli sprawdzisz plik Dockerfile z kontenerów, na przykład fballiano / magento2-apache-php
zobaczysz, że na końcu swojego pliku dodaje następujące polecenie: while true; śpij 1; Gotowe
Teraz polecam, abyś to zrobił
Następnie zobaczysz, czy w obrazie dokera wystąpił błąd, jeśli zakończy się na 0, prawdopodobnie potrzebuje jednego z tych poleceń, które będą spać na zawsze.
źródło
Istnieje wiele możliwych sposobów natychmiastowego wyjścia dokera. Dla mnie to był problem z moim
Dockerfile
. W tym pliku wystąpił błąd. MiałemENTRYPOINT ["dotnet", "M4Movie_Api.dll]
zamiastENTRYPOINT ["dotnet", "M4Movie_Api.dll"]
. Jak widać, na końcu przeoczyłem jeden cytat („).Aby przeanalizować problem, uruchomiłem swój pojemnik i szybko podłączyłem go, aby zobaczyć, jaki jest dokładnie problem.
Gdzie 4ea373efa21b to mój identyfikator kontenera. To prowadzi mnie do faktycznego problemu.
Po znalezieniu problemu musiałem ponownie zbudować, przywrócić, opublikować mój kontener.
źródło
Pochodząc z duplikatów, nie widzę tutaj żadnej odpowiedzi, która dotyczyłaby bardzo powszechnego przeciwwskazania uruchamiania głównego obciążenia pracą jako zadania w tle, a następnie zastanawiania się, dlaczego Docker kończy pracę.
W prostych słowach, jeśli masz
następnie albo wyjmij,
&
aby uruchomić zadanie na pierwszym planie, albo dodajna końcu skryptu, aby czekał na wszystkie zadania w tle.
Następnie nadal zakończy pracę, jeśli główne obciążenie zostanie zakończone, więc może uruchom to w
while true
pętli, aby zmusić go do ponownego uruchomienia na zawsze:(Zauważmy też, jak pisać
while true
. To wspólne, aby zobaczyć jak głupie rzeczywhile [ true ]
lubwhile [ 1 ]
które przypadkowo zdarzyć do pracy, ale nie oznacza to, co autor zapewne wyobrażał powinni rozumieć).źródło
Musisz uruchomić go z opcją -d, aby działał jako demon w tle.
źródło
Możesz uruchomić kontener za pomocą tej flagi restartu.
źródło
Ponieważ obraz jest linuksem, należy sprawdzić, czy wszystkie skrypty powłoki używane w kontenerze mają zakończenia linii unixowych. Jeśli mają na końcu ^ M, to są zakończeniami linii systemu Windows. Jednym ze sposobów, aby je naprawić, jest dos2unix na /usr/local/start-all.sh, aby przekonwertować je z systemu Windows na unix. Uruchomienie dokera w trybie interaktywnym może pomóc rozwiązać inne problemy. Możesz mieć literówkę nazwy pliku lub coś takiego. patrz https://en.wikipedia.org/wiki/Newline
źródło