Istnieje wiele powodów, dla których ansible może zawiesić się podczas zbierania faktów, ale zanim przejdziemy dalej, oto pierwszy test, który powinieneś zrobić w takiej sytuacji:
ansible -m ping <hostname>
Ten test po prostu łączy się z hostem i wykonuje wystarczającą ilość kodu, aby zwrócić:
<hostname> | SUCCESS => {
"changed": false,
"ping": "pong"
}
Jeśli to zadziała, możesz praktycznie wykluczyć wszelkie problemy z konfiguracją lub łącznością, ponieważ dowodzi to, że możesz rozwiązać docelową nazwę hosta, otworzyć połączenie, uwierzytelnić się i uruchomić moduł odpowiadający za pomocą zdalnego interpretera python.
Oto (niewyczerpująca) lista rzeczy, które mogą się nie udać na początku podręcznika:
Polecenie wykonane przez ansible czeka na interaktywne wejście
Pamiętam, że działo się to w starszych wersjach ansible, gdzie polecenie czekałoby na interaktywne wejście, które nigdy nie nadejdzie, takie jak hasło sudo (gdy zapomnisz -K
przełącznika) lub akceptacja nowego odcisku palca hosta ssh (dla nowego celu gospodarz).
Nowoczesne wersje ansible obsługują oba te przypadki z wdziękiem i natychmiast zgłaszają błąd w normalnych przypadkach użycia, więc jeśli nie robisz rzeczy takich jak wywołanie ssh lub sudo, nie powinieneś mieć tego rodzaju problemu. A nawet gdyby tak było, byłoby to po zebraniu faktów.
Dead master ssh connection
Istnieje kilka bardzo interesujących opcji przekazanych klientowi ssh w podanym tutaj dzienniku debugowania:
ControlMaster=auto
ControlPersist=60s
ControlPath=/home/vagrant/.ansible/cp/ansible-ssh-%h-%p-%r
Opcje te są udokumentowane w man ssh_config .
Domyślnie ansible będzie sprytnie pod względem korzystania z połączenia ssh. Dla danego hosta zamiast tworzyć nowe połączenie dla każdego zadania w grze, otworzy je raz i pozostanie otwarte dla całego podręcznika (a nawet wszystkich podręczników).
To dobrze, ponieważ ustanowienie nowego połączenia jest znacznie wolniejsze i wymaga intensywniejszych obliczeń niż korzystanie z już istniejącego.
W praktyce każde połączenie ssh sprawdzi istnienie gniazda w ~/.ansible/cp/some-host-specific-path
. Pierwsze połączenie nie może go znaleźć, więc łączy się normalnie, a następnie tworzy je. Każde kolejne połączenie będzie wtedy używać tego gniazda do przejścia przez już ustanowione połączenie.
Nawet jeśli ustanowione połączenie w końcu skończy się i zamyka po nieużywaniu przez wystarczająco długi czas, gniazdo jest również zamknięte, a my wracamy do punktu wyjścia.
Na razie w porządku.
Czasami jednak połączenie faktycznie zanika, ale klient ssh nadal uważa, że zostało ustanowione. Zazwyczaj dzieje się tak, gdy uruchamiasz podręcznik z laptopa i tracisz połączenie Wi-Fi (lub przełączasz się z Wi-Fi na Ethernet itp.)
Ten ostatni przykład jest straszna sytuacja: ty może ssh do urządzenia docelowego za pomocą domyślnej konfiguracji ssh, ale tak długo jak poprzednia gra jest nadal uważane za aktywne, ansibl nie będzie nawet próbować ustanowienie nowego.
W tym momencie chcemy po prostu pozbyć się tego starego gniazda, a najprostszym sposobem na to jest jego usunięcie:
# Delete all the current sockets (may disrupt currently running playbooks)
rm -r ~/.ansible/cp
# Delete only the affected socket (requires to know which one it is)
rm ~/.ansible/cp/<replace-by-your-socket>
Jest to idealne rozwiązanie dla jednorazowej poprawki, ale jeśli zdarza się to zbyt często, może być konieczne znalezienie rozwiązania długoterminowego. Oto kilka wskazówek, które mogą pomóc w osiągnięciu tego celu:
- Uruchamiaj poradniki z serwera (połączenie sieciowe jest znacznie bardziej stabilne niż w laptopie)
- Użyj konfiguracji ansible lub bezpośrednio konfiguracji klienta ssh, aby wyłączyć udostępnianie połączenia
- Korzystaj z tych samych zasobów, ale dostrajaj limity czasu, aby awaria połączenia nadrzędnego faktycznie upływała szybciej
Należy pamiętać, że w momencie pisania zmieniło się kilka opcji (na przykład moja ostatnia seria dała mi ControlPath=/home/toadjaune/.ansible/cp/871b533295
), ale ogólny pomysł jest nadal aktualny.
Zbieranie faktów zajmuje zbyt wiele czasu
Na początku każdej gry ansible zbiera wiele informacji o systemie docelowym i umieszcza je w faktach . Są to zmienne, których możesz użyć w swoim poradniku i są one zwykle bardzo przydatne, ale czasami uzyskanie tych informacji może być bardzo długie (złe punkty montowania, dyski z wysokim we / wy, duże obciążenie…)
Mówiąc to, nie bezwzględnie potrzebują faktów uruchomić playbook, a prawie na pewno nie wszystkie z nich, więc spróbujmy i wyłączyć, czego nie potrzebujesz. Kilka opcji:
Do celów debugowania bardzo wygodnie jest wywołać moduł instalacyjny bezpośrednio z wiersza poleceń:
ansible -m setup <hostname>
To ostatnie polecenie powinno się zawiesić, podobnie jak twój poradnik, i ostatecznie przekroczyć limit czasu (lub zakończyć się sukcesem). Teraz uruchommy ponownie moduł, wyłączając wszystko, co możemy:
ansible -m setup -a gather_subset='!all' <hostname>
Jeśli nadal się zawiesza, zawsze możesz spróbować całkowicie wyłączyć moduł w swojej grze, ale jest bardzo prawdopodobne, że twój problem jest gdzie indziej.
Jeśli jednak działa dobrze (i szybko), zajrzyj do dokumentacji modułu . Masz dwie opcje:
- Ogranicz zbieranie faktów do podzbioru, wyłączając to, czego nie potrzebujesz (zobacz możliwe wartości dla
gather_subset
)
gather_timeout
może również pomóc w rozwiązaniu problemu, dając więcej czasu (chociaż byłoby to naprawienie błędu przekroczenia limitu czasu, a nie zawieszenie się)
Inne sprawy
Oczywiście inne rzeczy mogą pójść nie tak. Kilka wskazówek ułatwiających debugowanie:
- Użyj ansible maximum verbosity level (
-vvvv
), ponieważ pokaże ci każde wykonane polecenie
- Użyj
ping
i setup
modułów bezpośrednio z wiersza polecenia, jak wyjaśniono powyżej
- Spróbuj ssh ręcznie, jeśli
ansible -m ping
nie działa
vagrant ssh
sprawdzić podczas zawieszenia, czy jest coś przydatnego wps
inetstat
? Ponadto jednym z pierwszych podejrzanych w zawieszaniu jest DNS - sprawdź, czy DNS jest rozpoznawany z poziomu maszyny wirtualnej.