Ważnym punktem w działaniu systemów rozproszonych jest obsługa awarii. Kubernetes pomaga w tym, korzystając z kontrolerów monitorujących stan systemu i restartujących usługi, które przestały działać. Jednak Kubernetes może wymusić zatrzymanie aplikacji, aby zapewnić ogólny stan systemu. W tej serii przyjrzymy się, jak możesz pomóc Kubernetesowi wydajniej wykonywać swoją pracę i skracać przestoje aplikacji.
Przed kontenerami większość aplikacji działała na maszynach wirtualnych lub fizycznych. Jeśli aplikacja uległa awarii lub zawiesiła się, anulowanie trwającego zadania i ponowne załadowanie programu zajęło dużo czasu. W najgorszym przypadku ktoś musiał rozwiązać ten problem ręcznie w nocy, w najbardziej nieodpowiednich godzinach. Jeśli tylko 1-2 pracujące maszyny wykonywały ważne zadanie, takie zakłócenie było całkowicie nie do przyjęcia.
Dlatego zamiast ręcznego ponownego uruchamiania zaczęto stosować monitorowanie na poziomie procesu, aby automatycznie ponownie uruchomić aplikację w przypadku nieprawidłowego zakończenia. Jeśli program ulegnie awarii, proces monitorowania przechwytuje kod zakończenia i ponownie uruchamia serwer. Wraz z pojawieniem się systemów takich jak Kubernetes, ten rodzaj reakcji na awarie systemu został po prostu zintegrowany z infrastrukturą.
Kubernetes wykorzystuje pętlę zdarzeń „obserwuj różnicę, podejmij działanie”, aby zapewnić, że zasoby pozostaną w dobrym stanie podczas podróży z kontenerów do samych węzłów.
Oznacza to, że nie musisz już ręcznie uruchamiać monitorowania procesów. Jeśli zasób nie przejdzie kontroli stanu, Kubernetes po prostu automatycznie zapewni mu zamiennik. Jednak Kubernetes robi znacznie więcej niż tylko monitorowanie aplikacji pod kątem awarii. Może utworzyć więcej kopii aplikacji do uruchomienia na wielu komputerach, zaktualizować aplikację lub uruchomić wiele wersji aplikacji jednocześnie.
Dlatego istnieje wiele powodów, dla których Kubernetes może zakończyć całkowicie zdrowy kontener. Na przykład, jeśli uaktualnisz wdrożenie, Kubernetes będzie powoli zatrzymywał stare pody podczas uruchamiania nowych. Jeśli zamkniesz węzeł, Kubernetes przestanie uruchamiać wszystkie pody w tym węźle. Wreszcie, jeśli w węźle skończą się zasoby, Kubernetes zamknie wszystkie pody, aby zwolnić te zasoby.
Dlatego niezwykle ważne jest, aby aplikacja zakończyła działanie przy minimalnym wpływie na użytkownika końcowego i minimalnym czasie odzyskiwania. Oznacza to, że przed wyłączeniem musi zapisać wszystkie dane, które wymagają zapisania, zamknąć wszystkie połączenia sieciowe, dokończyć pozostałe prace i zająć się innymi pilnymi zadaniami.
W praktyce oznacza to, że aplikacja musi być w stanie obsłużyć komunikat SIGTERM, sygnał zakończenia procesu, który jest domyślnym sygnałem dla narzędzia kill w systemach operacyjnych Unix. Po otrzymaniu tej wiadomości aplikacja powinna zostać zamknięta.
Gdy Kubernetes zdecyduje się zakończyć działanie poda, ma miejsce szereg zdarzeń. Przyjrzyjmy się każdemu krokowi wykonywanemu przez Kubernetes podczas zamykania kontenera lub zasobnika.
Powiedzmy, że chcemy zakończyć jeden z podów. W tym momencie przestanie odbierać nowy ruch — nie będzie to miało wpływu na kontenery działające w poddzie, ale cały nowy ruch zostanie zablokowany.
Przyjrzyjmy się hakowi preStop, czyli specjalnemu poleceniu lub żądaniu HTTP wysyłanemu do kontenerów w zasobniku. Jeśli Twoja aplikacja nie zamyka się poprawnie po otrzymaniu SIGTERM, możesz użyć preStop, aby poprawnie ją zamknąć.
Większość programów zakończy się pomyślnie po otrzymaniu sygnału SIGTERM, ale jeśli używasz kodu innej firmy lub systemu, nad którym nie masz w pełni kontroli, przechwytywanie preStop to świetny sposób na wymuszenie płynnego zamknięcia bez zmiany aplikacji.
Po wykonaniu tego hooka Kubernetes wyśle sygnał SIGTERM do kontenerów w podzespole, informując je, że wkrótce zostaną rozłączone. Po otrzymaniu tego sygnału Twój kod przejdzie do procesu zamykania. Proces ten może obejmować zatrzymanie wszelkich długotrwałych połączeń, takich jak połączenie z bazą danych lub strumień WebSocket, zapisanie bieżącego stanu i tym podobne.
Nawet jeśli korzystasz z hooka preStop, bardzo ważne jest, aby sprawdzić, co dokładnie dzieje się z Twoją aplikacją po wysłaniu do niej sygnału SIGTERM i jak się ona zachowuje, aby zdarzenia lub zmiany w działaniu systemu spowodowane wyłączeniem podu nie przyszły jako niespodzianka dla ciebie.
W tym momencie Kubernetes odczeka określoną ilość czasu, zwaną terminacjąGracePeriodSecond lub okresem, w którym należy bezpiecznie zamknąć system po otrzymaniu sygnału SIGTERM, przed podjęciem dalszych działań.
Domyślnie ten okres wynosi 30 sekund. Należy pamiętać, że działa on równolegle z hakiem preStop i sygnałem SIGTERM. Kubernetes nie będzie czekać na zakończenie przechwytywania preStop i SIGTERM — jeśli aplikacja zakończy działanie przed zakończeniem TerminationGracePeriod, Kubernetes natychmiast przejdzie do następnego kroku. Dlatego sprawdź, czy wartość tego okresu w sekundach jest nie mniejsza niż czas potrzebny do prawidłowego wyłączenia poda, a jeśli przekracza 30s, zwiększ okres do żądanej wartości w YAML. W podanym przykładzie są to lata 60.
I wreszcie ostatni krok polega na tym, że jeśli kontenery nadal działają po zakończeniuGracePeriod, wyślą sygnał SIGKILL i zostaną wymuszone usunięte. W tym momencie Kubernetes wyczyści także wszystkie inne obiekty pod.
Kubernetes kończy działanie podów z wielu powodów, dlatego w każdym przypadku upewnij się, że aplikacja kończy się prawidłowo, aby zapewnić stabilną usługę.
Kilka reklam 🙂
Dziękujemy za pobyt z nami. Podobają Ci się nasze artykuły? Chcesz zobaczyć więcej ciekawych treści? Wesprzyj nas składając zamówienie lub polecając znajomym,
Dell R730xd 2 razy taniej w centrum danych Equinix Tier IV w Amsterdamie? Tylko tutaj
Źródło: www.habr.com