Kubernetes: miks on oluline seadistada sĂŒsteemi ressursside haldamine?

Tavaliselt on vajalik tagada rakendusele pĂŒhendatud ressursipool. Aga mis juhtub siis, kui ĂŒhel ja samal sĂŒsteemil töötab mitu rakendust? Kuidas tagada, et igaĂŒhel on minimaalselt vajalikud ressursid? Kuidas piirata ressursikasutust? Kuidas jaotada koormust node'ide vahel? Kuidas tagada horisontaalse skaleerimise mehhanismi töö, kui rakenduste koormus kasvab?

Kubernetes: miks on oluline seadistada sĂŒsteemi ressursside haldamine?

Peame alustama peamistest ressursitĂŒĂŒpidest, mis sĂŒsteemis eksisteerivad — need on loomulikult protsessorite aeg ja operatiivmĂ€lu. K8s manifestides mÔÔdetakse neid ressursitĂŒĂŒpe jĂ€rgmistes ĂŒhikutes:

  • CPU — tuumades
  • RAM — baitides

Iga ressursi jaoks on vĂ”imalik mÀÀrata kahte tĂŒĂŒpi nĂ”udeid — taotlused ja limits. Requests – mÀÀratleb minimaalsed nĂ”uded vabadelt node'i ressurssidelt konteineri (ja kogu poda) kĂ€ivitamiseks, samas kui limits kehtestab rangelt piiratud ressursid, mis on konteinerile kergesti kĂ€tte saadavad.

Oluline on mĂ”ista, et manifestis ei ole tingimata vajalik mĂ”lemaid tĂŒĂŒpe selgelt mÀÀratleda, kuid kĂ€itumine on jĂ€rgmine:

  • Kui ainult limits ressurssi selgelt mÀÀratletakse, siis requests selle ressursi jaoks vĂ”tab automaatselt vÀÀrtuse, mis on vĂ”rdne limits'iga (seda saab tĂ”estada, kutsudes esile kirjeldamise). See tĂ€hendab, et konteineri töö on piiratud sama ressursihulgaga, nagu ta ise oma kĂ€ivitamiseks nĂ”uab.
  • Kui ressursi jaoks on selgelt mÀÀratud ainult requests, siis ei kehtestata sellele ressursile ĂŒlemisi piiranguid — st konteiner on piiratud ainult node'i enda ressurssidega.

Samuti on vÔimalik seadistada ressursihalduse mitte ainult konkreetse konteineri, vaid ka nimeruumi tasandil, kasutades jÀrgmisi elemente:

  • LimitRange — kirjeldab poliitikat piirangute tasemel konteineris/podis ns ja on vajalik, et kirjeldada vaikimisi piiranguid konteineris/podis, samuti takistada juba rasvade konteinerite/podide loomist (vĂ”i vastupidi), piirata nende arvu ja mÀÀrata vĂ”imaliku erinevuse vÀÀrtuste vahel limits ja requests.
  • ResourceQuotas — kirjeldavad ressursipiirangu poliitikat ĂŒldiselt kĂ”ikide konteinerite jaoks ns ja kasutatakse enamasti ressursside eraldamiseks keskkondade vahel (kasulik, kui keskkonnad ei ole rangelt eristatud sĂ”lmede tasandil)

Allpool on toodud nÀidised manifestidest, kus kehtestatakse ressursipiirangud:

  • Konkreetse konteineri tasandil:

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

    See tÀhendab, et antud juhul on nginx konteineri kÀitamiseks vÀhemalt vajalik vabade 1G RAM ja 0.2 CPU olemasolu sÔlmes, samas kui konteiner vÔib maksimaalselt kasutada 0.2 CPU ja kogu vabast RAM-st sÔlmes.

  • Kogu ns tasandil:

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

    See tĂ€hendab, et kĂ”ikide defauldis ns konteinerite requestide summa ei tohi ĂŒletada 300m CPU ja 1G RAM, samas kui limitide summa ei tohi ĂŒletada 700m CPU ja 2G RAM.

  • Default piirangud konteinerite jaoks 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

    See tĂ€hendab, et kĂ”ikide konteinerite jaoks default ns-is kehtestatakse request 100m CPU ja 1G RAM, limit – 1 CPU ja 2G. Samuti on seatud piirangud CPU (50m < x < 2) ja RAM (500M < x < 4G) requestide ja limitide vĂ”imalikele vÀÀrtustele.

  • Piirangud podide tasandil ns:

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

    See tÀhendab, et igas podis default ns-is kehtestatakse piirang 4 vCPU ja 1G.

NĂŒĂŒd sooviksin rÀÀkida, milliseid eeliseid vĂ”ivad need piirangud meile tuua.

Koormuse tasakaalustamise mehhanism sÔlmede vahel

Nagu teada, vastutab podide jaotumise eest sÔlmedes selline komponent nagu k8s scheduler, mis töötab teatud algoritmi alusel. See algoritm valib optimaalse sÔlme jaoks kÀivitamist kahes etapis:

  1. Filtreeimine
  2. Hinnang

See tĂ€hendab, et kirjelduse jĂ€rgi valitakse alguses need sĂ”lmed, kus podi kĂ€itamine on vĂ”imalik vastavalt kogumile predicates (sealhulgas kontrollitakse, kas sĂ”lmel on piisavalt ressursse podi kĂ€itamiseks — PodFitsResources), ja seejĂ€rel hinnatakse igat neist sĂ”lmedest vastavalt priorities punkte antakse (sealhulgas, mida rohkem vabu ressursse on sĂ”lmes – seda rohkem punkte sellele antakse – LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation) ja see kĂ€ivitatakse sĂ”lmes, millel on kĂ”ige rohkem punkte (kui sellele tingimusele vastab korraga mitu sĂ”lme, valitakse juhuslikult ĂŒks neist).

Siinkohal on oluline mĂ”ista, et scheduler hindab sĂ”lme saadaval olevaid ressursse andmete pĂ”hjal, mis on salvestatud etcd-s – st iga sĂ”lmes kĂ€ivitatud konteineri requested/limit ressursi summa, mitte ressursside tegeliku tarbimise pĂ”hjal. Selle teabe saab kĂ€skluse vĂ€ljundist. kubectl describe node $NODE, nĂ€iteks:

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

Siit nĂ€eme kĂ”iki konteinerite, mis on kĂ€ivitatud konkreetse sĂ”lme peal, ning ka ressursse, mida iga konteiner kĂŒsib. Ja siin on scheduler'i logid, kui kĂ€ivitada konteiner cronjob-cron-events-1573793820-xt6q9 (see teave scheduler'i logides ilmub, kui logimise tasemeks on seatud 10. tase kĂ€ivitamise kĂ€su argumentides –v=10):

logi

I1115 07:57:21.637791       1 scheduling_queue.go:908] Proovime planeerida pod'i nxs-stage/cronjob-cron-events-1573793820-xt6q9.                                                                                          
I1115 07:57:21.637804       1 scheduler.go:453] Üritame planeerida pod'i: nxs-stage/cronjob-cron-events-1573793820-xt6q9.                                                                                          
I1115 07:57:21.638285       1 predicates.go:829] Pod'i nxs-stage/cronjob-cron-events-1573793820-xt6q9 planeerimine sÔlmele nxs-k8s-s5 on lubatud, sÔlm töötab ainult 16 pod'ist 110.                                                                 
I1115 07:57:21.638300       1 predicates.go:829] Pod'i nxs-stage/cronjob-cron-events-1573793820-xt6q9 planeerimine sÔlmele nxs-k8s-s6 on lubatud, sÔlm töötab ainult 20 pod'ist 110.                                                                 
I1115 07:57:21.638322       1 predicates.go:829] Pod'i nxs-stage/cronjob-cron-events-1573793820-xt6q9 planeerimine sÔlmele nxs-k8s-s3 on lubatud, sÔlm töötab ainult 20 pod'ist 110.                                                                 
I1115 07:57:21.638322       1 predicates.go:829] Pod'i nxs-stage/cronjob-cron-events-1573793820-xt6q9 planeerimine sÔlmele nxs-k8s-s4 on lubatud, sÔlm töötab ainult 17 pod'ist 110.                                                                 
I1115 07:57:21.638334       1 predicates.go:829] Pod'i nxs-stage/cronjob-cron-events-1573793820-xt6q9 planeerimine sÔlmele nxs-k8s-s10 on lubatud, sÔlm töötab ainult 16 pod'ist 110.                                                                
I1115 07:57:21.638365       1 predicates.go:829] Pod'i nxs-stage/cronjob-cron-events-1573793820-xt6q9 planeerimine sÔlmele nxs-k8s-s12 on lubatud, sÔlm töötab ainult 9 pod'ist 110.                                                               
I1115 07:57:21.638334       1 predicates.go:829] Pod'i nxs-stage/cronjob-cron-events-1573793820-xt6q9 planeerimine sÔlmele nxs-k8s-s11 on lubatud, sÔlm töötab ainult 11 pod'ist 110.                                                               
I1115 07:57:21.638385       1 predicates.go:829] Pod'i nxs-stage/cronjob-cron-events-1573793820-xt6q9 planeerimine sÔlmele nxs-k8s-s1 on lubatud, sÔlm töötab ainult 19 pod'ist 110.                                                               
I1115 07:57:21.638402       1 predicates.go:829] Pod'i nxs-stage/cronjob-cron-events-1573793820-xt6q9 planeerimine sÔlmele nxs-k8s-s2 on lubatud, sÔlm töötab ainult 21 pod'ist 110.                                                               
I1115 07:57:21.638383       1 predicates.go:829] Pod'i nxs-stage/cronjob-cron-events-1573793820-xt6q9 planeerimine sÔlmele nxs-k8s-s9 on lubatud, sÔlm töötab ainult 16 pod'ist 110.                                                               
I1115 07:57:21.638335       1 predicates.go:829] Pod'i nxs-stage/cronjob-cron-events-1573793820-xt6q9 planeerimine sÔlmele nxs-k8s-s8 on lubatud, sÔlm töötab ainult 18 pod'ist 110.                                                               
I1115 07:57:21.638408       1 predicates.go:829] Pod'i nxs-stage/cronjob-cron-events-1573793820-xt6q9 planeerimine sÔlmele nxs-k8s-s13 on lubatud, sÔlm töötab ainult 8 pod'ist 110.                                                               
I1115 07:57:21.638478       1 predicates.go:1369] Pod'i nxs-stage/cronjob-cron-events-1573793820-xt6q9 planeerimine sÔlmele nxs-k8s-s10 on lubatud, olemasolevate pod'ide anti-afitiini tingimused on tÀidetud.                                                                                                               
I1115 07:57:21.638505       1 predicates.go:1369] Pod'i nxs-stage/cronjob-cron-events-1573793820-xt6q9 planeerimine sÔlmele nxs-k8s-s8 on lubatud, olemasolevate pod'ide anti-afitiini tingimused on tÀidetud.                                                                                                               
I1115 07:57:21.638577       1 predicates.go:1369] Pod'i nxs-stage/cronjob-cron-events-1573793820-xt6q9 planeerimine sÔlmele nxs-k8s-s9 on lubatud, olemasolevate pod'ide anti-afitiini tingimused on tÀidetud.                                                                                                               
I1115 07:57:21.638583       1 predicates.go:829] Pod'i nxs-stage/cronjob-cron-events-1573793820-xt6q9 planeerimine sÔlmele nxs-k8s-s7 on lubatud, sÔlm töötab ainult 25 pod'ist 110.                                                               
I1115 07:57:21.638932       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: Tasakaalustatud ressursijaotus, maht 39900 millikoore 66620178432 mÀlubaiti, koguur 2343 millikoore 9640186880 mÀlubaiti, punktid 9        
I1115 07:57:21.638946       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: VÀhenenud ressursi jaotamine, maht 39900 millikoore 66620178432 mÀlubaiti, koguur 2343 millikoore 9640186880 mÀlubaiti, punktid 8           
I1115 07:57:21.638961       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: Tasakaalustatud ressursijaotus, maht 39900 millikoore 66620170240 mÀlubaiti, koguur 4107 millikoore 11307422720 mÀlubaiti, punktid 9        
I1115 07:57:21.638971       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: Tasakaalustatud ressursijaotus, maht 39900 millikoore 66620178432 mÀlubaiti, koguur 5847 millikoore 24333637120 mÀlubaiti, punktid 7        
I1115 07:57:21.638975       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: VÀhenenud ressursi jaotamine, maht 39900 millikoore 66620170240 mÀlubaiti, koguur 4107 millikoore 11307422720 mÀlubaiti, punktid 8           
I1115 07:57:21.638990       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: VÀhenenud ressursi jaotamine, maht 39900 millikoore 66620178432 mÀlubaiti, koguur 5847 millikoore 24333637120 mÀlubaiti, punktid 7           
I1115 07:57:21.639022       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: TaintTolerationPriority, Punkte: (10)                                                                                              
I1115 07:57:21.639030       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: TaintTolerationPriority, Punkte: (10)                                                                                               
I1115 07:57:21.639034       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: TaintTolerationPriority, Punkte: (10)                                                                                               
I1115 07:57:21.639041       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: NodeAffinityPriority, Punkte: (0)                                                                                                            
I1115 07:57:21.639053       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: NodeAffinityPriority, Punkte: (0)                                                                                                             
I1115 07:57:21.639059       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: NodeAffinityPriority, Punkte: (0)                                                                                                             
I1115 07:57:21.639061       1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: InterPodAffinityPriority, Punkte: (0)                                                                                                                   
I1115 07:57:21.639063       1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: SelectorSpreadPriority, Punkte: (10)                                                                                                                   
I1115 07:57:21.639073       1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: InterPodAffinityPriority, Punkte: (0)                                                                                                                    
I1115 07:57:21.639077       1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: SelectorSpreadPriority, Punkte: (10)                                                                                                                    
I1115 07:57:21.639085       1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: InterPodAffinityPriority, Punkte: (0)                                                                                                                    
I1115 07:57:21.639088       1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: SelectorSpreadPriority, Punkte: (10)                                                                                                                    
I1115 07:57:21.639103       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: SelectorSpreadPriority, Punkte: (10)                                                                                                           
I1115 07:57:21.639109       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: SelectorSpreadPriority, Punkte: (10)                                                                                                            
I1115 07:57:21.639114       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: SelectorSpreadPriority, Punkte: (10)                                                                                                            
I1115 07:57:21.639127       1 generic_scheduler.go:781] Host nxs-k8s-s10 => Punktid 100037                                                                                                                                                                        
I1115 07:57:21.639150       1 generic_scheduler.go:781] Host nxs-k8s-s8 => Punktid 100034                                                                                                                                                                         
I1115 07:57:21.639154       1 generic_scheduler.go:781] Host nxs-k8s-s9 => Punktid 100037                                                                                                                                                                         
I1115 07:57:21.639267       1 scheduler_binder.go:269] AssumePodVolumes pod'i "nxs-stage/cronjob-cron-events-1573793820-xt6q9" jaoks, sÔlm "nxs-k8s-s10"                                                                                                               
I1115 07:57:21.639286       1 scheduler_binder.go:279] AssumePodVolumes pod'i "nxs-stage/cronjob-cron-events-1573793820-xt6q9" jaoks, sĂ”lm "nxs-k8s-s10": kĂ”ik PVC-d on ĂŒhendatud ja muud ei ole teha                                                                             
I1115 07:57:21.639333       1 factory.go:733] Üritame siduda cronjob-cron-events-1573793820-xt6q9 sĂ”lmele nxs-k8s-s10.

Siin nĂ€eme, et esialgu filtrib scheduler ning koostab nimekirja kolmest node'ist, kus kĂ€ivitamine on vĂ”imalik (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10). SeejĂ€rel arvutab see igasuguste parameetrite (sealhulgas BalancedResourceAllocation, LeastResourceAllocation) pĂ”hjal punktid nende node'ite jaoks, et mÀÀrata vĂ€lja sobivaim sĂ”lm. LĂ”puks plaanitakse kĂ”ige rohkem punkte saanud node'ile (siin on kohe kaks node'it, millel on sama punktide arv 100037, seega valitakse neist juhuslik — nxs-k8s-s10).

KokkuvĂ”teKui nodis töötavad podid, millele ei ole piiranguid mÀÀratud, on see k8s jaoks (ressursside tarbimise seisukohalt) sama, nagu oleks need podid sellel nodil tĂ€ielikult puuduvad. SeetĂ”ttu, kui teil on nĂ€iteks pod koos nĂ€ljase protsessiga (nt wowza), millele piiranguid ei ole mÀÀratud, vĂ”ib tekkida olukord, kus see pod tarbib kĂ”ik node'i ressursid, kuid k8s jaoks loetakse see node mittekoormatud ning sellele antakse sama palju punkte reastamisel (just nende ressursside hindamise punktides), kui node'ile, kus ei ole töötavaid pode, mis vĂ”ib lĂ”puks viia ebaĂŒhtlase koormuse jaotumiseni node'ite vahel.

Podi vÀlja tÔukamine

Nagu teada, antakse igale podile ĂŒks kolmest QoS-klassi:

  1. guaranuted kui iga konteineri jaoks podis on mÀÀratud memory ja cpu request ja limit ning need vÀÀrtused peavad olema vÔrdsed
  2. burstable kui vĂ€hemalt ĂŒhel konteineril podis on mÀÀratud request ja limit, kusjuures request < limit
  3. best effort kui ĂŒkski konteiner podis ei ole ressursside osas piiratud

Kui nodis on ressursid (ketas, mÀlu) lÔppenud, hakkab kubelet jÀrjestama ja vÀlja tÔukama pode teatud algoritmi alusel, mis arvestab podi prioriteeti ja selle QoS-klassi. NÀiteks, kui tegemist on RAM-iga, siis QoS-klassi alusel antakse punkte jÀrgmise pÔhimÔtte kohaselt:

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

See tÀhendab, et sama prioriteedi korral hakkab kubelet esmalt vÀlja tÔukama node'ist pode, mille QoS-klassi on best effort.

KokkuvÔte: kui soovite vÀhendada vajaliku podi vÀlja tÔukamise tÔenÀosust node'ist ressursipuuduse korral, peate lisaks prioriteedile hoolitsema ka request/limit mÀÀramise eest.

Rakenduse poodide horisontaalne automaatne skaleerimine (HPA)

Kui eesmĂ€rk on automaatselt suurendada ja vĂ€hendada poodide arvu sĂ”ltuvalt ressursikasutuse (sĂŒsteemi — CPU/RAM vĂ”i kasutaja — rps) nĂ”udest, vĂ”ib selle lahenduses aidata selline k8s element nagu HPA (Horisontaalne Pod Automaatskaalija). Selle algoritm pĂ”hineb jĂ€rgmisel:

  1. MÀÀratakse jÀlgitava ressursi praegused nÀidud (currentMetricValue)
  2. MÀÀratakse soovitud vÀÀrtused ressursi jaoks (desiredMetricValue), mis sĂŒsteemsete ressursside puhul mÀÀratakse request'ide abil
  3. MÀÀratakse praegune replikate arv (currentReplicas)
  4. JĂ€rgmise valemi abil arvutatakse soovitud replikate arv (desiredReplicas)
    desiredReplicas = [ currentReplicas * ( currentMetricValue / desiredMetricValue )]

Sel juhul ei toimu skaleerimist, kui koefitsient (currentMetricValue / desiredMetricValue) on lÀhedal 1 (samal ajal saame ise mÀÀrata lubatud tÀpsuse, mis vaikimisi on 0.1).

Vaatame hpa tööd rakenduse app-test nÀite pÔhjal (mida on kirjeldatud kui Deployment), kus on vajalik muuta replikate arvu sÔltuvalt CPU tarbimisest:

  • Rakenduse manifest

    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

    Kuna nĂ€eme, et rakenduse pood kĂ€ivitatakse algselt kahes eksemplaris, millest igas on kaks konteinerit nginx ja nginx-exporter, millest igaĂŒhele on mÀÀratud taotlused CPU jaoks.

  • HPA manifest

    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

    Kuna oleme loonud hpa, mis jÀlgib Deployment app-test ja reguleerib rakenduse poodide arvu CPU nÀidu pÔhjal (oodame, et pood peaks tarbima 30% oma taotletud CPU-st), samal ajal on replikate arv vahemikus 2-10.

    NĂŒĂŒd vaatame hpa töömehhanismi, kui koormust rakendada ĂŒhele poodidest:

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

KokkuvÔtteks saame jÀrgmise:

  • Soovitud vÀÀrtus (desiredMetricValue) - vastavalt hpa seadevale on see 30%
  • Praegune vÀÀrtus (currentMetricValue) - controller-manager arvutab keskmise ressursikasutuse protsentides, st teisisĂ”nu teeb jĂ€rgmist:
    1. Saab podide mÔÔdikute absoluutvÀÀrtused metric-serverist, st 101m ja 4m
    2. Arvutab keskmise absoluutvÀÀrtuse, st (101m + 4m) / 2 = 53m
    3. Saab absoluutvÀÀrtuse soovitud ressursikasutuse jaoks (selleks summeeritakse kÔigi konteinerite request'id) 60m + 30m = 90m
    4. Arvutab keskmise CPU kasutuse protsendi vÔrreldes podi request'iga, st 53m / 90m * 100% = 59%

NĂŒĂŒd on meil kĂ”ik vajalikud andmed, et mÀÀrata, kas replikate arvu on vaja muuta, selleks arvutame koefitsiendi:

ratio = 59% / 30% = 1.96

St, replikate arvu tuleks suurendada umbes 2 korda ja see peaks olema [2 * 1.96] = 4.

KokkuvÔte: Nagu on mÀrgata, et selle mehhanismi tööks on vajalik tingimus ka see, et kÔikide konteinerite jaoks on podis olemas request'id.

Horisontraalne automaatne skaleerimise mehhanism (Cluster Autoscaler)

Kuna negatiivse mĂ”ju vĂ€hendamiseks sĂŒsteemile koormuse tĂ”usude ajal ei pruugi seadistatud hpa olla piisav. NĂ€iteks hpa seadeid jĂ€rgides otsustab controller manager, et replikate arvu tuleb suurendada 2 korda, kuid node'idel ei ole piisavaid ressursse selliste podide kĂ€itamiseks (st node ei saa pakkuda podi request'eid) ja need podid lĂ€hevad Pending olekusse.

Sellisel juhul, kui teenusepakkujal on vastav IaaS/PaaS (nt GKE/GCE, AKS, EKS jne), vÔib meid aidata selline tööriist nagu Node Autoscaler. See vÔimaldab seadistada klastris maksimaalse ja minimaalse node'ite arvu ning automaatselt reguleerida praegust node'ite arvu (tehes API kÔnesid pilveteenuse pakkujaga node tellimiseks/kustutamiseks), kui klastris on ressursipuudus ja podid ei saa plaanitud (on Pending olekus).

KokkuvÔte: Noodide automaatseks skaleerimiseks on vajalik mÀÀrata konteinerite request'id podides, et k8s saaks Ôigesti hinnata node'ite koormust ja vastavalt teavitada, et klastris ei ole ressursse jÀrgmise podi kÀitamiseks.

KokkuvÔte

Tuleb mÀrkida, et konteineri ressursipiirangute seadmine ei ole rakenduse edukaks kÀivitamiseks vajalik, kuid see on siiski soovitatav jÀrgmistel pÔhjustel:

  1. Selleks, et scheduler töötaks tÀpsemalt k8s sÔlmede koormuse tasakaalustamise osas.
  2. Selleks, et vÀhendada tÔenÀosust, et tekib "pod'i vÀljatÔstmine".
  3. Selleks, et toimiks rakenduse podide horisontaalne automaatne skaleerimine (HPA).
  4. Selleks, et toimiks pilvepakkujate sÔlmede horisontaalne automaatne skaleerimine (Cluster Autoscaling).

Vaata ka teisi artikleid meie blogis:

Allikas: habr.com

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster