Sprawdzanie pulsu aplikacji – healthcheck

Trochę teorii

Tworząc swoją aplikacje i udostępniając jej funkcjonalność znajomej społeczności lub klientom dążymy by aplikacja działa stabilnie i żeby można było na niej polegać. Szybko tracimy zaufanie do witryn i aplikacji, które raz działają raz nie. Użytkownik takiej strony szybko się zniechęca i szuka alternatywy. To dlatego przy tworzeniu profesjonalnych witryn i zewnętrznych API podpisuje się tak zwane SLA, w którym często zawarta jest klauzula o gwarantowanej dostępności usługi. Ta dostępność zazwyczaj przewyższa 95% a często sięga 99% i więcej.  Dla przykładu dostępność standardowych serwerów na OVH wynosi 99.95% a wersje premium mają 99.99%. Serwery na Google Cloud mają jeszcze większy stopień gwarancji. 

 

Różne są sposoby zwiększania dostępności. Pierwszym krokiem jest wybranie stabilnego dostawcy infrastruktury, który dba o podstawowe warstwy sprzętu i sieci. W dalszej kolejności liczy się stabilność systemu operacyjnego, który przy eksploatacji poddawany jest aktualizacjom, backupom i różnym czynnością administracyjnym.  Kolejnym poziomem czuwania nad aplikacją jest demon lub innego rodzaju zarządca czuwającym nad procesem (procesami) aplikacji.

 

W Kubernetes w jakiejś mierze odpada nam problem monitorowania serwerów i systemów operacyjnym jednak o ostatnią warstwę, warstwę procesu musimy zadbać sami.  By sprostać temu zadaniu w k8s mamy do dyspozycji klauzule livenessProbe. Odnosi się ona do kontenera i w ramach poda może być użyta wielokrotnie. 

Szybki przegląd

Mamy kilka wariantów użycia livnessProbe w zależności z jakim typem kontenera mamy do czynienia. Mogą być kontenery udostępniające port na TCP lub UDP, mogą być takie, które udostępniają socket, często bazy danych udostępniają soket do komunikacji. Mogą być w reszcie takie, które udostępniają pliki lub robią jakieś operacje na  plikach.  Więc w skład funkcji próbkujących działanie kontenera mamy następujące możliwości:

  • httpGet – zwykłe żądanie http
    • path – ścieżka zapytania np.: /health_check
    • port – dość oczywisty parametr portu dla aplikacji np.: 8080
  • tcpSocket – wykonanie zapytanie na sockecie
    • port – w przypadku socketu zazwyczaj wystarcz port
  • exec – wykonanie polecenia na kontenerze
    • command – tutaj w postaci tablicy podajemy komendę i argumenty

oprócz metody mamy jeszcze kilka intuicyjnych argumentów

  • initialDelaySeconds – czas po którym będą wysyłane pingi
  • periodSeconds – czas oddzielający wysyłanie pingów
  • timeoutSeconds – czas oczekiwania na odpowiedź
  • successThreshold – ilość udanych pingów, po których można uznać usługę za sprawną
  • failureThreshold – ilość nieudanych pingów, po których można uznać usługę za uszkodzoną

Z życia wzięte

Większość aplikacji będzie pingowana przez httpGet, ja używam też tej funkcji do sprawdzania nginx-ów serwujących statyczne strony. Do sprawdzania PostgreSQL-a przydaje się tcpSocket lub exec.

Dla aplikacji bakcend-owej można użyć takiego testu:

Z kolei dla bazy danych SQL

Łatwo można sprawdzić czy dany pod ma healtcheck-a wpisując:

I w opisie w sekcji kontenery dostajemy coś takiego:

Wnioski

W małych aplikacjach taki mechanizm może się wydawać fanaberią, jednak pracując z mikrousługami warto wykorzystywać możliwości narzędzi szczególnie że są dostępne na wyciągniecie ręki. Musze też tu wspomnieć o pewnym niuansie związanym z healthchekami w Kubernetes. Przyznam że na testowym klastrze w Google Cloud gdzie się ustawia zazwyczaj trzy mikro maszyny takie healtcheki na każdym kontenerze mogą zjadać niebagatelny procent zasobów szczególnie gdy mamy podpiętego Heapstera i inne narzędzia monitorujące.

Bibliografia: kubernetes docs , reference