Kubernetes: miért olyan fontos a rendszer erőforráskezelésének beállítása?

Általában mindig felmerül a szükséglet, hogy biztosítsunk egy dedikált erőforráskört egy alkalmazás számára a helyes és stabil működéséhez. De mi történik, ha ugyanazon erőforrások mellett egyszerre több alkalmazás működik? Hogyan biztosítsuk a minimum szükséges erőforrásokat mindegyik számára? Hogyan korlátozhatjuk az erőforrás-felhasználást? Hogyan osszuk el helyesen a terhelést a csomópontok között? Hogyan biztosítható a vízszintes skálázás működése az alkalmazások terhelésének növekedése esetén?

Kubernetes: miért olyan fontos a rendszer erőforráskezelésének beállítása?

Először is fontos tisztázni, hogy milyen alapvető erőforrástípusok léteznek a rendszerben — ezek természetesen a processzoridő és a RAM. A k8s manifestekben ezek az erőforrástípusok a következő egységekben mérhetők:

  • CPU — magokban
  • RAM — bájtokban

Továbbá minden erőforrás esetében lehetőség van kétféle követelményt megadni — library-k segítségével. Általános formában a web-kérdések szerkezete három részből áll: és limits. A requests — leírja a minimális követelményeket az erőforrások szabad terheltségére a csomópontnál a konténer (és a pod összességében) elindításához, míg a limits a konténer számára elérhető erőforrások szigorú korlátait állítja be.

Fontos megérteni, hogy a manifestben nem kötelező egyértelműen meghatározni mindkét típust, a viselkedés a következő módon alakul:

  • Ha egyértelműen csak a limits erőforrás van megadva, akkor az requests automatikusan a limits értékét veszi fel (ezt a tárgy leírásának megadásával ellenőrizhetjük). Tehát a konténer működését gyakorlatilag a számára szükséges erőforrások mennyisége korlátozza.
  • Ha az erőforráshoz kifejezetten csak a requests van megadva, akkor nincs felső korlátozás erre az erőforrásra — azaz a konténer csak a csomópont saját erőforrásai által korlátozott.

Lehetséges az erőforrások kezelését nemcsak egy adott konténer szintjén beállítani, hanem namespace szinten is a következő entitások segítségével:

  • LimitRange — leírja a konténer/pod szintű korlátozások politikáját a ns-nél, és arra szolgál, hogy meghatározza a konténer/pod alapértelmezett korlátait, valamint megakadályozza a nyilvánvalóan túlméretezett konténerek/podok létrehozását (vagy éppen ellenkezőleg), korlátozza a mennyiségüket és meghatározza a limits és requests értékek közötti lehetséges eltéréseket.
  • ResourceQuotas — leírja az erőforrások korlátozási politikáját általában az összes konténerre vonatkozóan és általában az erőforrások szétválasztására használják a környezetek között (hasznos, ha a környezetek nem élesek a csomópontok szintjén).

Az alábbiakban olyan példák találhatók, amelyekben erőforrás-korlátozásokat állítanak be:

  • Egy adott konténer szintjén:

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

    Ezért ebben az esetben a nginx konténer indításához legalább 1G memória és 0.2 CPU szabadnak kell lennie a csomóponton, eközben a konténer legfeljebb 0.2 CPU-t és az összes elérhető memóriát felhasználhat a csomóponton.

  • Az egész ns szintjén:

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

    Ezért a default ns-ben lévő összes konténer kérésének összege nem haladhatja meg a 300m CPU-t és az 1G memóriát, míg a limit összegének 700m CPU-nak és 2G memóriának kell lennie.

  • Alapértelmezett korlátozások a konténerek számára az ns-ben:

    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

    Ezért az alapértelmezett namespace-ben minden konténer számára alapértelmezés szerint 100m CPU és 1G memória kérést állítanak be, a limit 1 CPU és 2G. Ugyanakkor korlátozás van a CPU (50m < x < 2) és a RAM (500M < x < 4G) kérés/limit lehetséges értékeire is.

  • A pods szintjén lévő korlátozások az ns-ben:

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

    Ezért a default ns-ben minden pod számára 4 vCPU és 1G korlátozást állítanak be.

Most szeretném bemutatni, milyen előnyöket nyújthat számunkra ezeknek a korlátozásoknak a beállítása.

A terheléskiegyenlítés mechanizmusa a csomópontok között

Ahogy ismert, a podok csomópontokra történő elosztásáért egy k8s komponens felelős, mint például scheduler, amely egy meghatározott algoritmus szerint működik. Ez az algoritmus a legoptimálisabb csomópont kiválasztása során két szakaszon megy keresztül:

  1. Szűrés
  2. Rangsorolás

