Kubernetes: pse është kaq e rëndësishme të konfiguroni menaxhimin e burimeve të sistemit?

Në përgjithësi, gjithmonë lind nevoja për të siguruar një grup të dedikuar burimesh për ndonjë aplikacion për të funksionuar saktë dhe me qëndrueshmëri. Por çfarë ndodh kur disa aplikacione punojnë në të njëjtat kapacitete? Si të sigurohen burimet minimale të nevojshme për secilin prej tyre? Si mund të kufizohet konsumimi i burimeve? Si të ndajmë ngarkesën në mënyrë të mençur midis nodave? Si të sigurohet funksionimi i mekanizmit të shtrirjes horizontale në rast të rritjes së ngarkesës në aplikacione?

Kubernetes: pse është kaq e rëndësishme të konfiguroni menaxhimin e burimeve të sistemit?

Duhet tĂ« fillojmĂ« me atĂ« se cilĂ«t janĂ« llojet kryesore tĂ« burimeve qĂ« ekzistojnĂ« nĂ« sistem – ky Ă«shtĂ« padyshim koha e procesorit dhe memoria e pĂ«rkohshme. NĂ« manifestet k8s kĂ«ta lloje burimesh matĂ«n nĂ« njĂ«sitĂ« e mĂ«poshtme:

  • CPU – nĂ« bĂ«rthamĂ«
  • RAM – nĂ« byte

ShkĂ«lqyeshĂ«m, pĂ«r secilin burim ka mundĂ«sinĂ« pĂ«r tĂ« caktuar dy lloje kĂ«rkesash – requests dhe limits. Requests – pĂ«rshkruan kĂ«rkesat minimale pĂ«r burimet e lira tĂ« nodit pĂ«r nisjen e kontejnerit (dhe tĂ« pod-it nĂ« tĂ«rĂ«si), ndĂ«rsa limits vendos njĂ« kufizim tĂ« fortĂ« pĂ«r burimet qĂ« i janĂ« tĂ« disponueshme kontejnerit.

ËshtĂ« e rĂ«ndĂ«sishme tĂ« kuptohet se nĂ« manifest nuk Ă«shtĂ« e nevojshme tĂ« pĂ«rcaktohen qartĂ« tĂ« dyja llojet, megjithatĂ«, sjellja do tĂ« jetĂ« si nĂ« vijim:

  • NĂ«se vetĂ«m limits e burimit janĂ« caktuar, requests pĂ«r kĂ«tĂ« burim automatikisht merr vlerĂ«n e barabartĂ« me limits (nĂ« kĂ«tĂ« mund tĂ« konfirmohet duke thirrur pĂ«rshkrimin e entiteteve). Pra, nĂ« fakt, puna e kontejnerit do tĂ« jetĂ« e kufizuar nga numri i tĂ« njĂ«jtave burime qĂ« kĂ«rkon pĂ«r nisjen e tij.
  • NĂ«se pĂ«r burimin Ă«shtĂ« caktuar vetĂ«m requests, atĂ«herĂ« nuk ka kufizime mĂ« sipĂ«r pĂ«r kĂ«tĂ« burim – pra, kontejneri Ă«shtĂ« i kufizuar vetĂ«m nga burimet e nodit tĂ« vet.

Gjithashtu, ekziston mundësia për të vendosur menaxhimin e burimeve jo vetëm në nivelin e kontejnerit të caktuar, por gjithashtu në nivelin e namespace përmes entiteteve të mëposhtme:

  • LimitRange – pĂ«rshkruan politikĂ«n e kufizimit nĂ« nivelin e kontejnerit/pod-it nĂ« ns dhe Ă«shtĂ« e nevojshme pĂ«r tĂ« pĂ«rshkruar kufijtĂ« e paracaktuar pĂ«r kontejner/pod, si dhe pĂ«r tĂ« parandaluar krijimin e kontejnerĂ«ve/pod-eve tĂ« trashĂ« (ose anasjelltas), pĂ«r tĂ« kufizuar numrin e tyre dhe pĂ«r tĂ« pĂ«rcaktuar ndryshimin e mundshĂ«m tĂ« vlerave nĂ« limits dhe requests.
  • KufijtĂ« e Burimeve PĂ«rshkruajnĂ« politikĂ«n e kufizimit nĂ« pĂ«rgjithĂ«si pĂ«r tĂ« gjitha kontejnerĂ«t nĂ« ns dhe pĂ«rdoret zakonisht pĂ«r ndarjen e burimeve sipas mjediseve (e dobishme kur mjediset nuk ndahen ashpĂ«r nĂ« nivelin e nodit)

Më poshtë janë disa shembuj manifestesh që vendosin kufizime për burimet:

  • NĂ« nivelin e njĂ« kontejneri tĂ« veçantĂ«:

    containers:
    - name: app-nginx
      image: nginx
      resources:
        requests:
          memory: 1Gi
        limits:
          cpu: 200m

    Pra, në këtë rast për të nisur një kontejner me nginx do të kërkohet si minimum prania e 1G RAM dhe 0.2 CPU në nod, ndërkohë që maksimumi që mund të konsumojë kontejneri është 0.2 CPU dhe të gjitha RAM të 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: 2Gi

    Pra, shuma e tĂ« gjitha kĂ«rkesave tĂ« kontejnerĂ«ve nĂ« ns-nĂ« e paracaktuar nuk mund tĂ« kalojĂ« 300m pĂ«r CPU dhe 1G pĂ«r RAM, ndĂ«rsa shuma e tĂ« gjitha kufizimeve — 700m pĂ«r CPU dhe 2G pĂ«r RAM.

  • Kufizimet e paracaktuara pĂ«r kontejnerĂ«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: 4Gi

    Pra, nĂ« namespace-n e paracaktuar pĂ«r tĂ« gjithĂ« kontejnerĂ«t me pĂ«rjashtim do tĂ« vendoset njĂ« kĂ«rkesĂ« prej 100m pĂ«r CPU dhe 1G pĂ«r RAM, kufizimi — 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-eve nĂ« ns:

    apiVersion: v1
    kind: LimitRange
    metadata:
     name: nxs-limit-pod
    spec:
     limits:
     - type: Pod
       max:
         cpu: 4
         memory: 1Gi

    Pra, për çdo pod në ns-në e paracaktuar do të vendoset një kufizim prej 4 vCPU dhe 1G.

Tani do të doja të flas për avantazhet që mund të na sjellë vendosja e këtyre kufizimeve.

Mekanizmi i balancimit të ngarkesës midis nodave

Siç dihet, shpërndarjen e pod-eve midis nodave e menaxhon një komponent k8s, siç është scheduler, i cili funksionon sipas një algoritmi të caktuar. Ky algoritëm gjatë zgjedhjes së nodit optimal për nisjen kalon nëpër dy etapa:

  1. Filtrimi
  2. Radhitja

Pra, sipas politikĂ«s tĂ« pĂ«rshkruar fillimisht zgjidhen nodet, nĂ« tĂ« cilat Ă«shtĂ« e mundur tĂ« niset pod-i nĂ« bazĂ« tĂ« njĂ« seti tĂ« predicates (duke pĂ«rfshirĂ« kontrollimin e mjaftueshmĂ«risĂ« sĂ« burimeve nĂ« nod pĂ«r tĂ« nisin pod-in — PodFitsResources), dhe pastaj pĂ«r secilĂ«n nga kĂ«to nodet, sipas priorities PiketĂ« janĂ« tĂ« mbledhura (pĂ«rfshirĂ«, sa mĂ« shumĂ« burime tĂ« lira tĂ« ketĂ« nodi - aq mĂ« shumĂ« pikĂ« i jepet atij - LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation) dhe ekzekutohet nĂ« nodin me numrin mĂ« tĂ« madh tĂ« pikĂ«ve (nĂ«se disa nodĂ« pĂ«rmbushin kĂ«tĂ« kusht, njĂ«ri prej tyre zgjidhet rastĂ«sisht).

Megjithatë, duhet të kuptoni se scheduler, kur vlerëson burimet e disponueshme të nodit, orientoheshe nga të dhënat që ruhen në etcd - dmth, nga shuma e requested/limit të burimeve të çdo pod-i të ekzekutuar në këtë nod, por jo nga konsumi aktual i burimeve. Këto informacione mund të merren në daljen 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ë gjithë pod-ët e ekzekutuar në një nod të caktuar, si dhe burimet që kërkon secili prej pod-eve. Ja se si duken log-et e scheduler-it gjatë ekzekutimit të pod-it cronjob-cron-events-1573793820-xt6q9 (kjo informacion do të shfaqet në log-un e scheduler-it kur vendoset niveli i 10-të i logimit në argumentet e komandës -v=10):

log

I1115 07:57:21.637791 1 scheduling_queue.go:908] Po për të caktuar pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 do të provojë tani
I1115 07:57:21.637804 1 scheduler.go:453] Po përpiqem të caktoj pod: nxs-stage/cronjob-cron-events-1573793820-xt6q9
I1115 07:57:21.638285 1 predicates.go:829] Caktimi i pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 në nodën nxs-k8s-s5 lejohet, nodi po punon vetëm 16 nga 110 pods.
I1115 07:57:21.638300 1 predicates.go:829] Caktimi i pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 në nodën nxs-k8s-s6 lejohet, nodi po punon vetëm 20 nga 110 pods.
I1115 07:57:21.638322 1 predicates.go:829] Caktimi i pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 në nodën nxs-k8s-s3 lejohet, nodi po punon vetëm 20 nga 110 pods.
I1115 07:57:21.638322 1 predicates.go:829] Caktimi i pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 në nodën nxs-k8s-s4 lejohet, nodi po punon vetëm 17 nga 110 pods.
I1115 07:57:21.638334 1 predicates.go:829] Caktimi i pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 në nodën nxs-k8s-s10 lejohet, nodi po punon vetëm 16 nga 110 pods.
I1115 07:57:21.638365 1 predicates.go:829] Caktimi i pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 në nodën nxs-k8s-s12 lejohet, nodi po punon vetëm 9 nga 110 pods.
I1115 07:57:21.638334 1 predicates.go:829] Caktimi i pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 në nodën nxs-k8s-s11 lejohet, nodi po punon vetëm 11 nga 110 pods.
I1115 07:57:21.638385 1 predicates.go:829] Caktimi i pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 në nodën nxs-k8s-s1 lejohet, nodi po punon vetëm 19 nga 110 pods.
I1115 07:57:21.638402 1 predicates.go:829] Caktimi i pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 në nodën nxs-k8s-s2 lejohet, nodi po punon vetëm 21 nga 110 pods.
I1115 07:57:21.638383 1 predicates.go:829] Caktimi i pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 në nodën nxs-k8s-s9 lejohet, nodi po punon vetëm 16 nga 110 pods.
I1115 07:57:21.638335 1 predicates.go:829] Caktimi i pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 në nodën nxs-k8s-s8 lejohet, nodi po punon vetëm 18 nga 110 pods.
I1115 07:57:21.638408 1 predicates.go:829] Caktimi i pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 në nodën nxs-k8s-s13 lejohet, nodi po punon vetëm 8 nga 110 pods.
I1115 07:57:21.638478 1 predicates.go:1369] Caktimi i pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 në nodën nxs-k8s-s10 lejohet, kushtet e anti-affinity të pods ekzistuese janë përmbushur.
I1115 07:57:21.638505 1 predicates.go:1369] Caktimi i pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 në nodën nxs-k8s-s8 lejohet, kushtet e anti-affinity të pods ekzistuese janë përmbushur.
I1115 07:57:21.638577 1 predicates.go:1369] Caktimi i pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 në nodën nxs-k8s-s9 lejohet, kushtet e anti-affinity të pods ekzistuese janë përmbushur.
I1115 07:57:21.638583 1 predicates.go:829] Caktimi i pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 në nodën nxs-k8s-s7 lejohet, nodi po punon 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 Shpërndarjes së Burimeve, kapacitet 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: Shpërndarja më e Pakuptueshme e Burimeve, kapacitet 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 Shpërndarjes së Burimeve, kapacitet 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 Shpërndarjes së Burimeve, kapacitet 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: Shpërndarja më e Pakuptueshme e Burimeve, kapacitet 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: Shpërndarja më e Pakuptueshme e Burimeve, kapacitet 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 TaintToleration, Pika: (10)
I1115 07:57:21.639030 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: Prioriteti TaintToleration, Pika: (10)
I1115 07:57:21.639034 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: Prioriteti TaintToleration, Pika: (10)
I1115 07:57:21.639041 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: Prioriteti NodeAffinity, Pika: (0)
I1115 07:57:21.639053 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: Prioriteti NodeAffinity, Pika: (0)
I1115 07:57:21.639059 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: Prioriteti NodeAffinity, Pika: (0)
I1115 07:57:21.639061 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: Prioriteti InterPodAffinity, Pika: (0)
I1115 07:57:21.639063 1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: Prioriteti SelectorSpread, Pika: (10)
I1115 07:57:21.639073 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: Prioriteti InterPodAffinity, Pika: (0)
I1115 07:57:21.639077 1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: Prioriteti SelectorSpread, Pika: (10)
I1115 07:57:21.639085 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: Prioriteti InterPodAffinity, Pika: (0)
I1115 07:57:21.639088 1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: Prioriteti SelectorSpread, Pika: (10)
I1115 07:57:21.639103 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: Prioriteti SelectorSpread, Pika: (10)
I1115 07:57:21.639109 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: Prioriteti SelectorSpread, Pika: (10)
I1115 07:57:21.639114 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: Prioriteti SelectorSpread, 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 Volume-ve të Pod për pod "nxs-stage/cronjob-cron-events-1573793820-xt6q9", nodi "nxs-k8s-s10"
I1115 07:57:21.639286 1 scheduler_binder.go:279] Supozimi i Volume-ve të Pod për pod "nxs-stage/cronjob-cron-events-1573793820-xt6q9", nodi "nxs-k8s-s10": të gjitha PVC-të e lidhura dhe nuk ka asgjë për të bërë
I1115 07:57:21.639333 1 factory.go:733] Po përpiqem të lidhem cronjob-cron-events-1573793820-xt6q9 me nxs-k8s-s10

KĂ«tu shohim se fillimisht scheduler-i filtron dhe formon njĂ« listĂ« prej 3 nodash, ku Ă«shtĂ« e mundur tĂ« niseni (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10). Pastaj bĂ«het llogaritja e pikĂ«ve sipas disa parametrave (pĂ«rfshirĂ« Balancimin e ShpĂ«rndarjes sĂ« Burimeve, ShpĂ«rndarjen e Burimeve mĂ« tĂ« PaktĂ«) pĂ«r secilĂ«n prej kĂ«tyre nodave me qĂ«llim pĂ«r tĂ« pĂ«rcaktuar nodin mĂ« tĂ« pĂ«rshtatshĂ«m. NĂ« fund, parashikohet tĂ« ngarkohet nĂ« nodin me numrin mĂ« tĂ« madh tĂ« pikĂ«ve (kĂ«tu menjĂ«herĂ« dy nodet kanĂ« tĂ« njĂ«jtin numĂ«r pikĂ«sh 100037, prandaj zgjidhet njĂ«ra prej tyre nĂ« mĂ«nyrĂ« tĂ« rastĂ«sishme — nxs-k8s-s10).

Përfundimi: nëse në nodë punojnë pod-e për të cilat nuk janë caktuar limite, atëherë për k8s (nga perspektiva e konsumit të burimeve) do të ishte barasvlerë me faktin se në këtë nodë këto pod-e nuk ekzistojnë fare. Prandaj, nëse keni, në mënyrë të kushtëzuar, një pod me një proces të etur për burime (p.sh. wowza) dhe për të nuk janë caktuar limite, mund të ndodhë një situatë, kur realisht ky pod ka konsumuar të gjitha burimet e nodit, por në të njëjtën kohë për k8s ky nod konsiderohet i papërngarkuar dhe do të marrë të njëjtën sasi pikësh në renditje (pikërisht në pikët e vlerësimit të burimeve të disponueshme), si nodi që nuk ka pod-e në funksionim, duke rezultuar kështu në një shpërndarje të pabarabartë të ngarkesave midis nodave.

Përzënia e pod-it

Siç dihet — çdo pod-i caktohet njĂ« nga 3 klasat QoS:

  1. garantuar — caktohet kur pĂ«r çdo kontejner nĂ« pod janĂ« caktuar request dhe limit pĂ«r memory dhe cpu, dhe kĂ«to vlera duhet tĂ« jenĂ« tĂ« njĂ«jta
  2. instanca burstable. — tĂ« paktĂ«n njĂ« kontejner nĂ« pod ka request dhe limit, ku request < limit
  3. pĂ«rpjekje maksimale — kur asnjĂ« kontejner nĂ« pod nuk Ă«shtĂ« i kufizuar nĂ« burime

Në këtë mënyrë, kur në nodë vërehet mungesë burimesh (disk, memorie), kubelet fillon të renditë dhe të përzë pod-et sipas një algoritmi të caktuar që merr parasysh prioritetin e pod-it dhe klasën e tij QoS. Për shembull, nëse behet fjalë për RAM, atëherë në përputhje me klasën QoS caktohen pikë sipas parimit të mëposhtëm:

  • Guaranteed: -998
  • BestEffort: 1000
  • Burstable: min(max(2, 1000 — (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)

Kështu, me të njëjtin prioritet, kubelet në radhë të parë do të përzë nga nod-i pod-et me klasën QoS përpjekje maksimale.

Përfundimi: nëse dëshironi të zvogëloni mundësinë e përzënies së një pod-i të nevojshëm nga nod-i në rastin e mungesës së burimeve në të, është e nevojshme, përveç prioritetit, të kujdeseni gjithashtu për caktimin e request/limit për të.

Mekanizmi i autoskalimit horizontal të podëve të aplikacionit (HPA)

Kur detyra Ă«shtĂ« tĂ« rritet dhe tĂ« ulet automatikisht numri i podĂ«ve nĂ« varĂ«si tĂ« pĂ«rdorimit tĂ« burimeve (sĂ« sistemit — CPU/RAM ose tĂ« pĂ«rdoruesit — rps), njĂ« entitet i tillĂ« i k8s mund tĂ« ndihmojĂ« si HPA (Horizontal Pod Autoscaler). Algoritmi i tij pĂ«rfshin kĂ«tĂ«:

  1. Përcaktohen treguesit aktualë të burimeve në vëzhgim (currentMetricValue)
  2. Përcaktohen vlerat e dëshiruara për burimin (desiredMetricValue), të cilat për burimet sistemike përcaktohen me anë të kërkesave
  3. Përcaktohet numri aktual i replikave (currentReplicas)
  4. Me formulën e mëposhtme llogaritet numri i dëshiruar i replikave (desiredReplicas)
    desiredReplicas = [ currentReplicas * ( currentMetricValue / desiredMetricValue )]

Në këtë rast, nuk do të ndodhë shkallëzim kur koeficienti (currentMetricValue / desiredMetricValue) është afër 1 (ndërsa ne mund të caktojmë tolerancën e pranuar vetë, e cila për default është 0.1).

Le të shqyrtojmë funksionimin e hpa në shembullin e aplikacionit app-test (i 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-status

    Pra, shohim se pod-i me aplikacionin fillimisht nisi në dy kopje, secila prej të cilave përmban dy kontejnerë nginx dhe nginx-exporter, për secilin prej të cilave është caktuar requests për CPU.

  • Manifesti 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

    Pra, kemi krijuar hpa, i cili do të monitorojë Deployment app-test dhe do të rregullojë numrin e podëve me aplikacionin në bazë të treguesit të CPU (ne presim se pod-i duhet të konsumojë 30% të CPU e kërkuar), ndërsa numri i replikave ndodhet në intervalin 2-10.

    Tani, le të shqyrtojmë mekanizmin e punës të hpa, nëse i japim ngarkesë një prej podëve:

     # kubectl top pod
     NAME                                                   CPU(cores)   MEMORY(bytes)
     app-test-78559f8f44-pgs58            101m         243Mi
     app-test-78559f8f44-cj4jz            4m           240Mi

Dhe kështu kemi këtë:

  • Vlera e dĂ«shiruar (desiredMetricValue) — sipas konfigurimeve hpa Ă«shtĂ« 30%
  • Vlera aktuale (currentMetricValue) — pĂ«r llogaritjen controller-manager llogarit mesataren e konsumit tĂ« burimeve nĂ« %, pra teorikisht bĂ«n si mĂ« poshtĂ«:
    1. Merr vlerat absolute të metrikeve të pods nga serveri metric, dmth, 101m dhe 4m
    2. Llogarit mesataren absolute, dmth, (101m + 4m) / 2 = 53m
    3. Merr vlerën absolute për konsumimin e dëshiruar të burimit (për këtë, janë të summuar kërkesat e të gjithë konteinerëve) 60m + 30m = 90m
    4. Llogarit procentin mesatar të konsumit të CPU-së në lidhje me kërkesat 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ë llogaritëm koeficientin:

ratio = 59% / 30% = 1.96

Pra, numri i replikave duhet të rritet me ~2 herë dhe të arrijë [2 * 1.96] = 4.

Përfundimi: Siç mund të vëreni, për të funksionuar ky mekanizëm, kushti i nevojshëm është gjithashtu ekzistenca e kërkesave për të gjitha konteinerët në pod-in e vëzhguar.

Mekanizmi i automatikës horizontale të node-ve (Cluster Autoscaler)

Për të neutralizuar ndikimin negativ në sistem gjatë shpërthimeve të ngarkesës, thjesht konfigurimi i hpa mund të jetë i pamjaftueshëm. Për shembull, sipas konfigurimeve, në hpa controller manager merr vendimin për të rritur numrin e replikave 2 herë, megjithatë në node nuk ka burime të lira për të iniciuar kaq shumë pods (dmth, node nuk mund të ofrojë burimet e kërkuara të pod-it requests) dhe këto pods kalojnë në gjendjen Pending.

Në këtë rast, nëse ofruesi ka një IaaS/PaaS përkatës (për shembull, GKE/GCE, AKS, EKS etj.), na ndihmon një mjet si Node Autoscaler. Ai lejon vendosjen e një numri maksimal dhe minimal të node-ve në klaster dhe automatikisht rregullon numrin aktual të node-ve (duke kontaktuar API-në e ofruesit të cloud për të porositur/zhdukur një node), kur vërehet mungesa e burimeve në klaster dhe pods nuk mund të planifikohen (janë në gjendjen Pending).

Përfundimi: për mundësinë e automatikës së node-ve është e nevojshme të vendosen kërkesat në konteinerët e pods, në mënyrë që k8s të mund të vlerësojë saktësisht ngarkesën e node-ve dhe përkatësisht të raportojë se për të iniciuar pod-in e radhës nuk ka burime në klaster.

Përfundim

ËshtĂ« e rĂ«ndĂ«sishme tĂ« theksohet se vendosja e kufizimeve tĂ« resurseve pĂ«r konteinerin nuk Ă«shtĂ« njĂ« kusht i domosdoshĂ«m pĂ«r fillimin e suksesshĂ«m tĂ« aplikacionit, megjithatĂ«, Ă«shtĂ« mĂ« mirĂ« tĂ« bĂ«het pĂ«r arsyet e mĂ«poshtme:

  1. Për të punuar më saktë scheduler-i në lidhje me balancimin e ngarkesës mes node-ve k8s
  2. Për të ulur probabilitetin e ndodhjes së ngjarjes "zhvitje e pod-it"
  3. Për punën e automatik-skalimit horizontal të pod-eve të aplikacionit (HPA)
  4. Për punën e automatik-skalimit horizontal të node-ve (Cluster Autoscaling) te ofruesit e cloud-it

Lexoni gjithashtu artikuj të tjerë në blogun tonë:

Burimi: habr.com

Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster