Najlepsze praktyki Kubernetes. Konfiguracja żądań i limitów zasobów

Najlepsze praktyki Kubernetes. Tworzenie małych kontenerów
Najlepsze praktyki Kubernetes. Organizacja Kubernetes z przestrzenią nazw
Najlepsze praktyki Kubernetes. Sprawdzanie żywotności Kubernetes za pomocą testów Readiness i Liveness

Dla każdego zasobu Kubernetes istnieje możliwość skonfigurowania dwóch typów wymagań - Requests i Limits. Pierwsze opisuje minimalne wymagania dotyczące dostępności wolnych zasobów węzła, niezbędnych do uruchomienia kontenera lub poda, a drugie sztywno ogranicza zasoby dostępne dla kontenera.

Kiedy Kubernetes planuje pod, bardzo ważne jest, aby kontenery miały wystarczające zasoby do normalnego działania. Jeśli planujesz wdrożyć dużą aplikację na węźle z ograniczonymi zasobami, istnieje duże prawdopodobieństwo, że nie będzie ona działać z powodu braku pamięci lub niewystarczającej mocy procesora. W tym artykule omówimy, jak można rozwiązać problemy z brakiem mocy obliczeniowej za pomocą żądań zasobów i ograniczeń.

Żądania Requests i ograniczenia Limits to mechanizmy, które Kubernetes wykorzystuje do zarządzania takimi zasobami jak procesor i pamięć. Requests to to, dzięki czemu kontener gwarantowanie otrzymuje żądany zasób. Jeśli kontener żąda zasobu, Kubernetes zaplanuje go tylko na tym węźle, który jest w stanie go zapewnić. Ograniczenia Limits kontrolują, że zasoby żądane przez kontener nigdy nie przekroczą określonej wartości.

Najlepsze praktyki Kubernetes. Konfiguracja żądań i limitów zasobów

Kontener może zwiększać moce obliczeniowe tylko do określonego limitu, po czym będzie ograniczony. Przyjrzyjmy się, jak to działa. Istnieją dwa typy zasobów - procesor i pamięć. Planista Kubernetes wykorzystuje dane o tych zasobach, aby ustalić, gdzie uruchamiać Twoje pady. Typowa specyfikacja zasobów dla poda wygląda tak.

Najlepsze praktyki Kubernetes. Konfiguracja żądań i limitów zasobów

Każdy kontener w podzie może ustawiać własne limity i zapotrzebowania, wszystko odbywa się w sposób addytywny. Zasoby procesora określane są w mili-core'ach. Jeśli twój kontener potrzebuje do działania dwóch pełnych rdzeni, ustalasz wartość 2000m. Jeśli natomiast kontener wymaga tylko 1/4 rdzenia, wartość wyniesie 250m. Pamiętaj, że jeśli przydzielisz wartość zasobów procesora większą niż liczba rdzeni największego węzła, uruchomienie twojego poda w ogóle nie zostanie zaplanowane. Podobna sytuacja zajdzie, jeśli będziesz miał pod, który potrzebuje czterech rdzeni, a klaster Kubernetes składa się tylko z dwóch podstawowych maszyn wirtualnych.

O ile twoja aplikacja nie jest specjalnie zaprojektowana do wykorzystania zalet wielu rdzeni (na myśli mam takie programy jak zaawansowane obliczenia naukowe oraz operacje na bazach danych), to najlepszą praktyką jest ustawienie zapotrzebowania CPU na 1 lub mniej, a następnie uruchomienie większej liczby replik dla skalowalności. Takie rozwiązanie nada systemowi większą elastyczność i niezawodność.

Kiedy mowa o limitach procesora, sytuacja staje się ciekawsza, ponieważ jest on uważany za zasób kompresowalny. Jeśli twoja aplikacja zacznie zbliżać się do limitu mocy procesora, Kubernetes zacznie spowalniać twój kontener, wykorzystując CPU Throttling — obniżenie częstotliwości procesora. Oznacza to, że procesor będzie sztucznie ograniczany, co może prowadzić do gorszej wydajności aplikacji, jednak proces nie zostanie przerwany ani zakończony.

Zasoby pamięci określane są w bajtach. Zazwyczaj wartość w ustawieniach mierzona jest w mebibajtach Mib, ale możesz ustawić dowolną wartość, od bajtów do petabajtów. Sytuacja z pamięcią jest podobna do tej z CPU — jeśli umieścisz zapotrzebowanie na ilość pamięci przekraczającą dostępność pamięci na twoich węzłach, wykonanie tego poda nie będzie zaplanowane. Jednak w odróżnieniu od zasobów procesora, pamięć nie jest kompresowalna, ponieważ nie ma sposobu na ograniczenie jej użycia. Dlatego wykonanie kontenera zostanie zatrzymane, gdy tylko przekroczy przydzieloną mu pamięć.

Najlepsze praktyki Kubernetes. Konfiguracja żądań i limitów zasobów

Ważne jest, aby pamiętać, że nie możesz ustawić zapytań, które przekraczają rozmiar zasobów, jakie mogą zapewnić twoje węzły. Cechy wspólnych zasobów dla maszyn wirtualnych GKE można znaleźć w linkach umieszczonych poniżej tego wideo.

W idealnym świecie domyślne ustawienia kontenera powinny być wystarczające, aby procesy przebiegały gładko. Jednak rzeczywistość jest inna – ludzie mogą łatwo zapomnieć o konfiguracji wykorzystania zasobów, a hakerzy mogą ustawić zapytania i ograniczenia przekraczające rzeczywiste możliwości infrastruktury. Aby zapobiec takim scenariuszom, można skonfigurować kwoty zasobów ResourceQuota oraz zakresy limitów LimitRange.

Po utworzeniu przestrzeni nazw można je zablokować za pomocą kwot. Na przykład, jeśli masz przestrzenie nazw prod i dev, stosuje się wzór, w którym kwoty dla produkcji są całkowicie nieobecne, a kwoty dla rozwoju są bardzo rygorystyczne. Pozwala to na to, aby w przypadku nagłego wzrostu ruchu, prod mógł zająć cały dostępny zasób, całkowicie blokując dev.

Kwota zasobów może wyglądać w ten sposób. W tym przykładzie mamy 4 sekcje – to 4 dolne linie kodu.

Najlepsze praktyki Kubernetes. Konfiguracja żądań i limitów zasobów

Przyjrzyjmy się każdemu z nich. Requests.cpu to maksymalna liczba skumulowanych zapytań mocy procesora, które mogą pochodzić ze wszystkich kontenerów w przestrzeni nazw. W tym przykładzie możesz mieć 50 kontenerów z zapytaniami po 10m, pięć kontenerów z zapytaniami po 100m lub po prostu jeden kontener z zapytaniem 500m. Dopóki całkowita liczba requests.cpu tej przestrzeni nazw będzie mniejsza niż 500m, wszystko będzie w porządku.

Zapytana pamięć requests.memory to maksymalna wartość skumulowanych zapytań pamięci, które mogą mieć wszystkie kontenery w przestrzeni nazw. Podobnie jak wcześniej, możesz mieć 50 kontenerów po 2 MiB, pięć kontenerów po 20 MiB lub jeden kontener z 100 MiB, dopóki całkowita liczba zapytanej pamięci w przestrzeni nazw będzie mniejsza niż 100 mebibajtów.

Limits.cpu to maksymalna skumulowana wartość mocy procesora, którą mogą wykorzystać wszystkie kontenery w przestrzeni nazw. Można to postrzegać jako limit zapytań mocy procesora.

Ostatecznie, limits.memory to maksymalna ilość pamięci ogólnej, którą mogą wykorzystać wszystkie kontenery w przestrzeni nazw. To ograniczenie sumarycznych żądań pamięci.
Domyślnie kontenery w klastrze Kubernetes działają z nieograniczonymi zasobami obliczeniowymi. Dzięki kwotom zasobów, administratorzy klastra mogą ograniczyć zużycie zasobów oraz ich tworzenie na podstawie przestrzeni nazw. W przestrzeni nazw moduł pod lub kontener może zużywać tyle mocy CPU i pamięci, ile zostało określone przez kwotę zasobów przestrzeni nazw. Istnieje jednak obawa, że jeden pod lub kontener może zmonopolizować wszystkie dostępne zasoby. Aby zapobiec takiej sytuacji, stosuje się zakres limitów Limit Range - politykę ograniczającą przydział zasobów (dla podów lub kontenerów) w przestrzeni nazw.