Ezért a leírt politika szerint először a csomópontok közül választják ki azokat, ahol a pod indítása lehetséges a predikátumok készlete alapján, predicates (beleértve annak ellenőrzését is, hogy elegendő erőforrás áll-e rendelkezésre a pod indításához — PodFitsResources), majd ezek közül az összes csomópont közül az adott prioritások szerint rangsorolják. priorities pontokat osztanak ki (beleértve, hogy minél több erőforrás áll rendelkezésre a csomóponton, annál több pontot kap — LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation) és a legnagyobb pontszámmal rendelkező csomóponton indul el (ha több csomópont is megfelel ennek a feltételnek, akkor véletlenszerűen választanak közülük).

Fontos megérteni, hogy a scheduler az elérhető csomóponti erőforrások értékelésekor az etcd-ben tárolt adatokra támaszkodik — azaz minden egyes pod által a csomóponton igényelt/korlátozott erőforrás összegére, nem pedig a tényleges erőforrás-felhasználásra. Ezt az információt a következő parancs kimenetében kaphatjuk meg: kubectl describe node $NODE, például:

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

Itt látjuk az összes podot, amely egy adott csomóponton fut, valamint a podok által igényelt erőforrásokat. Íme, hogyan néznek ki a scheduler naplói a cronjob-cron-events-1573793820-xt6q9 pod indításakor (ez az információ a scheduler naplóban akkor jelenik meg, ha a 10-es fokozatú naplózást állítjuk be a parancs elindításakor megadott argumentumokban —v=10):

napló

I1115 07:57:21.637791       1 scheduling_queue.go:908] Próbálkozik a pod ütemezésével: nxs-stage\/cronjob-cron-events-1573793820-xt6q9                                                                                                                                           
I1115 07:57:21.637804       1 scheduler.go:453] A pod ütemezésére tett kísérlet: nxs-stage\/cronjob-cron-events-1573793820-xt6q9                                                                                                                                                    
I1115 07:57:21.638285       1 predicates.go:829] Az nxs-k8s-s5 csomóponton való ütemezés engedélyezett, a csomópont csak 16 podot futtat a 110-ből.                                                                               
I1115 07:57:21.638300       1 predicates.go:829] Az nxs-k8s-s6 csomóponton való ütemezés engedélyezett, a csomópont csak 20 podot futtat a 110-ből.                                                                               
I1115 07:57:21.638322       1 predicates.go:829] Az nxs-k8s-s3 csomóponton való ütemezés engedélyezett, a csomópont csak 20 podot futtat a 110-ből.                                                                               
I1115 07:57:21.638322       1 predicates.go:829] Az nxs-k8s-s4 csomóponton való ütemezés engedélyezett, a csomópont csak 17 podot futtat a 110-ből.                                                                               
I1115 07:57:21.638334       1 predicates.go:829] Az nxs-k8s-s10 csomóponton való ütemezés engedélyezett, a csomópont csak 16 podot futtat a 110-ből.                                                                              
I1115 07:57:21.638365       1 predicates.go:829] Az nxs-k8s-s12 csomóponton való ütemezés engedélyezett, a csomópont csak 9 podot futtat a 110-ből.                                                                               
I1115 07:57:21.638334       1 predicates.go:829] Az nxs-k8s-s11 csomóponton való ütemezés engedélyezett, a csomópont csak 11 podot futtat a 110-ből.                                                                              
I1115 07:57:21.638385       1 predicates.go:829] Az nxs-k8s-s1 csomóponton való ütemezés engedélyezett, a csomópont csak 19 podot futtat a 110-ből.                                                                               
I1115 07:57:21.638402       1 predicates.go:829] Az nxs-k8s-s2 csomóponton való ütemezés engedélyezett, a csomópont csak 21 podot futtat a 110-ből.                                                                               
I1115 07:57:21.638383       1 predicates.go:829] Az nxs-k8s-s9 csomóponton való ütemezés engedélyezett, a csomópont csak 16 podot futtat a 110-ből.                                                                               
I1115 07:57:21.638335       1 predicates.go:829] Az nxs-k8s-s8 csomóponton való ütemezés engedélyezett, a csomópont csak 18 podot futtat a 110-ből.                                                                               
I1115 07:57:21.638408       1 predicates.go:829] Az nxs-k8s-s13 csomóponton való ütemezés engedélyezett, a csomópont csak 8 podot futtat a 110-ből.                                                                               
I1115 07:57:21.638478       1 predicates.go:1369] Az nxs-k8s-s10 csomóponton való ütemezés engedélyezett, az existing pods anti-affinity terms teljesültek.                                                                         
I1115 07:57:21.638505       1 predicates.go:1369] Az nxs-k8s-s8 csomóponton való ütemezés engedélyezett, az existing pods anti-affinity terms teljesültek.                                                                          
I1115 07:57:21.638577       1 predicates.go:1369] Az nxs-k8s-s9 csomóponton való ütemezés engedélyezett, az existing pods anti-affinity terms teljesültek.                                                                          
I1115 07:57:21.638583       1 predicates.go:829] Az nxs-k8s-s7 csomóponton való ütemezés engedélyezett, a csomópont csak 25 podot futtat a 110-ből.                                                                               
I1115 07:57:21.638932       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: BalancedResourceAllocation, kapacitás 39900 millicore, 66620178432 bájt memória, összes kérés 2343 millicore, 9640186880 bájt memória, pontszám 9        
I1115 07:57:21.638946       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: LeastResourceAllocation, kapacitás 39900 millicore, 66620178432 bájt memória, összes kérés 2343 millicore, 9640186880 bájt memória, pontszám 8           
I1115 07:57:21.638961       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: BalancedResourceAllocation, kapacitás 39900 millicore, 66620170240 bájt memória, összes kérés 4107 millicore, 11307422720 bájt memória, pontszám 9        
I1115 07:57:21.638971       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: BalancedResourceAllocation, kapacitás 39900 millicore, 66620178432 bájt memória, összes kérés 5847 millicore, 24333637120 bájt memória, pontszám 7        
I1115 07:57:21.638975       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: LeastResourceAllocation, kapacitás 39900 millicore, 66620170240 bájt memória, összes kérés 4107 millicore, 11307422720 bájt memória, pontszám 8           
I1115 07:57:21.638990       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: LeastResourceAllocation, kapacitás 39900 millicore, 66620178432 bájt memória, összes kérés 5847 millicore, 24333637120 bájt memória, pontszám 7           
I1115 07:57:21.639022       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s10: TaintTolerationPriority, Pontszám: (10)                                                                                                        
I1115 07:57:21.639030       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s8: TaintTolerationPriority, Pontszám: (10)                                                                                                         
I1115 07:57:21.639034       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s9: TaintTolerationPriority, Pontszám: (10)                                                                                                         
I1115 07:57:21.639041       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s10: NodeAffinityPriority, Pontszám: (0)                                                                                                            
I1115 07:57:21.639053       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s8: NodeAffinityPriority, Pontszám: (0)                                                                                                             
I1115 07:57:21.639059       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s9: NodeAffinityPriority, Pontszám: (0)                                                                                                             
I1115 07:57:21.639061       1 interpod_affinity.go:237] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s10: InterPodAffinityPriority, Pontszám: (0)                                                                                                                   
I1115 07:57:21.639063       1 selector_spreading.go:146] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s10: SelectorSpreadPriority, Pontszám: (10)                                                                                                                   
I1115 07:57:21.639073       1 interpod_affinity.go:237] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s8: InterPodAffinityPriority, Pontszám: (0)                                                                                                                    
I1115 07:57:21.639077       1 selector_spreading.go:146] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s8: SelectorSpreadPriority, Pontszám: (10)                                                                                                                    
I1115 07:57:21.639085       1 interpod_affinity.go:237] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s9: InterPodAffinityPriority, Pontszám: (0)                                                                                                                    
I1115 07:57:21.639088       1 selector_spreading.go:146] cronjob-cron-events-1573793820-nxs-k8s-s9: SelectorSpreadPriority, Pontszám: (10)                                                                                                                    
I1115 07:57:21.639103       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s10: SelectorSpreadPriority, Pontszám: (10)                                                                                                         
I1115 07:57:21.639109       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s8: SelectorSpreadPriority, Pontszám: (10)                                                                                                          
I1115 07:57:21.639114       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-nxs-stage -> nxs-k8s-s9: SelectorSpreadPriority, Pontszám: (10)                                                                                                          
I1115 07:57:21.639127       1 generic_scheduler.go:781] Gazda nxs-k8s-s10 => Pontszám 100037                                                                                                                                                                            
I1115 07:57:21.639150       1 generic_scheduler.go:781] Gazda nxs-k8s-s8 => Pontszám 100034                                                                                                                                                                             
I1115 07:57:21.639154       1 generic_scheduler.go:781] Gazda nxs-k8s-s9 => Pontszám 100037                                                                                                                                                                             
I1115 07:57:21.639267       1 scheduler_binder.go:269] AssumePodVolumes a pod neve "nxs-stage\/cronjob-cron-events-1573793820-xt6q9", csomópont "nxs-k8s-s10"                                                                                                               
I1115 07:57:21.639286       1 scheduler_binder.go:279] AssumePodVolumes a pod neve "nxs-stage\/cronjob-cron-events-1573793820-xt6q9", csomópont "nxs-k8s-s10": minden PVC meg van kötve, és nincs mit tenni                                                                             
I1115 07:57:21.639333       1 factory.go:733] Kísérlet a cronjob-cron-events-1573793820-xt6q9 nxs-k8s-s10-hez való kötésére

Itt láthatjuk, hogy a scheduler kezdetben kiszűri és létrehozza a lehetséges indítási csomópontok listáját (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10). Ezután több paraméter (beleértve a BalancedResourceAllocation, LeastResourceAllocation) alapján pontszámot számít ki ezeken a csomópontokon, hogy meghatározza a legmegfelelőbb csomópontot. Végül a legmagasabb pontszámú csomóponton tervezésre kerül (itt közvetlenül két csomópont azonos 100037 pontot kapott, ezért az egyiküket véletlenszerűen választják — nxs-k8s-s10).

Következtetés: ha a csomóponton olyan podok futnak, amelyekhez nincsenek korlátozások megadva, akkor a k8s számára (a erőforrások felhasználása szempontjából) ez tükrözi azt, mintha a csomóponton ezek a podok egyáltalán nem lennének. Ezért, ha van például egy pod, amelynek egy erőforrásigényes folyamata van (például wowza), és nincsenek megadva korlátozások, akkor olyan helyzet adódhat, hogy ez a pod ténylegesen elhasználja az összes csomóponti erőforrást, de a k8s számára ez a csomópont továbbra is alacsony terhelésűnek számít, és a pontok rangsorolásánál ugyanannyi pontot kap, mint azon csomópont, ahol nincsenek futó podok, ami végső soron egyenlőtlen tehereloszlást eredményezhet a csomópontok között.

Pod eltávolítása

Mint tudjuk, minden podhoz egy a 3 QoS-osztályból egyik kerül hozzáadásra:

  1. guaranuted — akkor kerül kijelölésre, amikor minden konténerben meg van adva a memóriára és CPU-ra a request és limit, és ezek az értékek meg kell, hogy egyezzenek
  2. burstable — legalább egy konténer a podban rendelkezik request és limit paraméterekkel, és a request < limit
  3. best effort — amikor egyetlen konténer sem korlátozott erőforrások tekintetében a podban

Ezért, ha a csomóponton erőforráshiány (lemez, memória) tapasztalható, a kubelet elkezd rangsorolni és eltávolítani a podokat egy bizonyos algoritmus szerint, amely figyelembe veszi a pod prioritását és a QoS-osztályát. Például, ha RAM-ról van szó, akkor a QoS osztály alapján a következő elv szerint pontokat kap:

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

Tehát azonos prioritás esetén a kubelet először a best effort QoS-osztályú podokat eltávolítja a csomópontból.

Következtetés: ha csökkenteni akarja az esélyét annak, hogy a szükséges podot eltávolítsák a csomópontból erőforráshiány miatt, akkor a prioritás mellett arról is gondoskodnia kell, hogy a podhoz request/limit meg legyen adva.

Az alkalmazás podjainak vízszintes automatikus skálázási mechanizmusa (HPA)

Amikor az a feladat, hogy automatikusan növeljük vagy csökkentsük a podok számát az erőforrások (rendszerszintű — CPU/RAM vagy felhasználói — rps) felhasználása alapján, segíthet egy ilyen entitás k8s, mint HPA (Horizontal Pod Autoscaler). Az algoritmus lényege a következő:

  1. A megfigyelt erőforrás jelenlegi értékeinek meghatározása (currentMetricValue)
  2. A kívánt értékek meghatározása az erőforrás számára (desiredMetricValue), amelyeket a rendszererőforrások esetében a request segítségével adunk meg
  3. A jelenlegi replikák számának meghatározása (currentReplicas)
  4. A következő képlet segítségével kiszámítjuk a kívánt replikák számát (desiredReplicas)
    desiredReplicas = [ currentReplicas * ( currentMetricValue / desiredMetricValue )]

Ebben az esetben nem történik skálázás, ha a hányados (currentMetricValue / desiredMetricValue) közeli az 1-hez (ebben az esetben az elfogadható hibahatárt magunk is beállíthatjuk, alapértelmezés szerint 0,1).

