Kubernetes: miért olyan fontos a rendszererőforrás-kezelés beállítása?

Általános szabály, hogy mindig szükség van egy dedikált erőforráskészlet biztosítására egy alkalmazás számára a megfelelő és stabil működés érdekében. De mi van akkor, ha több alkalmazás fut ugyanazon a teljesítményen? Hogyan biztosítsuk mindegyiküket a minimálisan szükséges erőforrásokkal? Hogyan korlátozhatja az erőforrás-felhasználást? Hogyan lehet helyesen elosztani a terhelést a csomópontok között? Hogyan biztosítható a vízszintes méretezési mechanizmus működése, ha az alkalmazás terhelése növekszik?

Kubernetes: miért olyan fontos a rendszererőforrás-kezelés beállítása?

Kezdje azzal, hogy milyen fő erőforrástípusok vannak a rendszerben - ez természetesen a processzoridő és a RAM. A k8s manifesztekben ezeket az erőforrástípusokat a következő mértékegységekben mérjük:

  • CPU - magokban
  • RAM - bájtban

Ezen túlmenően minden erőforráshoz kétféle követelmény állítható be - kéri и határértékek. Kérések – a csomópont ingyenes erőforrásaira vonatkozó minimális követelményeket írja le egy tároló (és a pod egészének) futtatásához, míg a korlátok szigorúan korlátozzák a tároló rendelkezésére álló erőforrásokat.

Fontos megérteni, hogy a jegyzéknek nem kell egyértelműen meghatároznia mindkét típust, de a viselkedés a következő lesz:

  • Ha egy erőforrásnak csak a korlátai vannak kifejezetten megadva, akkor az erre az erőforrásra vonatkozó kérések automatikusan a korlátokkal megegyező értéket vesznek fel (ezt a leírási entitások meghívásával ellenőrizheti). Azok. Valójában a tároló ugyanannyi erőforrásra lesz korlátozva, amelyre a futtatásához szüksége van.
  • Ha egy erőforráshoz csak kérések vannak kifejezetten megadva, akkor erre az erőforrásra nincs felső korlátozás beállítva - pl. a tárolót csak magának a csomópontnak az erőforrásai korlátozzák.

Az erőforrás-kezelést nem csak egy adott tároló szintjén, hanem névtér szinten is beállíthatja a következő entitások használatával:

  • LimitRange — leírja a korlátozási politikát a tartály/hüvely szintjén ns-ben, és szükséges a tartály/hüvely alapértelmezett korlátainak leírásához, valamint a nyilvánvalóan zsíros tartályok/hüvelyek létrehozásának megakadályozásához (vagy fordítva), számának korlátozásához és meghatározza a korlátok és kérések értékeinek lehetséges eltérését
  • Erőforráskvóták — általánosságban írja le a korlátozási szabályzatot az összes ns-ben lévő tárolóra, és általában az erőforrások környezetek közötti elhatárolására szolgál (hasznos, ha a környezetek nincsenek szigorúan elhatárolva csomóponti szinten)

Az alábbiakban példák láthatók az erőforráskorlátokat beállító jegyzékekre:

  • Az adott tároló szintjén:

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

    Azok. ebben az esetben egy konténer nginx-szel való futtatásához legalább 1 G szabad RAM-ra és 0.2 CPU-ra lesz szüksége a csomóponton, míg a konténer legfeljebb 0.2 CPU-t és a csomóponton elérhető összes RAM-ot fogyaszthat.

  • Az ns egész szám szintjén:

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

    Azok. az összes kérelem konténer összege az alapértelmezett ns-ben nem haladhatja meg a 300 m-t a CPU és az 1G-t az OP esetében, és az összes korlát összege 700 m a CPU és a 2G az OP esetében.

  • A tárolók alapértelmezett korlátai 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

    Azok. az összes tároló alapértelmezett névterében a kérés 100 m-re lesz beállítva a CPU-nál és 1G-re az OP-nál, a korlát pedig - 1 CPU és 2G. Ugyanakkor a CPU (50m < x < 2) és a RAM (500M < x < 4G) kérés/korlátozás lehetséges értékeinek korlátja is be van állítva.

  • Pod-szintű korlátozások ns:

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

    Azok. Az alapértelmezett ns-ben minden egyes pod esetében 4 vCPU és 1G lesz a korlát.

Most szeretném elmondani, milyen előnyökkel járhat számunkra ezeknek a korlátozásoknak a beállítása.

Terheléselosztó mechanizmus a csomópontok között

Mint tudod, a k8s komponens felelős a pod-ok csomópontok közötti elosztásáért, mint pl ütemező, amely egy meghatározott algoritmus szerint működik. Ez az algoritmus két szakaszon megy keresztül, amikor kiválasztja az optimális indítandó csomópontot:

  1. szűrő
  2. Körű

