Najlepsze praktyki Kubernetesa. Konfigurowanie żądań zasobów i limitów

Najlepsze praktyki Kubernetesa. Tworzenie małych pojemników
Najlepsze praktyki Kubernetesa. Organizacja Kubernetesa z przestrzenią nazw
Najlepsze praktyki Kubernetesa. Weryfikacja żywotności Kubernetesa za pomocą testów gotowości i żywotności

Dla każdego zasobu Kubernetes możesz skonfigurować dwa typy wymagań – Żądania i Limity. Pierwsza opisuje minimalne wymagania dotyczące dostępności wolnych zasobów węzła niezbędnych do uruchomienia kontenera lub poda, druga ściśle ogranicza zasoby dostępne dla kontenera.

Kiedy Kubernetes planuje pody, bardzo ważne jest, aby kontenery miały wystarczającą ilość zasobów do prawidłowego działania. Jeśli planujesz wdrożyć dużą aplikację w węźle o ograniczonych zasobach, możliwe, że nie zostanie ona uruchomiona, ponieważ w węźle kończy się pamięć lub kończy się moc procesora. W tym artykule przyjrzymy się, jak rozwiązać problemy z niedoborami mocy obliczeniowej, korzystając z żądań i limitów zasobów.

Żądania i limity to mechanizmy używane przez Kubernetes do zarządzania zasobami, takimi jak procesor i pamięć. Żądania zapewniają, że kontener otrzyma żądany zasób. Jeśli kontener zażąda zasobu, Kubernetes zaplanuje go tylko w węźle, który może go udostępnić. Limity kontrolują, czy zasoby żądane przez kontener nigdy nie przekroczą określonej wartości.

Najlepsze praktyki Kubernetesa. Konfigurowanie żądań zasobów i limitów

Kontener może zwiększyć swoją moc obliczeniową jedynie do pewnego limitu, po przekroczeniu którego będzie ona ograniczona. Zobaczmy jak to działa. Istnieją więc dwa rodzaje zasobów - procesor i pamięć. Harmonogram Kubernetes wykorzystuje dane o tych zasobach, aby dowiedzieć się, gdzie uruchomić pody. Typowa specyfikacja zasobów dla poda wygląda następująco.

Najlepsze praktyki Kubernetesa. Konfigurowanie żądań zasobów i limitów

Każdy kontener w kapsule może ustawić własne zapytania i limity, wszystko to jest addytywne. Zasoby procesora są definiowane w milirdzeniowych. Jeśli Twój kontener potrzebuje do działania dwóch pełnych rdzeni, ustawiasz wartość na 2000m. Jeśli kontener potrzebuje tylko mocy 1/4 rdzenia, wartość wyniesie 250m. Pamiętaj, że jeśli przypiszesz wartość zasobu procesora większą niż liczba rdzeni największego węzła, uruchomienie poda nie zostanie w ogóle zaplanowane. Podobna sytuacja będzie miała miejsce, jeśli masz Poda, który potrzebuje czterech rdzeni, a klaster Kubernetes składa się tylko z dwóch głównych maszyn wirtualnych.

O ile aplikacja nie jest zaprojektowana specjalnie do wykorzystania wielu rdzeni (przychodzą mi na myśl programy takie jak złożone obliczenia naukowe i operacje na bazach danych), najlepszą praktyką jest ustawienie żądań procesora na 1 lub niższą, a następnie uruchomienie większej liczby replik w celu zapewnienia skalowalności. Rozwiązanie to zapewni systemowi większą elastyczność i niezawodność.

Jeśli chodzi o ograniczenia procesora, sytuacja staje się bardziej interesująca, ponieważ jest on uważany za zasób ściśliwy. Jeśli Twoja aplikacja zacznie zbliżać się do limitu mocy procesora, Kubernetes zacznie spowalniać Twój kontener za pomocą CPU Throttling – zmniejszając częstotliwość procesora. Oznacza to, że procesor zostanie sztucznie dławiony, co spowoduje potencjalnie gorszą wydajność aplikacji, ale proces nie zostanie przerwany ani wstrzymany.

