Najczęściej popełniane błędy na początku przygody z Kubernetes

Kubernetes popularne błędy na początku

Jeżeli Twoja ścieżka Kubernauty zawiodła Cię już dalej niż minikube i postanowiłeś zmierzyć się z pełnowymiarowym klastrem Kubernetes warto dowiedzieć się o cudzych błędach (podobno na tych lepiej jest się uczyć).

1. Home Made Kubernetes

Jeżeli myślisz, że samodzielna instalacja klastra na własnych VM to jest dobry pomysł to warto go przemyśleć jeszcze raz. Na początku warto sprawdzić dostępne opcje managed – jak Azure Kubernetes Service (AKS), AWS Elastic Kubernetes Service (EKS) lub inne. Dlaczego? Zarządzany Kubernetes zdejmuje z nas obowiązek robienia backupu bazy danych Kubernetes (ETCD) i tak na prawdę myślenia o tym, że musi być ona ciągle dostępna (High Availability). Podobnie rzecz się ma z samym Master Node’em – nie trzeba o nim specjalnie myśleć (HA). Kolejnym argumentem za zarządzanymi instancjami Kubernetesa jest cyber bezpieczeństwo – instalując klaster samodzielnie konieczna jest dodatkowa konfiguracja (patrz punkt 2).
Ostatnim argumentem w tym punkcie jest to, że Kubernetes jest trudny. Oczywiście – na PowerPoint’cie wygląda prosto, wręcz banalnie biorąc pod uwagę to co zapewnia. Podczas pracy będziesz musiał zmierzyć się z bardzo skomplikowanymi sytuacjami gdzie czas nie będzie Twoim sprzymierzeńcem.

2. kubeadm init a produkcyjność klastra

Jeżeli już zdecydowałeś się na rozwiązanie home made to pewnie spotkałeś się z kubeadm. Dokumentacja kubeadm mówi co prawda, że używa się go aby otrzymać minimum viable cluster i warto o tym pamiętać – że to jest minimum. Na takim klastrze nie będzie dashboard’u, narzędzi do monitorowania czy konfiguracji dla magazynów danych (persistent volume). Najważniejsze jednak, że nie będzie tam również wielu ustawień odpowiadających za bezpieczeństwo – jak brak szyfrowania bazy ETCD, domyślne ustawienia –allow-privileged czy –anonymous-auth, brak ustawień audit i wielu, wielu innych. Dobrym testem dla zabezpieczeń własnego klastra jest kube-bench – szerzej opisany w innym wpisie Czy Mój Kubernetes Jest Bezpieczny? Czyli K8s Security 101.

3. Za małe maszyny dla Node’ów

Fascynacja automatyczną orkiestracją popycha zwykle ludzi w kierunku tworzenia dużej ilości małych maszyn wirtualnych które mają pracować jako tzw. Worker Node (aka minion). Warto jednak pamiętać, że nie obciążony Node potrzebuje około ~1GB RAM i ~1 CPU Core (Docker + Kubelet + OS) a gdzie tu jeszcze instancje kontenerów które chcemy tam uruchamiać!? Dobrym pomysłem na start jest maszyna wirtualna z przynajmniej 2 CPU i 4GB RAM.

Czy to znaczy, że lepsza jest mała ilość dużych maszyn? Odpowiedź brzmi – nie (oczywiście, mogą istnieć scenariusze w których takie ustawienie ma sens). Stawiając na małą ilość maszyn ryzykujemy duże zamieszanie gdy jedna z nich odmówi posłuszeństwa. Niedostępność jednego dużego node’a, spowoduje że wiele podów zostanie przeniesionych na te działające maszyny ale może okazać się, że te już nie mają na tyle dostępnych zasobów. Idealnym rozwiązaniem wydaje się posiadanie większego stadka „średnich” maszyn.

4. Nie używanie Resource Limitów

Niektóre zarządzalne Kubernetesy (jak np. GKE) domyślnie ustawiają dla podów resource limity (default limit jest dobry pod warunkiem – patrz 5.) Co może się jednak stać gdyby tak nie ustawiać tych limitów – bo np. ciężko powiedzieć ile aplikacja będzie potrzebować pamięci/cpu?

Zbadany empirycznie (z produkcji) scenariusz wygląda następująco: niektóre aplikacje nazwijmy je bez limitu mogą pożerać więcej i więcej pamięci RAM. Obok tych pożerających, są też takie które nie są tak bardzo zasobożerne, ale na skutek rozpychania się aplikacji bez limitu, niektóre z nich mogą zostać poproszone o przeniesienie się na inny Node. Problem nastąpi kiedy okaże się z innego Node’a z wolnymi zasobami już nie ma w klastrze. Wtedy ratuje nas autoscaling dla Node’ów albo właśnie resource limits, które w takim wypadku zrestartują niesforną aplikację.

5. Używanie Resource Limitów (w ciemno)

Wiadomo – używać limitów na zasoby warto a nawet trzeba. Jeżeli jednak Resource limits albo Resource requests używa się bez dobrego sprawdzenia ile tak na prawdę dany serwis potrzebuje – można się wpędzić w niemałe kłopoty.

Załóżmy, że ustawienia dla poda wygląda tak:

   resources:
      requests:
        memory: "256Mi"
        cpu: "250m"
      limits:
        memory: "512Mi"
        cpu: "500m"

W takim przypadku – jeżeli nasz serwis/aplikacja będzie potrzebować mniej lub dużo mniej zasobów niż request – możemy dojść do sytuacji w której (przy wielu instancjach serwisów) Node w ogóle nie będzie obciążony a Kubernetes odmówi kolejnego deploymentu ze względu na brak zasobów (suma zasobów z request’ów będzie większa od ilości dostępnych).

Sytuacja oczywiście może być również odwrotna: aplikacja może potrzebować więcej niż ma ustawione w limitach – a przez to, po osiągnięciu np. 512MB wykorzystania pamięci zostanie zrestartowana. Nie trudno sobie wyobrazić problemy, które mogą wystąpić gdy serwisy się ciągle restartują.

CDN

Jak już wspominałem Kubernetes jest trudny, więc te 5 punktów to oczywiście nie jedyne o których warto pomyśleć ale od nich warto zacząć.

Jeżeli Ty masz jakieś ciekawe przypadki rzeczy na które warto zwrócić uwagę – pomóż innym i podziel się nimi na moim fanpage.