Stworzyłem Kube Eagle — eksportera Prometheus. Okazało się, że to świetne narzędzie, które pomaga lepiej zrozumieć zasoby małych i średnich klastrów. W efekcie zaoszczędziłem nie jedną stówkę, ponieważ dobrałem odpowiednie typy maszyn i dostosowałem ograniczenia zasobów aplikacji do obciążeń roboczych.
Opowiem o zaletach , ale najpierw wyjaśnię, co doprowadziło do zamieszania i dlaczego potrzebny był solidny monitoring.
Zarządzałem kilkoma klastrami od 4 do 50 węzłów. W każdym klastrze było maksymalnie 200 mikroserwisów i aplikacji. Aby efektywniej wykorzystać dostępny sprzęt, większość wdrożeń była skonfigurowana z burstable pamięcią operacyjną i zasobami CPU. Dzięki temu pod'y mogły sięgnąć po dostępne zasoby, jeśli zajdzie taka potrzeba, nie przeszkadzając innym aplikacjom na tym węźle. No, czy to nie świetne?
I chociaż klaster zużywał stosunkowo mało CPU (8%) i pamięci (40%), ciągle mieliśmy problemy z wyparciem podów, gdy próbowały przydzielić więcej pamięci niż dostępne na węźle. Mieliśmy wtedy tylko jeden panel do monitorowania zasobów Kubernetes. Taki właśnie:
Panel Grafana z metrykami cAdvisor
Z takim panelem węzły, które konsumują dużo pamięci i CPU, nie stanowią problemu. Problem polega na zrozumieniu, co jest przyczyną. Aby pod'y pozostały na miejscu, można było oczywiście ustawić gwarantowane zasoby dla wszystkich podów (żądane zasoby równe limitowi). Ale to nie jest mądre wykorzystanie sprzętu. Klaster miał kilka setek gigabajtów pamięci, podczas gdy niektóre węzły cierpiały na głód, a inne miały w zapasie po 4–10 GB.
Okazuje się, że scheduler Kubernetes nierównomiernie rozdzielał obciążenia robocze według dostępnych zasobów. Scheduler Kubernetes bierze pod uwagę różne konfiguracje: reguły affinity, taints i tolerancje, selektory węzłów, które mogą ograniczać dostępne węzły. W moim przypadku nic takiego nie było, a pod'y były planowane w zależności od żądanych zasobów na każdym węźle.
Dla pod'a wybierany był węzeł z największą ilością dostępnych zasobów, który spełniał wymagania żądania. Okazało się, że żądane zasoby na węzłach nie pokrywają się z rzeczywistym wykorzystaniem i tutaj na pomoc przyszedł Kube Eagle oraz jego możliwości monitorowania zasobów.
Prawie wszystkie moje klastry Kubernetes były monitorowane tylko za pomocą i . Node Exporter dostarcza statystyki dotyczące wejścia/wyjścia oraz wykorzystania dysku, CPU i pamięci RAM, podczas gdy Kube State Metrics pokazuje metryki obiektów Kubernetes, na przykład zapotrzebowanie i limity dotyczące zasobów CPU i pamięci.
Musimy połączyć metryki zużycia z metrykami zapotrzebowań i limitów w Grafanie, a wtedy uzyskamy pełne informacje o problemie. Brzmi prosto, ale w rzeczywistości w tych dwóch narzędziach etykiety mają różne nazwy, a niektóre metryki wcale nie mają etykiet metadanych. Kube Eagle robi to wszystko samodzielnie, a panel wygląda tak:
Udało nam się rozwiązać wiele problemów z zasobami i zaoszczędzić sprzęt:
- Niektórzy deweloperzy nie wiedzieli, ile zasobów potrzebują mikroserwisy (lub po prostu nie zwracali na to uwagi). Nie mieliśmy sposobu, aby znaleźć nieprawidłowe zapotrzebowania na zasoby — do tego potrzebne są dane o zużyciu oraz zapotrzebowania i limity. Teraz widzą metryki Prometheus, monitorują faktyczne wykorzystanie i dostosowują zapotrzebowania i limity.
- Aplikacje JVM zjadają tyle pamięci RAM, ile są w stanie. Garbage Collector zwalnia pamięć tylko wtedy, gdy wykorzystanie przekracza 75%. A ponieważ większość serwisów korzysta z pamięci burstable, RAM był zawsze zajmowany przez JVM. Dlatego wszystkie te aplikacje Java pochłaniały znacznie więcej pamięci, niż oczekiwano.
- Niektóre aplikacje żądały zbyt dużo pamięci, a scheduler Kubernetes nie przydzielał tych węzłów innym aplikacjom, mimo że w rzeczywistości były one mniej obciążone niż inne węzły. Jeden deweloper przypadkowo dodał dodatkową cyfrę w zapotrzebowaniu, przejmując dużą część pamięci RAM: 20 GB zamiast 2. Nikt tego nie zauważył. Aplikacja miała 3 repliki, więc ucierpiały aż 3 węzły.
- Wprowadziliśmy ograniczenia zasobów, przeplanowaliśmy pody z odpowiednimi zapotrzebowaniami i osiągnęliśmy idealną równowagę wykorzystania sprzętu w całym klastrze. Niektóre węzły można było nawet zamknąć. Potem zauważyliśmy, że mamy nieprawidłowe maszyny (zorientowane na CPU, a nie na pamięć). Zmieniliśmy typ i usunęliśmy jeszcze kilka węzłów.
Podsumowanie
Z zasobami burstable w klastrze skuteczniej wykorzystujesz dostępny sprzęt, ale scheduler Kubernetes planuje pody na podstawie zapotrzebowań, co może przynieść kłopoty. Aby upiec dwie pieczenie na jednym ogniu: unikać problemów i maksymalnie wykorzystywać zasoby, potrzebny jest dobry monitoring. I do tego się przyda. (eksporter Prometheus i panel monitoringu Grafana).
Źródło: habr.com