Nézzük meg a hpa működését a következő példával, ahol egy app-test nevű alkalmazás (Deployment-ként leírva) a CPU felhasználás alapján szükséges változtatni a replikák számát:

  • Az alkalmazás manifestje

    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

    Tehát azt látjuk, hogy az alkalmazás podjából eredetileg kettő példányban fut, mindkettőben két konténer található: nginx és nginx-exporter, amelyekhez library-k segítségével. Általános formában a web-kérdések szerkezete három részből áll: a CPU-t meghatároztuk.

  • HPA manifestje

    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

    Tehát létrehoztunk egy hpa-t, amely figyelemmel kíséri az app-test Deploymentet és szabályozza a podok számát az alkalmazás esetében a CPU mutató alapján (elvárásunk, hogy a pod 30% -át fogyasztja a számára kért CPU-nak), miközben a replikák száma a 2-10 közötti tartományban mozog.

    Most nézzük meg a hpa működését, ha terhelést helyezünk el az egyik podon:

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

Összességében a következőt kapjuk:

  • A kívánt érték (desiredMetricValue) az hpa beállítások szerint 30%-ra van állítva.
  • A jelenlegi érték (currentMetricValue) - a controller-manager az erőforrás fogyasztásának átlagos értékét számítja %, azaz feltételezhetően a következőt teszi:
    1. Megkapja a podok metrikáinak abszolút értékeit a metric-szerverből, azaz 101m és 4m.
    2. Kiszámítja az átlagos abszolút értéket, azaz (101m + 4m) / 2 = 53m.
    3. Megkapja az erőforrás kívánt fogyasztásának abszolút értékét (ehhez összeadja a konténerek kéréseit) 60m + 30m = 90m.
    4. Kiszámítja a CPU fogyasztásának átlagos százalékát a pod kéréseihez viszonyítva, azaz 53m / 90m * 100% = 59%.

Most már minden szükséges információval rendelkezünk ahhoz, hogy meghatározzuk, szükséges-e módosítani a replikák számát, ezért számítsuk ki az arányt:

ratio = 59% / 30% = 1.96.

Azaz a replikák számának körülbelül 2-szeresére kell növekednie, tehát [2 * 1.96] = 4.

Következtetés: Ahogy látható, hogy ez a mechanizmus működjön, szükséges, hogy all konténerekre vonatkozóan legyenek kérések a figyelt podban.

A csomópontok vízszintes automatikus skálázási mechanizmusa (Cluster Autoscaler).

Ahhoz, hogy minimálisra csökkentsük a rendszerre gyakorolt negatív hatásokat a terhelés spike-jai során, a beállított hpa néha nem elegendő. Például, a hpa beállításai szerint a controller manager azt a döntést hozza, hogy a replikák számát 2-szer kell növelni, azonban a csomópontokon nincs elegendő szabad erőforrás az ilyen számú pod elindításához (azaz a csomópont nem képes biztosítani a pod kéréseinek erőforrásait), és ezek a podok Pending állapotba kerülnek.

Ebben az esetben, ha a szolgáltatónak van megfelelő IaaS/PaaS (például GKE/GCE, AKS, EKS stb.), segíthet egy olyan eszköz, mint a Node Autoscaler.Ez lehetővé teszi a maximum és minimum számú csomópont beállítását a klaszterben, és automatikusan szabályozza a jelenlegi csomópontok számát (a felhőszolgáltató API-jához fordulva csomópont rendelésére/eltávolítására), amikor erőforráshiányt észlelnek a klaszterben, és a podok nem tudnak ütemeződni (Pending állapotba kerülnek).

Következtetés: Az automatikus skálázáshoz a csomópontokban a konténerek kéréseinek megadása szükséges, hogy a k8s helyesen értékelhesse a csomópontok terheltségét, és ennek megfelelően jelezze, hogy a következő pod elindításához nincs elegendő erőforrás a klaszterben.

Zárás

Érdemes megjegyezni, hogy a konténer erőforrás-korlátozásának beállítása nem kötelező feltétele az alkalmazás sikeres futtatásának, mégis javasolt, a következő okok miatt:

  1. A scheduler pontosabb működése érdekében a k8s csomópontok közötti terhelés elosztásában.
  2. A "pod kilakoltatásának" valószínűségének csökkentése érdekében.
  3. Az alkalmazások podjainak horizontális automatikus skálázásának működése érdekében (HPA).
  4. A csomópontok horizontális automatikus skálázásának működése érdekében (Cluster Autoscaling) felhőszolgáltatóknál.

Olvasd el többi cikkünket a blogunkban:

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster