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

Трябва да започнем с основните типове ресурси, които съществуват в системата — това са преди всичко CPU времето и оперативната памет. В манифестите на k8s тези типове ресурси се измерват в следните единици:
- CPU — в ядра
- RAM — в байтове
Освен това за всеки ресурс има възможност да се зададат два типа изисквания — requests и limits. Requests — описват минималните изисквания за свободните ресурси на нода за стартиране на контейнера (и на пода като цяло), докато limits задава ригидно ограничение на ресурсите, налични за контейнера.
Важно е да разберем, че в манифеста не е задължително да определяме и двата типа изисквания, като поведението ще бъде следното:
- Ако е зададено само limits за ресурса, то requests за този ресурс автоматично приема стойност, равна на limits (в това можете да се уверите, като извикате describe на съответната същност). Т.е. фактически работата на контейнера ще бъде ограничена до същото количество ресурси, от което се нуждае за стартирането си.
- Ако за ресурса е зададено само requests, то не се задават никакви ограничения върху този ресурс — т.е. контейнерът е ограничен само от ресурсите на самия нод.
Съществува и възможност за настройка на управление на ресурсите не само на ниво контейнер, но и на ниво namespace чрез следните същности:
- LimitRange — описва политиката за ограничаване на ниво контейнер/пода в ns и е необходима, за да опише дефолтните ограничения за контейнер/под, както и да предотврати създаването на излишно големи контейнери/пода (или обратно), да ограничи тяхното количество и да определи възможната разлика в стойностите на limits и requests.
- ResourceQuotas — описва политиката за ограничаване общо за всички контейнери в ns и се използва, обикновено, за разделяне на ресурсите по среди (полезно е, когато средите не са строго разделени на нива на нодове)
По-долу са предоставени примери за манифести, където се определят ограничения за ресурсите:
На ниво конкретен контейнер:
containers: - name: app-nginx image: nginx resources: requests: memory: 1Gi limits: cpu: 200mТ.е. в този случай за стартиране на контейнер с nginx ще са необходими поне налични 1G RAM и 0.2 CPU на нода, при това максимум контейнерът може да използва 0.2 CPU и цялата налична RAM на нода.
На ниво цяло ns:
apiVersion: v1 kind: ResourceQuota metadata: name: nxs-test spec: hard: requests.cpu: 300m requests.memory: 1Gi limits.cpu: 700m limits.memory: 2GiТ.е. сумата на всички requests на контейнерите в дефолтното ns не може да надвишава 300m за CPU и 1G за RAM, а сумата на всички limits — 700m за CPU и 2G за RAM.
Дефолтни ограничения за контейнерите в ns:
apiVersion: v1 kind: LimitRange metadata: name: nxs-limit-per-container spec: limits: - type: Container defaultRequest: cpu: 100m memory: 1Gi default: cpu: 1 memory: 2Gi min: cpu: 50m memory: 500Mi max: cpu: 2 memory: 4GiТ.е. в дефолтния namespace за всички контейнери по подразбиране ще бъде зададен request от 100m за CPU и 1G за RAM, limit — 1 CPU и 2G. При това е установено и ограничение на възможните стойности в request/limit за CPU (50m < x < 2) и RAM (500M < x < 4G).
Ограничения на ниво подове в ns:
apiVersion: v1 kind: LimitRange metadata: name: nxs-limit-pod spec: limits: - type: Pod max: cpu: 4 memory: 1GiТ.е. за всеки под в дефолтното ns ще бъде установено ограничение от 4 vCPU и 1G.
Сега бих искал да разказвам какви предимства може да ни донесе установяването на тези ограничения.
Механизъм за баланс на натоварването между нодовете
Както е известно, за разпределението на подовете по нодовете отговаря компонент k8s, като scheduler, който работи според определен алгоритъм. Този алгоритъм при избора на оптимален узел за стартиране преминава през две фази:
- Филтриране
- Ранжиране
Т.е. според описаната политика първоначално се избират нодовете, на които е възможно стартиране на пода въз основа на набор от predicates (включително се проверява дали ресурсите на нода са достатъчни за стартиране на пода — PodFitsResources), а след това за всеки от тези ноди, съгласно priorities Натрупват се точки (включително, колкото повече свободни ресурси има нодата - толкова повече точки се присвояват на нея - LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation) и се стартира на нодата с най-много точки (ако това условие е изпълнено от няколко ноди, се избира произволна от тях).
В същото време е важно да се разбере, че scheduler при оценка на наличните ресурси на нодата се ръководи от данните, съхранявани в etcd - т.е. от сумата на requested/limit ресурсите на всеки под, стартиран на тази нода, но не и от фактическото потребление на ресурси. Тази информация може да бъде получена в изхода на командата kubectl describe node $NODE, например:
# kubectl describe nodes nxs-k8s-s1
..
Non-terminated Pods: (9 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
--------- ---- ------------ ---------- --------------- ------------- ---
ingress-nginx nginx-ingress-controller-754b85bf44-qkt2t 0 (0%) 0 (0%) 0 (0%) 0 (0%) 233d
kube-system kube-flannel-26bl4 150m (0%) 300m (1%) 64M (0%) 500M (1%) 233d
kube-system kube-proxy-exporter-cb629 0 (0%) 0 (0%) 0 (0%) 0 (0%) 233d
kube-system kube-proxy-x9fsc 0 (0%) 0 (0%) 0 (0%) 0 (0%) 233d
kube-system nginx-proxy-k8s-worker-s1 25m (0%) 300m (1%) 32M (0%) 512M (1%) 233d
nxs-monitoring alertmanager-main-1 100m (0%) 100m (0%) 425Mi (1%) 25Mi (0%) 233d
nxs-logging filebeat-lmsmp 100m (0%) 0 (0%) 100Mi (0%) 200Mi (0%) 233d
nxs-monitoring node-exporter-v4gdq 112m (0%) 122m (0%) 200Mi (0%) 220Mi (0%) 233d
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 487m (3%) 822m (5%)
memory 15856217600 (2%) 749976320 (3%)
ephemeral-storage 0 (0%) 0 (0%)Тук виждаме всички подове, стартирани на конкретната нода, както и ресурсите, които всеки от подовете изисква. Ето как изглеждат логовете на scheduler при стартиране на пода cronjob-cron-events-1573793820-xt6q9 (тази информация в логовете на scheduler ще се появи при настройка на 10-то ниво на логиране в аргументите на командата за стартиране —v=10):
лог
I1115 07:57:21.637791 1 scheduling_queue.go:908] Ще опитам да насроча под nxs-stage/cronjob-cron-events-1573793820-xt6q9
I1115 07:57:21.637804 1 scheduler.go:453] Опитвам да насроча под: nxs-stage/cronjob-cron-events-1573793820-xt6q9
I1115 07:57:21.638285 1 predicates.go:829] Насрочването на Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 на Възел nxs-k8s-s5 е разрешено, Възелът изпълнява само 16 от 110 Pods.
I1115 07:57:21.638300 1 predicates.go:829] Насрочването на Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 на Възел nxs-k8s-s6 е разрешено, Възелът изпълнява само 20 от 110 Pods.
I1115 07:57:21.638322 1 predicates.go:829] Насрочването на Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 на Възел nxs-k8s-s3 е разрешено, Възелът изпълнява само 20 от 110 Pods.
I1115 07:57:21.638322 1 predicates.go:829] Насрочването на Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 на Възел nxs-k8s-s4 е разрешено, Възелът изпълнява само 17 от 110 Pods.
I1115 07:57:21.638334 1 predicates.go:829] Насрочването на Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 на Възел nxs-k8s-s10 е разрешено, Възелът изпълнява само 16 от 110 Pods.
I1115 07:57:21.638365 1 predicates.go:829] Насрочването на Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 на Възел nxs-k8s-s12 е разрешено, Възелът изпълнява само 9 от 110 Pods.
I1115 07:57:21.638334 1 predicates.go:829] Насрочването на Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 на Възел nxs-k8s-s11 е разрешено, Възелът изпълнява само 11 от 110 Pods.
I1115 07:57:21.638385 1 predicates.go:829] Насрочването на Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 на Възел nxs-k8s-s1 е разрешено, Възелът изпълнява само 19 от 110 Pods.
I1115 07:57:21.638402 1 predicates.go:829] Насрочването на Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 на Възел nxs-k8s-s2 е разрешено, Възелът изпълнява само 21 от 110 Pods.
I1115 07:57:21.638383 1 predicates.go:829] Насрочването на Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 на Възел nxs-k8s-s9 е разрешено, Възелът изпълнява само 16 от 110 Pods.
I1115 07:57:21.638335 1 predicates.go:829] Насрочването на Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 на Възел nxs-k8s-s8 е разрешено, Възелът изпълнява само 18 от 110 Pods.
I1115 07:57:21.638408 1 predicates.go:829] Насрочването на Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 на Възел nxs-k8s-s13 е разрешено, Възелът изпълнява само 8 от 110 Pods.
I1115 07:57:21.638478 1 predicates.go:1369] Насрочването на Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 на Възел nxs-k8s-s10 е разрешено, условията за антагонизъм на съществуващи подове са удовлетворени.
I1115 07:57:21.638505 1 predicates.go:1369] Насрочването на Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 на Възел nxs-k8s-s8 е разрешено, условията за антагонизъм на съществуващи подове са удовлетворени.
I1115 07:57:21.638577 1 predicates.go:1369] Насрочването на Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 на Възел nxs-k8s-s9 е разрешено, условията за антагонизъм на съществуващи подове са удовлетворени.
I1115 07:57:21.638583 1 predicates.go:829] Насрочването на Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 на Възел nxs-k8s-s7 е разрешено, Възелът изпълнява само 25 от 110 Pods.
I1115 07:57:21.638932 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: Балансирано разпределение на ресурсите, капацитет 39900 милиядни ядра 66620178432 байта памет, обща заявка 2343 милиядни ядра 9640186880 байта памет, оценка 9
I1115 07:57:21.638946 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: Най-малко разпределение на ресурси, капацитет 39900 милиядни ядра 66620178432 байта памет, обща заявка 2343 милиядни ядра 9640186880 байта памет, оценка 8
I1115 07:57:21.638961 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: Балансирано разпределение на ресурсите, капацитет 39900 милиядни ядра 66620170240 байта памет, обща заявка 4107 милиядни ядра 11307422720 байта памет, оценка 9
I1115 07:57:21.638971 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: Балансирано разпределение на ресурсите, капацитет 39900 милиядни ядра 66620178432 байта памет, обща заявка 5847 милиядни ядра 24333637120 байта памет, оценка 7
I1115 07:57:21.638975 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: Най-малко разпределение на ресурси, капацитет 39900 милиядни ядра 66620170240 байта памет, обща заявка 4107 милиядни ядра 11307422720 байта памет, оценка 8
I1115 07:57:21.638990 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: Най-малко разпределение на ресурси, капацитет 39900 милиядни ядра 66620178432 байта памет, обща заявка 5847 милиядни ядра 24333637120 байта памет, оценка 7
I1115 07:57:21.639022 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: Приоритет за толерантност на замърсявания, оценка: (10)
I1115 07:57:21.639030 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: Приоритет за толерантност на замърсявания, оценка: (10)
I1115 07:57:21.639034 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: Приоритет за толерантност на замърсявания, оценка: (10)
I1115 07:57:21.639041 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: Приоритет на привързаност към възела, оценка: (0)
I1115 07:57:21.639053 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: Приоритет на привързаност към възела, оценка: (0)
I1115 07:57:21.639059 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: Приоритет на привързаност към възела, оценка: (0)
I1115 07:57:21.639061 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: Приоритет за междуподова привързаност, оценка: (0)
I1115 07:57:21.639063 1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: Приоритет за разпространение на селектори, оценка: (10)
I1115 07:57:21.639073 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: Приоритет за междуподова привързаност, оценка: (0)
I1115 07:57:21.639077 1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: Приоритет за разпространение на селектори, оценка: (10)
I1115 07:57:21.639085 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: Приоритет за междуподова привързаност, оценка: (0)
I1115 07:57:21.639088 1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: Приоритет за разпространение на селектори, оценка: (10)
I1115 07:57:21.639103 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: Приоритет за разпространение на селектори, оценка: (10)
I1115 07:57:21.639109 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: Приоритет за разпространение на селектори, оценка: (10)
I1115 07:57:21.639114 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: Приоритет за разпространение на селектори, оценка: (10)
I1115 07:57:21.639127 1 generic_scheduler.go:781] Хост nxs-k8s-s10 => Оценка 100037
I1115 07:57:21.639150 1 generic_scheduler.go:781] Хост nxs-k8s-s8 => Оценка 100034
I1115 07:57:21.639154 1 generic_scheduler.go:781] Хост nxs-k8s-s9 => Оценка 100037
I1115 07:57:21.639267 1 scheduler_binder.go:269] AssumePodVolumes за под "nxs-stage/cronjob-cron-events-1573793820-xt6q9", възел "nxs-k8s-s10"
I1115 07:57:21.639286 1 scheduler_binder.go:279] AssumePodVolumes за под "nxs-stage/cronjob-cron-events-1573793820-xt6q9", възел "nxs-k8s-s10": всички PVCs свързани и нищо не трябва да се прави
I1115 07:57:21.639333 1 factory.go:733] Опит за свързване на cronjob-cron-events-1573793820-xt6q9 с nxs-k8s-s10Тук виждаме, че в началото scheduler извършва филтриране и създава списък от 3 ноди, на които е възможно да се стартира (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10). След това се извършва броене на точки по няколко параметра (включително BalancedResourceAllocation, LeastResourceAllocation) за всяка от тези ноди, с цел да се определи най-подходящият възел. В крайна сметка подът се планира на нодата с най-много точки (тук веднага две ноди имат еднакъв брой точки 100037, затова се избира случайна от тях — nxs-k8s-s10).
Извод: ако на нодата работят подове, за които не са зададени ограничения, то за k8s (от гледна точка на потреблението на ресурси) това ще бъде равносилно на ситуация, в която на тази нода такива подове изобщо не присъстват. Затова, ако условно имате pod с изискващ процес (например, wowza) и за него не са зададени ограничения, е възможно да възникне ситуация, в която фактически този под е изял всичките ресурси на нодата, но за k8s, тази нода се счита за ненатоварена и ще получава същото количество точки при ранжиране (точно в раздела с оценка на наличните ресурси), както и нодата, на която няма работещи подове, което в крайна сметка може да доведе до неравномерно разпределение на натоварването между нодите.
Изгонване на пода
Както е известно — на всеки под се присвоява един от 3 QoS-класа:
- guaranuted — назначава се тогава, когато за всеки контейнер в пода за памет и CPU са зададени request и limit, като тези стойности трябва да съвпадат
- burstable — поне един контейнер в пода има request и limit, при това request < limit
- best effort — когато нито един контейнер в пода не е ограничен по ресурси
В същото време, когато на нодата има недостиг на ресурси (диск, памет), kubelet започва да ранжира и изгонва подове по определен алгоритъм, който взима предвид приоритета на пода и неговия QoS-клас. Например, ако става въпрос за RAM, то на основание QoS клас се начисляват точки по следния принцип:
- Guaranteed: -998
- BestEffort: 1000
- Burstable: min(max(2, 1000 — (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)
Т.е. при еднакъв приоритет, kubelet ще изгонва от нодата подовете с QoS-клас best effort на първо място.
Извод: ако искате да намалите вероятността от изгонване на необходимия под от нодата при недостиг на ресурси на нея, то наред с приоритета трябва да се погрижите и за задаването на request/limit за него.
Механизм за хоризонтално автоматично мащабиране на подовете на приложението (HPA)
Когато задачата е автоматично да увеличи или намали броя на подовете в зависимост от използването на ресурси (системни — CPU/RAM или потребителски — rps), в решаването на този проблем може да помогне такава сущност на k8s като HPA (Horizontal Pod Autoscaler). Алгоритъмът на който е следният:
- Определят се текущите показатели на наблюдавания ресурс (currentMetricValue)
- Определят се желаните стойности за ресурса (desiredMetricValue), които за системните ресурси се задават чрез request
- Определя се текущият брой на репликите (currentReplicas)
- По следната формула се изчислява желаното количество реплики (desiredReplicas)
desiredReplicas = [ currentReplicas * ( currentMetricValue / desiredMetricValue )]
При това мащабиране няма да се случи, когато коефициентът (currentMetricValue / desiredMetricValue) е близък до 1 (при това допустимата грешка можем да задаваме сами, по подразбиране тя е равна на 0.1).
Нека разгледаме работата на hpa на примера на приложението app-test (описано като Deployment), където е необходимо да се промени количеството реплики в зависимост от потреблението на CPU:
Манифест на приложението
kind: Deployment apiVersion: apps/v1beta2 metadata: name: app-test spec: selector: matchLabels: app: app-test replicas: 2 template: metadata: labels: app: app-test spec: containers: - name: nginx image: registry.nixys.ru/generic-images/nginx imagePullPolicy: Always resources: requests: cpu: 60m ports: - name: http containerPort: 80 - name: nginx-exporter image: nginx/nginx-prometheus-exporter resources: requests: cpu: 30m ports: - name: nginx-exporter containerPort: 9113 args: - -nginx.scrape-uri - http://127.0.0.1:80/nginx-statusТ.е. виждаме, че подът с приложението първоначално се стартира в два екземпляра, всеки от които съдържа два контейнера nginx и nginx-exporter, за всеки от които е зададен requests за CPU.
Манифест на HPA
apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler metadata: name: app-test-hpa spec: maxReplicas: 10 minReplicas: 2 scaleTargetRef: apiVersion: extensions/v1beta1 kind: Deployment name: app-test metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 30Т.е. създадохме hpa, който ще следи за Deployment app-test и ще регулира количеството подове с приложението на база показателя cpu (очакваме, че подът трябва да консумира 30% от заявеното му CPU), при това количеството реплики варира в диапазона 2-10.
Сега, нека разгледаме механизма на работа на hpa, ако натоварим един от подовете:
# kubectl top pod NAME CPU(cores) MEMORY(bytes) app-test-78559f8f44-pgs58 101m 243Mi app-test-78559f8f44-cj4jz 4m 240Mi
И така, имаме следното:
- Желаната стойност (desiredMetricValue) — съгласно настройките на hpa, е 30%
- Текущата стойност (currentMetricValue) — за изчисление, controller-manager изчислява средната стойност на потребление на ресурса в %, т.е. условно прави следното:
- Получава абсолютни стойности на метриките на подовете от metric-сервера, т.е. 101m и 4m
- Изчислява средното абсолютното значение, т.е. (101m + 4m) / 2 = 53m
- Получава абсолютната стойност за желаното потребление на ресурса (за това се сумират requests на всички контейнери) 60m + 30m = 90m
- Изчислява средния процент на потребление на CPU спрямо requests на пода, т.е. 53m / 90m * 100% = 59%
Сега имаме всичко необходимо, за да определим дали е необходимо да променим броя на репликите, за това изчисляваме коефициента:
ratio = 59% / 30% = 1.96
Т.е. броят на репликите трябва да бъде увеличен приблизително два пъти и да бъде [2 * 1.96] = 4.
Изход: Както може да се види, за да работи този механизъм, е необходимо условие също така да има requests за всички контейнери в наблюдавания под.
Механизмът за хоризонтално автоматично скалиране на нодовете (Cluster Autoscaler)
За да се неутрализира негативното влияние върху системата при пикова натовареност, наличието на настроен hpa често е недостатъчно. Например, съгласно настройките в hpa controller manager взема решение, че броят на репликите е необходимо да се увеличи два пъти, но на нодовете няма свободни ресурси за стартиране на такова количество подове (т.е. нодата не може да предостави исканите ресурси на пода requests) и тези подове преминават в състояние Pending.
В този случай, ако провайдърът има съответното IaaS/PaaS (например, GKE/GCE, AKS, EKS и т.н.), такъв инструмент като Node Autoscalerможе да ни помогне. Той позволява да зададете максимален и минимален брой ноди в кластера и автоматично да регулира текущия брой ноди (чрез обращение към API на облачния провайдър за поръчка/изтриване на нода), когато се наблюдава недостиг на ресурси в кластера и подовете не могат да бъдат планирани (намират се в състояние Pending).
Изход: за възможността за автоматично скалиране на нодовете е необходимо да се задават requests в контейнери на подовете, за да може k8s правилно да оценява натоварването на нодовете и съответно да сигнализира, че за стартиране на следващия под в кластера няма ресурси.
Заключение
Трябва да се отбележи, че настройката на ограничения за ресурсите на контейнера не е задължително условие за успешното стартиране на приложението, но все пак е добре да се направи по следните причини:
- За по-точна работа на scheduler в частта за балансиране на натоварването между нодовете в k8s
- За намаляване на вероятността от възникване на събитие "изгонване на пода"
- За работата на хоризонталното автоматично мащабиране на подовете на приложението (HPA)
- За работата на хоризонталното автоматично мащабиране на нодовете (Cluster Autoscaling) при облачните доставчици
Също така прочетете други статии в нашия блог:
Източник: habr.com
