Как да получите достъп до ресурси на Kubernetes Pod

Как да получите достъп до ресурси на Kubernetes PodНаградата от Тохад

Когато започвате с Kubernetes, е обичайно да забравяте за настройването на контейнерни ресурси. На този етап е достатъчно да се уверите, че изображението на Docker работи и може да бъде разгърнато в клъстера Kubernetes.

Но по-късното приложение трябва да бъде внедрено в производствен клъстер заедно с други приложения. За да направите това, трябва да разпределите ресурси за контейнера и да се уверите, че има достатъчно от тях, за да стартира и работи приложението и няма да има проблеми в други работещи приложения.

Отбор Kubernetes aaS от Mail.ru преведе статия за ресурси на контейнер (CPU & MEM), заявки за ресурси и ограничения. Ще научите какви предимства предоставят тези настройки и какво се случва, ако не бъдат зададени.

Компютърни ресурси

Имаме два вида ресурси със следните единици:

  • Централен процесор (CPU) - ядра;
  • Памет (MEM) - байтове.

За всеки контейнер са посочени ресурси. В следния файл Pod YAML ще видите раздел за ресурси, който съдържа заявените и ограничените ресурси:

  • Изисквани ресурси на под = сбор от заявените ресурси на всички подове;
  • Лимит на ресурси на Pod = Сума от всички лимити на ресурси на Pod.

apiVersion: v1
kind: Pod
metadata:
  name: backend-pod-name
  labels:
    application: backend
spec:
  containers:
    — name: main-container
      image: my-backend
      tag: v1
      ports:
      — containerPort: 8080
      resources:
        requests:
          cpu: 0.2 # REQUESTED CPU: 200m cores
          memory: "1Gi" # REQUESTED MEM: 1Gi
        limits:
          cpu: 1 # MAX CPU USAGE: 1 core
          memory: "1Gi" # MAX MEM USAGE:  1Gi
    — name: other-container
      image: other-app
      tag: v1
      ports:
      — containerPort: 8000
      resources:
        requests:
          cpu: "200m" # REQUESTED CPU: 200m cores
          memory: "0.5Gi" # REQUESTED MEM: 0.5Gi
        limits:
          cpu: 1 # MAX CPU USAGE: 1 core
          memory: "1Gi" # MAX MEM USAGE:  1Gi

Пример за заявени и ограничени ресурси

Област resources.requested от спецификацията на Pod - един от елементите, който се използва за намиране на желания възел. Вече можете да планирате внедряване на Pod върху него. Как намирате подходящ възел?

Kubernetes се състои от няколко компонента, включително главния възел или главния възел (Kubernetes Control Plane). Има няколко процеса в главния възел: kube-apiserver, kube-controller-manager и kube-scheduler.

Процесът на kube-scheduler е отговорен за разглеждане на новосъздадени подове и търсене на възможни работни възли, които отговарят на всички заявки за под, включително броя на заявените ресурси. Списъкът с възли, намерени от kube-scheduler, се класира. Подът е планиран на възела с най-високи резултати.

Как да получите достъп до ресурси на Kubernetes PodКъде ще бъде поставена лилавата капсула?

Картината показва, че kube-scheduler трябва да планира нов лилав Pod. Клъстерът Kubernetes съдържа два възела: A и B. Както можете да видите, kube-scheduler не може да планира Pod към възел A - наличните (непоискани) ресурси не съответстват на заявките на лилавия Pod. Например, 1 GB памет, поискана от лилавата Pod, няма да се побере на възел A, тъй като наличната памет е 0,5 GB. Но възел B има достатъчно ресурси. Накрая kube-scheduler решава, че местоназначението на лилавия Pod е възел B.

Сега знаем как исканите ресурси влияят върху избора на възел за изпълнение на Pod. Но какъв е ефектът от пределните ресурси?

Ограничението на ресурсите е ограничение, което CPU/MEM не може да премине. Ресурсът на процесора обаче е гъвкав, така че контейнери, които достигнат ограниченията на процесора, няма да доведат до изключване на Pod. Вместо това ще започне дроселиране на процесора. Ако лимитът на MEM бъде достигнат, тогава контейнерът ще бъде спрян поради OOM-Killer и рестартиран, ако е разрешено от настройката RestartPolicy.

Подробно заявени и ограничени ресурси

Как да получите достъп до ресурси на Kubernetes PodСвързване на ресурси между Docker и Kubernetes

Най-добрият начин да обясните как работят заявените ограничения и ограниченията на ресурсите е да си представите връзката между Kubernetes и Docker. На фигурата по-горе можете да видите как са свързани полетата на Kubernetes и флаговете за стартиране на Docker.

Памет: заявка и лимит

containers:
...
 resources:
   requests:
     memory: "0.5Gi"
   limits:
     memory: "1Gi"

Както бе споменато по-горе, паметта се измерва в байтове. Базиран на Документация на Kubernetes, можем да посочим паметта като число. Обикновено това е цяло число, например 2678 - тоест 2678 байта. Можете също да използвате суфикси G и Gi, основното е да запомните, че те не са еквивалентни. Първият е десетичен, а вторият е двоичен. Като пример, споменат в документацията на k8s: 128974848, 129e6, 129M, 123Mi — практически са еквивалентни.