Azok. a leírt házirend szerint kezdetben olyan csomópontok kerülnek kiválasztásra, amelyeken lehetőség van egy készlet alapján pod indítására állítmányok (beleértve annak ellenőrzését, hogy a csomópont rendelkezik-e elegendő erőforrással a pod futtatásához – PodFitsResources), majd minden egyes csomópont esetében, a prioritások pontokat kapnak (beleértve, minél több szabad erőforrással rendelkezik egy csomópont, annál több pontot rendel hozzá - LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation), és a pod a legtöbb pontot elérő csomóponton indul (ha több csomópont teljesíti ezt a feltételt egyszerre, akkor véletlenszerűen kiválasztott) .

Ugyanakkor meg kell értenie, hogy az ütemezőt egy csomópont rendelkezésre álló erőforrásainak felmérésekor az etcd-ben tárolt adatok vezérlik - azaz. az ezen a csomóponton futó egyes pod kért/korlátozott erőforrásának mennyiségére, de nem a tényleges erőforrás-felhasználásra. Ez az információ a parancs kimenetéből nyerhető 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áthatjuk az összes, egy adott csomóponton futó pod-ot, valamint az egyes pod-ok által kért erőforrásokat. És így néznek ki az ütemező naplói, amikor a cronjob-cron-events-1573793820-xt6q9 pod elindul (ez az információ megjelenik az ütemező naplójában, amikor beállítja a 10. naplózási szintet az indítási parancs -v=10 argumentumában):

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

Itt látjuk, hogy kezdetben az ütemező szűr, és létrehoz egy listát 3 csomópontból, amelyeken elindítható (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10). Ezután több paraméter (beleértve a BalancedResourceAllocation, LeastResourceAllocation) alapján kiszámítja a pontszámokat minden egyes csomópontra, hogy meghatározza a legmegfelelőbb csomópontot. Végső soron a pod a legtöbb ponttal rendelkező csomóponton van ütemezve (itt egyszerre két csomópontnak ugyanannyi pontja van 100037, tehát egy véletlenszerű lesz kiválasztva - nxs-k8s-s10).

Teljesítmény: ha egy csomópont olyan podokat futtat, amelyekre nincsenek korlátozások beállítva, akkor a k8s esetén (erőforrás-felhasználás szempontjából) ez egyenértékű lesz azzal, mintha ezen a csomóponton egyáltalán nem lennének ilyen pod-ok. Ezért, ha feltételesen van egy torkos folyamattal rendelkező pod (például wowza), és nincsenek rá korlátozások beállítva, akkor olyan helyzet állhat elő, amikor ez a pod ténylegesen megette a csomópont összes erőforrását, de k8s esetén ez a csomópont terheletlennek minősül, és ugyanannyi pontot kap, amikor (pontosan a rendelkezésre álló erőforrásokat értékelő pontokban) olyan csomópontként rangsorolják, amely nem rendelkezik működő podokkal, ami végső soron a terhelés egyenetlen eloszlásához vezethet a csomópontok között.

Pod kilakoltatása

Mint tudják, minden podhoz hozzá van rendelve a 3 QoS osztály egyike:

  1. garantált — akkor van hozzárendelve, ha a pod minden egyes tárolójához egy kérés és korlát van megadva a memóriához és a cpu-hoz, és ezeknek az értékeknek meg kell egyeznie
  2. robbanékony — a podban legalább egy tárolónak van kérése és korlátja, kérés < limittel
  3. legjobb erőfeszítés — ha a podban egyetlen tároló sem korlátozott erőforrással

