Zakonisht, ka gjithmonë nevojë për të siguruar një grup të dedikuar burimesh për një aplikacion për funksionimin e tij të saktë dhe të qëndrueshëm. Por çfarë ndodh nëse disa aplikacione funksionojnë në të njëjtën kapacitet? Si mund të sigurohet që çdo aplikacion të ketë burimet minimale të nevojshme? Si mund të kufizohet konsumimi i burimeve? Si mund të shpërndahen ngarkesat midis nodave? Si mund të sigurohet funksionimi i mekanizmit të skalimit horizontal në rast të rritjes së ngarkesës mbi aplikacionet?

Duhet tĂ« fillojmĂ« nga llojet kryesore tĂ« burimeve qĂ« ekzistojnĂ« nĂ« sistem â kĂ«to janĂ«, natyrisht, koha e procesorit dhe memorja operative. NĂ« manifestet e k8s, kĂ«to lloje burimesh maten nĂ« njĂ«sitĂ« e mĂ«poshtme:
- CPU â nĂ« bĂ«rthama
- RAM â nĂ« byte
PĂ«r secilin burim, ekziston mundĂ«sia pĂ«r tĂ« caktuar dy lloje kĂ«rkesh â requests dhe kufizimet. KĂ«rkesat â pĂ«rshkruan kĂ«rkesat minimale pĂ«r burimet e lira nĂ« nodĂ« pĂ«r tĂ« filluar konteinerin (dhe pod-in nĂ« pĂ«rgjithĂ«si), ndĂ«rsa kufijtĂ« vendosin njĂ« kufizim tĂ« fortĂ« pĂ«r burimet qĂ« i janĂ« tĂ« disponueshme konteinerit.
ĂshtĂ« e rĂ«ndĂ«sishme tĂ« kuptohet se nuk Ă«shtĂ« e nevojshme tĂ« pĂ«rcaktohen qartĂ« tĂ« dyja llojet nĂ« manifest, por sjellja do tĂ« jetĂ« si mĂ« poshtĂ«:
- Nëse është caktuar vetëm kufiri i burimeve, atëherë kërkesa për këtë burim automatikisht merr vlerën e kufijve (kjo mund të konfirmohet duke thirrur përshkrimin e entitetit). Pra, faktikisht puna e konteinerit do të kufizohet në atë numër burimesh që kërkon për nisjen e tij.
- NĂ«se pĂ«r burimin Ă«shtĂ« caktuar vetĂ«m kĂ«rkesa, atĂ«herĂ« nuk ka kufizime tĂ« tjera pĂ«r kĂ«tĂ« burim â pra, konteineri Ă«shtĂ« i kufizuar vetĂ«m nga burimet e vetĂ« nodĂ«s.
Gjithashtu ekziston mundësia për të konfiguruar menaxhimin e burimeve jo vetëm në nivelin e konteinerit përkatës, por edhe në nivelin e namespace me anë të entiteteve të mëposhtme:
- LimitRange â pĂ«rshkruan politikĂ«n e kufizimit nĂ« nivelin e konteinerit/pod-it nĂ« ns dhe Ă«shtĂ« e nevojshme pĂ«r tĂ« pĂ«rshkruar kufizimet e paracaktuara pĂ«r konteiner/pod, si dhe pĂ«r tĂ« parandaluar krijimin e konteinerĂ«ve/pod-ve tĂ« trashĂ« (apo pĂ«rndryshe), pĂ«r t'i kufizuar ata nĂ« numĂ«r dhe pĂ«r tĂ« pĂ«rcaktuar ndryshimin e mundshĂ«m tĂ« vlerave nĂ« kufij dhe kĂ«rkesa.
- ResourceQuotas â pĂ«rshkruan politikĂ«n e kufizimit nĂ« pĂ«rgjithĂ«si pĂ«r tĂ« gjithĂ« konteinerĂ«t nĂ« ns dhe pĂ«rdoret, zakonisht, pĂ«r tĂ« ndarĂ« burimet sipas mjediseve (e dobishme kur ambientet nuk janĂ« tĂ« ndara rreptĂ«sisht nĂ« nivel nodash).
Më poshtë janë disa shembuj manifestesh ku vendosen kufizime për burimet:
Në nivelin e konteinerit përkatës:
containers: - name: app-nginx image: nginx resources: requests: memory: 1Gi limits: cpu: 200mPra, në këtë rast për të filluar një konteiner me nginx kërkohet të paktën një 1G të lirë RAM dhe 0.2 CPU në nodë, ndërsa maksimumi i konteinerit mund të konsumojë 0.2 CPU dhe të gjithë RAM-në e disponueshme në nodë.
Në nivelin e të gjithë ns:
apiVersion: v1 kind: ResourceQuota metadata: name: nxs-test spec: hard: requests.cpu: 300m requests.memory: 1Gi limits.cpu: 700m limits.memory: 2GiPra, shuma e tĂ« gjitha kĂ«rkesave tĂ« konteinerĂ«ve nĂ« ns-nĂ« e paracaktuar nuk mund tĂ« kalojĂ« 300m pĂ«r CPU dhe 1G pĂ«r RAM, ndĂ«rsa shuma e tĂ« gjithĂ« kufijve â 700m pĂ«r CPU dhe 2G pĂ«r RAM.
Kufizimet e paracaktuara për konteinerët 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: 4GiPra, nĂ« namespace-in e paracaktuar pĂ«r tĂ« gjithĂ« konteinerĂ«t, si standard, do tĂ« vendoset kĂ«rkesa prej 100m pĂ«r CPU dhe 1G pĂ«r RAM, kufiri â 1 CPU dhe 2G. gjithashtu, Ă«shtĂ« vendosur njĂ« kufizim mbi vlerat e mundshme nĂ« kĂ«rkesĂ«/kufizim pĂ«r CPU (50m < x < 2) dhe RAM (500M < x < 4G).
Kufizimet në nivelin e pod-ve të ns:
apiVersion: v1 kind: LimitRange metadata: name: nxs-limit-pod spec: limits: - type: Pod max: cpu: 4 memory: 1GiPra, për çdo pod në namespace-in e paracaktuar do të vendoset një kufizim prej 4 vCPU dhe 1G.
Tani do të dëshiroja të flas për avantazhet që mund të na japin vendosja e këtyre kufizimeve.
Mekanizmi i balancimit të ngarkesës midis nodave
Siç dihet, për shpërndarjen e pod-ve midis nodave është përgjegjës një komponent i k8s, i quajtur scheduler, i cili punon sipas një algoritmi të caktuar. Ky algoritëm kalon nëpër dy faza gjatë zgjedhjes së nodit optimal për nisje:
- Filtrimi
- Renditja
Pra, sipas politikĂ«s sĂ« pĂ«rshkruar, fillimisht zgjidhen nodet ku Ă«shtĂ« e mundur tĂ« niset pod-i mbi bazĂ«n e njĂ« grupi predicates (pĂ«rfshirĂ« kontrollimin e mjaftueshmĂ«risĂ« sĂ« burimeve nĂ« nodĂ« pĂ«r ngritjen e pod-it â PodFitsResources), dhe pastaj pĂ«r secilĂ«n prej kĂ«tyre nodĂ«ve, sipas priorities akumulohen pikĂ« (pĂ«rfshirĂ«, sa mĂ« shumĂ« burime tĂ« lira nĂ« nodĂ« â aq mĂ« shumĂ« pikĂ« i jepet â LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation) dhe pod-i Ă«shtĂ« i lidhur nĂ« nodĂ«n me numrin mĂ« tĂ« madh tĂ« pikĂ«ve (nĂ«se ky kusht plotĂ«sohet nga disa nodĂ«, njĂ«ra prej tyre zgjidhet rastĂ«sisht).
ĂshtĂ« e rĂ«ndĂ«sishme tĂ« kuptohet se scheduler nĂ« vlerĂ«simin e burimeve tĂ« disponueshme tĂ« nodit orienton nĂ« tĂ« dhĂ«nat qĂ« ruhen nĂ« etcd - dhe domethĂ«nĂ« nĂ« shumĂ«n e requested/limit burimeve tĂ« çdo pod-i tĂ« nisur nĂ« kĂ«tĂ« nod, por jo pĂ«r konsumimin e burimeve reale. KĂ«to informacione mund tĂ« merren nga dalja e komandĂ«s kubectl describe node $NODE, pĂ«r shembull:
# 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%)KĂ«tu shohim tĂ« gjitha pod-et e nisura nĂ« njĂ« nod tĂ« caktuar, si dhe burimet qĂ« kĂ«rkon secili nga pod-et. Ja si duken log-et e scheduler gjatĂ« nisjes sĂ« pod-it cronjob-cron-events-1573793820-xt6q9 (kjo informacion do tĂ« shfaqet nĂ« log-et e scheduler nĂ«se vendosni nivelin 10 tĂ« logimit nĂ« argumentet e komandĂ«s sĂ« nisjes âv=10):
log
I1115 07:57:21.637791 1 scheduling_queue.go:908] Po përpiqet të planifikojë pod-in nxs-stage\/cronjob-cron-events-1573793820-xt6q9
I1115 07:57:21.637804 1 scheduler.go:453] Po përpiqet të planifikojë pod-in: nxs-stage\/cronjob-cron-events-1573793820-xt6q9
I1115 07:57:21.638285 1 predicates.go:829] Planifikimi i Pod nxs-stage\/cronjob-cron-events-1573793820-xt6q9 në Node nxs-k8s-s5 është i lejuar, Node po ekzekuton vetëm 16 nga 110 Pods.
I1115 07:57:21.638300 1 predicates.go:829] Planifikimi i Pod nxs-stage\/cronjob-cron-events-1573793820-xt6q9 në Node nxs-k8s-s6 është i lejuar, Node po ekzekuton vetëm 20 nga 110 Pods.
I1115 07:57:21.638322 1 predicates.go:829] Planifikimi i Pod nxs-stage\/cronjob-cron-events-1573793820-xt6q9 në Node nxs-k8s-s3 është i lejuar, Node po ekzekuton vetëm 20 nga 110 Pods.
I1115 07:57:21.638322 1 predicates.go:829] Planifikimi i Pod nxs-stage\/cronjob-cron-events-1573793820-xt6q9 në Node nxs-k8s-s4 është i lejuar, Node po ekzekuton vetëm 17 nga 110 Pods.
I1115 07:57:21.638334 1 predicates.go:829] Planifikimi i Pod nxs-stage\/cronjob-cron-events-1573793820-xt6q9 në Node nxs-k8s-s10 është i lejuar, Node po ekzekuton vetëm 16 nga 110 Pods.
I1115 07:57:21.638365 1 predicates.go:829] Planifikimi i Pod nxs-stage\/cronjob-cron-events-1573793820-xt6q9 në Node nxs-k8s-s12 është i lejuar, Node po ekzekuton vetëm 9 nga 110 Pods.
I1115 07:57:21.638334 1 predicates.go:829] Planifikimi i Pod nxs-stage\/cronjob-cron-events-1573793820-xt6q9 në Node nxs-k8s-s11 është i lejuar, Node po ekzekuton vetëm 11 nga 110 Pods.
I1115 07:57:21.638385 1 predicates.go:829] Planifikimi i Pod nxs-stage\/cronjob-cron-events-1573793820-xt6q9 në Node nxs-k8s-s1 është i lejuar, Node po ekzekuton vetëm 19 nga 110 Pods.
I1115 07:57:21.638402 1 predicates.go:829] Planifikimi i Pod nxs-stage\/cronjob-cron-events-1573793820-xt6q9 në Node nxs-k8s-s2 është i lejuar, Node po ekzekuton vetëm 21 nga 110 Pods.
I1115 07:57:21.638383 1 predicates.go:829] Planifikimi i Pod nxs-stage\/cronjob-cron-events-1573793820-xt6q9 në Node nxs-k8s-s9 është i lejuar, Node po ekzekuton vetëm 16 nga 110 Pods.
I1115 07:57:21.638335 1 predicates.go:829] Planifikimi i Pod nxs-stage\/cronjob-cron-events-1573793820-xt6q9 në Node nxs-k8s-s8 është i lejuar, Node po ekzekuton vetëm 18 nga 110 Pods.
I1115 07:57:21.638408 1 predicates.go:829] Planifikimi i Pod nxs-stage\/cronjob-cron-events-1573793820-xt6q9 në Node nxs-k8s-s13 është i lejuar, Node po ekzekuton vetëm 8 nga 110 Pods.
I1115 07:57:21.638478 1 predicates.go:1369] Planifikimi i Pod nxs-stage\/cronjob-cron-events-1573793820-xt6q9 në Node nxs-k8s-s10 është i lejuar, kushtet e anti-afinitetit janë përmbushur.
I1115 07:57:21.638505 1 predicates.go:1369] Planifikimi i Pod nxs-stage\/cronjob-cron-events-1573793820-xt6q9 në Node nxs-k8s-s8 është i lejuar, kushtet e anti-afinitetit janë përmbushur.
I1115 07:57:21.638577 1 predicates.go:1369] Planifikimi i Pod nxs-stage\/cronjob-cron-events-1573793820-xt6q9 në Node nxs-k8s-s9 është i lejuar, kushtet e anti-afinitetit janë përmbushur.
I1115 07:57:21.638583 1 predicates.go:829] Planifikimi i Pod nxs-stage\/cronjob-cron-events-1573793820-xt6q9 në Node nxs-k8s-s7 është i lejuar, Node po ekzekuton vetëm 25 nga 110 Pods.
I1115 07:57:21.638932 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: Balancimi i Burimeve, kapaciteti 39900 millicores 66620178432 bytes memorie, kërkesa totale 2343 millicores 9640186880 bytes memorie, pikëzimi 9
I1115 07:57:21.638946 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: Ndarja më e Vogël e Burimeve, kapaciteti 39900 millicores 66620178432 bytes memorie, kërkesa totale 2343 millicores 9640186880 bytes memorie, pikëzimi 8
I1115 07:57:21.638961 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: Balancimi i Burimeve, kapaciteti 39900 millicores 66620170240 bytes memorie, kërkesa totale 4107 millicores 11307422720 bytes memorie, pikëzimi 9
I1115 07:57:21.638971 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: Balancimi i Burimeve, kapaciteti 39900 millicores 66620178432 bytes memorie, kërkesa totale 5847 millicores 24333637120 bytes memorie, pikëzimi 7
I1115 07:57:21.638975 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: Ndarja më e Vogël e Burimeve, kapaciteti 39900 millicores 66620170240 bytes memorie, kërkesa totale 4107 millicores 11307422720 bytes memorie, pikëzimi 8
I1115 07:57:21.638990 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: Ndarja më e Vogël e Burimeve, kapaciteti 39900 millicores 66620178432 bytes memorie, kërkesa totale 5847 millicores 24333637120 bytes memorie, pikëzimi 7
I1115 07:57:21.639022 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: Prioriteti i Tolerancave ndaj njollave, Pika: (10)
I1115 07:57:21.639030 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: Prioriteti i Tolerancave ndaj njollave, Pika: (10)
I1115 07:57:21.639034 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: Prioriteti i Tolerancave ndaj njollave, Pika: (10)
I1115 07:57:21.639041 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: Prioriteti i Afinitetit të Nodes, Pika: (0)
I1115 07:57:21.639053 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: Prioriteti i Afinitetit të Nodes, Pika: (0)
I1115 07:57:21.639059 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: Prioriteti i Afinitetit të Nodes, Pika: (0)
I1115 07:57:21.639061 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: Prioriteti i Afinitetit ndërmjet Pods, Pika: (0)
I1115 07:57:21.639063 1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: Prioriteti i Shpërndarjes së Selektores, Pika: (10)
I1115 07:57:21.639073 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: Prioriteti i Afinitetit ndërmjet Pods, Pika: (0)
I1115 07:57:21.639077 1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: Prioriteti i Shpërndarjes së Selektores, Pika: (10)
I1115 07:57:21.639085 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: Prioriteti i Afinitetit ndërmjet Pods, Pika: (0)
I1115 07:57:21.639088 1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: Prioriteti i Shpërndarjes së Selektores, Pika: (10)
I1115 07:57:21.639103 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: Prioriteti i Shpërndarjes së Selektores, Pika: (10)
I1115 07:57:21.639109 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: Prioriteti i Shpërndarjes së Selektores, Pika: (10)
I1115 07:57:21.639114 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: Prioriteti i Shpërndarjes së Selektores, Pika: (10)
I1115 07:57:21.639127 1 generic_scheduler.go:781] Host nxs-k8s-s10 => Pika 100037
I1115 07:57:21.639150 1 generic_scheduler.go:781] Host nxs-k8s-s8 => Pika 100034
I1115 07:57:21.639154 1 generic_scheduler.go:781] Host nxs-k8s-s9 => Pika 100037
I1115 07:57:21.639267 1 scheduler_binder.go:269] Supozimi i Vëllimeve të Pod për pod "nxs-stage\/cronjob-cron-events-1573793820-xt6q9", node "nxs-k8s-s10"
I1115 07:57:21.639286 1 scheduler_binder.go:279] Supozimi i Vëllimeve të Pod për pod "nxs-stage\/cronjob-cron-events-1573793820-xt6q9", node "nxs-k8s-s10": të gjitha PVC-të janë lidhur dhe nuk ka asgjë për të bërë
I1115 07:57:21.639333 1 factory.go:733] Po pĂ«rpiqet tĂ« lidhĂ« cronjob-cron-events-1573793820-xt6q9 nĂ« nxs-k8s-s10KĂ«tu shohim se fillimisht scheduler-i filtrin dhe formon njĂ« listĂ« prej 3 nodash, nĂ« tĂ« cilat Ă«shtĂ« e mundur tĂ« startohet (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10). MĂ« pas, bĂ«het njĂ« llogaritje e pikĂ«ve sipas disa parametrave (pĂ«rfshirĂ« BalancedResourceAllocation, LeastResourceAllocation) pĂ«r secilĂ«n nga kĂ«to nodĂ« me qĂ«llim pĂ«r tĂ« pĂ«rcaktuar nodĂ«n mĂ« tĂ« pĂ«rshtatshme. NĂ« fund, plani parashikohet tĂ« realizohet nĂ« nodĂ«n me numrin mĂ« tĂ« madh tĂ« pikĂ«ve (kĂ«tu, dy nodat kanĂ« njĂ« numĂ«r tĂ« njĂ«jtĂ« pikĂ«sh 100037, prandaj zgjidhet njĂ«ra rastĂ«sisht â nxs-k8s-s10).
Përfundim: nëse në nodë punojnë pods, për të cilat nuk janë caktuar kufizime, atëherë për k8s (nga këndvështimi i konsumit të burimeve) kjo do të ishte ekuivalente me faktin se në këtë nodë këto pods nuk do të ishin fare. Prandaj, nëse keni, për shembull, një pod me një proces të kërkuar (siç është wowza) dhe për të nuk janë caktuar kufizime, ndodh që ky pod ka marrë të gjitha burimet e nodës, por për k8s, kjo nodë konsiderohet e papërngarkuar dhe do t'i akordohet i njëjtë numri pikësh gjatë rangimit (saktësisht në pikët për vlerësimin e burimeve të disponueshme), si nodës që nuk ka pods aktive, që në fund mund të rezultojë në një shpërndarje të pavendosur të ngarkesës mes nodave.
Shkëputja e podit
Siç dihet â çdo pod i caktohet njĂ« nga 3 klasat QoS:
- guaranteed â caktohet kur pĂ«r secilin kontejner brenda podit pĂ«r memory dhe cpu Ă«shtĂ« caktuar request dhe limit, dhe kĂ«to vlera duhet tĂ« pĂ«rputhen
- burstable â kur sĂ« paku njĂ« kontejner nĂ« pod ka request dhe limit, duke pasur parasysh qĂ« request < limit
- pĂ«rpjekje mĂ« tĂ« mira â kur asnjĂ« kontejner nĂ« pod nuk ka kufizime pĂ«r burimet
Kurse, kur në nodë vërehet mungesë burimesh (disc, memorie), kubelet fillon të rendisë dhe të shkarkojë pods sipas një algoritmi të caktuar, i cili merr parasysh përparësitë e podit dhe klasën e tij QoS. Për shembull, nëse flasim për RAM, pikët akordohen me klasën QoS sipas parimit të mëposhtëm:
- Guaranteed: -998
- BestEffort: 1000
- Burstable: min(max(2, 1000 â (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)
Pra, me një përparësi identike, kubelet në radhë të parë do të shkarkojë pods me klasën QoS best effort.
Përfundim: nëse dëshironi të zvogëloni probabilitetin e shkarkimit të një podi të nevojshëm nga nodë në rast të mungesës së burimeve në të, atëherë përveç përparësisë është e nevojshme të kujdeseni për caktimin e request/limit për të.
Mekanizmi i autoskalimit horizontal të pods të aplikacionit (HPA)
Kur Ă«shtĂ« e nevojshme tĂ« rritet dhe ulet numri i pods varĂ«sisht nga pĂ«rdorimi i burimeve (sistemit â CPU/RAM ose pĂ«rdoruesve â rps) nĂ« zgjidhjen e saj ndihmon njĂ« entitet i k8s i tillĂ« si HPA (Horizontal Pod Autoscaler). Algoritmi i tij pĂ«rfshin:
- Përcaktohen treguesit aktualë të burimit të monitoruar (currentMetricValue)
- Përcaktohen vlerat e dëshiruara për burimin (desiredMetricValue), të cilat për burimet sistemore caktohen me anë të request
- Përcaktohet numri aktual i replikave (currentReplicas)
- Sipas formulës së mëposhtme llogaritet numri i dëshiruar i replikave (desiredReplicas)
desiredReplicas = [ currentReplicas * ( currentMetricValue / desiredMetricValue )]
Në këtë mënyrë, nuk do të ndodhi skalim kur koeficienti (currentMetricValue / desiredMetricValue) është afër 1 (në këtë rast ne mund të caktojmë tolerancën tonë, e cila me default është 0.1).
Të shohim funksionimin e hpa në shembullin e aplikacionit app-test (të përshkruar si Deployment), ku është e nevojshme të ndryshohet numri i replikave, në varësi të konsumit të CPU:
Manifesti i aplikacionit
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-statusPra, shohim se podi me aplikacionin fillimisht startohet në dy ekzemplarë, secili prej të cilëve përmban dy kontejnerë nginx dhe nginx-exporter, për secilin prej të cilëve është caktuar requests për CPU.
Manifesti i 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: 30Kështu, krijuam një hpa, i cili do të monitorojë Deployment app-test dhe do të rregullojë numrin e pods të aplikacionit bazuar në indikatorin e cpu (ne presim që podi të konsumojë 30% të CPU të kërkuar), ndersa numri i replikave është midis 2-10.
Tani, le të shqyrtojmë mekanizmin e funksionimit të hpa, nëse ngarkojmë një nga pods:
# kubectl top pod NAME CPU(cores) MEMORY(bytes) app-test-78559f8f44-pgs58 101m 243Mi app-test-78559f8f44-cj4jz 4m 240Mi
Pra, kemi këtë:
- Vlera e dĂ«shiruar (desiredMetricValue) â sipas cilĂ«simeve tĂ« hpa Ă«shtĂ« 30%
- Vlera aktuale (currentMetricValue) â pĂ«r llogaritjen controller-manager llogarit mesataren e konsumit tĂ« burimeve nĂ« %, dmth. pĂ«r tĂ« thĂ«nĂ« ndryshe:
- Merr vlerat absolute të metrikave të podëve nga metric-server, dmth. 101m dhe 4m
- Llogarit mesataren absolute, dmth. (101m + 4m) / 2 = 53m
- Merr vlerën absolute për konsumimin e dëshiruar të burimeve (për këtë, mblidhen kërkesat e të gjitha kontejnerëve) 60m + 30m = 90m
- Llogarit përqindjen mesatare të konsumit të CPU-së në raport me kërkesën e pod-it, dmth. 53m / 90m * 100% = 59%
Tani kemi gjithçka të nevojshme për të përcaktuar nëse duhet të ndryshojmë numrin e replikave, për këtë llogitim koeficientin:
ratio = 59% / 30% = 1.96
Dmth. numri i replikave duhet të rritet në ~2 herë dhe të arrijë [2 * 1.96] = 4.
Dalja: Siç mund të vërehet, për të funksionuar ky mekanizëm është e nevojshme që të gjitha kontejnerët në pod-in e vëzhguar të kenë kërkesa.
Mekanizmi i automatizimit horizontal të nodave (Cluster Autoscaler)
Për të zbutur ndikimin negativ në sistem në rastin e shpërthimeve të ngarkesës, thjesht vendosja e hpa të konfiguruar nuk është mjaft. Për shembull, sipas cilësimeve në hpa controller manager merr vendimin se numri i replikave duhet të rritet 2 herë, megjithatë në nodë nuk ka burime të lira për të drejtuar një numër kaq të madh pod-esh (dmth. nodi nuk mund të ofrojë burimet e kërkuara nga kërkesa e pod-it) dhe këta pod-e kalojnë në gjendjen Pending.
Në këtë rast, nëse ofruesi ka përkatësisht IaaS/PaaS (për shembull, GKE/GCE, AKS, EKS etj.), një mjet si Node Autoscaler. Ai lejon përcaktimin e numrit maksimal dhe minimal të nodave në klaster dhe rregullon automatikisht numrin aktual të nodave (nëpërmjet thirrjes së API-s së ofruesit të cloud për porositjen/fshirjen e nodave), kur vërehet mungesa e burimeve në klaster dhe pod-ët nuk mund të planifikohen (ndodhen në gjendjen Pending).
Dalja: për mundësimin e automatizimit të nodave është e nevojshme të vendosen kërkesa në kontejnerët e pod-eve, në mënyrë që k8s të mund të vlerësojë saktësisht ngarkesën e nodave dhe përkatësisht të raportojë se për të drejtuar një pod të ri burimet në klaster nuk janë në dispozicion.
Përfundimi
Duhet theksuar se vendosja e kufizimeve të burimeve të kontejnerit nuk është një kusht i domosdoshëm për fillimin e suksesshëm të aplikacionit, megjithatë është gjithsesi e rekomandueshme për arsyet e mëposhtme:
- Për një funksionim më të saktë të scheduler-it në lidhje me balancimin e ngarkesës midis nodave k8s
- Për të ulur probabilitetin që ndodhi ngjarja 'shkarkimi i pod-it'
- Për funksionimin e automatizimit horizontal të pod-eve të aplikacionit (HPA)
- Për funksionimin e automatizimit horizontal të nodave (Cluster Autoscaling) te ofruesit e cloud
Shihni gjithashtu artikuj të tjerë në blogun tonë:
Burimi: habr.com
