Kubernetes: kāpēc ir tik svarīgi konfigurēt sistēmas resursu pārvaldību?

Parasti vienmēr ir nepiecieÅ”ams nodroÅ”ināt Ä«paÅ”u resursu kopumu lietojumprogrammai, lai tā darbotos pareizi un stabili. Bet ko darÄ«t, ja vairākas lietojumprogrammas darbojas ar vienu jaudu? Kā nodroÅ”ināt katru no tiem minimāli nepiecieÅ”amos resursus? Kā jÅ«s varat ierobežot resursu patēriņu? Kā pareizi sadalÄ«t slodzi starp mezgliem? Kā nodroÅ”ināt horizontālā mērogoÅ”anas mehānisma darbÄ«bu, ja palielinās lietojumprogrammu slodze?

Kubernetes: kāpēc ir tik svarīgi konfigurēt sistēmas resursu pārvaldību?

Jums jāsāk ar to, kādi galvenie resursu veidi pastāv sistēmā - tas, protams, ir procesora laiks un RAM. K8s manifestos Å”ie resursu veidi tiek mērÄ«ti Ŕādās vienÄ«bās:

  • CPU - kodolos
  • RAM - baitos

Turklāt katram resursam ir iespējams noteikt divu veidu prasÄ«bas - pieprasÄ«jumi Šø ierobežojumi. PieprasÄ«jumi ā€” apraksta minimālās prasÄ«bas mezgla brÄ«vajiem resursiem, lai palaistu konteineru (un apkopi kopumā), savukārt ierobežojumi nosaka stingru konteineram pieejamo resursu ierobežojumu.

Ir svarÄ«gi saprast, ka manifestā nav skaidri jādefinē abi veidi, taču uzvedÄ«ba bÅ«s Ŕāda:

  • Ja ir skaidri norādÄ«ti tikai resursa ierobežojumi, Ŕī resursa pieprasÄ«jumi automātiski iegÅ«st vērtÄ«bu, kas vienāda ar ierobežojumiem (to varat pārbaudÄ«t, izsaucot apraksta entÄ«tijas). Tie. faktiski konteiners tiks ierobežots lÄ«dz tādam paÅ”am resursu daudzumam, kas nepiecieÅ”ams tā darbÄ«bai.
  • Ja resursam ir skaidri norādÄ«ti tikai pieprasÄ«jumi, tad Å”im resursam netiek noteikti augŔējie ierobežojumi - t.i. konteineru ierobežo tikai paÅ”a mezgla resursi.

Ir iespējams arÄ« konfigurēt resursu pārvaldÄ«bu ne tikai konkrēta konteinera lÄ«menÄ«, bet arÄ« nosaukumvietas lÄ«menÄ«, izmantojot Ŕādas entÄ«tijas:

  • LimitRange ā€” apraksta ierobežojumu politiku konteinera/podiņu lÄ«menÄ« ns un ir nepiecieÅ”ama, lai aprakstÄ«tu noklusējuma ierobežojumus konteineram/podiņam, kā arÄ« novērstu acÄ«mredzami treknu tvertņu/podiņu izveidi (vai otrādi), ierobežotu to skaitu un noteikt iespējamo robežu un pieprasÄ«jumu vērtÄ«bu atŔķirÄ«bu
  • Resursu kvotas ā€” vispārÄ«gi aprakstiet ierobežojumu politiku visiem ns konteineriem, un to parasti izmanto, lai norobežotu resursus starp vidēm (noderÄ«ga, ja vide nav stingri norobežota mezgla lÄ«menÄ«)

Tālāk ir sniegti manifestu piemēri, kas nosaka resursu ierobežojumus.

  • Konkrētā konteinera lÄ«menÄ«:

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

    Tie. Å”ajā gadÄ«jumā, lai palaistu konteineru ar nginx, mezglā bÅ«s nepiecieÅ”ams vismaz 1 G brÄ«vas RAM un 0.2 CPU, savukārt konteiners var patērēt ne vairāk kā 0.2 CPU un visu mezglā pieejamo RAM.

  • Vesela skaitļa lÄ«menÄ« ns:

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

    Tie. visu pieprasÄ«jumu konteineru summa noklusējuma ns nevar pārsniegt 300 m CPU un 1 G operatoram, un visu ierobežojumu summa ir 700 m CPU un 2 G operatoram.

  • Noklusējuma ierobežojumi konteineriem 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. noklusējuma nosaukumvietā visiem konteineriem pieprasÄ«jums tiks iestatÄ«ts uz 100 m CPU un 1 G operatoram, ierobežojums ā€” 1 CPU un 2G. Tajā paŔā laikā tiek iestatÄ«ts arÄ« ierobežojums iespējamām vērtÄ«bām CPU (50m < x < 2) un RAM (500M < x < 4G) pieprasÄ«jumā/limitā.

  • Pod lÄ«meņa ierobežojumi ns:

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

    Tie. katram podam noklusējuma ns būs 4 vCPU un 1G ierobežojums.

Tagad es vēlētos jums pastāstÄ«t, kādas priekÅ”rocÄ«bas mums var sniegt Å”o ierobežojumu noteikÅ”ana.

Slodzes līdzsvaroŔanas mehānisms starp mezgliem

Kā zināms, k8s komponents ir atbildÄ«gs par podiņu sadali starp mezgliem, piemēram plānotājs, kas darbojas pēc noteikta algoritma. Izvēloties optimālo palaiÅ”anas mezglu, Å”is algoritms iziet divus posmus:

  1. filtrēŔana
  2. RādīŔana

Tie. saskaņā ar aprakstÄ«to politiku sākotnēji tiek atlasÄ«ti mezgli, uz kuriem ir iespējams palaist podziņu, pamatojoties uz komplektu predikāti (tostarp pārbaudi, vai mezglam ir pietiekami daudz resursu, lai palaistu podziņu ā€” PodFitsResources), un pēc tam katram no Å”iem mezgliem saskaņā ar prioritātes tiek pieŔķirti punkti (tostarp, jo vairāk mezglam ir brÄ«vu resursu, jo vairāk punktu tam tiek pieŔķirts - LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation) un pods tiek palaists mezglā ar visvairāk punktu (ja vairāki mezgli vienlaikus atbilst Å”im nosacÄ«jumam, tad tiek izvēlēts nejauÅ”s).

Tajā paŔā laikā jums ir jāsaprot, ka plānotājs, novērtējot mezgla pieejamos resursus, vadās pēc datiem, kas tiek glabāti etcd - t.i. par pieprasÄ«tā/limita resursa apjomu katrā podā, kas darbojas Å”ajā mezglā, bet ne par faktisko resursu patēriņu. Å o informāciju var iegÅ«t no komandas izejas kubectl describe node $NODE, piemēram:

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

Å eit redzami visi podi, kas darbojas noteiktā mezglā, kā arÄ« resursi, ko katrs pods pieprasa. LÅ«k, kā izskatās plānotāja žurnāli, kad tiek palaists cronjob-cron-events-1573793820-xt6q9 pod (Ŕī informācija tiks parādÄ«ta plānotāja žurnālā, kad startÄ“Å”anas komandas argumentos -v=10 iestatÄ«siet 10. reÄ£istrÄ“Å”anas lÄ«meni):

žurnāls

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

Å eit mēs redzam, ka sākotnēji plānotājs filtrē un Ä£enerē sarakstu ar 3 mezgliem, kuros to var palaist (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10). Pēc tam tas aprēķina punktus, pamatojoties uz vairākiem parametriem (tostarp BalancedResourceAllocation, LeastResourceAllocation) katram no Å”iem mezgliem, lai noteiktu vispiemērotāko mezglu. Galu galā pods tiek ieplānots mezglā ar lielāko punktu skaitu (Å”eit diviem mezgliem vienlaikus ir vienāds punktu skaits 100037, tāpēc tiek izvēlēts nejauÅ”s - nxs-k8s-s10).

secinājums: ja mezglā darbojas podi, kuriem nav noteikti ierobežojumi, tad k8s (no resursu patēriņa viedokļa) tas bÅ«s lÄ«dzvērtÄ«gi tam, it kā uz Ŕī mezgla Ŕādu podiņu nebÅ«tu vispār. Tāpēc, ja jums nosacÄ«ti ir pods ar rijÄ«gu procesu (piemēram, wowza) un tam nav noteikti ierobežojumi, tad var rasties situācija, kad Å”is pods faktiski apēda visus mezgla resursus, bet k8s Å”is mezgls tiek uzskatÄ«ts par nenoslogotu, un tam tiks pieŔķirts vienāds punktu skaits, klasificējot (precÄ«zi punktos, novērtējot pieejamos resursus) kā mezglu, kuram nav strādājoÅ”u podiņu, kas galu galā var izraisÄ«t nevienmērÄ«gu slodzes sadalÄ«jumu starp mezgliem.

Podas izlikŔana

Kā jÅ«s zināt, katram podam ir pieŔķirta viena no 3 QoS klasēm:

  1. garantēta ā€” tiek pieŔķirts, ja katram podā esoÅ”ajam konteineram ir norādÄ«ts pieprasÄ«jums un ierobežojums atmiņai un centrālajam procesoram, un Ŕīm vērtÄ«bām ir jāsakrÄ«t
  2. pārsprāgstoÅ”s ā€” vismaz vienam konteineram podā ir pieprasÄ«jums un ierobežojums ar pieprasÄ«jumu < limits
  3. labākās pÅ«les ā€” ja nevienam podam esoÅ”ajam konteineram nav ierobežoti resursi

Tajā paŔā laikā, kad mezglam trÅ«kst resursu (diska, atmiņas), kubelet sāk ranžēt un izlikt podi saskaņā ar noteiktu algoritmu, kas ņem vērā pod prioritāti un tā QoS klasi. Piemēram, ja mēs runājam par RAM, tad, pamatojoties uz QoS klasi, punkti tiek pieŔķirti pēc Ŕāda principa:

  • Garantētā: -998
  • BestEffort: 1000
  • PārsprāgstoÅ”s: min(maks.(2, 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)

Tie. ar tādu paŔu prioritāti, kubelet vispirms izliks no mezgla apvidus ar vislabāko QoS klasi.

secinājums: ja vēlaties samazināt iespēju, ka vēlamais pods tiks izlikts no mezgla, ja tam trÅ«kst resursu, tad lÄ«dzās prioritātei ir jāparÅ«pējas arÄ« par pieprasÄ«juma/limita iestatÄ«Å”anu tam.

Mehānisms aplikāciju bloku horizontālai automātiskai mērogoÅ”ana (HPA)

Kad uzdevums ir automātiski palielināt un samazināt podiņu skaitu atkarÄ«bā no resursu izmantoÅ”anas (sistēma - CPU/RAM vai lietotājs - rps), tāda k8s entÄ«tija kā HPA (Horizontal Pod Autoscaler). Kuras algoritms ir Ŕāds:

  1. Tiek noteikti novērotā resursa paÅ”reizējie rādÄ«jumi (currentMetricValue)
  2. Resursam tiek noteiktas vēlamās vērtības (desiredMetricValue), kuras sistēmas resursiem tiek iestatītas, izmantojot pieprasījumu
  3. Ir noteikts paÅ”reizējais repliku skaits (currentReplicas)
  4. Šī formula aprēķina vēlamo repliku skaitu (vēlamās replikas)
    wishReplicas = [ currentReplicas * ( currentMetricValue / wishMetricValue )]

Å ajā gadÄ«jumā mērogoÅ”ana nenotiks, ja koeficients (currentMetricValue / wishMetricValue) ir tuvu 1 (Å”ajā gadÄ«jumā mēs paÅ”i varam iestatÄ«t pieļaujamo kļūdu; pēc noklusējuma tā ir 0.1).

ApskatÄ«sim, kā hpa darbojas, izmantojot lietotņu testa lietojumprogrammas piemēru (aprakstÄ«ts kā Deployment), kur nepiecieÅ”ams mainÄ«t repliku skaitu atkarÄ«bā no CPU patēriņa:

  • Lietojumprogrammas manifests

    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. mēs redzam, ka lietojumprogrammu komplekts sākotnēji tiek palaists divos gadījumos, no kuriem katrā ir divi nginx un nginx-eksportētāja konteineri, kuriem katram ir norādīts pieprasījumi CPU.

  • HPA manifests

    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. Mēs izveidojām hpa, kas uzraudzÄ«s izvietoÅ”anas lietotnes testu un pielāgos aplikāciju skaitu ar lietojumprogrammu, pamatojoties uz CPU indikatoru (mēs sagaidām, ka podam vajadzētu patērēt 30% no tā pieprasÄ«tā CPU), reprodukciju skaitam ir diapazons no 2-10.

    Tagad apskatīsim hpa darbības mehānismu, ja vienam no pavardiem pieliekam slodzi:

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

Kopumā mums ir Ŕādas lietas:

  • Vēlamā vērtÄ«ba (desiredMetricValue) - saskaņā ar hpa iestatÄ«jumiem mums ir 30%
  • PaÅ”reizējā vērtÄ«ba (currentMetricValue) - aprēķinam kontrolieris-pārzinis aprēķina resursu patēriņa vidējo vērtÄ«bu %, t.i. nosacÄ«ti veic Ŕādas darbÄ«bas:
    1. Saņem absolūtās apvidus metrikas vērtības no metrikas servera, t.i. 101m un 4m
    2. Aprēķina vidējo absolÅ«to vērtÄ«bu, t.i. (101 m + 4 m) / 2 = 53 m
    3. Iegūst absolūto vērtību vēlamajam resursu patēriņam (tam tiek summēti visu konteineru pieprasījumi) 60m + 30m = 90m
    4. Aprēķina vidējo CPU patēriņa procentuālo daļu attiecÄ«bā pret pieprasÄ«jumu pod, t.i. 53 m / 90 m * 100% = 59%

Tagad mums ir viss nepiecieÅ”amais, lai noteiktu, vai mums ir jāmaina kopiju skaits; lai to izdarÄ«tu, mēs aprēķinām koeficientu:

ratio = 59% / 30% = 1.96

Tie. kopiju skaits jāpalielina ~2 reizes un jāsasniedz [2 * 1.96] = 4.

Secinājums: Kā redzat, lai Å”is mehānisms darbotos, nepiecieÅ”ams nosacÄ«jums ir pieprasÄ«jumu klātbÅ«tne visiem konteineriem novērotajā podā.

Mezglu horizontālās automātiskās mērogoÅ”anas mehānisms (Cluster Autoscaler)

Lai neitralizētu negatÄ«vo ietekmi uz sistēmu slodzes pieauguma laikā, nepietiek ar konfigurētu hpa. Piemēram, saskaņā ar hpa kontrollera pārvaldnieka iestatÄ«jumiem tas nolemj, ka reprodukciju skaits ir jāpalielina 2 reizes, bet mezgliem nav brÄ«vu resursu, lai palaistu tik daudz podiņu (t.i., mezgls nevar nodroÅ”ināt pieprasÄ«tie resursi uz pieprasÄ«jumu aplikumu), un Å”ie aplikumi pārslēdzas uz gaidÄ«Å”anas stāvokli.

Å ajā gadÄ«jumā, ja pakalpojumu sniedzējam ir atbilstoÅ”s IaaS/PaaS (piemēram, GKE/GCE, AKS, EKS utt.), rÄ«ks, piemēram, Node Autoscaler. Tas ļauj iestatÄ«t maksimālo un minimālo mezglu skaitu klasterÄ« un automātiski pielāgot paÅ”reizējo mezglu skaitu (izsaucot mākoņa pakalpojumu sniedzēja API, lai pasÅ«tÄ«tu/noņemtu mezglu), ja klasterÄ« un podiņos trÅ«kst resursu. nevar ieplānot (ir gaidÄ«Å”anas stāvoklÄ«).

Secinājums: Lai varētu veikt mezglu automātisko mērogoÅ”anu, ir jāiestata pieprasÄ«jumi pod konteineros, lai k8s varētu pareizi novērtēt mezglu slodzi un attiecÄ«gi ziņot, ka klasterÄ« nav resursu, lai palaistu nākamo pod.

Secinājums

Jāņem vērā, ka konteinera resursu ierobežojumu iestatÄ«Å”ana nav obligāta prasÄ«ba, lai lietojumprogramma darbotos veiksmÄ«gi, taču labāk to darÄ«t Ŕādu iemeslu dēļ:

  1. PrecÄ«zākai plānotāja darbÄ«bai slodzes lÄ«dzsvaroÅ”anas ziņā starp k8s mezgliem
  2. Lai samazinātu iespējamÄ«bu, ka notiks ā€œpodiņu izlikÅ”anaā€.
  3. Lietojumprogrammu bloku (HPA) horizontālajai automātiskajai mērogoÅ”anas darbÄ«bai
  4. Mezglu horizontālajai automātiskajai mērogoÅ”anai (Cluster Autoscaling) mākoņpakalpojumu sniedzējiem

Lasiet arī citus rakstus mūsu emuārā:

Avots: www.habr.com

Pievieno komentāru