Uruchom maszynę, zaloguj się i odkryj, że tunel wstał i zmarł kilka sekund później. Profil był w porządku, certyfikat był w porządku, a jedynym śladem, który pozostał, jest dziennik z tego rozruchu. To, co zwykle się stało, to wyścig: jednostka wystartowała, zanim maszyna miała adres, a kolejność, którą deklarowała, nie znaczyła tego, na co wygląda. Wszystko poniżej dotyczy udowodnienia tego wyścigu na podstawie dowodów i poprawnego jego zamknięcia.

Cel jest punktem spotkania, nie menedżerem

network-online.target nie ma pojęcia, czym jest sieć. To punkt koordynacji, który zbiera tę usługę, która ma opóźnić start, dopóki połączenie nie będzie użyteczne, i deleguje definicję do tego menedżera sieci, który jest właścicielem maszyny. Na większości pulpitów i serwerów oznacza to usługę oczekiwania dostarczaną przez NetworkManager lub systemd-networkd. Jeśli nie włączysz żadnej, cel nie ma na co czekać, więc kończy się w chwili, gdy coś go wciągnie, co może nastąpić długo przed odpowiedzią DHCP. Linia kolejności w twojej jednostce była uczciwa i mimo to bezużyteczna.

Pierwsze pytanie nie brzmi więc, co deklaruje twoja jednostka. Lecz czy cokolwiek na tej maszynie naprawdę wykonuje oczekiwanie.

Czytaj ostatni rozruch, a nie plik jednostki

Pliki jednostek opisują intencję, a dziennik opisuje, co się stało. Poproś tylko o ten rozruch, z monotonicznymi znacznikami czasu, aby każdy komunikat siedział na jednym zegarze. Następnie znajdź dwie linie: moment, w którym jednostka tunelu zaczęła startować, oraz moment, w którym pojawił się adres albo zakończyła się usługa oczekiwania. Uporządkuj te dwie liczby, a wyścig jest albo potwierdzony, albo wykluczony.

Widok zależności to potwierdza. Jeśli krytyczny łańcuch jednostki tunelu nie zawiera usługi oczekiwania, nic na tej ścieżce nie opóźniło startu, a cel nie wykonał pracy, którą zakładałeś. Dwa widoki, jeden wniosek.

systemctl list-units --type=service --state=running | grep wait-online
journalctl -b -o short-monotonic -u openvpn-client@office

Dodaj oczekiwanie, potem ponowną próbę

Użyj drop-inu zamiast edytować zapakowaną jednostkę, aby aktualizacja pakietu nie odrzuciła zmiany po cichu. Znaczenie mają dwie dyrektywy: jednostka musi być uporządkowana po celu i musi wciągnąć cel do tej samej transakcji. Sama kolejność nie przywołuje celu; robi to pragnienie.

Zapakowana jednostka klienta OpenVPN już nosi oba. Jednostki pisane ręcznie zwykle noszą jedno albo żadne, co warto sprawdzić, zanim cokolwiek dodasz.

[Service]
Restart=on-failure
RestartSec=15

Dlaczego stały sen to pułapka

Sen w ExecStartPre wydaje się poprawką kolejności, a zachowuje się jak opóźnienie z dodatkowymi krokami. Spowalnia każdy rozruch, także te, które były zdrowe, i mimo to przegrywa, gdy połączenie trwa dłużej niż wybrana liczba.

Co gorsza, ukrywa, czy usługa oczekiwania działa, więc następna awaria jawi się jako zupełnie nowy problem, a nie ten sam z innym czasem. Krótkie opóźnienie restartu jest lepszym narzędziem: nic nie kosztuje przy zdrowym rozruchu i zamienia przegrany wyścig w kolejną próbę. Utrzymuj interwał skromny i pozwól jednostce odnieść sukces. Jeśli restartuje się wiecznie, profil jest zepsuty i żadna liczba prób tego nie zmieni, więc czytaj dziennik, zamiast podnosić interwał.

Gdy kolejność jest poprawna, a nazwy wciąż zawodzą

Aktywna jednostka z trasą tunelu oznacza, że kolejność wykonała swoją pracę, a pozostały błąd siedzi o warstwę wyżej. Zwykłą formą jest ustawienie resolvera stosowane przez skrypt up tunelu, zanim połączenie lub resolver były gotowe je utrzymać. Porównaj stan resolvera podczas awarii ze stanem po restarcie jednostki tunelu.

Jeśli restart naprawia wyszukiwania, masz defekt kolejności startu, a nie zły serwer DNS, i te dwa wymagają różnych poprawek. Następnie udowodnij całość zimnym rozruchem zamiast restartu usługi, ponieważ restart działa wobec sieci, która już jest podniesiona, i ukryje dokładnie ten defekt, którego szukasz. Powtórz to z połączeniem celowo wolnym i traktuj jednostkę, która działa tylko przy szybkiej sieci, jako wciąż zepsutą.

Powiązane artykuły