Kubernetes: kodėl taip svarbu nustatyti sistemos išteklių valdymą?

Paprastai, norint, kad programa veiktų teisingai ir stabiliai, visada reikia suteikti tam skirtą išteklių telkinį. Bet ką daryti, jei kelios programos veikia tuo pačiu maitinimu? Kaip kiekvieną iš jų aprūpinti minimaliais reikiamais ištekliais? Kaip galite apriboti išteklių naudojimą? Kaip teisingai paskirstyti apkrovą tarp mazgų? Kaip užtikrinti, kad horizontalaus mastelio keitimo mechanizmas veiktų, jei padidėtų programų apkrova?

Kubernetes: kodėl taip svarbu nustatyti sistemos išteklių valdymą?

Pradėti reikia nuo to, kokie pagrindiniai ištekliai egzistuoja sistemoje – tai, žinoma, yra procesoriaus laikas ir RAM. K8s manifestuose šie išteklių tipai matuojami šiais vienetais:

  • CPU – branduoliuose
  • RAM – baitais

Be to, kiekvienam ištekliui galima nustatyti dviejų tipų reikalavimus - prašymai и ribos. Užklausos – aprašomi minimalūs reikalavimai laisviems mazgo ištekliams, kad būtų galima paleisti sudėtinį rodinį (ir grupę kaip visumą), o apribojimai nustato griežtą sudėtinio rodinio išteklių ribą.

Svarbu suprasti, kad manifeste nebūtina aiškiai apibrėžti abiejų tipų, tačiau elgsena bus tokia:

  • Jei aiškiai nurodytos tik ištekliaus ribos, šio resurso užklausos automatiškai įgauna reikšmę, lygią riboms (tai galite patikrinti iškvietę aprašomuosius objektus). Tie. Tiesą sakant, konteineris bus apribotas iki tiek išteklių, kiek reikia jam paleisti.
  • Jei ištekliui yra aiškiai nurodytos tik užklausos, tai šiam ištekliui nenustatyti jokie viršutiniai apribojimai – t.y. konteinerį riboja tik paties mazgo ištekliai.

Taip pat galima konfigūruoti išteklių valdymą ne tik konkretaus konteinerio, bet ir vardų erdvės lygiu, naudojant šiuos objektus:

  • LimitRange — aprašo apribojimų politiką konteinerio / ankšties lygyje ns ir reikalinga norint apibūdinti numatytuosius konteinerio / ankšties apribojimus, taip pat užkirsti kelią akivaizdžiai riebalų talpyklų / ankščių susidarymui (arba atvirkščiai), apriboti jų skaičių ir nustatyti galimą ribų ir užklausų verčių skirtumą
  • Išteklių kvotos — apskritai apibūdinkite apribojimų politiką, taikomą visiems ns konteineriams ir paprastai naudojama siekiant atskirti išteklius tarp aplinkų (naudinga, kai aplinka nėra griežtai atribota mazgo lygiu)

Toliau pateikiami apraiškų, nustatančių išteklių apribojimus, pavyzdžiai:

  • Konkretaus konteinerio lygiu:

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

    Tie. Šiuo atveju, norint paleisti konteinerį su nginx, mazge reikės mažiausiai 1 G laisvos RAM ir 0.2 procesoriaus, o talpykla gali sunaudoti daugiausia 0.2 procesoriaus ir visos turimos mazgo RAM.

  • Sveikųjų skaičių lygyje ns:

    apiVersion: v1
    kind: ResourceQuota
    metadata:
      name: nxs-test
    spec:
      hard:
        requests.cpu: 300m
        requests.memory: 1Gi
        limits.cpu: 700m
        limits.memory: 2Gi

    Tie. visų užklausų konteinerių suma numatytuosiuose ns negali viršyti 300 m CPU ir 1 G OP, o visų limitų suma yra 700 m CPU ir 2 G OP.

  • Numatytieji ns konteinerių apribojimai:

    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

    Tie. numatytoje visų konteinerių vardų srityje užklausa bus nustatyta į 100 m CPU ir 1G OP, riba – 1 CPU ir 2G. Tuo pačiu metu taip pat nustatomas galimų procesoriaus (50 m < x < 2) ir RAM (500 M < x < 4G) užklausos / limito verčių limitas.

  • Pod lygio apribojimai ns:

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

    Tie. kiekvienam podeliui numatytajame ns bus 4 vCPU ir 1G limitas.

