De obicei, apare întotdeauna necesitatea de a asigura un grup dedicat de resurse pentru o anumită aplicație, pentru a funcționa corect și stabil. Dar ce se întâmplă dacă mai multe aplicații rulează pe aceleași resurse? Cum putem asigura resursele minim necesare pentru fiecare dintre ele? Cum putem limita consumul de resurse? Cum putem distribui corect încărcătura între noduri? Cum putem asigura funcționarea mecanismului de scalare orizontală în cazul creșterii încărcăturii pe aplicații?

Trebuie să începem cu tipurile principale de resurse care există în sistem — acestea sunt, desigur, timpul CPU și memoria RAM. În manifestele k8s, aceste tipuri de resurse sunt măsurate în următoarele unități:
- CPU — în nuclee
- RAM — în octeți
Pentru fiecare resursă există posibilitatea de a defini două tipuri de cerințe — requests. și limits. Requests — descrie cerințele minime pentru resursele disponibile ale nodului pentru a porni un container (și podul în general), în timp ce limits stabilește o limită strictă a resurselor disponibile pentru container.
Este important de înțeles că în manifest nu este obligatoriu să definim în mod explicit ambele tipuri, comportamentul va fi următorul:
- Dacă este specificat explicit doar limits pentru o resursă, atunci requests pentru acea resursă va prelua automat valoarea egală cu limits (acest lucru se poate verifica prin apelarea descrierii entității). Adică, în fapt, funcționarea containerului va fi limitată la aceeași cantitate de resurse pe care le solicită pentru a porni.
- Dacă pentru o resursă este specificat explicit doar requests, nu se impun restricții suplimentare pe acea resursă — adică, containerul este limitat doar de resursele nodului însuși.
De asemenea, există posibilitatea de a configura gestionarea resurselor nu doar la nivelul unui container specific, ci și la nivelul namespace-ului folosind următoarele entități:
- LimitRange — descrie politica de limitare la nivelul containerului/podului în ns și este necesară pentru a descrie limitările implicite pentru container/pod, precum și pentru a preveni crearea containerelor/podurilor excesiv de mari (sau invers), limitându-le numărul și stabilind o diferență posibilă între valori în limits și requests.
- ResourceQuotas — descrie politica de restricție în general pentru toate containerele din ns și este folosită, în mod obișnuit, pentru a delimita resursele pe medii (utilă atunci când mediile nu sunt strict separate la nivel de noduri)
Mai jos sunt exemple de manifeste în care sunt stabilite limitele pentru resurse:
La nivelul unui container specific:
containers: - name: app-nginx image: nginx resources: requests: memory: 1Gi limits: cpu: 200mAdică, în acest caz, pentru a lansa un container cu nginx, este necesară o capacitate liberă de cel puțin 1G RAM și 0.2 CPU pe nod, iar maximul pe care îl poate utiliza containerul este 0.2 CPU și întreaga memorie disponibilă pe nod.
La nivelul întregului ns:
apiVersion: v1 kind: ResourceQuota metadata: name: nxs-test spec: hard: requests.cpu: 300m requests.memory: 1Gi limits.cpu: 700m limits.memory: 2GiAdică, suma tuturor cererilor containerelor din ns-ul implicit nu poate depăși 300m pentru CPU și 1G pentru RAM, iar suma tuturor limitelor nu poate depăși 700m pentru CPU și 2G pentru RAM.
Limitele implicite pentru containere în 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: 4GiAdică, în namespace-ul implicit, pentru toate containerele va fi setată în mod implicit o cerere de 100m pentru CPU și 1G pentru RAM, limita fiind de 1 CPU și 2G. De asemenea, sunt stabilite limitele pentru valorile posibile în cerere/limită pentru CPU (50m < x < 2) și RAM (500M < x < 4G).
Limitele la nivelul podurilor din ns:
apiVersion: v1 kind: LimitRange metadata: name: nxs-limit-pod spec: limits: - type: Pod max: cpu: 4 memory: 1GiAdică, pentru fiecare pod din ns-ul implicit va fi stabilită o limită de 4 vCPU și 1G.
Acum aș dori să discut despre avantajele pe care ni le poate aduce stabilirea acestor limite.
Mecanismul de echilibrare a încărcăturii între noduri
După cum se știe, distribuția podurilor pe noduri este gestionată de un component k8s, numit scheduler, care funcționează pe baza unui algoritm specific. Acest algoritm, în procesul de alegere a nodului optim pentru lansare, parcurge două etape:
- Filtrare
- Clasificare
Adică, conform politicii descrise, inițial sunt selectate nodurile pe care este posibil să se lanseze poduri pe baza unui set de predicates (inclusiv verificând dacă nodul are suficiente resurse pentru a lansa podul — PodFitsResources), iar apoi, pentru fiecare dintre aceste noduri, conform priorities se acordă puncte (inclusiv, cu cât nodul are mai multe resurse libere, cu atât mai multe puncte i se alocă — LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation) și se rulează pe nodul cu cel mai mare număr de puncte (dacă mai multe noduri îndeplinesc această condiție, se alege unul aleatoriu dintre ele).
Trebuie să înțelegem că scheduler-ul, în evaluarea resurselor disponibile ale nodului, se bazează pe datele stocate în etcd — adică pe suma resurselor solicitate/limitate ale fiecărui pod, care rulează pe acest nod, dar nu pe consumul efectiv al resurselor. Această informație poate fi obținută din ieșirea comenzii kubectl describe node $NODE, de exemplu:
# 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%)Aici vedem toate podurile rulate pe un anumit nod, precum și resursele solicitate de fiecare dintre ele. Iată cum arată log-urile scheduler-ului în timpul rulării pod-ului cronjob-cron-events-1573793820-xt6q9 (această informație va apărea în log-ul scheduler-ului la setarea nivelului 10 de logare în argumentele comenzii de execuție —v=10):
log
I1115 07:57:21.637791 1 scheduling_queue.go:908] Se pregătește să încerce să programeze podul nxs-stage/cronjob-cron-events-1573793820-xt6q9
I1115 07:57:21.637804 1 scheduler.go:453] Încercând să programeze podul: nxs-stage/cronjob-cron-events-1573793820-xt6q9
I1115 07:57:21.638285 1 predicates.go:829] Programarea podului nxs-stage/cronjob-cron-events-1573793820-xt6q9 pe nodul nxs-k8s-s5 este permisă, nodul rulează doar 16 din 110 poduri.
I1115 07:57:21.638300 1 predicates.go:829] Programarea podului nxs-stage/cronjob-cron-events-1573793820-xt6q9 pe nodul nxs-k8s-s6 este permisă, nodul rulează doar 20 din 110 poduri.
I1115 07:57:21.638322 1 predicates.go:829] Programarea podului nxs-stage/cronjob-cron-events-1573793820-xt6q9 pe nodul nxs-k8s-s3 este permisă, nodul rulează doar 20 din 110 poduri.
I1115 07:57:21.638322 1 predicates.go:829] Programarea podului nxs-stage/cronjob-cron-events-1573793820-xt6q9 pe nodul nxs-k8s-s4 este permisă, nodul rulează doar 17 din 110 poduri.
I1115 07:57:21.638334 1 predicates.go:829] Programarea podului nxs-stage/cronjob-cron-events-1573793820-xt6q9 pe nodul nxs-k8s-s10 este permisă, nodul rulează doar 16 din 110 poduri.
I1115 07:57:21.638365 1 predicates.go:829] Programarea podului nxs-stage/cronjob-cron-events-1573793820-xt6q9 pe nodul nxs-k8s-s12 este permisă, nodul rulează doar 9 din 110 poduri.
I1115 07:57:21.638334 1 predicates.go:829] Programarea podului nxs-stage/cronjob-cron-events-1573793820-xt6q9 pe nodul nxs-k8s-s11 este permisă, nodul rulează doar 11 din 110 poduri.
I1115 07:57:21.638385 1 predicates.go:829] Programarea podului nxs-stage/cronjob-cron-events-1573793820-xt6q9 pe nodul nxs-k8s-s1 este permisă, nodul rulează doar 19 din 110 poduri.
I1115 07:57:21.638402 1 predicates.go:829] Programarea podului nxs-stage/cronjob-cron-events-1573793820-xt6q9 pe nodul nxs-k8s-s2 este permisă, nodul rulează doar 21 din 110 poduri.
I1115 07:57:21.638383 1 predicates.go:829] Programarea podului nxs-stage/cronjob-cron-events-1573793820-xt6q9 pe nodul nxs-k8s-s9 este permisă, nodul rulează doar 16 din 110 poduri.
I1115 07:57:21.638335 1 predicates.go:829] Programarea podului nxs-stage/cronjob-cron-events-1573793820-xt6q9 pe nodul nxs-k8s-s8 este permisă, nodul rulează doar 18 din 110 poduri.
I1115 07:57:21.638408 1 predicates.go:829] Programarea podului nxs-stage/cronjob-cron-events-1573793820-xt6q9 pe nodul nxs-k8s-s13 este permisă, nodul rulează doar 8 din 110 poduri.
I1115 07:57:21.638478 1 predicates.go:1369] Programarea podului nxs-stage/cronjob-cron-events-1573793820-xt6q9 pe nodul nxs-k8s-s10 este permisă, condițiile anti-afinitate pentru podurile existente sunt satisfăcute.
I1115 07:57:21.638505 1 predicates.go:1369] Programarea podului nxs-stage/cronjob-cron-events-1573793820-xt6q9 pe nodul nxs-k8s-s8 este permisă, condițiile anti-afinitate pentru podurile existente sunt satisfăcute.
I1115 07:57:21.638577 1 predicates.go:1369] Programarea podului nxs-stage/cronjob-cron-events-1573793820-xt6q9 pe nodul nxs-k8s-s9 este permisă, condițiile anti-afinitate pentru podurile existente sunt satisfăcute.
I1115 07:57:21.638583 1 predicates.go:829] Programarea podului nxs-stage/cronjob-cron-events-1573793820-xt6q9 pe nodul nxs-k8s-s7 este permisă, nodul rulează doar 25 din 110 poduri.
I1115 07:57:21.638932 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: BalancedResourceAllocation, capacitate 39900 milicore 66620178432 octeți de memorie, cerere totală 2343 milicore 9640186880 octeți de memorie, scor 9
I1115 07:57:21.638946 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: LeastResourceAllocation, capacitate 39900 milicore 66620178432 octeți de memorie, cerere totală 2343 milicore 9640186880 octeți de memorie, scor 8
I1115 07:57:21.638961 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: BalancedResourceAllocation, capacitate 39900 milicore 66620170240 octeți de memorie, cerere totală 4107 milicore 11307422720 octeți de memorie, scor 9
I1115 07:57:21.638971 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: BalancedResourceAllocation, capacitate 39900 milicore 66620178432 octeți de memorie, cerere totală 5847 milicore 24333637120 octeți de memorie, scor 7
I1115 07:57:21.638975 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: LeastResourceAllocation, capacitate 39900 milicore 66620170240 octeți de memorie, cerere totală 4107 milicore 11307422720 octeți de memorie, scor 8
I1115 07:57:21.638990 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: LeastResourceAllocation, capacitate 39900 milicore 66620178432 octeți de memorie, cerere totală 5847 milicore 24333637120 octeți de memorie, scor 7
I1115 07:57:21.639022 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: TaintTolerationPriority, Scor: (10)
I1115 07:57:21.639030 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: TaintTolerationPriority, Scor: (10)
I1115 07:57:21.639034 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: TaintTolerationPriority, Scor: (10)
I1115 07:57:21.639041 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: NodeAffinityPriority, Scor: (0)
I1115 07:57:21.639053 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: NodeAffinityPriority, Scor: (0)
I1115 07:57:21.639059 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: NodeAffinityPriority, Scor: (0)
I1115 07:57:21.639061 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: InterPodAffinityPriority, Scor: (0)
I1115 07:57:21.639063 1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: SelectorSpreadPriority, Scor: (10)
I1115 07:57:21.639073 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: InterPodAffinityPriority, Scor: (0)
I1115 07:57:21.639077 1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: SelectorSpreadPriority, Scor: (10)
I1115 07:57:21.639085 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: InterPodAffinityPriority, Scor: (0)
I1115 07:57:21.639088 1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: SelectorSpreadPriority, Scor: (10)
I1115 07:57:21.639103 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: SelectorSpreadPriority, Scor: (10)
I1115 07:57:21.639109 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: SelectorSpreadPriority, Scor: (10)
I1115 07:57:21.639114 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: SelectorSpreadPriority, Scor: (10)
I1115 07:57:21.639127 1 generic_scheduler.go:781] Host nxs-k8s-s10 -> Scor 100037
I1115 07:57:21.639150 1 generic_scheduler.go:781] Host nxs-k8s-s8 -> Scor 100034
I1115 07:57:21.639154 1 generic_scheduler.go:781] Host nxs-k8s-s9 -> Scor 100037
I1115 07:57:21.639267 1 scheduler_binder.go:269] AssumePodVolumes pentru podul "nxs-stage/cronjob-cron-events-1573793820-xt6q9", nodul "nxs-k8s-s10"
I1115 07:57:21.639286 1 scheduler_binder.go:279] AssumePodVolumes pentru podul "nxs-stage/cronjob-cron-events-1573793820-xt6q9", nodul "nxs-k8s-s10": toate PVC-urile sunt legate și nimic de făcut
I1115 07:57:21.639333 1 factory.go:733] Încercând să leagă cronjob-cron-events-1573793820-xt6q9 de nxs-k8s-s10Aici vedem că inițial scheduler-ul realizează filtrarea și formează o listă de 3 noduri pe care poate fi efectuată lansarea (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10). Apoi, calculează punctele pe baza mai multor parametri (inclusiv BalancedResourceAllocation, LeastResourceAllocation) pentru fiecare dintre aceste noduri, cu scopul de a determina nodul cel mai potrivit. În cele din urmă, se plasează pe nodul cu cel mai mare număr de puncte (aici, imediat două noduri au același număr de puncte 100037, așa că se alege aleatoriu dintre ele — nxs-k8s-s10).
Ieșire: dacă pe nod rulează poduri pentru care nu sunt stabilite limite, pentru k8s (din perspectiva consumului de resurse) aceasta va fi echivalent cu faptul că pe acest nod astfel de poduri nu există deloc. Prin urmare, dacă aveți, să spunem, un pod cu un proces într-un consum mare de resurse (de exemplu, wowza) și pentru acesta nu sunt stabilite limite, ar putea apărea o situație în care acest pod să consume toate resursele nodului, dar pentru k8s acest nod este considerat neîncărcat și va primi același număr de puncte la clasificare (exact în punctele de evaluare a resurselor disponibile) ca și nodul pe care nu există poduri active, ceea ce în final poate duce la o distribuție inegală a sarcinii între noduri.
Evacuarea podului
După cum se știe — fiecărui pod îi este atribuit una dintre cele 3 clase QoS:
- garantat — se atribuie atunci când pentru fiecare container din pod sunt stabilite request și limit pentru memorie și CPU, iar aceste valori trebuie să fie egale
- burstable — cel puțin un container din pod are request și limit, în timp ce request < limit
- cea mai bună efort — atunci când niciun container din pod nu este restricționat în ceea ce privește resursele
În acest context, atunci când pe nod se observă o lipsă de resurse (discuri, memorie), kubelet începe să clasificareze și să evacueze pod-urile conform unui algoritm specific, care ia în considerare prioritatea pod-ului și clasa sa QoS. De exemplu, dacă este vorba despre RAM, atunci baza punctelor se calculează după următorul principiu:
- Guaranteed: -998
- BestEffort: 1000
- Burstable: min(max(2, 1000 — (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)
Adică, cu aceeași prioritate, kubelet va evacua în primul rând podurile cu clasa QoS cea mai bună efort.
Ieșire: dacă doriți să diminuați probabilitatea evacuării pod-ului necesar de pe nod în cazul lipsei de resurse pe acesta, trebuie să vă asigurați, pe lângă prioritate, și că aveți stabilite request/limit pentru acesta.
Mecanismul de scalare orizontală a podurilor aplicației (HPA)
Când este necesar să se crească și să se reducă automat numărul de pod-uri în funcție de utilizarea resurselor (sistemice — CPU/RAM sau utilizator — rps), o entitate k8s utilă ar putea fi HPA (Horizontal Pod Autoscaler). Algoritmul său este următorul:
- Se determină valorile actuale ale resursei observate (currentMetricValue)
- Se determină valorile dorite pentru resursă (desiredMetricValue), care pentru resursele sistemice sunt stabilite prin request
- Se determină numărul actual de replici (currentReplicas)
- Numărul dorit de replici (desiredReplicas) se calculează după următoarea formulă
desiredReplicas = [ currentReplicas * ( currentMetricValue / desiredMetricValue )]
În acest caz, scalarea nu va avea loc atunci când raportul (currentMetricValue / desiredMetricValue) este aproape de 1 (iar toleranța pe care o putem stabili noi poate fi folosită, implicit fiind egală cu 0.1).
Să luăm în considerare funcționarea hpa prin exemplul aplicației app-test (descrisă ca Deployment), unde este necesară modificarea numărului de replici în funcție de consumul de CPU:
Manifestul aplicației
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-statusAdică, observăm că podul cu aplicația este inițial lansat în două exemplare, fiecare dintre acestea conținând două containere nginx și nginx-exporter, pentru fiecare fiind stabilit requests. pentru CPU.
Manifestul 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: 30Adică, am creat un hpa care va monitoriza Deployment app-test și va regla numărul de pod-uri cu aplicația pe baza indicatorului cpu (așteptăm ca pod-ul să consume 30% din CPU-ul solicitat), în timp ce numărul de replici se află în intervalul 2-10.
Acum, să examinăm mecanismul funcționării hpa, dacă se aplică o sarcină pe unul dintre poduri:
# kubectl top pod NAME CPU(cores) MEMORY(bytes) app-test-78559f8f44-pgs58 101m 243Mi app-test-78559f8f44-cj4jz 4m 240Mi
Astfel, avem următoarele:
- Valoarea dorită (desiredMetricValue) — conform setărilor hpa, este de 30%
- Valoarea actuală (currentMetricValue) — pentru calcul, controller-managerul determină media consumului de resurse în %, ceea ce înseamnă că efectuează următoarele operațiuni:
- Obține valorile absolute ale metodelor de la serverul metric, adică 101m și 4m
- Calculează media valorilor absolute, adică (101m + 4m) / 2 = 53m
- Obține valoarea absolută pentru consumul dorit de resurse (pentru aceasta se adună request-urile tuturor containerelor) 60m + 30m = 90m
- Calculează procentul mediu de consum CPU în raport cu request-ul podului, adică 53m / 90m * 100% = 59%
Acum avem tot ce este necesar pentru a determina dacă trebuie să modificăm numărul de replici, pentru aceasta calculăm coeficientul:
ratio = 59% / 30% = 1.96
Adică numărul de replici ar trebui să fie crescut de aproximativ 2 ori, ceea ce înseamnă [2 * 1.96] = 4.
Concluzie: Așa cum se poate observa, pentru ca acest mecanism să funcționeze, este necesar ca requests să fie specifice pentru toate containerele din podul monitorizat.
Mecanismul de scalare orizontală a nodurilor (Cluster Autoscaler)
Pentru a diminua impactul negativ asupra sistemului în cazul vârfurilor de încărcare, simpla existență a unui hpa configurat poate fi insuficientă. De exemplu, conform setărilor din hpa, managerul controller determină că numărul de replici trebuie să fie dublat, însă pe noduri nu sunt resurse libere pentru a rula un astfel de număr de poduri (adică nodul nu poate oferi resursele solicitate de poduri requests) și aceste poduri trec în starea Pending.
În acest caz, dacă furnizorul dispune de un IaaS/PaaS corespunzător (de exemplu, GKE/GCE, AKS, EKS etc.), un instrument comme ar fi Node Autoscaler. Acesta permite setarea unui număr maxim și minim de noduri în cluster și reglează automat numărul curent de noduri (prin apeluri API către furnizorul de cloud pentru a comanda/șterge un nod), atunci când se observă o lipsă de resurse în cluster și podurile nu pot fi planificate (se află în starea Pending).
Concluzie: Pentru a permite scalarea automată a nodurilor, este necesar să specificați requests în containerele podurilor, astfel încât k8s să poată evalua corect încărcarea nodurilor și, în consecință, să informeze că nu sunt resurse disponibile în cluster pentru a lansa un nou pod.
Concluzie
Este important de menționat că stabilirea limitelor de resurse pentru un container nu este o condiție obligatorie pentru lansarea cu succes a unei aplicații, dar este totuși recomandată din următoarele motive:
- Pentru a îmbunătăți funcționarea scheduler-ului în ceea ce privește echilibrarea sarcinii între nodurile k8s
- Pentru a reduce probabilitatea apariției evenimentului „evacuare pod”
- Pentru a permite scalarea orizontală automată a podurilor aplicației (HPA)
- Pentru a permite scalarea orizontală automată a nodurilor (Cluster Autoscaling) de către furnizorii de cloud
Citiți și alte articole de pe blogul nostru:
Sursa: habr.com
