Kubernetes: Firwat ass et sou wichteg System Ressource Gestioun ze konfiguréieren?

Als Regel, ass et ëmmer e Besoin fir eng engagéierten Pool vu Ressourcen fir eng Applikatioun fir seng korrekt a stabil Operatioun ze bidden. Awer wat wann e puer Uwendungen op der selwechter Kraaft lafen? Wéi jiddereng vun hinnen mat de Minimum néideg Ressourcen ze bidden? Wéi kënnt Dir Ressourceverbrauch limitéieren? Wéi richteg d'Laascht tëscht Wirbelen ze verdeelen? Wéi sécherzestellen datt den horizontalen Skaléierungsmechanismus funktionnéiert wann d'Applikatiounslaascht eropgeet?

Kubernetes: Firwat ass et sou wichteg System Ressource Gestioun ze konfiguréieren?

Dir musst ufänken mat wéi eng Haaptarten vu Ressourcen am System existéieren - dëst ass natierlech Prozessor Zäit a RAM. A k8s Manifestatiounen ginn dës Ressourcentypen an de folgenden Eenheeten gemooss:

  • CPU - an Kären
  • RAM - an Bytes

Ausserdeem, fir all Ressource ass et méiglech zwou Aarte vun Ufuerderungen ze setzen - Ufro и Grenzen. Ufroen - beschreift d'Mindestfuerderunge fir gratis Ressourcen vun engem Node fir e Container (a Pod als Ganzt) ze bedreiwen, während Limiten eng haart Limit op d'Ressourcen, déi dem Container verfügbar sinn, setzen.

Et ass wichteg ze verstoen datt de Manifest net béid Aarte explizit muss definéieren, awer d'Verhalen wäert wéi follegt sinn:

  • Wann nëmmen d'Limite vun enger Ressource explizit spezifizéiert sinn, da hëlt d'Ufroe fir dës Ressource automatesch e Wäert gläich wéi d'Limiten (Dir kënnt dat verifizéieren andeems Dir Entitéite beschreiwen. Déi. tatsächlech, de Container gëtt op déi selwecht Quantitéit vun Ressourcen limitéiert ginn et Lafen verlaangt.
  • Wann nëmmen Ufroe fir eng Ressource explizit spezifizéiert sinn, da gi keng iewescht Restriktiounen op dës Ressource gesat - d.h. de Container ass nëmme limitéiert duerch d'Ressourcen vum Node selwer.

Et ass och méiglech d'Ressourcemanagement net nëmmen um Niveau vun engem spezifesche Container ze konfiguréieren, awer och um Nummraumniveau mat de folgenden Entitéiten:

  • LimitRange - beschreift d'Restriktiounspolitik um Container / Pod Niveau an ns an ass néideg fir d'Standardlimite vum Container / Pod ze beschreiwen, souwéi d'Schafung vu offensichtlech fett Container / Pods ze verhënneren (oder ëmgedréint), hir Zuel ze limitéieren a bestëmmen de méiglechen Ënnerscheed an de Wäerter a Grenzen an Ufroen
  • RessourceQuoten - beschreift d'Restriktiounspolitik allgemeng fir all Container an ns a gëtt als Regel benotzt fir Ressourcen tëscht Ëmfeld ze delimitéieren (nëtzlech wann Ëmfeld net strikt um Nodeniveau ofgrenzt)

Déi folgend sinn Beispiller vu Manifestatiounen déi Ressourcelimite setzen:

  • Op dem spezifesche Containerniveau:

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

    Déi. an dësem Fall, fir e Container mat nginx ze lafen, braucht Dir op d'mannst 1G gratis RAM an 0.2 CPU op der Node, während maximal de Container 0.2 CPU an all verfügbare RAM op der Node konsuméiere kann.

  • Am ganzen Niveau ns:

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

    Déi. d'Zomm vun all Ufro Container an der Default ns kann net däerfte 300m fir d'CPU an 1G fir d'OP, an d'Zomm vun all Limite ass 700m fir d'CPU an 2G fir d'OP.

  • Standard Limite fir Container an 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

    Déi. am Standard Nummraum fir all Behälter, Ufro gëtt op 100m fir CPU an 1G fir OP gesat ginn, Limite - 1 CPU an 2G. Zur selwechter Zäit gëtt och eng Limit op déi méiglech Wäerter an Ufro / Limit fir CPU (50m < x < 2) a RAM (500M < x < 4G) gesat.

  • Pod-Niveau Restriktiounen ns:

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

    Déi. fir all Pod am Standard ns gëtt et eng Limite vu 4 vCPU an 1G.