Zakres limitów zapewnia ograniczenia, które mogą:

  • zapewniać minimalne i maksymalne wykorzystanie zasobów obliczeniowych dla każdego modułu lub kontenera w przestrzeni nazw;
  • wymuszać minimalne i maksymalne żądanie pamięci Storage Request dla każdego PersistentVolumeClaim w przestrzeni nazw;
  • wymuszać ustalanie stosunku pomiędzy żądaniem Request a ograniczeniem Limit dla zasobu w przestrzeni nazw;
  • ustalać Requests/Limits domyślnie dla zasobów obliczeniowych w przestrzeni nazw i automatycznie wprowadzać je do kontenerów podczas uruchamiania.

W ten sposób możesz stworzyć zakres limitów w swojej przestrzeni nazw. W przeciwieństwie do kwoty, która dotyczy całej przestrzeni nazw, Limit Range dotyczy poszczególnych kontenerów. Może to zapobiec tworzeniu przez użytkowników zbyt małych lub przeciwnie, gigantycznych kontenerów w przestrzeni nazw. Zakres limitów Limit Range może wyglądać tak.

Najlepsze praktyki Kubernetes. Konfiguracja żądań i limitów zasobów

Podobnie jak w poprzednim przypadku, można tu wyróżnić 4 sekcje. Przyjrzyjmy się każdemu z nich.
W sekcji default ustalane są domyślne ograniczenia dla kontenera w podzie. Jeśli ustawisz te wartości w zakresie limitów, to wszelkie kontenery, dla których te wartości nie zostały wyraźnie określone, będą kierowane przez wartości domyślne.

W sekcji domyślne żądanie defaultRequest ustawione są domyślne żądania dla kontenera w podzie. Ponownie, jeśli ustawisz te wartości w zakresie maksymalnym, to wszelkie kontenery, dla których te parametry nie są jawnie określone, będą korzystać z tych wartości domyślnych.

W sekcji max określone są maksymalne limity, które mogą być ustawione dla kontenera w podzie. Wartości w sekcji default i limity dla kontenera nie mogą być ustawione powyżej tego limitu. Ważne jest, że jeśli ustawiona jest wartość max, a sekcja default jest nieobecna, to maksymalna wartość staje się wartością domyślną.

W sekcji min określone są minimalne żądania, które mogą być ustawione dla kontenera w podzie. Przy tym wartości w sekcji default i żądania dla kontenera nie mogą być ustawione poniżej tego limitu.

Ponownie, ważne jest, że jeśli ta wartość jest ustawiona, a default – nie, to minimalna wartość staje się żądaniem domyślnym.

Ostatecznie te żądania zasobów są używane przez scheduler Kubernetes do realizacji twoich obciążeń roboczych. Aby prawidłowo skonfigurować swoje kontenery, bardzo ważne jest zrozumienie, jak to działa. Załóżmy, że chcesz uruchomić kilka modułów w swoim klastrze. Zakładając, że specyfikacje podu są ważne, w harmonogramie Kubernetes używana będzie cykliczna równoważenie dla wyboru węzła do realizacji obciążenia roboczego.

Najlepsze praktyki Kubernetes. Konfiguracja żądań i limitów zasobów

Kubernetes sprawdzi, czy węzeł Node 1 ma wystarczające zasoby do realizacji żądań kontenerów podu. Jeśli nie, przejdzie do następnego węzła. Jeśli żaden z węzłów w systemie nie jest w stanie zaspokoić żądań, pody przechodzą w stan oczekiwania Pending state. Dzięki funkcjom takim jak automatyczne skalowanie węzłów, Google Kubernetes Engine (GKE) może automatycznie wykryć stan oczekiwania i utworzyć kilka dodatkowych węzłów.

Jeśli później pojawi się nadmiarowa pojemność węzłów, funkcja automatycznego skalowania zmniejszy ich liczbę, aby zaoszczędzić ci pieniądze. Dlatego Kubernetes planuje pody na podstawie żądań. Jednak limit może być wyższy niż żądania i w niektórych przypadkach węzeł może faktycznie wyczerpać zasoby. Nazywamy ten stan stanem overcommitment.

Najlepsze praktyki Kubernetes. Konfiguracja żądań i limitów zasobów

Jak już wspomniałem, jeśli mówimy o procesorze, Kubernetes zacznie ograniczać zasoby dla podów. Każdy pod otrzyma tyle, ile poprosił, ale jeśli nie osiągnie limitu, zacznie być stosowane throttling.

Jeśli chodzi o zasoby pamięci, Kubernetes musi podejmować decyzje, które pody usunąć, a które zatrzymać, dopóki nie zwolnisz zasobów systemowych, w przeciwnym razie cała system się zawali.

Wyobraźmy sobie scenariusz, w którym masz maszynę, która wyczerpała limit pamięci – jak w takim przypadku zareaguje Kubernetes?

Kubernetes będzie szukał podów, które używają więcej zasobów, niż prosiły. Jeżeli twoje kontenery w ogóle nie mają ustawionych Requests, to oznacza, że domyślnie wykorzystują więcej, niż prosiły, po prostu dlatego, że w ogóle nic nie prosiły! Takie kontenery stają się głównymi kandydatami do wyłączenia. Kolejnymi kandydatami są kontenery, które zaspokoiły wszystkie swoje prośby, ale nadal są poniżej maksymalnego limitu.

Jeśli Kubernetes znajdzie kilka podów, które przekroczyły parametry swoich prośb, to posortuje je według priorytetu, a następnie usunie te o najniższym priorytecie. Jeśli wszystkie moduły mają ten sam priorytet, Kubernetes zakończy pracę tych podów, które przekroczyły swoje prośby bardziej niż inne pody.

W bardzo rzadkich przypadkach Kubernetes może przerwać działanie podów, które nadal mieszczą się w ramach swoich prośb. Może się to zdarzyć, gdy krytyczne komponenty systemu, takie jak agent Kubelet lub Docker, zaczynają wykorzystywać więcej zasobów, niż zostało dla nich zarezerwowanych.
Na wczesnych etapach działalności małych firm klaster Kubernetes może działać doskonale bez ustawiania prośb o zasoby i ograniczeń, ale w miarę wzrostu zespołów i projektów ryzykujesz napotkanie problemów w tej dziedzinie. Dodanie prośb i ograniczeń do twoich modułów i przestrzeni nazw wymaga niewielkich dodatkowych wysiłków i może zaoszczędzić wiele kłopotów.

Najlepsze praktyki Kubernetes. Prawidłowe wyłączanie Terminate

Odtwarzaj wideo

Trochę reklamy 🙂

Dziękujemy, że jesteś z nami. Podobają Ci się nasze artykuły? Chcesz zobaczyć więcej interesujących materiałów? Wspieraj nas składając zamówienie lub polecając nas znajomym, chmurowe VPS dla programistów od 4,99 $, unikatowy odpowiednik serwerów entry-level, który został stworzony przez nas dla Ciebie: Cała prawda o VPS (KVM) E5-2697 v3 (6 rdzeni) 10GB DDR4 480GB SSD 1Gbps od 19 $ lub jak prawidłowo podzielić serwer? (dostępne opcje z RAID1 i RAID10, do 24 rdzeni i do 40GB DDR4).

Dell R730xd dwa razy tańszy w centrum danych Equinix Tier IV w Amsterdamie? Tylko u nas 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100TB od 199 dolarów w Holandii! Dell R420 — 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB — od 99 dolarów! Czytaj o tym Jak zbudować infrastrukturę klasy korporacyjnej z zastosowaniem serwerów Dell R730xd E5-2650 v4 kosztujących 9000 euro za grosze?

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster