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

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?

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

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: 200m

    Pra, 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: 2Gi

    Pra, 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: 4Gi

    Pra, 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: 1Gi

    Pra, 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:

  1. Filtrimi
  2. 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-s10

KĂ«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:

  1. 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
  2. burstable — kur sĂ« paku njĂ« kontejner nĂ« pod ka request dhe limit, duke pasur parasysh qĂ« request < limit
  3. 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:

  1. Përcaktohen treguesit aktualë të burimit të monitoruar (currentMetricValue)
  2. Përcaktohen vlerat e dëshiruara për burimin (desiredMetricValue), të cilat për burimet sistemore caktohen me anë të request
  3. Përcaktohet numri aktual i replikave (currentReplicas)
  4. 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-status

    Pra, 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: 30

    Kë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:
    1. Merr vlerat absolute të metrikave të podëve nga metric-server, 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ë burimeve (për këtë, mblidhen kërkesat e të gjitha kontejnerëve) 60m + 30m = 90m
    4. 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:

  1. Për një funksionim më të saktë të scheduler-it në lidhje me balancimin e ngarkesës midis nodave k8s
  2. Për të ulur probabilitetin që ndodhi ngjarja 'shkarkimi i pod-it'
  3. Për funksionimin e automatizimit horizontal të pod-eve të aplikacionit (HPA)
  4. 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

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