Kubernetes został wymyślony i zainicjowany w Google – wydawać by się mogło, że ich produkt – Google Kubernetes Engine będzie najbardziej dojrzałym z zarządzanych klastrów (inne: EKS – Amazon, AKS – Microsoft Azure).
Czy na pewno?
Patrząc na fragment skryptu o nazwie health-monitor.sh można zacząć się zastanawiać:
W skrócie – skrypt uruchamiany jest co jakiś czas i sprawdza czy proces docker odpowiada (używając komendy docker ps – pokaż działające kontenery). Jeżeli po 10 sekundach nie ma odpowiedzi zostaje wywołana kolejna komenda:
pkill docker
Drastycznie? Przejdźmy do drugiej funkcji z tego skryptu – o miłej nazwie kubelet-monitoring. Kubelet to proces, który jest uruchamiany przez klaster Kubernetes na wszystkich nodach (taki agent) i zajmuje się uruchamianiem kontenerów na każdym z tych nodów. Jak widać jest to kluczowy proces dla każdego node’a i ważne jest żeby działał poprawnie. Dlatego Kubelet wystawia endpoint /healthz (domyślnie na porcie 10250) który jest odpytywany co jakiś czas przez Node Controller (inny agent na masterze sprawdzający czy jego nody żyją). Wygląda to pięknie, po co więc dodatkowy skrypt instalowany na tej samej maszynie co Kubelet? Okazuje się, że jest potrzebny bo Kubernetes Master (za pośrednictwem Node Controllera) dowie się, że Kubelet przestał odpowiadać i jedyne co zrobi, to uruchomi pody na innym nodzie. Bez sentymentów oznaczy go jako Not Ready lub Unknown i nie będzie mu dawał żadnej pracy.
Pasywny i aktywny monitoring
To co robi Node Controller wygląda więc na typowy pasywny monitoring, a skrypt od kolegów z Google działa bardziej aktywnie. W przypadku braku odpowiedzi z endpointa /healthz zostaje wywołana komenda:
pkill kubelet
Oczywiście serwisy docker i kubelet zostana uruchomione ponownie – jak większość ludzi – ludzie z Google również są związani kajdanami do systemd. (cytat z dokumentacji K3s -> link)
W jakim scenariuszu taki skrypt może być przydatny?
No, no, no, no, no, no, no, no, no ,no ,no, no there’s no limit
- Uruchamiasz aplikacje na Kubernetes bez ustawiania cpu limit i memory limit w swoim deploymencie
- Aplikacja zaczyna pożerać więcej i więcej – „there’s no limit”
- Kubelet przestaje odpowiadać (bo nie może się dopchać do procesora)
- Master zauważa brak odpowiedzi od jednego z Nodów
- Master przenosi morderczą aplikację na inny Node
- Goto 2
Taka pętla śmierci może się przytrafić każdemu – wystarczy deployment bez limitu i aplikacja z problemami. Rezultatem jest Kubernetes klaster, który nie działa i nie ważne czy tam było 5 czy 500 maszyn.
Pomysł deweloperów Google Cloud Platform wydaje się w takiej perspektywie co najmniej dobry. Jedyne co nie budzi wielkiego zaufania, to komentarz jednego z nich w tym kodzie:
# TODO(andyzheng0831): replace it with a more reliable method if possible.