Параметър на Kubernetes limits.memory съвпада със знамето --memory от Docker. В случай на request.memory няма стрелка за Docker, защото Docker не използва това поле. Може да попитате дали това изобщо е необходимо? Да нужда. Както казах преди, полето има значение за Kubernetes. Въз основа на информацията от него kube-scheduler решава към кой възел да планира Pod.

Какво се случва, ако няма достатъчно памет за заявката?

Ако контейнерът е достигнал границите на заявената памет, тогава Pod се поставя в група от Pod, които спират, когато няма достатъчно памет в възела.

Какво се случва, ако зададете ограничението на паметта твърде ниско?

Ако даден контейнер надхвърли лимита на паметта, той ще бъде прекратен поради OOM-Killed. И ще се рестартира, ако е възможно въз основа на RestartPolicy, където е стойността по подразбиране Always.

Какво се случва, ако не посочите исканата памет?

Kubernetes ще вземе ограничението и ще го зададе като стандартно.

Какво може да се случи, ако не посочите лимит на паметта?

Контейнерът няма ограничения, той може да използва толкова памет, колкото иска. Ако той започне да използва цялата налична памет на възела, тогава OOM ще го убие. След това контейнерът ще бъде рестартиран, ако е възможно въз основа на RestartPolicy.

Какво се случва, ако не посочите ограничения на паметта?

Това е най-лошият сценарий: планировчикът не знае колко ресурси са необходими на контейнера и това може да причини сериозни проблеми на възела. В този случай би било хубаво да имате ограничения по подразбиране в пространството от имена (зададени от LimitRange). Без ограничение по подразбиране - Pod няма ограничение, може да използва толкова памет, колкото иска.

Ако заявената памет е повече, отколкото възелът може да предложи, Pod няма да бъде планиран. Важно е да запомните това Requests.memory не е минималната стойност. Това е описание на количеството памет, което е достатъчно, за да поддържа контейнера работещ през цялото време.

Обикновено се препоръчва да зададете същата стойност за request.memory и limit.memory. Това не позволява на Kubernetes да планира Pod на възел, който има достатъчно памет, за да стартира Pod, но не достатъчно, за да работи. Имайте предвид, че планирането на Kubernetes Pod взема предвид само requests.memoryИ limits.memory не взема предвид.

CPU: заявка и лимит

containers:
...
 resources:
   requests:
     cpu: 1
   limits:
     cpu: "1200m"

С процесора нещата са малко по-сложни. Връщайки се към картината с връзката между Kubernetes и Docker, можете да видите това request.cpu соответствует --cpu-shares, като има предвид, че limit.cpu съвпада със знамето cpus в Docker.

Процесорът, поискан от Kubernetes, се умножава по 1024, делът на циклите на процесора. Ако искате да поискате 1 пълно ядро, тогава трябва да добавите cpu: 1както е показано по-горе.

Заявката за пълно ядро ​​(пропорция = 1024) не означава, че вашият контейнер ще го получи. Ако вашата хост машина има само едно ядро ​​и използвате повече от един контейнер, тогава всички контейнери трябва да споделят наличния CPU помежду си. как става това Нека погледнем снимката.

Как да получите достъп до ресурси на Kubernetes Pod
Заявка за процесор - едноядрена система

Нека си представим, че имате едноядрена хост система, работеща с контейнери. Мама (Kubernetes) изпече пай (CPU) и иска да го сподели с децата си (контейнери). Три деца искат цял ​​пай (пропорция = 1024), друго дете иска половин пай (512). Мама иска да бъде справедлива и прави проста сметка.

# Сколько пирогов хотят дети?
# 3 ребенка хотят по целому пирогу и еще один хочет половину пирога
cakesNumberKidsWant = (3 * 1) + (1 * 0.5) = 3.5
# Выражение получается так:
3 (ребенка/контейнера) * 1 (целый пирог/полное ядро) + 1 (ребенок/контейнер) * 0.5 (половина пирога/половина ядра)
# Сколько пирогов испечено?
availableCakesNumber = 1
# Сколько пирога (максимально) дети реально могут получить?
newMaxRequest = 1 / 3.5 =~ 28%

Въз основа на изчислението три деца ще получат 28% от ядрото, а не цялото ядро. Четвъртото дете ще получи 14% от пълното ядро, а не половината. Но нещата ще бъдат различни, ако имате многоядрена система.

Как да получите достъп до ресурси на Kubernetes Pod
Заявка за CPU - Многоядрена (4) система

На изображението по-горе можете да видите, че три деца искат цял ​​пай, а едно иска половината. Тъй като мама изпече четири пая, всяко от децата й ще получи толкова, колкото иска. В многоядрена система ресурсите на процесора се разпределят между всички налични процесорни ядра. Ако даден контейнер е ограничен до по-малко от едно пълно процесорно ядро, той все още може да го използва на 100%.