Elo wéilt ech Iech soen wéi eng Virdeeler dës Restriktiounen setzen eis kënne ginn.

Belaaschtungsmechanismus tëscht Noden

Wéi Dir wësst, ass d'K8s Komponent verantwortlech fir d'Verdeelung vu Pods tëscht Noden, wéi z Scheduler, deen no engem spezifesche Algorithmus funktionnéiert. Dësen Algorithmus geet duerch zwou Etappen wann Dir den optimalen Node wielt fir ze starten:

  1. Filter
  2. Rangéiert

Déi. no der beschriwwen Politik, sinn d'Node am Ufank ausgewielt op deenen et méiglech ass e Pod op Basis vun engem Set ze starten Prädikat (dorënner ze kontrolléieren ob den Node genuch Ressourcen huet fir de Pod ze lafen - PodFitsResources), an dann fir all eenzel vun dësen Noden, laut Prioritéite sinn Punkte ginn ausgezeechent (inklusiv, wat méi fräi Ressourcen e Node huet, wat méi Punkten et zougewisen gëtt - LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation) an de Pod gëtt um Node mat de meeschte Punkten lancéiert (wann e puer Noden dës Konditioun gläichzäiteg erfëllen, dann eng zoufälleg gëtt ausgewielt).

Zur selwechter Zäit musst Dir verstoen datt de Scheduler, wann Dir déi verfügbar Ressourcen vun engem Node beurteelt, vun den Daten guidéiert gëtt, déi an etcd gespäichert sinn - d.h. fir de Montant vun der ugefrote / Limit Ressource vun all Pod Lafen op dësem Node, awer net fir déi aktuell Ressource Konsum. Dës Informatioun kann aus dem Kommando Output kritt ginn kubectl describe node $NODE, zum Beispill:

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

Hei gesi mir all Pods op engem spezifesche Node lafen, souwéi d'Ressourcen déi all Pod freet. An hei ass wéi d'Scheduleger Logbicher ausgesinn wann de cronjob-cron-events-1573793820-xt6q9 Pod gestart gëtt (dës Informatioun erschéngt am Scheduler Log wann den 10. ):

aloggen

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

Hei gesi mir datt am Ufank de Scheduler filtert a generéiert eng Lëscht vun 3 Noden op deenen et lancéiert ka ginn (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10). Da berechent et Partituren op Basis vu verschiddene Parameteren (inklusiv BalancedResourceAllocation, LeastResourceAllocation) fir all eenzel vun dësen Noden fir de gëeegentste Node ze bestëmmen. Schlussendlech ass de Pod um Node mat der héchster Unzuel u Punkte geplangt (hei hunn zwee Wirbelen gläichzäiteg déiselwecht Zuel vu Punkten 100037, sou datt e zoufälleg ausgewielt gëtt - nxs-k8s-s10).

Konklusioun: wann e Node Pods leeft fir déi keng Restriktiounen gesat ginn, dann fir k8s (aus der Siicht vum Ressourceverbrauch) wäert dëst gläichwäerteg sinn wéi wann et guer keng sou Pods op dësem Node wier. Dofir, wann Dir, bedingt, e Pod mat engem gluttonesche Prozess (zum Beispill wowza) hutt a keng Restriktiounen dofir gesat ginn, da kann eng Situatioun entstoen wann dëse Pod tatsächlech all d'Ressourcen vum Node giess huet, awer fir k8s dësen Node gëtt als entlaascht ugesinn an et gëtt déiselwecht Unzuel u Punkte beim Ranking ausgezeechent (präzis a Punkten déi verfügbare Ressourcen beurteelen) als Node, deen keng funktionnéierend Pods huet, wat schlussendlech zu enger ongläicher Verdeelung vun der Belaaschtung tëscht Noden féiere kann.

Pod seng Eviction

Wéi Dir wësst, gëtt all Pod eng vun 3 QoS Klassen zougewisen:

  1. garantéiert - gëtt zougewisen wann fir all Container am Pod eng Ufro a Limit fir Erënnerung a CPU spezifizéiert sinn, an dës Wäerter musse passen
  2. burstable - op d'mannst ee Container am Pod huet eng Ufro an eng Limit, mat Ufro < Limit
  3. beschte Effort - wann keen eenzege Container am Pod Ressource limitéiert ass

Zur selwechter Zäit, wann e Node e Mangel u Ressourcen erliewt (Disk, Erënnerung), fänkt kubelet un Pods ze rangéieren an ze evict no engem spezifesche Algorithmus, deen d'Prioritéit vum Pod a senger QoS Klass berücksichtegt. Zum Beispill, wa mir iwwer RAM schwätzen, da baséiert op der QoS Klass, ginn Punkten no dem folgende Prinzip ausgezeechent:

  • Garantéiert: -998
  • BestEffort: 1000
  • Burstable: min(max(2, 1000 - (1000 * MemoryRequestBytes) / machineMemoryCapacityBytes), 999)

Déi. mat der selwechter Prioritéit wäert de kubelet éischt pods mat de beschte Efforten QoS Klass aus dem Node evict.

Konklusioun: wann Dir d'Wahrscheinlechkeet reduzéiere wëllt datt de gewënschten Pod aus dem Node evictéiert gëtt am Fall vun engem Mangel u Ressourcen op et, dann zesumme mat der Prioritéit, musst Dir och këmmeren fir d'Ufro / Limit dofir ze setzen.

Mechanismus fir horizontal Autoscaling vun Applikatioun Pods (HPA)

Wann d'Aufgab ass automatesch d'Zuel vun de Pods ze erhéijen an erofzesetzen ofhängeg vun der Notzung vun de Ressourcen (System - CPU / RAM oder Benotzer - rps), sou eng k8s Entitéit wéi HPA (Horizontal Pod Autoscaler). Den Algorithmus vun deem ass wéi follegt:

  1. Déi aktuell Liesunge vun der observéierter Ressource gi bestëmmt (currentMetricValue)
  2. Déi gewënschte Wäerter fir d'Ressource ginn festgeluegt (gewënschteMetricValue), déi fir Systemressourcen mat Ufro gesat ginn
  3. Déi aktuell Unzuel vun de Repliken gëtt festgeluecht (currentReplicas)
  4. Déi folgend Formel berechent déi gewënscht Zuel vu Repliken (gewënschte Repliken)
    desireReplicas = [ currentReplicas * ( currentMetricValue / wantedMetricValue )]

An dësem Fall wäert d'Skaléierung net geschéien wann de Koeffizient (currentMetricValue / desireMetricValue) no bei 1 ass (an dësem Fall kënne mir den zulässleche Feeler selwer setzen; Par défaut ass et 0.1).

Loosst eis kucken wéi hpa funktionnéiert mam Beispill vun der App-Test Applikatioun (als Deployment beschriwwen), wou et néideg ass d'Zuel vun de Repliken ze änneren ofhängeg vum CPU Konsum:

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

    Déi. mir gesinn datt d'Applikatioun Pod am Ufank an zwee Fäll lancéiert gëtt, all vun deenen zwee nginx an nginx-Exporter Container enthält, fir jidderee vun deenen e spezifizéierte Ufro fir CPU.

  • 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

    Déi. Mir hunn en hpa erstallt, deen den Deployment App-Test iwwerwaacht an d'Zuel vun de Pods mat der Applikatioun reguléiert baséiert op dem CPU Indikator (mir erwaarden datt de Pod 30% Prozent vun der CPU konsuméiere soll, déi se freet), mat der Unzuel vun de Repliken am Beräich vun 2-10.

    Loosst eis elo de Mechanismus vun der HP Operatioun kucken, wa mir eng Laascht op ee vun den Hierden applizéieren:

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

Am Ganzen hu mir déi folgend:

  • De gewënschte Wäert (gewënschteMetricValue) - laut den hpa Astellunge hu mir 30%
  • Aktuelle Wäert (currentMetricValue) - fir d'Berechnung berechent de Controller-Manager den Duerchschnëttswäert vum Ressourceverbrauch an %, d.h. bedingt mécht déi folgend:
    1. Kritt absolut Wäerter vu Pod Metriken vum metresche Server, d.h. 101m a 4m
    2. Berechent den Duerchschnëttsabsolutwäert, d.h. (101m + 4m) / 2 = 53m
    3. Kritt den absolute Wäert fir de gewënschten Ressourceverbrauch (fir dëst sinn d'Ufroe vun all Container zesummegefaasst) 60m + 30m = 90m
    4. Berechent den duerchschnëttleche Prozentsaz vum CPU Konsum relativ zum Ufro Pod, d.h. 53m / 90m * 100% = 59%

Elo hu mir alles wat mir brauchen fir ze bestëmmen ob mir d'Zuel vun de Repliken änneren mussen; Fir dëst ze maachen, berechene mir de Koeffizient:

ratio = 59% / 30% = 1.96

Déi. d'Zuel vun de Repliken soll ëm ~ 2 Mol eropgesat ginn an op [2 * 1.96] = 4.

Fazit: Wéi Dir gesitt, fir datt dëse Mechanismus funktionnéiert, ass eng noutwenneg Bedingung d'Präsenz vun Ufroe fir all Container am beobachtete Pod.

Mechanismus fir horizontal Autoskaléierung vun Noden (Cluster Autoscaler)

Fir den negativen Impakt op de System während Laaschtschlag ze neutraliséieren, ass eng konfiguréiert hpa net genuch. Zum Beispill, laut den Astellungen am hpa Controller Manager, entscheet et datt d'Zuel vun de Repliken ëm 2 Mol erhéicht muss ginn, awer d'Knueten hu keng gratis Ressourcen fir sou eng Zuel vu Pods ze lafen (dh den Node kann net de gefrot Ressourcen op den Ufro Pod) an dës Pods wiesselen an den Pending Staat.

An dësem Fall, wann de Provider eng entspriechend IaaS / PaaS huet (zum Beispill, GKE / GCE, AKS, EKS, etc.), e Tool wéi Node Autoscaler. Et erlaabt Iech d'maximal an d'Mindestzuel vun de Wirbelen am Cluster ze setzen an automatesch d'aktuell Zuel vun de Wirbelen unzepassen (andeems de Cloud Provider API rufft fir en Node ze bestellen / ewechzehuelen) wann et e Mangel u Ressourcen am Cluster an de Pods ass kann net geplangt ginn (sinn am Pending Staat).

Fazit: Fir Knäppercher autoskaléieren ze kënnen, ass et néideg Ufroen an de Podcontainer ze setzen, sou datt k8s d'Laascht op den Noden korrekt beurteelen an deementspriechend berichten datt et keng Ressourcen am Cluster sinn fir den nächste Pod ze starten.

Konklusioun

Et sollt bemierkt datt d'Astellung vun Container Ressource Limiten net eng Fuerderung ass fir d'Applikatioun erfollegräich ze lafen, awer et ass nach ëmmer besser dat ze maachen aus de folgende Grënn:

  1. Fir méi genee Operatioun vum Scheduler am Sënn vun der Belaaschtung tëscht k8s Noden
  2. Fir d'Wahrscheinlechkeet vun engem "Pod Eviction" Event ze reduzéieren
  3. Fir horizontal Autoscaling vun Applikatioun Pods (HPA) ze schaffen
  4. Fir horizontal Autoscaling vun Noden (Cluster Autoscaling) fir Cloud Provider

Liest och aner Artikelen op eisem Blog:

Source: will.com

Setzt e Commentaire