Zasoby pamięci są definiowane w bajtach. Zwykle wartość w ustawieniach jest mierzona w mebibajtach Mib, ale możesz ustawić dowolną wartość, od bajtów do petabajtów. Tutaj obowiązuje ta sama sytuacja, co w przypadku procesora - jeśli złożysz żądanie dotyczące ilości pamięci większej niż ilość pamięci w twoich węzłach, wykonanie tego poda nie zostanie zaplanowane. Jednak w przeciwieństwie do zasobów procesora, pamięć nie jest kompresowana, ponieważ nie ma możliwości ograniczenia jej wykorzystania. Dlatego wykonywanie kontenera zostanie zatrzymane, gdy tylko przekroczy on przydzieloną mu pamięć.

Najlepsze praktyki Kubernetesa. Konfigurowanie żądań zasobów i limitów

Należy pamiętać, że nie można konfigurować żądań przekraczających zasoby, jakie mogą zapewnić węzły. Specyfikacje zasobów udostępnionych dla maszyn wirtualnych GKE można znaleźć w linkach pod tym filmem.

W idealnym świecie domyślne ustawienia kontenera wystarczą, aby przepływy pracy przebiegały sprawnie. Ale prawdziwy świat taki nie jest, ludzie mogą łatwo zapomnieć o skonfigurowaniu wykorzystania zasobów, albo hakerzy ustawią żądania i ograniczenia, które przekraczają rzeczywiste możliwości infrastruktury. Aby zapobiec takim scenariuszom, można skonfigurować przydziały zasobów ResourceQuota i LimitRange.

Po utworzeniu przestrzeni nazw można ją zablokować przy użyciu kwot. Na przykład, jeśli masz przestrzenie nazw prod i dev, schemat jest taki, że nie ma żadnych przydziałów produkcyjnych i bardzo rygorystyczne przydziały programistyczne. Dzięki temu prod w przypadku gwałtownego wzrostu ruchu może przejąć cały dostępny zasób, całkowicie blokując programistę.

Limit zasobów może wyglądać następująco. W tym przykładzie są 4 sekcje - są to 4 dolne linie kodu.

Najlepsze praktyki Kubernetesa. Konfigurowanie żądań zasobów i limitów

Przyjrzyjmy się każdemu z nich. Requests.cpu to maksymalna liczba połączonych żądań procesora, które mogą pochodzić ze wszystkich kontenerów w przestrzeni nazw. W tym przykładzie możesz mieć 50 kontenerów z 10 milionami żądań, pięć kontenerów z 100 milionami żądań lub tylko jeden kontener z 500 milionami żądań. Dopóki łączna liczba żądań.cpu danej przestrzeni nazw będzie mniejsza niż 500m, wszystko będzie dobrze.

Żądania dotyczące pamięci.pamięć to maksymalna liczba połączonych żądań pamięci, jakie mogą mieć wszystkie kontenery w przestrzeni nazw. Podobnie jak w poprzednim przypadku, możesz mieć 50 kontenerów 2 MIB, pięć kontenerów 20 MIB lub pojedynczy kontener 100 MIB, o ile całkowita ilość pamięci żądanej w przestrzeni nazw jest mniejsza niż 100 mebibajtów.

Limity.cpu to maksymalna łączna ilość mocy procesora, z której mogą korzystać wszystkie kontenery w przestrzeni nazw. Możemy uznać to za limit żądań mocy procesora.

Wreszcie limity.memory to maksymalna ilość pamięci współdzielonej, z której mogą korzystać wszystkie kontenery w przestrzeni nazw. Jest to limit całkowitej liczby żądań pamięci.
Dlatego domyślnie kontenery w klastrze Kubernetes działają z nieograniczonymi zasobami obliczeniowymi. Dzięki przydziałom zasobów administratorzy klastrów mogą ograniczać zużycie zasobów i tworzenie zasobów w oparciu o przestrzeń nazw. W przestrzeni nazw zasobnik lub kontener może zużywać tyle mocy procesora i pamięci, ile określono na podstawie przydziału zasobów przestrzeni nazw. Istnieje jednak obawa, że ​​jeden zasobnik lub kontener może zmonopolizować wszystkie dostępne zasoby. Aby zapobiec takiej sytuacji stosuje się limit range – politykę ograniczającą alokację zasobów (dla podów lub kontenerów) w przestrzeni nazw.

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

  • Zapewnij minimalne i maksymalne wykorzystanie zasobów obliczeniowych dla każdego modułu lub kontenera w przestrzeni nazw;
  • wymuszaj minimalne i maksymalne żądania przechowywania Starage Request dla każdego PersistentVolumeClaim w przestrzeni nazw;
  • wymuszać relację między żądaniem a limitem zasobu w przestrzeni nazw;
  • ustaw domyślne żądania/limity dla zasobów obliczeniowych w przestrzeni nazw i automatycznie wstawiaj je do kontenerów w czasie wykonywania.

W ten sposób możesz utworzyć zakres limitów w swojej przestrzeni nazw. W przeciwieństwie do limitu, który dotyczy całej przestrzeni nazw, Limit Range jest używany dla poszczególnych kontenerów. Może to uniemożliwić użytkownikom tworzenie bardzo małych lub odwrotnie gigantycznych kontenerów w przestrzeni nazw. Zakres limitu może wyglądać następująco.

Najlepsze praktyki Kubernetesa. Konfigurowanie żądań zasobów i limitów

Podobnie jak w poprzednim przypadku, tutaj można wyróżnić 4 sekcje. Przyjrzyjmy się każdemu.
Sekcja domyślna ustawia domyślne limity kontenera w zasobniku. Jeśli ustawisz te wartości na skrajny zakres, wówczas wszystkie kontenery, dla których te wartości nie zostały jawnie ustawione, będą miały wartości domyślne.

Domyślna sekcja żądania defaultRequest konfiguruje domyślne żądania dla kontenera w zasobniku. Ponownie, jeśli ustawisz te wartości na skrajny zakres, wówczas wszystkie kontenery, które nie ustawią jawnie tych opcji, domyślnie będą miały te wartości.

Sekcja max określa maksymalne limity, które można ustawić dla kontenera w pod. Wartości w domyślnych limitach sekcji i kontenerów nie mogą być ustawione powyżej tego limitu. Należy pamiętać, że jeśli wartość jest ustawiona na max i nie ma sekcji domyślnej, wówczas wartość maksymalna staje się wartością domyślną.

Sekcja min określa minimalną liczbę żądań, które można ustawić dla kontenera w zasobniku. Jednak wartości w sekcji domyślnej i zapytaniach dla kontenera nie mogą być ustawione poniżej tego limitu.

Ponownie należy zauważyć, że jeśli ta wartość jest ustawiona, domyślna wartość nie jest, wówczas domyślnym monitem staje się wartość minimalna.

Te żądania zasobów są ostatecznie wykorzystywane przez program planujący Kubernetes do wykonywania obciążeń. Aby poprawnie skonfigurować kontenery, bardzo ważne jest zrozumienie, jak to działa. Załóżmy, że chcesz uruchomić wiele zasobników w swoim klastrze. Zakładając, że specyfikacje podów są prawidłowe, harmonogram Kubernetes użyje równoważenia okrężnego, aby wybrać węzeł do uruchomienia obciążenia.

Najlepsze praktyki Kubernetesa. Konfigurowanie żądań zasobów i limitów

Kubernetes sprawdzi, czy węzeł 1 ma wystarczające zasoby, aby spełnić żądania z kontenerów podów, a jeśli nie, przejdzie do następnego węzła. Jeśli żaden z węzłów w systemie nie będzie w stanie spełnić żądań, pody przejdą w stan Oczekujące. Korzystając z funkcji silnika Google Kubernetes, takich jak automatyczne skalowanie węzłów, GKE może automatycznie wykryć stan oczekiwania i utworzyć kilka dodatkowych węzłów.

Jeśli później zabraknie Ci mocy obliczeniowej węzła, automatyczne skalowanie zmniejszy liczbę węzłów, co pozwoli Ci zaoszczędzić pieniądze. Właśnie dlatego Kubernetes planuje pody na podstawie żądań. Jednak limit może być wyższy niż liczba żądań, a w niektórych przypadkach w węźle może faktycznie zabraknąć zasobów. Nazywamy ten stan stanem nadmiernego zaangażowania.

Najlepsze praktyki Kubernetesa. Konfigurowanie żądań zasobów i limitów

Jak powiedziałem, jeśli chodzi o procesor, Kubernetes zacznie ograniczać pody. Każdy pod otrzyma tyle, ile zażądał, ale jeśli nie osiągnie limitu, zacznie obowiązywać ograniczanie przepustowości.

Jeśli chodzi o zasoby pamięci, Kubernetes jest zmuszony podejmować decyzje, które pody usunąć, a które zachować, dopóki nie zwolnią się zasoby systemowe lub cały system ulegnie awarii.

Wyobraźmy sobie scenariusz, w którym na komputerze kończy się pamięć — jak Kubernetes sobie z tym poradzi?

Kubernetes będzie szukać podów, które zużywają więcej zasobów, niż żądały. Jeśli więc Twoje kontenery w ogóle nie mają żadnych żądań, oznacza to, że domyślnie używają więcej, niż prosiły, po prostu dlatego, że o nic nie prosiły! Takie kontenery stają się głównymi kandydatami do zamknięcia. Kolejni kandydaci to kontenery, które spełniły wszystkie swoje żądania, ale nadal znajdują się poniżej maksymalnego limitu.

Jeśli więc Kubernetes znajdzie kilka podów, które przekroczyły parametry żądania, posortuje je według priorytetu, a następnie usunie pody o najniższym priorytecie. Jeśli wszystkie pody mają ten sam priorytet, Kubernetes zakończy te pody, które przekraczają swoje żądania bardziej niż inne pody.

W bardzo rzadkich przypadkach Kubernetes może przerwać pody, które nadal znajdują się w zakresie ich żądań. Może się tak zdarzyć, gdy krytyczne komponenty systemu, takie jak agent Kubelet czy Docker, zaczną zużywać więcej zasobów, niż było dla nich zarezerwowane.
Zatem na wczesnych etapach rozwoju małych firm klaster Kubernetes może działać dobrze bez ustawiania żądań zasobów i ograniczeń, ale gdy zespoły i projekty zaczną się powiększać, istnieje ryzyko wystąpienia problemów w tym obszarze. Dodawanie zapytań i ograniczeń do modułów i przestrzeni nazw wymaga bardzo niewielkiego dodatkowego wysiłku i może zaoszczędzić wiele kłopotów.

Najlepsze praktyki Kubernetesa. Prawidłowe zamknięcie Zakończ

Kilka reklam 🙂

Dziękujemy za pobyt z nami. Podobają Ci się nasze artykuły? Chcesz zobaczyć więcej ciekawych treści? Wesprzyj nas składając zamówienie lub polecając znajomym, VPS w chmurze dla programistów od 4.99 USD, unikalny odpowiednik serwerów klasy podstawowej, który został przez nas wymyślony dla Ciebie: Cała prawda o VPS (KVM) E5-2697 v3 (6 rdzeni) 10GB DDR4 480GB SSD 1Gbps od 19$ czyli jak udostępnić serwer? (dostępne z RAID1 i RAID10, do 24 rdzeni i do 40 GB DDR4).

Dell R730xd 2 razy taniej w centrum danych Equinix Tier IV w Amsterdamie? Tylko tutaj 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6 GHz 14C 64 GB DDR4 4x960 GB SSD 1 Gb/s 100 Telewizor od 199 USD w Holandii! Dell R420 — 2x E5-2430 2.2 GHz 6C 128 GB DDR3 2x960 GB SSD 1 Gb/s 100 TB — od 99 USD! Czytać o Jak zbudować firmę infrastrukturalną klasy z wykorzystaniem serwerów Dell R730xd E5-2650 v4 o wartości 9000 euro za grosz?

Źródło: www.habr.com

Dodaj komentarz