Горните изчисления са опростени, за да се разбере как процесорът се споделя между контейнерите. Разбира се, освен самите контейнери, има и други процеси, които също използват ресурси на процесора. Когато процесите в един контейнер са неактивни, други могат да използват неговия ресурс. CPU: "200m" соответствует CPU: 0,2, което означава приблизително 20% от едно ядро.

Сега нека поговорим за limit.cpu. Ограничаващото CPU Kubernetes се умножава по 100. Резултатът е времето, което контейнерът може да използва на всеки 100 µs (cpu-period).

limit.cpu съответства на флага на Docker --cpus. Това е нова комбинация от старо --cpu-period и --cpu-quota. Като го зададем, ние указваме колко от наличните ресурси на процесора контейнерът може да достигне максимално, преди да започне дроселирането:

  • процесори - комбинация cpu-period и cpu-quota. cpus = 1.5 е еквивалентно на настройка cpu-period = 100000 и cpu-quota = 150000;
  • период на процесора - Период CPU CFS планировчик, по подразбиране 100 микросекунди;
  • процесорна квота е броят микросекунди вътре cpu-periodТова, към което е ограничен контейнерът.

Какво се случва, ако инсталирате недостатъчно заявен процесор?

Ако контейнерът се нуждае от повече от зададеното, тогава той ще открадне процесора от други процеси.

Какво се случва, ако зададете ограничение за недостатъчен процесор?

Тъй като ресурсът на процесора е регулируем, дроселирането ще се включи.

Какво се случва, ако не зададете заявка за CPU?

Както в случая с паметта, стойността на заявката е равна на ограничението.

Какво се случва, ако не посочите лимит на процесора?

Контейнерът ще използва толкова CPU, колкото му е необходимо. Ако политиката за процесора по подразбиране (LimitRange) е дефинирана в пространството от имена, тогава това ограничение се използва и за контейнера.

Какво се случва, ако не са посочени нито заявка, нито лимит на процесора?

Както при паметта, това е най-лошият сценарий. Планировчикът не знае от колко ресурси се нуждае вашия контейнер и това може да причини сериозни проблеми на възела. За да избегнете това, трябва да зададете ограничения по подразбиране за пространства от имена (LimitRange).

Не забравяйте, че ако поискате повече CPU, отколкото възлите могат да осигурят, Pod няма да бъде планиран. Requests.cpu - не минималната стойност, а стойност, достатъчна за стартиране на Pod и работа без откази. Ако приложението не извършва сложни изчисления, най-добрият вариант е да го инсталирате request.cpu <= 1 и стартирайте толкова копия, колкото е необходимо.

Идеално количество искани ресурси или лимит на ресурси

Научихме за ограничението на изчислителните ресурси. Сега е време да отговоря на въпроса: „Колко ресурси са необходими на моя Pod, за да стартира приложението без проблеми? Каква е идеалната сума?

За съжаление, няма ясни отговори на тези въпроси. Ако не знаете как работи вашето приложение, от колко процесор или памет се нуждае, най-добрият вариант е да дадете на приложението много памет и процесор и след това да стартирате сравнителни тестове.

В допълнение към тестовете за ефективност, наблюдавайте поведението на приложението при мониторинг през седмицата. Ако графиките показват, че приложението ви консумира по-малко ресурси, отколкото сте поискали, тогава можете да намалите количеството изискван процесор или памет.

За пример вижте това Графана табло. Той показва разликата между заявените ресурси или ограничението на ресурсите и текущото използване на ресурсите.

Заключение

Заявката за ресурс и ограничението помагат да се поддържа здравият клъстер на Kubernetes. Правилното конфигуриране на лимити минимизира разходите и поддържа приложенията активни и работещи по всяко време.

Накратко, има няколко неща, които трябва да имате предвид:

  1. Изисквани ресурси – конфигурация, която се взема предвид при стартиране (когато Kubernetes планира да хоства приложението). Обратно, ограничаването на ресурсите е важно по време на изпълнение – когато приложението вече работи на хоста.
  2. В сравнение с паметта, процесорът е регулиран ресурс. В случай на липса на процесор, вашият Pod няма да се изключи, дроселиращият механизъм ще се включи.
  3. Заявените ресурси и ресурсният лимит не са минимални и максимални стойности! Като посочите ресурсите, които да поискате, вие гарантирате, че приложението работи гладко.
  4. Добра практика е заявката за памет да бъде равна на лимита на паметта.
  5. Иска се инсталиране на добре CPU <=1ако приложението не извършва сложни изчисления.
  6. Ако поискате повече ресурси, отколкото има даден възел, Pod никога няма да бъде планиран за този възел.
  7. Използвайте тестване на натоварването и наблюдение, за да определите правилното количество заявени ресурси/ограничения на ресурсите.

Надявам се тази статия да ви помогне да разберете основната концепция за ограничаване на ресурсите. И можете да приложите това знание в работата си.

Good Luck!

Какво друго да прочетете:

  1. Наблюдаемост на SRE: пространства от имена и метрична структура.
  2. 90+ полезни инструмента за Kubernetes: внедряване, управление, наблюдение, сигурност и други.
  3. Нашият канал Около Kubernetes в Telegram.

Източник: www.habr.com

Добавяне на нов коментар