Korzystam z rabbitmq i prostej próbki pytona stąd wraz z docker-compose. Mój problem polega na tym, że muszę poczekać, aż Rabbitmq się w pełni uruchomi. Z tego, co szukałem do tej pory, nie wiem, jak czekać z kontenerem x (w moim przypadku robotnikiem), aż zostanie uruchomiony y (rabbitmq).
Znalazłem ten post na blogu, na którym sprawdza, czy drugi host jest online. Znalazłem również to polecenie dokera :
czekać
Zastosowanie: docker czekać CONTAINER [CONTAINER ...]
Blokuj, aż kontener się zatrzyma, a następnie wydrukuj kod wyjścia.
Oczekiwanie na zatrzymanie kontenera może nie jest tym, czego szukam, ale jeśli tak, to czy można użyć tego polecenia w oknie docker-compose.yml? Jak dotąd moim rozwiązaniem jest poczekanie kilku sekund i sprawdzenie portu, ale czy to jest sposób na osiągnięcie tego ?. Jeśli nie czekam, pojawia się błąd.
docker-compose.yml
worker:
build: myapp/.
volumes:
- myapp/.:/usr/src/app:ro
links:
- rabbitmq
rabbitmq:
image: rabbitmq:3-management
przykładowa python hello (rabbit.py):
import pika
import time
import socket
pingcounter = 0
isreachable = False
while isreachable is False and pingcounter < 5:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect(('rabbitmq', 5672))
isreachable = True
except socket.error as e:
time.sleep(2)
pingcounter += 1
s.close()
if isreachable:
connection = pika.BlockingConnection(pika.ConnectionParameters(
host="rabbitmq"))
channel = connection.channel()
channel.queue_declare(queue='hello')
channel.basic_publish(exchange='',
routing_key='hello',
body='Hello World!')
print (" [x] Sent 'Hello World!'")
connection.close()
Plik Docker dla pracownika:
FROM python:2-onbuild
RUN ["pip", "install", "pika"]
CMD ["python","rabbit.py"]
Aktualizacja lis 2015 :
Możliwym rozwiązaniem może być skrypt powłoki lub oczekiwanie w twoim programie. Ale po zobaczeniu tego problemu szukam polecenia lub funkcji docker / docker-compose.
Wspominają o rozwiązaniu służącym do kontroli stanu zdrowia, które może być najlepszym rozwiązaniem. Otwarte połączenie TCP nie oznacza, że usługa jest gotowa lub może pozostać gotowa. Ponadto muszę zmienić punkt wejścia w pliku dokera.
Mam więc nadzieję na odpowiedź z komendami docker-komponuj na pokładzie, co, mam nadzieję, będzie miało miejsce, jeśli zakończą ten problem.
Aktualizacja z marca 2016 r
Jest to propozycja dla zapewnienia wbudowany sposobem określenia, czy dany pojemnik jest „żywy”. Więc docker-compose może z niego skorzystać w najbliższej przyszłości.
Aktualizacja z czerwca 2016 r
Wygląda na to, że kontrola zdrowia zostanie zintegrowana z dokerem w wersji 1.12.0
Aktualizacja ze stycznia 2017 r
Znalazłem rozwiązanie komponowania dokera patrz: Docker Compose poczekaj na kontener X przed uruchomieniem Y
źródło
Odpowiedzi:
Wreszcie znalazłem rozwiązanie z metodą dokowania-komponowania. Ponieważ format pliku dokowania-komponuj 2.1, możesz zdefiniować kontrole kondycji .
Zrobiłem to w przykładowym projekcie, w którym musisz zainstalować przynajmniej dokera 1.12.0+. Musiałem także rozszerzyć plik Dockerfile do zarządzania królikami , ponieważ curl nie jest zainstalowany na oficjalnym obrazie.
Teraz sprawdzam, czy strona zarządzania kontenera rabbitmq jest dostępna. Jeśli curl zakończy się kodem wyjścia 0, aplikacja kontenera (python pika) zostanie uruchomiona i opublikuje komunikat w kolejce hello. Teraz działa (wyjście).
docker-compose (wersja 2.1):
wynik:
Dockerfile (rabbitmq + curl):
Wersja 3 nie obsługuje już formy warunku depend_on . Więc przeniosłem się z depend_on, aby zrestartować po awarii. Teraz mój kontener aplikacji uruchomi się ponownie 2-3 razy, aż będzie działał, ale nadal jest funkcją komponowania dokera bez nadpisywania punktu wejścia.
docker-compose (wersja 3):
źródło
ping
używa ICMP, więc nie obsługuje portów TCP. Możenc
przetestować port TCP. Prawdopodobnie lepiej użyćpsql -h localhost -p 5432
i zapytać o coś.condition
formadepends_on
została usunięta, aledepends_on
sama jest nadal dostępna w v3depends_on
zecondition
został usunięty?Natywnie nie jest to jeszcze możliwe. Zobacz także to żądanie funkcji .
Do tej pory musisz to zrobić w swoich kontenerach,
CMD
aby poczekać, aż pojawią się wszystkie wymagane usługi.W
Dockerfile
sCMD
możesz odwołać się do własnego skryptu startowego, który otacza uruchamianie usługi kontenera. Zanim go uruchomisz, zaczekaj na zależną, taką jak:Plik Docker
start.sh
Prawdopodobnie musisz również zainstalować netcat
Dockerfile
. Nie wiem, co jest wstępnie zainstalowane na obrazie Pythona.Istnieje kilka narzędzi, które zapewniają łatwą w użyciu logikę oczekiwania na proste kontrole portów TCP:
Na bardziej złożone oczekiwania:
źródło
Za pomocą
restart: unless-stopped
lubrestart: always
może rozwiązać ten problem.Jeśli pracownik
container
zatrzyma się, gdy rabbitMQ nie będzie gotowy, zostanie zrestartowany, aż będzie.źródło
Całkiem niedawno dodali tę
depends_on
funkcję .Edytować:
Począwszy od komponowania wersji 2.1+, możesz tego użyć
depends_on
w połączeniu zhealthcheck
:Z dokumentów :
Przed wersją 2.1
Nadal możesz używać
depends_on
, ale wpływa to tylko na kolejność uruchamiania usług - nie jeśli są one gotowe przed uruchomieniem usługi zależnej.Wydaje się, że wymaga co najmniej wersji 1.6.0.
Użycie wyglądałoby mniej więcej tak:
Z dokumentów:
Uwaga: jak rozumiem, chociaż ustawia to kolejność ładowania kontenerów. Nie gwarantuje to, że usługa wewnątrz kontenera rzeczywiście się załadowała.
Na przykład postgres pojemnik może być włączony. Ale sama usługa postgres może nadal inicjować się w kontenerze.
źródło
depends_on
”. docs.docker.com/compose/compose-file/#dependsondepends_on
nie czeka, aż kontener będzie wready
stanie (cokolwiek to może znaczyć w twoim przypadku). Czeka tylko, aż kontener będzie w stanie „uruchomionym”.możesz także dodać go do opcji polecenia np.
https://github.com/docker/compose/issues/374#issuecomment-156546513
aby poczekać na porcie, możesz również użyć czegoś takiego
Aby wydłużyć czas oczekiwania, możesz zhakować trochę więcej:
źródło
restart: on-failure
zrobił dla mnie lewę ... patrz poniżejźródło
Do rozpoczęcia zamawiania kontenera użyj
Do oczekiwania na poprzedni kontener uruchom skrypt
Ten artykuł pomoże Ci https://docs.docker.com/compose/startup-order/
źródło
Możesz również rozwiązać ten problem, ustawiając punkt końcowy, który czeka na uruchomienie usługi, używając netcat (używając skryptu docker-wait ). Podoba mi się to podejście, ponieważ nadal masz czystą
command
sekcjędocker-compose.yml
i nie musisz dodawać do aplikacji kodu specyficznego dla dokera:Następnie twój
docker-entrypoint.sh
:Jest to obecnie udokumentowane w oficjalnej dokumentacji dokera .
PS: Należy zainstalować
netcat
w instancji dokera, jeśli nie jest to dostępne. Aby to zrobić, dodaj to doDocker
pliku:źródło
Istnieje gotowe do użycia narzędzie o nazwie „ docker-wait ”, którego można używać do oczekiwania.
źródło
Próbowałem na wiele różnych sposobów, ale podobała się jej prostota: https://github.com/ufoscout/docker-compose-wait
Pomysł, że można użyć ENV vars w pliku doker redagowania przedłożyć wykaz usług gospodarze (z otworami), który powinien być „oczekiwany” tak:
WAIT_HOSTS: postgres:5432, mysql:3306, mongo:27017
.Powiedzmy, że masz następujący plik docker-compose.yml (copy / past from repo README ):
Następnie, aby usługi mogły czekać, należy dodać następujące dwa wiersze do plików Docker (do pliku Docker usług, które powinny oczekiwać na uruchomienie innych usług):
Kompletny przykład takiego przykładowego pliku Docker (ponownie z repozytorium projektu README ):
Aby uzyskać szczegółowe informacje na temat możliwego użycia, zobacz README
źródło
https://github.com/ufoscout/docker-compose-wait
bibliotekę :) Sposób, w jaki korzystasz z tej biblioteki, nie zmienia odpowiedzi, z której możesz skorzystać. Bezpieczeństwo jest złożonym tematem i jeśli posuniemy się daleko, powinniśmy sprawdzić, co ta biblioteka robi w środku, nawet jeśli KOPIUJEMY ją :) Więc lepiej sprecyzuj swój komentarz w następujący sposób: „Zdecydowanie odradzam korzystanie z tej biblioteki z hiperłącza ”. Mam nadzieję, że się zgadzasz, dzięki za podpowiedź!na podstawie tego postu na blogu https://8thlight.com/blog/dariusz-pasciak/2016/10/17/docker-compose-wait-for-dependencies.html
Skonfigurowałem mój,
docker-compose.yml
jak pokazano poniżej:Następnie robię dla run =>:
docker-compose up start_dependencies
rabbitmq
usługa uruchomi się w trybie demona,start_dependencies
zakończy pracę.źródło
"curl", "-f", "http://localhost:15672"
którego należy zainstalowaćmanagement
wtyczkę, i sprawdzanie poprawności, które już jest przestarzałe - to najlepsza odpowiedź. Prosty przykład działania z czekiem za pomocąnc
- downvote. ha, ok ...docker-compose run --name app-test --rm "app" bash -l -c 'echo Waiting for mysql service start... && while ! nc -z db-server 3306; do sleep 1; done && echo Connected! && /bin/bash /script/ci_tests.sh'
W wersji 3 pliku Docker Compose możesz użyć RESTART .
Na przykład:
docker-compose.yml
Zauważ, że użyłem depend_on zamiast linków, ponieważ ten ostatni jest przestarzały w wersji 3.
Nawet jeśli działa, może nie być idealnym rozwiązaniem, ponieważ restartujesz kontener dokera przy każdej awarii.
Mają wygląd RESTART_POLICY również. pozwala dostroić zasady restartu.
Podczas korzystania z funkcji Komponuj w produkcji najlepszą praktyką jest użycie zasady ponownego uruchamiania:
źródło
Jednym z alternatywnych rozwiązań jest użycie rozwiązania do aranżacji kontenerów, takiego jak Kubernetes. Kubernetes ma obsługę kontenerów init, które działają do końca, zanim inne kontenery będą mogły się uruchomić. Możesz znaleźć tutaj przykład z kontenerem Linux Server SQL Server 2017, w którym kontener API używa kontenera init do zainicjowania bazy danych
https://www.handsonarchitect.com/2018/08/understand-kubernetes-object-init.html
źródło
Oto przykład, w którym
main
kontener czeka naworker
rozpoczęcie odpowiedzi na ping:Jednak właściwym sposobem jest użycie
healthcheck
(> = 2.1).źródło
Niezalecane w przypadku poważnych wdrożeń, ale tutaj jest zasadniczo polecenie „poczekaj x sekund”.
W
docker-compose
wersji3.4
dodanostart_period
instrukcjęhealthcheck
. Oznacza to, że możemy wykonać następujące czynności:docker-compose.yml
:status.sh
:To, co się tutaj dzieje, polega na tym, że
healthcheck
wywoływane jest po 5 sekundach. To wywołujestatus.sh
skrypt, który zawsze zwraca „Bez problemu”. Właśnie zmusiliśmyzmq_client
kontener do oczekiwania 5 sekund przed rozpoczęciem!Uwaga: ważne, że masz
version: "3.4"
. Jeśli tego.4
nie ma, dokerowanie-komponowanie narzeka.źródło
start_period
robi. Ta konfiguracja oznacza okres karencji, w którym nieudane kontrole stanu nie liczą się jako próby. Jeśli to się powiedzie wcześnie, jest uważane za zdrowe. Po okresie początkowym awaria będzie liczona jako ponowna próba. Zobacz docs.docker.com/engine/reference/builder/#healthcheckMam tylko 2 pliki do komponowania i zaczynam pierwszy, a drugi później. Mój skrypt wygląda tak:
źródło