Zvyčajne vzniká potreba zabezpečiť vyhradenú skupinu zdrojov pre aplikáciu na jej správnu a stabilnú činnosť. Ale čo ak na tých istých prostriedkoch pracuje niekoľko aplikácií súčasne? Ako zabezpečiť minimálne potrebné zdroje pre každú z nich? Akým spôsobom je možné obmedziť spotrebu zdrojov? Ako správne rozdeliť záťaž medzi uzlami? Ako zabezpečiť fungovanie mechanizmu horizontálneho škálovania v prípade rastu zaťaženia aplikácií?

Treba začať tým, aké hlavné typy zdrojov existujú v systéme — samozrejme, ide o procesorový čas a operačnú pamäť. V manifestoch k8s sa tieto typy zdrojov merajú v nasledujúcich jednotkách:
- CPU — v jadrach
- RAM — v bajtoch
Pre každý zdroj je pritom možné nastaviť dva typy požiadaviek — requests a limits. Requests popisuje minimálne požiadavky na voľné zdroje uzla pre spustenie kontajnera (a podu ako celku), zatiaľ čo limits stanovuje prísne obmedzenie zdrojov dostupných pre kontajner.
Je dôležité pochopiť, že v manifeste nie je nevyhnutné výslovne definovať oba typy, pričom správanie bude nasledujúce:
- Ak je výslovne zadané iba limits zdroja, requests pre tento zdroj automaticky nadobúda hodnotu rovnu limits (v tom sa môžete presvedčiť vyvolaním describe entity). T.j. vlastne práca kontajnera bude obmedzená na rovnaké množstvo zdrojov, ktoré potrebuje pre svoj štart.
- Ak je pre zdroj výslovne zadané len requests, žiadne obmedzenia pre tento zdroj nie sú nastavené — t.j. kontajner je obmedzený iba zdrojmi samotného uzla.
Existuje tiež možnosť nastaviť správu zdrojov nielen na úrovni konkrétneho kontajnera, ale aj na úrovni namespace pomocou nasledujúcich entít:
- LimitRange — popisuje politiku obmedzenia na úrovni kontajnera/podu v ns a je potrebná na to, aby sa opísali predvolené obmedzenia na kontajner/pod, ako aj na zabránenie vytváraniu zjavne prekročených kontajnerov/podov (alebo naopak), obmedzovať ich počet a určiť možný rozdiel hodnôt v limits a requests.
- ResourceQuotas — opisujú politiku obmedzenia vo všeobecnosti pre všetky kontajnery v ns a zvyčajne sa používa na rozdelenie zdrojov medzi prostrediami (užitočné, keď nie sú prostredia prísne rozdelené na úrovni uzlov)
Nižšie sú uvedené príklady manifestov, kde sú nastavené obmedzenia na zdroje:
Na úrovni konkrétneho kontajnera:
containers: - name: app-nginx image: nginx resources: requests: memory: 1Gi limits: cpu: 200mT.j. v tomto prípade na spustenie kontajnera s nginx bude potrebné mať aspoň 1G voľnej RAM a 0.2 CPU na uzle, pritom maximálne kontajner môže získať 0.2 CPU a celú dostupnú RAM na uzle.
Na úrovni celého ns:
apiVersion: v1 kind: ResourceQuota metadata: name: nxs-test spec: hard: requests.cpu: 300m requests.memory: 1Gi limits.cpu: 700m limits.memory: 2GiT.j. súčet všetkých request kontajnerov v predvolenom ns nemôže prekročiť 300m pre CPU a 1G pre RAM, zatiaľ čo súčet všetkých limitov — 700m pre CPU a 2G pre RAM.
Predvolené obmedzenia pre kontajnery v 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: 4GiT.j. v predvolenom namespace pre všetky kontajnery bude predvolene nastavený request na 100m pre CPU a 1G pre RAM, limit — 1 CPU a 2G. Zároveň je nastavené aj obmedzenie pre možné hodnoty v request/limit pre CPU (50m < x < 2) a RAM (500M < x < 4G).
Obmedzenia na úrovni podov ns:
apiVersion: v1 kind: LimitRange metadata: name: nxs-limit-pod spec: limits: - type: Pod max: cpu: 4 memory: 1GiT.j. pre každý pod v predvolenom ns bude nastavené obmedzenie na 4 vCPU a 1G.
Teraz by som chcel povedať, aké výhody nám môže priniesť nastavenie týchto obmedzení.
Mechanizmus vyvažovania zaťaženia medzi uzlami
Ako je známe, za rozdeľovanie podov medzi uzlami zodpovedá taký komponent k8s, ako scheduler, ktorý pracuje na základe určitého algoritmu. Tento algoritmus pri vyberaní optimálneho uzla na spustenie prechádza dvoma fázami:
- Filtrácia
- Rangovanie
T.j. v súlade s opísanou politikou sa najprv vyberajú uzly, na ktorých je možné spustiť pod na základe súboru predicates (vrátane kontroly, či má uzol dostatok zdrojov na spustenie podu — PodFitsResources), a potom pre každý z týchto uzlov, podľa priorities body získavajú body (a to vrátane toho, že čím viac voľných zdrojov má uzol, tým viac bodov mu je pridelených — LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation) a pod sa spúšťa na uzle s najvyšším počtom bodov (ak tomuto kritériu vyhovuje viacero uzlov, vyberie sa náhodný z nich).
Pri tom je potrebné si uvedomiť, že scheduler pri hodnotení dostupných zdrojov uzla sa riadi údajmi, ktoré sú uložené v etcd — t.j. súčtom requested/limit zdroja každého podu, ktorý je spustený na tomto uzle, ale nie skutočnou spotrebou zdrojov. Túto informáciu je možné získať z výstupu príkazu kubectl describe node $NODE, napríklad:
# 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%)Tu vidíme všetky podi spustené na konkrétnom uzle, ako aj zdroje, ktoré požaduje každý z podov. A takto vyzerajú záznamy scheduler pri spustení podu cronjob-cron-events-1573793820-xt6q9 (táto informácia v zázname scheduler sa objaví pri nastavení úrovne logovania na 10 v argumentoch príkazu spustenia —v=10):
záznam
I1115 07:57:21.637791 1 scheduling_queue.go:908] Chystá sa naplánovať pod nxs-stage/cronjob-cron-events-1573793820-xt6q9
I1115 07:57:21.637804 1 scheduler.go:453] Pokus o naplánovanie podu: nxs-stage/cronjob-cron-events-1573793820-xt6q9
I1115 07:57:21.638285 1 predicates.go:829] Naplánovať pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 na uzle nxs-k8s-s5 je povolené, uzol beží iba s 16 zo 110 podov.
I1115 07:57:21.638300 1 predicates.go:829] Naplánovať pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 na uzle nxs-k8s-s6 je povolené, uzol beží iba s 20 zo 110 podov.
I1115 07:57:21.638322 1 predicates.go:829] Naplánovať pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 na uzle nxs-k8s-s3 je povolené, uzol beží iba s 20 zo 110 podov.
I1115 07:57:21.638322 1 predicates.go:829] Naplánovať pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 na uzle nxs-k8s-s4 je povolené, uzol beží iba s 17 zo 110 podov.
I1115 07:57:21.638334 1 predicates.go:829] Naplánovať pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 na uzle nxs-k8s-s10 je povolené, uzol beží iba s 16 zo 110 podov.
I1115 07:57:21.638365 1 predicates.go:829] Naplánovať pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 na uzle nxs-k8s-s12 je povolené, uzol beží iba s 9 zo 110 podov.
I1115 07:57:21.638334 1 predicates.go:829] Naplánovať pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 na uzle nxs-k8s-s11 je povolené, uzol beží iba s 11 zo 110 podov.
I1115 07:57:21.638385 1 predicates.go:829] Naplánovať pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 na uzle nxs-k8s-s1 je povolené, uzol beží iba s 19 zo 110 podov.
I1115 07:57:21.638402 1 predicates.go:829] Naplánovať pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 na uzle nxs-k8s-s2 je povolené, uzol beží iba s 21 zo 110 podov.
I1115 07:57:21.638383 1 predicates.go:829] Naplánovať pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 na uzle nxs-k8s-s9 je povolené, uzol beží iba s 16 zo 110 podov.
I1115 07:57:21.638335 1 predicates.go:829] Naplánovať pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 na uzle nxs-k8s-s8 je povolené, uzol beží iba s 18 zo 110 podov.
I1115 07:57:21.638408 1 predicates.go:829] Naplánovať pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 na uzle nxs-k8s-s13 je povolené, uzol beží iba s 8 zo 110 podov.
I1115 07:57:21.638478 1 predicates.go:1369] Naplánovať pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 na uzle nxs-k8s-s10 je povolené, existujúce podmínky anti-affinity sú splnené.
I1115 07:57:21.638505 1 predicates.go:1369] Naplánovať pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 na uzle nxs-k8s-s8 je povolené, existujúce podmínky anti-affinity sú splnené.
I1115 07:57:21.638577 1 predicates.go:1369] Naplánovať pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 na uzle nxs-k8s-s9 je povolené, existujúce podmínky anti-affinity sú splnené.
I1115 07:57:21.638583 1 predicates.go:829] Naplánovať pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 na uzle nxs-k8s-s7 je povolené, uzol beží iba s 25 zo 110 podov.
I1115 07:57:21.638932 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: BalancedResourceAllocation, kapacita 39900 milikórov 66620178432 bajtov pamäte, celkový požiadavok 2343 milikórov 9640186880 bajtov pamäte, skóre 9
I1115 07:57:21.638946 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: LeastResourceAllocation, kapacita 39900 milikórov 66620178432 bajtov pamäte, celkový požiadavok 2343 milikórov 9640186880 bajtov pamäte, skóre 8
I1115 07:57:21.638961 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: BalancedResourceAllocation, kapacita 39900 milikórov 66620170240 bajtov pamäte, celkový požiadavok 4107 milikórov 11307422720 bajtov pamäte, skóre 9
I1115 07:57:21.638971 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: BalancedResourceAllocation, kapacita 39900 milikórov 66620178432 bajtov pamäte, celkový požiadavok 5847 milikórov 24333637120 bajtov pamäte, skóre 7
I1115 07:57:21.638975 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: LeastResourceAllocation, kapacita 39900 milikórov 66620170240 bajtov pamäte, celkový požiadavok 4107 milikórov 11307422720 bajtov pamäte, skóre 8
I1115 07:57:21.638990 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: LeastResourceAllocation, kapacita 39900 milikórov 66620178432 bajtov pamäte, celkový požiadavok 5847 milikórov 24333637120 bajtov pamäte, skóre 7
I1115 07:57:21.639022 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s10: TaintTolerationPriority, skóre: (10)
I1115 07:57:21.639030 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s8: TaintTolerationPriority, skóre: (10)
I1115 07:57:21.639034 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s9: TaintTolerationPriority, skóre: (10)
I1115 07:57:21.639041 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s10: NodeAffinityPriority, skóre: (0)
I1115 07:57:21.639053 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s8: NodeAffinityPriority, skóre: (0)
I1115 07:57:21.639059 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s9: NodeAffinityPriority, skóre: (0)
I1115 07:57:21.639061 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s10: InterPodAffinityPriority, skóre: (0)
I1115 07:57:21.639063 1 selector_spreading.go:146] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s10: SelectorSpreadPriority, skóre: (10)
I1115 07:57:21.639073 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s8: InterPodAffinityPriority, skóre: (0)
I1115 07:57:21.639077 1 selector_spreading.go:146] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s8: SelectorSpreadPriority, skóre: (10)
I1115 07:57:21.639085 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s9: InterPodAffinityPriority, skóre: (0)
I1115 07:57:21.639088 1 selector_spreading.go:146] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s9: SelectorSpreadPriority, skóre: (10)
I1115 07:57:21.639103 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s10: SelectorSpreadPriority, skóre: (10)
I1115 07:57:21.639109 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s8: SelectorSpreadPriority, skóre: (10)
I1115 07:57:21.639114 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s9: SelectorSpreadPriority, skóre: (10)
I1115 07:57:21.639127 1 generic_scheduler.go:781] Host nxs-k8s-s10 => skóre 100037
I1115 07:57:21.639150 1 generic_scheduler.go:781] Host nxs-k8s-s8 => skóre 100034
I1115 07:57:21.639154 1 generic_scheduler.go:781] Host nxs-k8s-s9 => skóre 100037
I1115 07:57:21.639267 1 scheduler_binder.go:269] AssumePodVolumes pre pod "nxs-stage/cronjob-cron-events-1573793820-xt6q9", uzol "nxs-k8s-s10"
I1115 07:57:21.639286 1 scheduler_binder.go:279] AssumePodVolumes pre pod "nxs-stage/cronjob-cron-events-1573793820-xt6q9", uzol "nxs-k8s-s10": všetky PVC sú priradené a nič sa nedá urobiť
I1115 07:57:21.639333 1 factory.go:733] Pokus o priradenie cronjob-cron-events-1573793820-xt6q9 k nxs-k8s-s10Tu vidíme, že pôvodne plánovač vykonáva filtrovanie a vytvára zoznam zo 3 nód, na ktorých je možné spustiť (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10). Následne počíta body podľa niekoľkých parametrov (vrátane BalancedResourceAllocation, LeastResourceAllocation) pre každú z týchto nód s cieľom určiť najvhodnejší uzol. Nakoniec sa plánuje na nód s najvyšším počtom bodov (tu sú dve nody so zhodným počtom bodov 100037, takže sa náhodne vyberie jedna z nich — nxs-k8s-s10).
Záver: ak na nódach pracujú pod, pre ktoré nie sú stanovené obmedzenia, potom pre k8s (z hľadiska spotreby zdrojov) to bude rovné tomu, ako keby na tejto nód neexistovali žiadne pod. Preto, ak máte, podmienečne, pod s náročným procesom (napríklad wowza) a pre neho nie sú stanovené obmedzenia, môže nastať taká situácia, kedy tento pod skutočne zoberie všetky zdroje nód, ale pre k8s sa táto nód považuje za nenáročnú a pri hodnotení (presne v bodoch hodnotenia dostupných zdrojov) získa rovnaký počet bodov ako nód, na ktorej nie sú aktívne pod, čo môže nakoniec viesť k nerovnomernému rozdeleniu záťaže medzi nódami.
Vysťahovanie podu
Ako je známe — každému podu sa priraďuje jedna z 3 QoS tried:
- guaranuted — priraďuje sa vtedy, keď pre každý kontajner v pod je pre pamäť a CPU stanovený request a limit, pričom tieto hodnoty musia byť rovnaké
- burstable — aspoň jeden kontajner v pod má request a limit, pričom request < limit
- best effort — keď ani jeden kontajner v pod nie je obmedzený podľa zdrojov
Pri tom, keď sa na nódach pozoruje nedostatok zdrojov (disku, pamäte), kubelet začína hodnotiť a vysťahovať pod'y podľa určitého algoritmu, ktorý zohľadňuje prioritu podu a jeho QoS triedu. Napríklad, ak ide o RAM, body sú prideľované na základe QoS triedy podľa nasledujúceho princípu:
- Guaranteed: -998
- BestEffort: 1000
- Burstable: min(max(2, 1000 — (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)
T.j. pri rovnakej prioritne, kubelet najprv vysťahuje z nód pody s QoS triedou best effort.
Záver: ak chcete znížiť pravdepodobnosť vysťahovania potrebného podu z nód v prípade nedostatku zdrojov na nej, je potrebné vedľa priority tiež zabezpečiť a stanovenie request/limit pre neho.
Mechaniz horizontálneho automatického škálovania podov aplikácie (HPA)
Keď je úlohou automaticky zvyšovať a znižovať počet podov v závislosti od vyžitia zdrojov (systémových - CPU/RAM alebo používateľských - rps), môže nám pri jej riešení pomôcť taká entita k8s ako HPA (Horizontal Pod Autoscaler). Algoritmus je nasledovný:
- Určujú sa aktuálne hodnoty sledovaných zdrojov (currentMetricValue)
- Určujú sa požadované hodnoty pre zdroj (desiredMetricValue), ktoré pre systémové zdroje sú nastavené pomocou request
- Určuje sa aktuálny počet replik (currentReplicas)
- Nasledujúcou formulkou sa vypočíta požadovaný počet replik (desiredReplicas)
desiredReplicas = [ currentReplicas * ( currentMetricValue / desiredMetricValue )]
Pri tom neprebehne škálovanie, keď je pomer (currentMetricValue / desiredMetricValue) blízky 1 (pri tom môžeme nastaviť tolerovanú odchýlku, ktorá je predvolene 0.1).
Zvážme fungovanie hpa na príklade aplikácie app-test (opisanej ako Deployment), kde je potrebné meniť počet replik v závislosti od spotreby CPU:
Manifest aplikácie
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-statusT.j. vidíme, že pod s aplikáciou sa pôvodne spúšťa v dvoch inštanciách, z ktorých každá obsahuje dva kontejnery nginx a nginx-exporter, pre každý z ktorých je nastavené requests pre CPU.
Manifest 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: 30T.j. vytvorili sme hpa, ktorý bude sledovať Deployment app-test a regulovať počet podov s aplikáciou na základe ukazovateľa CPU (očakávame, že pod by mal spotrebovať 30% percent z požadovaného CPU), pričom počet replik je v rozmedzí 2-10.
Teraz zvážme mechanizmus fungovania hpa, ak zaťažíme jeden z podov:
# kubectl top pod NAME CPU(cores) MEMORY(bytes) app-test-78559f8f44-pgs58 101m 243Mi app-test-78559f8f44-cj4jz 4m 240Mi
Celkovo máme nasledovné:
- Požadovaná hodnota (desiredMetricValue) — podľa nastavení hpa je u nás rovná 30%
- Aktuálna hodnota (currentMetricValue) — pre výpočty controller-manager vypočíta priemernú hodnotu spotreby zdrojov v %, t.j. hypoteticky robí nasledujúce:
- Získa absolútne hodnoty metrických údajov pods z metric-servera, t.j. 101m a 4m
- Vypočíta priemernú absolútnu hodnotu, t.j. (101m + 4m) / 2 = 53m
- Získa absolútnu hodnotu pre požadovanú spotrebu zdrojov (na tento účel sa sčíta request všetkých kontajnerov) 60m + 30m = 90m
- Vypočíta priemerné percento spotreby CPU vzhľadom na request podu, t.j. 53m / 90m * 100% = 59%
Teraz máme všetko potrebné na to, aby sme určili, či je potrebné zmeniť počet replik, na to vypočítame koeficient:
ratio = 59% / 30% = 1.96
T.j. počet replik by mal byť zvýšený približne 2-krát a dosiahnuť [2 * 1.96] = 4.
Výstup: Ako si môžete všimnúť, pre fungovanie tohto mechanizmu je nevyhnutnou podmienkou mať requests pre všetky kontajnery v sledovanom pode.
Mechanizmus horizontálneho automatizovaného škálovania uzlov (Cluster Autoscaler)
Aby sa zmiernil negatívny dopad na systém pri nárazoch zaťaženia, nastavenie hpa niekedy nestačí. Napríklad, podľa nastavení v hpa controller manager rozhoduje o tom, že počet replik je potrebné zvýšiť 2-krát, avšak na uzloch nie sú voľné zdroje na spustenie takého počtu pods (t.j. uzol nemôže poskytnúť požadované zdroje podu requests) a tieto pady prechádzajú do stavu Pending.
V tomto prípade, ak má poskytovateľ príslušný IaaS/PaaS (napríklad GKE/GCE, AKS, EKS atď.), môže nám pomôcť taký nástroj, ako Node Autoscaler. Umožňuje nastaviť maximálny a minimálny počet uzlov v klastri a automaticky regulovať aktuálny počet uzlov (prostredníctvom volania API poskytovateľa cloudu na objednanie/odstránenie uzla), keď sa pozoruje nedostatok zdrojov v klastri a pady nemôžu byť naplánované (nachádzajú sa v stave Pending).
Výstup: na možnosť automatizovaného škálovania uzlov je potrebné nastaviť requests v kontajneroch pods, aby k8s mohol správne vyhodnotiť zaťaženie uzlov a následne oznámiť, že na spustenie ďalšieho podu nie sú v klastri zdroje.
Záver
Je dôležité poznamenať, že nastavenie obmedzení zdrojov kontajnera nie je povinnou podmienkou pre úspešné spustenie aplikácie, avšak je to predsa len lepšie z nasledujúcich dôvodov:
- Pre presnejšiu prácu scheduleru v oblasti vyvažovania záťaže medzi uzlami k8s
- Na zníženie pravdepodobnosti výskytu udalosti 'vysídlenie podu'
- Pre funkčnosť horizontálneho automatického škálovania podov aplikácie (HPA)
- Pre funkčnosť horizontálneho automatického škálovania uzlov (Cluster Autoscaling) u cloudových poskytovateľov
Čítajte tiež ďalšie články na našom blogu:
Zdroj: habr.com