Ugyanakkor, amikor egy csomópont erőforráshiányt tapasztal (lemez, memória), a kubelet elkezdi rangsorolni és kiüríteni a podokat egy adott algoritmus szerint, amely figyelembe veszi a pod prioritását és annak QoS osztályát. Például, ha a RAM-ról beszélünk, akkor a QoS osztály alapján a pontok a következő elv szerint járnak:

  • Garantált:-998
  • Legjobb erőfszítés: 1000
  • Burstable: min(max(2, 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)

Azok. azonos prioritás mellett a kubelet először a legjobb QoS osztályú podokat üríti ki a csomópontból.

Teljesítmény: ha csökkenteni szeretné annak valószínűségét, hogy erőforráshiány esetén a kívánt pod kikerüljön a csomópontból, akkor a prioritás mellett gondoskodnia kell a kérés/limit beállításáról is.

Mechanizmus az alkalmazási podok vízszintes automatikus skálázásához (HPA)

Amikor a feladat a podok számának automatikus növelése és csökkentése az erőforrások felhasználásától függően (rendszer - CPU/RAM vagy felhasználó - rps), akkor egy ilyen k8s entitás, mint pl. HPA (Horizontal Pod Autoscaler). Ennek algoritmusa a következő:

  1. Meghatározzák a megfigyelt erőforrás aktuális értékeit (currentMetricValue)
  2. Meghatározzák az erőforrás kívánt értékeit (desiredMetricValue), amelyeket a rendszererőforrásokhoz kéréssel állítanak be
  3. Meg van határozva a replikák aktuális száma (currentReplicas)
  4. A következő képlet kiszámítja a replikák kívánt számát (kívánt replikák)
    wishReplicas = [ currentReplicas * ( currentMetricValue / kívántMetricValue )]

Ebben az esetben a skálázás nem történik meg, ha az együttható (currentMetricValue / kívántMetricValue) közel van 1-hez (ebben az esetben magunk állíthatjuk be a megengedett hibát, alapértelmezés szerint 0.1).

Nézzük meg, hogyan működik a hpa az app-teszt alkalmazás példáján (leírása szerint Deployment), ahol a replikák számát a CPU-fogyasztástól függően módosítani kell:

  • Alkalmazásjegyzék

    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

    Azok. azt látjuk, hogy az alkalmazáscsomag kezdetben két példányban indul el, amelyek mindegyike két nginx és nginx-exporter tárolót tartalmaz, amelyek mindegyikéhez egy meghatározott kéri CPU számára.

  • HPA kiáltvány

    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

    Azok. Létrehoztunk egy hpa-t, amely figyeli a Deployment app-tesztet, és beállítja a podok számát az alkalmazással a cpu indikátor alapján (azt várjuk, hogy a pod a kért CPU 30%-át fogja fogyasztani), a replikák száma pedig a 2-10.

    Most nézzük meg a hpa működési mechanizmusát, ha az egyik kandallóra terhelést alkalmazunk:

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

Összességében az alábbiakkal rendelkezünk:

  • A kívánt érték (desiredMetricValue) - a hpa beállítások szerint 30%
  • Aktuális érték (currentMetricValue) - a számításhoz a vezérlő-menedzser kiszámítja az erőforrás-felhasználás átlagos értékét %-ban, azaz. feltételesen a következőket teszi:
    1. Megkapja a pod-metrikák abszolút értékeit a metrikaszervertől, pl. 101m és 4m
    2. Kiszámítja az átlagos abszolút értéket, pl. (101m + 4m) / 2 = 53m
    3. Lekéri a kívánt erőforrás-felhasználás abszolút értékét (ehhez az összes konténer igényét összegzik) 60m + 30m = 90m
    4. Kiszámítja a CPU-fogyasztás átlagos százalékos arányát a kérelem podhoz viszonyítva, azaz. 53 m / 90 m * 100% = 59%

Most már minden megvan, ami ahhoz kell, hogy meghatározzuk, meg kell-e változtatni a replikák számát; ehhez kiszámítjuk az együtthatót:

ratio = 59% / 30% = 1.96

Azok. a replikák számát ~2-szeresére kell növelni, és értéke [2 * 1.96] = 4.

Következtetés: Amint látható, a mechanizmus működéséhez szükséges feltétel a kérések jelenléte a megfigyelt podban lévő összes konténerre vonatkozóan.

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

A terhelési túlfeszültségek során a rendszerre gyakorolt ​​negatív hatások semlegesítésére nem elegendő egy konfigurált hpa. Például a hpa vezérlőkezelő beállításai szerint úgy dönt, hogy a replikák számát 2-szeresére kell növelni, de a csomópontoknak nincs szabad erőforrásuk ekkora számú pod futtatásához (azaz a csomópont nem tudja biztosítani a kért erőforrásokat a kérelmek sorba), és ezek a sorba rendezések függőben lévő állapotba kapcsolnak.

Ebben az esetben, ha a szolgáltató rendelkezik megfelelő IaaS/PaaS-szel (például GKE/GCE, AKS, EKS stb.), akkor egy olyan eszköz, mint pl. Node Autoscaler. Lehetővé teszi a fürtben lévő csomópontok maximális és minimális számának beállítását, és a csomópontok aktuális számának automatikus beállítását (a felhőszolgáltató API meghívásával egy csomópont megrendeléséhez/eltávolításához), ha erőforráshiány van a fürtben és a podokban. nem ütemezhetők (Függő állapotban vannak).

Következtetés: A csomópontok automatikus méretezése érdekében kéréseket kell beállítani a pod-tárolókban, hogy a k8s helyesen tudja felmérni a csomópontok terhelését, és ennek megfelelően jelenteni tudja, hogy a fürtben nincsenek erőforrások a következő pod indításához.

Következtetés

Megjegyzendő, hogy a tárolóerőforrás-korlátok beállítása nem feltétele az alkalmazás sikeres futtatásának, de a következő okok miatt mégis jobb ezt megtenni:

  1. Az ütemező pontosabb működéséhez a k8s csomópontok közötti terheléselosztás szempontjából
  2. A „hüvely kilakoltatási” esemény bekövetkezésének valószínűségének csökkentése érdekében
  3. Az alkalmazásdobozok vízszintes automatikus skálázásához (HPA) a működéshez
  4. Csomópontok vízszintes automatikus skálázásához (Cluster Autoscaling) felhőszolgáltatók számára

Olvassa el blogunk további cikkeit is:

Forrás: will.com

Hozzászólás