Kubernetes: prečo je také dôležité nakonfigurovať správu systémových zdrojov?

Spravidla je vždy potrebné poskytnúť aplikácii vyhradený fond zdrojov pre jej správnu a stabilnú prevádzku. Ale čo ak niekoľko aplikácií beží na rovnakom výkone? Ako poskytnúť každému z nich minimálne potrebné zdroje? Ako môžete obmedziť spotrebu zdrojov? Ako správne rozložiť zaťaženie medzi uzly? Ako zabezpečiť fungovanie mechanizmu horizontálneho škálovania, ak sa zaťaženie aplikácie zvýši?

Kubernetes: prečo je také dôležité nakonfigurovať správu systémových zdrojov?

Musíte začať s tým, aké hlavné typy zdrojov existujú v systéme - to je samozrejme čas procesora a RAM. V manifestoch k8s sú tieto typy zdrojov merané v nasledujúcich jednotkách:

  • CPU - v jadrách
  • RAM - v bajtoch

Navyše pre každý zdroj je možné nastaviť dva typy požiadaviek - Žiadosti и limity. Požiadavky – popisuje minimálne požiadavky na voľné zdroje uzla na spustenie kontajnera (a podu ako celku), zatiaľ čo limity nastavujú pevný limit na zdroje dostupné pre kontajner.

Je dôležité pochopiť, že manifest nemusí explicitne definovať oba typy, ale správanie bude nasledovné:

  • Ak sú explicitne špecifikované iba limity zdroja, požiadavky na tento zdroj automaticky nadobudnú hodnotu rovnajúcu sa limitom (môžete to overiť volaním entít popisu). Tie. v skutočnosti bude kontajner obmedzený na rovnaké množstvo zdrojov, ktoré potrebuje na spustenie.
  • Ak sú pre zdroj explicitne špecifikované iba požiadavky, tak pre tento zdroj nie sú nastavené žiadne horné obmedzenia – t.j. kontajner je obmedzený iba prostriedkami samotného uzla.

Je tiež možné nakonfigurovať správu zdrojov nielen na úrovni konkrétneho kontajnera, ale aj na úrovni menného priestoru pomocou nasledujúcich entít:

  • LimitRange — opisuje politiku obmedzovania na úrovni kontajnera/struku v ns a je potrebný na opísanie predvolených limitov na kontajneri/struku, ako aj na zabránenie vytváraniu zjavne tučných nádob/strukov (alebo naopak), na obmedzenie ich počtu a určiť možný rozdiel v hodnotách limitov a požiadaviek
  • Kvóty na zdroje — opíšte politiku obmedzení vo všeobecnosti pre všetky kontajnery v ns a spravidla sa používa na vymedzenie zdrojov medzi prostrediami (užitočné, keď prostredia nie sú presne vymedzené na úrovni uzla)

Nasledujú príklady manifestov, ktoré nastavujú limity prostriedkov:

  • Na úrovni konkrétneho kontajnera:

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

    Tie. v tomto prípade na spustenie kontajnera s nginx budete potrebovať aspoň 1G voľnej pamäte RAM a 0.2 CPU na uzle, pričom maximálne kontajner môže spotrebovať 0.2 CPU a všetku dostupnú RAM v uzle.

  • Na celočíselnej úrovni ns:

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

    Tie. súčet všetkých kontajnerov požiadaviek v predvolenom ns nemôže presiahnuť 300 m pre CPU a 1G pre OP a súčet všetkých limitov je 700 m pre CPU a 2G pre OP.

  • Predvolené limity pre kontajnery v 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

    Tie. v predvolenom mennom priestore pre všetky kontajnery bude požiadavka nastavená na 100 m pre CPU a 1G pre OP, limit - 1 CPU a 2G. Zároveň je nastavený aj limit na možné hodnoty v požiadavke/limite pre CPU (50m < x < 2) a RAM (500M < x < 4G).

  • Obmedzenia na úrovni pod:

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

    Tie. pre každý modul v predvolenom ns bude limit 4 vCPU a 1G.

Teraz by som vám chcel povedať, aké výhody nám môže poskytnúť nastavenie týchto obmedzení.

Mechanizmus vyrovnávania záťaže medzi uzlami

Ako viete, komponent k8s je zodpovedný za distribúciu podov medzi uzlami, ako napr plánovač, ktorý pracuje podľa špecifického algoritmu. Tento algoritmus prechádza dvoma fázami pri výbere optimálneho uzla na spustenie:

  1. filtrovanie
  2. Rozsah

Tie. podľa opísanej politiky sa na začiatku vyberú uzly, na ktorých je možné spustiť pod na základe množiny predikáty (vrátane kontroly, či má uzol dostatok zdrojov na spustenie modulu – PodFitsResources), a potom pre každý z týchto uzlov podľa priority pridelia sa body (vrátane toho, že čím viac voľných zdrojov uzol má, tým viac bodov je mu pridelených - LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation) a modul sa spustí na uzle s najväčším počtom bodov (ak túto podmienku spĺňa viacero uzlov naraz, potom vyberie sa náhodný).

Zároveň musíte pochopiť, že plánovač sa pri posudzovaní dostupných zdrojov uzla riadi údajmi, ktoré sú uložené v etcd - t.j. pre množstvo požadovaného/obmedzeného zdroja každého modulu spusteného na tomto uzle, ale nie pre skutočnú spotrebu prostriedkov. Tieto informácie je možné získať z výstupu príkazu kubectl describe node $NODE, napríklad:

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

Tu vidíme všetky moduly bežiace na konkrétnom uzle, ako aj zdroje, ktoré každý modul požaduje. A takto vyzerajú protokoly plánovača, keď sa spustí modul cronjob-cron-events-1573793820-xt6q9 (táto informácia sa objaví v protokole plánovača, keď nastavíte 10. úroveň protokolovania v argumentoch spúšťacieho príkazu -v=10):

log

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

Tu vidíme, že plánovač spočiatku filtruje a generuje zoznam 3 uzlov, na ktorých môže byť spustený (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10). Potom vypočíta skóre na základe niekoľkých parametrov (vrátane BalancedResourceAllocation, LeastResourceAllocation) pre každý z týchto uzlov, aby určil najvhodnejší uzol. Nakoniec je modul naplánovaný na uzol s najvyšším počtom bodov (tu majú dva uzly naraz rovnaký počet bodov 100037, takže je vybraný náhodný - nxs-k8s-s10).

Výkon: ak uzol prevádzkuje pody, pre ktoré nie sú nastavené žiadne obmedzenia, potom pre k8s (z hľadiska spotreby zdrojov) to bude ekvivalentné tomu, ako keby na tomto uzle žiadne také pody neboli. Preto, ak máte podmienečne pod s obžerským procesom (napríklad wowza) a nie sú preň stanovené žiadne obmedzenia, môže nastať situácia, keď tento pod skutočne zjedol všetky zdroje uzla, ale pre k8s tento uzol sa považuje za nezaťažený a bude mu pridelený rovnaký počet bodov pri hodnotení (presne v bodoch posudzujúcich dostupné zdroje) ako uzol, ktorý nemá pracovné moduly, čo v konečnom dôsledku môže viesť k nerovnomernému rozloženiu zaťaženia medzi uzly.

Pod je vysťahovanie

Ako viete, každému modulu je priradená jedna z 3 tried QoS:

  1. zaručené — je priradené, keď pre každý kontajner v pod je špecifikovaná požiadavka a limit pre pamäť a procesor a tieto hodnoty sa musia zhodovať
  2. prasknuteľný — aspoň jeden kontajner v pod má požiadavku a limit, pričom požiadavka < limit
  3. maximálne úsilie — keď ani jeden kontajner v pod nemá obmedzené zdroje

Súčasne, keď uzol zaznamená nedostatok zdrojov (disk, pamäť), kubelet začne hodnotiť a vyhadzovať moduly podľa špecifického algoritmu, ktorý berie do úvahy prioritu modulu a jeho triedu QoS. Napríklad, ak hovoríme o RAM, potom na základe triedy QoS sa body udeľujú podľa nasledujúceho princípu:

  • Garantujeme: -998
  • BestEffort: 1000
  • Trhateľný: min(max(2, 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)

Tie. s rovnakou prioritou kubelet najskôr vytlačí moduly s najlepším úsilím triedy QoS z uzla.

Výkon: ak chcete znížiť pravdepodobnosť vysťahovania požadovaného modulu z uzla v prípade nedostatku zdrojov na ňom, potom sa spolu s prioritou musíte postarať aj o nastavenie požiadavky/limitu preň.

Mechanizmus pre horizontálne automatické škálovanie aplikačných modulov (HPA)

Keď je úlohou automaticky zvyšovať a znižovať počet podov v závislosti od využitia zdrojov (systém - CPU/RAM alebo užívateľ - rps), taká k8s entita ako napr. HPA (Horizontal Pod Autoscaler). Algoritmus ktorého je nasledujúci:

  1. Sú určené aktuálne hodnoty pozorovaného zdroja (currentMetricValue)
  2. Požadované hodnoty pre zdroj sú určené (desiredMetricValue), ktoré sa pre systémové zdroje nastavujú pomocou požiadavky
  3. Je určený aktuálny počet replík (currentReplicas)
  4. Nasledujúci vzorec vypočíta požadovaný počet replík (desiredReplicas)
    požadovanéRepliky = [ currentReplicas * ( currentMetricValue / requiredMetricValue )]

V tomto prípade k škálovaniu nedôjde, keď sa koeficient (currentMetricValue / requiredMetricValue) blíži k 1 (v tomto prípade si môžeme sami nastaviť prípustnú chybu, štandardne je to 0.1).

Pozrime sa, ako hpa funguje na príklade aplikácie app-test (opísanej ako Deployment), kde je potrebné zmeniť počet replík v závislosti od spotreby CPU:

  • Manifest aplikácie

    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. vidíme, že aplikačná podložka sa na začiatku spustí v dvoch inštanciách, z ktorých každá obsahuje dva kontajnery nginx a nginx-exporter, pre každý z nich špecifikovaný Žiadosti pre CPU.

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

    Tie. Vytvorili sme hpa, ktorá bude monitorovať test aplikácie Deployment a regulovať počet modulov s aplikáciou na základe indikátora CPU (očakávame, že modul by mal spotrebovať 30 % percent CPU, ktoré požaduje), pričom počet replík bude v rozmedzí 2-10.

    Teraz sa pozrime na mechanizmus prevádzky hpa, ak aplikujeme zaťaženie na jedno z ohnísk:

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

Celkovo máme nasledovné:

  • Požadovaná hodnota (desiredMetricValue) - podľa nastavenia hpa máme 30%
  • Aktuálna hodnota (currentMetricValue) - pre výpočet controller-manažér vypočíta priemernú hodnotu spotreby zdrojov v %, t.j. podmienečne robí nasledovné:
    1. Prijíma absolútne hodnoty metrík pod zo servera metrík, t.j. 101m a 4m
    2. Vypočíta priemernú absolútnu hodnotu, t.j. (101 m + 4 m) / 2 = 53 m
    3. Získa absolútnu hodnotu pre požadovanú spotrebu zdrojov (na tento účel sa spočítajú požiadavky všetkých kontajnerov) 60 m + 30 m = 90 m
    4. Vypočíta priemerné percento spotreby CPU vzhľadom na požiadavku pod, t.j. 53 m / 90 m * 100 % = 59 %

Teraz máme všetko, čo potrebujeme, aby sme určili, či potrebujeme zmeniť počet replík; na tento účel vypočítame koeficient:

ratio = 59% / 30% = 1.96

Tie. počet replík by sa mal zväčšiť ~2-krát a dosiahnuť [2 * 1.96] = 4.

Záver: Ako vidíte, na to, aby tento mechanizmus fungoval, je nevyhnutnou podmienkou prítomnosť požiadaviek na všetky kontajnery v sledovanom podu.

Mechanizmus pre horizontálne automatické škálovanie uzlov (Cluster Autoscaler)

Na neutralizáciu negatívneho vplyvu na systém počas rázov záťaže nestačí mať nakonfigurovaný hpa. Napríklad podľa nastavení v správcovi ovládača hpa sa rozhodne, že počet replík je potrebné zvýšiť 2-krát, no uzly nemajú voľné zdroje na spustenie takého počtu modulov (t. j. uzol nemôže poskytnúť požadované zdroje do skupiny žiadostí) a tieto moduly sa prepnú do stavu Čakajúce.

V tomto prípade, ak má poskytovateľ zodpovedajúce IaaS/PaaS (napríklad GKE/GCE, AKS, EKS atď.), nástroj ako Autoscaler uzlov. Umožňuje vám nastaviť maximálny a minimálny počet uzlov v klastri a automaticky upraviť aktuálny počet uzlov (zavolaním API poskytovateľa cloudu na objednanie/odstránenie uzla), keď je nedostatok zdrojov v klastri a podoch. nie je možné naplánovať (sú v stave Čaká sa).

Záver: Aby bolo možné automaticky škálovať uzly, je potrebné nastaviť požiadavky v kontajneroch pod, aby k8 mohli správne posúdiť zaťaženie uzlov a podľa toho hlásiť, že v klastri nie sú žiadne zdroje na spustenie ďalšieho pod.

Záver

Je potrebné poznamenať, že nastavenie limitov prostriedkov kontajnera nie je podmienkou na úspešné spustenie aplikácie, ale stále je lepšie tak urobiť z nasledujúcich dôvodov:

  1. Pre presnejšiu prevádzku plánovača z hľadiska vyrovnávania záťaže medzi uzlami k8s
  2. Na zníženie pravdepodobnosti výskytu udalosti „vysťahovania pod“.
  3. Na fungovanie horizontálneho automatického škálovania aplikačných modulov (HPA).
  4. Pre horizontálne automatické škálovanie uzlov (Cluster Autoscaling) pre poskytovateľov cloudu

Prečítajte si aj ďalšie články na našom blogu:

Zdroj: hab.com

Pridať komentár