Dabar norėčiau jums pasakyti, kokių pranašumų mums gali suteikti šie apribojimai.

Apkrovos balansavimo mechanizmas tarp mazgų

Kaip žinote, k8s komponentas yra atsakingas už ankščių paskirstymą tarp mazgų, tokių kaip Planuotojas, kuris veikia pagal konkretų algoritmą. Šis algoritmas pasirenka du etapus, kai pasirenkamas optimalus paleidimo mazgas:

  1. filtravimas
  2. Range

Tie. pagal aprašytą politiką iš pradžių parenkami mazgai, kuriais remiantis galima paleisti podą pagal rinkinį predikatai (įskaitant patikrinimą, ar mazgas turi pakankamai išteklių podiui paleisti – PodFitsResources), o tada kiekvienam iš šių mazgų, atsižvelgiant į prioritetai suteikiami taškai (įskaitant, kuo daugiau mazgas turi laisvų išteklių, tuo daugiau taškų jam priskiriama – LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation) ir podas paleidžiamas daugiausiai taškų surinkusiame mazge (jei keli mazgai iš karto atitinka šią sąlygą, tada pasirenkamas atsitiktinis).

Tuo pačiu reikia suprasti, kad planuotojas, vertindamas turimus mazgo resursus, vadovaujasi duomenimis, kurie saugomi etcd – t.y. už prašomą / ribinį kiekvieno šiame mazge veikiančio bloko išteklių kiekį, bet ne už faktinį išteklių suvartojimą. Šią informaciją galima gauti iš komandos išvesties kubectl describe node $NODE, pavyzdžiui:

# 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%)

Čia matome visus konkrečiame mazge veikiančius blokus, taip pat išteklius, kurių reikalauja kiekvienas blokas. Štai kaip atrodo planuotojo žurnalai, kai paleidžiamas cronjob-cron-events-1573793820-xt6q9 pod (ši informacija bus rodoma planavimo žurnale, kai paleidimo komandos argumentuose bus nustatytas 10 registravimo lygis -v=10 ):

žurnalas

I1115 07:57:21.637791       1 scheduling_queue.go:908] About to try and schedule pod nxs-stage/cronjob-cron-events-1573793820-xt6q9                                                                                                                                           
I1115 07:57:21.637804       1 scheduler.go:453] Attempting to schedule pod: nxs-stage/cronjob-cron-events-1573793820-xt6q9                                                                                                                                                    
I1115 07:57:21.638285       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s5 is allowed, Node is running only 16 out of 110 Pods.                                                                               
I1115 07:57:21.638300       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s6 is allowed, Node is running only 20 out of 110 Pods.                                                                               
I1115 07:57:21.638322       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s3 is allowed, Node is running only 20 out of 110 Pods.                                                                               
I1115 07:57:21.638322       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s4 is allowed, Node is running only 17 out of 110 Pods.                                                                               
I1115 07:57:21.638334       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s10 is allowed, Node is running only 16 out of 110 Pods.                                                                              
I1115 07:57:21.638365       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s12 is allowed, Node is running only 9 out of 110 Pods.                                                                               
I1115 07:57:21.638334       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s11 is allowed, Node is running only 11 out of 110 Pods.                                                                              
I1115 07:57:21.638385       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s1 is allowed, Node is running only 19 out of 110 Pods.                                                                               
I1115 07:57:21.638402       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s2 is allowed, Node is running only 21 out of 110 Pods.                                                                               
I1115 07:57:21.638383       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s9 is allowed, Node is running only 16 out of 110 Pods.                                                                               
I1115 07:57:21.638335       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s8 is allowed, Node is running only 18 out of 110 Pods.                                                                               
I1115 07:57:21.638408       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s13 is allowed, Node is running only 8 out of 110 Pods.                                                                               
I1115 07:57:21.638478       1 predicates.go:1369] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s10 is allowed, existing pods anti-affinity terms satisfied.                                                                         
I1115 07:57:21.638505       1 predicates.go:1369] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s8 is allowed, existing pods anti-affinity terms satisfied.                                                                          
I1115 07:57:21.638577       1 predicates.go:1369] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s9 is allowed, existing pods anti-affinity terms satisfied.                                                                          
I1115 07:57:21.638583       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s7 is allowed, Node is running only 25 out of 110 Pods.                                                                               
I1115 07:57:21.638932       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: BalancedResourceAllocation, capacity 39900 millicores 66620178432 memory bytes, total request 2343 millicores 9640186880 memory bytes, score 9        
I1115 07:57:21.638946       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: LeastResourceAllocation, capacity 39900 millicores 66620178432 memory bytes, total request 2343 millicores 9640186880 memory bytes, score 8           
I1115 07:57:21.638961       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: BalancedResourceAllocation, capacity 39900 millicores 66620170240 memory bytes, total request 4107 millicores 11307422720 memory bytes, score 9        
I1115 07:57:21.638971       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: BalancedResourceAllocation, capacity 39900 millicores 66620178432 memory bytes, total request 5847 millicores 24333637120 memory bytes, score 7        
I1115 07:57:21.638975       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: LeastResourceAllocation, capacity 39900 millicores 66620170240 memory bytes, total request 4107 millicores 11307422720 memory bytes, score 8           
I1115 07:57:21.638990       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: LeastResourceAllocation, capacity 39900 millicores 66620178432 memory bytes, total request 5847 millicores 24333637120 memory bytes, score 7           
I1115 07:57:21.639022       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: TaintTolerationPriority, Score: (10)                                                                                                        
I1115 07:57:21.639030       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: TaintTolerationPriority, Score: (10)                                                                                                         
I1115 07:57:21.639034       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: TaintTolerationPriority, Score: (10)                                                                                                         
I1115 07:57:21.639041       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: NodeAffinityPriority, Score: (0)                                                                                                            
I1115 07:57:21.639053       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: NodeAffinityPriority, Score: (0)                                                                                                             
I1115 07:57:21.639059       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: NodeAffinityPriority, Score: (0)                                                                                                             
I1115 07:57:21.639061       1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: InterPodAffinityPriority, Score: (0)                                                                                                                   
I1115 07:57:21.639063       1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: SelectorSpreadPriority, Score: (10)                                                                                                                   
I1115 07:57:21.639073       1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: InterPodAffinityPriority, Score: (0)                                                                                                                    
I1115 07:57:21.639077       1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: SelectorSpreadPriority, Score: (10)                                                                                                                    
I1115 07:57:21.639085       1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: InterPodAffinityPriority, Score: (0)                                                                                                                    
I1115 07:57:21.639088       1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: SelectorSpreadPriority, Score: (10)                                                                                                                    
I1115 07:57:21.639103       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: SelectorSpreadPriority, Score: (10)                                                                                                         
I1115 07:57:21.639109       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: SelectorSpreadPriority, Score: (10)                                                                                                          
I1115 07:57:21.639114       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: SelectorSpreadPriority, Score: (10)                                                                                                          
I1115 07:57:21.639127       1 generic_scheduler.go:781] Host nxs-k8s-s10 => Score 100037                                                                                                                                                                            
I1115 07:57:21.639150       1 generic_scheduler.go:781] Host nxs-k8s-s8 => Score 100034                                                                                                                                                                             
I1115 07:57:21.639154       1 generic_scheduler.go:781] Host nxs-k8s-s9 => Score 100037                                                                                                                                                                             
I1115 07:57:21.639267       1 scheduler_binder.go:269] AssumePodVolumes for pod "nxs-stage/cronjob-cron-events-1573793820-xt6q9", node "nxs-k8s-s10"                                                                                                               
I1115 07:57:21.639286       1 scheduler_binder.go:279] AssumePodVolumes for pod "nxs-stage/cronjob-cron-events-1573793820-xt6q9", node "nxs-k8s-s10": all PVCs bound and nothing to do                                                                             
I1115 07:57:21.639333       1 factory.go:733] Attempting to bind cronjob-cron-events-1573793820-xt6q9 to nxs-k8s-s10

Čia matome, kad iš pradžių planuoklis filtruoja ir sugeneruoja 3 mazgų, kuriuose jį galima paleisti, sąrašą (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10). Tada jis apskaičiuoja balus pagal kelis parametrus (įskaitant BalancedResourceAllocation, LeastResourceAllocation) kiekvienam iš šių mazgų, kad nustatytų tinkamiausią mazgą. Galiausiai blokas suplanuojamas mazge, kuriame yra didžiausias taškų skaičius (čia du mazgai vienu metu turi tą patį taškų skaičių 100037, todėl pasirenkamas atsitiktinis - nxs-k8s-s10).

Produkcija: jei mazgas valdo blokus, kuriems nenustatyti jokie apribojimai, tai k8s (išteklių suvartojimo požiūriu) tai bus tolygu, tarsi šiame mazge tokių blokų iš viso nebūtų. Todėl, jei sąlyginai turite podą su gluttonišku procesu (pavyzdžiui, wowza) ir jam nenustatyti jokie apribojimai, gali susidaryti situacija, kai šis podas iš tikrųjų suvalgė visus mazgo išteklius, o k8s šis mazgas yra laikomas neapkrautu ir jam bus suteiktas tiek pat balų, kai reitinguojamas (tiksliai taškais, įvertinus turimus išteklius) kaip mazgas, neturintis veikiančių podų, o tai galiausiai gali lemti netolygų apkrovos paskirstymą tarp mazgų.

Podo iškeldinimas

Kaip žinote, kiekvienam podui priskiriama viena iš 3 QoS klasių:

  1. garantuotas – priskiriamas, kai kiekvienam podelyje esančiam konteineriui yra nurodyta užklausa ir limitas atminčiai ir procesoriui, ir šios reikšmės turi sutapti
  2. sprogstamasis — bent vienas konteineris talpykloje turi užklausą ir limitą, o užklausa < limit
  3. geriausios pastangos — kai nėra nei vieno konteinerio talpyklos ištekliai riboti

Tuo pačiu metu, kai mazgas patiria išteklių (disko, atminties) trūkumą, kubelet pradeda reitinguoti ir iškeldinti blokus pagal konkretų algoritmą, kuriame atsižvelgiama į bloko prioritetą ir jo QoS klasę. Pavyzdžiui, jei kalbame apie RAM, tada pagal QoS klasę taškai suteikiami tokiu principu:

  • Garantija: -998 val
  • BestEffort: 1000
  • Plyštantis: min(maks.(2, 1000 - (1000 * atminties užklausos baitai) / mašinos atminties talpa baitai), 999)

Tie. su tuo pačiu prioritetu, kubeletas pirmiausia iškels iš mazgo geriausios kokybės QoS klasės blokus.

Produkcija: jei norite sumažinti tikimybę, kad norimas podas bus iškeldintas iš mazgo, jei jame trūksta resursų, tuomet kartu su prioritetu turite pasirūpinti ir užklausos/limicijos nustatymu.

Horizontaliojo automatinio aplikacijų mastelio keitimo (HPA) mechanizmas

Kai užduotis yra automatiškai padidinti ir sumažinti podų skaičių, priklausomai nuo išteklių naudojimo (sistema - CPU/RAM arba vartotojas - rps), toks k8s subjektas kaip HPA (Horizontal Pod Autoscaler). Kurio algoritmas yra toks:

  1. Nustatomi dabartiniai stebimo ištekliaus rodmenys (currentMetricValue)
  2. Nustatomos norimos išteklių reikšmės (desiredMetricValue), kurios sistemos ištekliams nustatomos naudojant užklausą
  3. Nustatytas dabartinis kopijų skaičius (currentReplicas)
  4. Ši formulė apskaičiuoja pageidaujamą kopijų skaičių (norimas replikos)
    wishReplicas = [ currentReplicas * ( currentMetricValue / wishMetricValue )]

Šiuo atveju mastelio keitimas neįvyks, kai koeficientas (currentMetricValue / wishMetricValue) yra artimas 1 (šiuo atveju leistiną klaidą galime nustatyti patys; pagal nutylėjimą ji yra 0.1).

Pažiūrėkime, kaip veikia hpa, naudodami programos testavimo programos pavyzdį (apibūdintą kaip diegimas), kur reikia pakeisti kopijų skaičių, atsižvelgiant į procesoriaus suvartojimą:

  • Programos manifestas

    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

    Tie. matome, kad programų rinkinys iš pradžių paleidžiamas dviem atvejais, kurių kiekviename yra du nginx ir nginx-eksportuotojo konteineriai, kiekvienam iš kurių nurodytas prašymai CPU.

  • HPA manifestas

    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

    Tie. Sukūrėme hpa, kuri stebės diegimo programos testą ir reguliuos blokų skaičių su programa pagal procesoriaus indikatorių (tikimės, kad podas sunaudos 30% jo reikalaujamo procesoriaus), o kopijų skaičius bus 2-10 diapazone.

    Dabar pažiūrėkime į hpa veikimo mechanizmą, jei vieną iš židinių apkrausime:

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

Iš viso turime:

  • Norima reikšmė (desiredMetricValue) – pagal hpa nustatymus turime 30 proc.
  • Dabartinė vertė (currentMetricValue) - skaičiavimui, valdiklis-vadybininkas apskaičiuoja vidutinę išteklių suvartojimo reikšmę %, t.y. sąlygiškai atlieka šiuos veiksmus:
    1. Gauna absoliučias pod metrikos reikšmes iš metrikos serverio, t.y. 101m ir 4m
    2. Apskaičiuoja vidutinę absoliučiąją reikšmę, t.y. (101m + 4m) / 2 = 53m
    3. Gauna absoliučią norimo išteklių suvartojimo vertę (tam sumuojamos visų konteinerių užklausos) 60m + 30m = 90m
    4. Skaičiuoja vidutinį procesoriaus suvartojimo procentą, palyginti su užklausų bloku, t.y. 53 m / 90 m * 100 % = 59 %

Dabar turime viską, ko reikia norint nustatyti, ar reikia pakeisti kopijų skaičių, apskaičiuojame koeficientą:

ratio = 59% / 30% = 1.96

Tie. kopijų skaičius turėtų būti padidintas ~2 kartus ir sudaryti [2 * 1.96] = 4.

Išvada: Kaip matote, norint, kad šis mechanizmas veiktų, būtina sąlyga yra užklausų dėl visų konteinerių buvimas stebimoje dėžutėje.

Horizontalaus automatinio mazgų skalavimo mechanizmas (Cluster Autoscaler)

Norint neutralizuoti neigiamą poveikį sistemai apkrovos šuolių metu, neužtenka sukonfigūruoto hpa. Pavyzdžiui, pagal nustatymus hpa valdiklio tvarkyklėje jis nusprendžia, kad reikia padidinti replikų skaičių 2 kartus, tačiau mazgai neturi laisvų resursų tokiam podų skaičiui paleisti (t.y. mazgas negali pateikti užklausų išteklių į užklausų grupę) ir šios grupės persijungia į būseną Laukiama.

Tokiu atveju, jei teikėjas turi atitinkamą IaaS / PaaS (pavyzdžiui, GKE / GCE, AKS, EKS ir kt.), įrankis, pvz., Node Autoscaler. Tai leidžia nustatyti maksimalų ir mažiausią mazgų skaičių klasteryje ir automatiškai koreguoti esamą mazgų skaičių (paskambinus debesies paslaugų teikėjo API, kad užsakytumėte / pašalintumėte mazgą), kai klasteryje ir blokuose trūksta išteklių. negali būti suplanuoti (būsenoje Laukiama).

Išvada: Kad būtų galima automatizuoti mazgų skalę, reikia nustatyti užklausas pod konteineriuose, kad k8s galėtų teisingai įvertinti mazgų apkrovą ir atitinkamai pranešti, kad klasteryje nėra resursų paleisti kitą podą.

išvada

Reikėtų pažymėti, kad konteinerio išteklių apribojimų nustatymas nėra būtinas reikalavimas, kad programa veiktų sėkmingai, tačiau vis tiek geriau tai padaryti dėl šių priežasčių:

  1. Tikslesniam planuoklio veikimui apkrovos balansavimo tarp k8s mazgų atžvilgiu
  2. Sumažinti „ankšties iškeldinimo“ įvykio tikimybę
  3. Kad veiktų horizontalus automatinis aplikacijų keitimas (HPA).
  4. Horizontaliam automatiniam mazgų mastelio keitimui (Cluster Autoscaling) debesų paslaugų teikėjams

Taip pat skaitykite kitus mūsų tinklaraščio straipsnius:

Šaltinis: www.habr.com

Добавить комментарий