Kubernetes: kial estas tiel grave agordi sisteman rimedadministradon?

Kiel regulo, ĉiam necesas provizi dediĉitan aron da rimedoj al aplikaĵo por ĝia ĝusta kaj stabila funkciado. Sed kio se pluraj aplikoj funkcias per la sama potenco? Kiel provizi al ĉiu el ili la minimumajn necesajn rimedojn? Kiel vi povas limigi konsumon de rimedoj? Kiel ĝuste distribui la ŝarĝon inter nodoj? Kiel certigi, ke la horizontala skala mekanismo funkcias se la aplika ŝarĝo pliiĝas?

Kubernetes: kial estas tiel grave agordi sisteman rimedadministradon?

Vi devas komenci per kiaj ĉefaj specoj de rimedoj ekzistas en la sistemo - ĉi tio, kompreneble, estas procesora tempo kaj RAM. En k8s-manifestoj ĉi tiuj rimedspecoj estas mezuritaj en la sekvaj unuoj:

  • CPU - en kernoj
  • RAM - en bajtoj

Krome, por ĉiu rimedo eblas agordi du specojn de postuloj - petoj и limoj. Petoj - priskribas la minimumajn postulojn por senpagaj resursoj de nodo por prizorgi ujon (kaj pod kiel tutaĵo), dum limoj fiksas malmolan limon al la rimedoj disponeblaj al la ujo.

Gravas kompreni, ke la manifesto ne devas eksplicite difini ambaŭ tipojn, sed la konduto estos jena:

  • Se nur la limoj de rimedo estas eksplicite specifitaj, tiam petoj por ĉi tiu rimedo aŭtomate prenas valoron egala al limoj (vi povas kontroli tion vokante priskribi entojn). Tiuj. fakte, la ujo estos limigita al la sama kvanto de rimedoj, kiujn ĝi postulas por funkcii.
  • Se nur petoj estas eksplicite specifitaj por rimedo, tiam neniuj supraj limigoj estas fiksitaj sur ĉi tiu rimedo - t.e. la ujo estas limigita nur de la rimedoj de la nodo mem.

Eblas ankaŭ agordi rimedadministradon ne nur je la nivelo de specifa ujo, sed ankaŭ ĉe la nomspaca nivelo uzante la jenajn entojn:

  • LimitRange — priskribas la limigan politikon ĉe la ujo/pod-nivelo en ns kaj necesas por priskribi la defaŭltajn limojn sur la ujo/pod, kaj ankaŭ malhelpi la kreadon de evidente grasaj ujoj/pod (aŭ inverse), limigi ilian nombron kaj determini la eblan diferencon en la valoroj en limoj kaj petoj
  • Rimedaj Kvotoj — priskribu la limigan politikon ĝenerale por ĉiuj ujoj en ns kaj estas uzata, kiel regulo, por limigi resursojn inter medioj (utila kiam medioj ne estas strikte limigitaj ĉe la noda nivelo)

La sekvantaroj estas ekzemploj de manifestoj, kiuj fiksas rimedlimojn:

  • Je la specifa ujo-nivelo:

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

    Tiuj. en ĉi tiu kazo, por ruli ujon kun nginx, vi bezonos almenaŭ 1G da libera RAM kaj 0.2 CPU sur la nodo, dum maksimume la ujo povas konsumi 0.2 CPU kaj ĉiujn disponeblajn RAM sur la nodo.

  • Je la entjernivelo ns:

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

    Tiuj. la sumo de ĉiuj petaj ujoj en la defaŭlta ns ne povas superi 300m por la CPU kaj 1G por la OP, kaj la sumo de ĉiuj limoj estas 700m por la CPU kaj 2G por la OP.

  • Defaŭltaj limoj por ujoj en 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

    Tiuj. en la defaŭlta nomspaco por ĉiuj ujoj, peto estos agordita al 100m por CPU kaj 1G por OP, limo - 1 CPU kaj 2G. Samtempe, limo ankaŭ estas fiksita al la eblaj valoroj en peto/limo por CPU (50m < x < 2) kaj RAM (500M < x < 4G).

  • Pod-nivelaj restriktoj ns:

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

    Tiuj. por ĉiu pod en la defaŭlta ns estos limo de 4 vCPU kaj 1G.

Nun mi ŝatus diri al vi, kiajn avantaĝojn povas doni al ni agordi ĉi tiujn limigojn.

Ŝarĝbalanca mekanismo inter nodoj

Kiel vi scias, la k8s-komponento respondecas pri la distribuado de balgoj inter nodoj, kiel ekzemple planificador, kiu funkcias laŭ specifa algoritmo. Ĉi tiu algoritmo trairas du stadiojn kiam elektas la optimuman nodon por lanĉi:

  1. Filtrado
  2. Gaming

Tiuj. laŭ la priskribita politiko oni komence elektas nodojn, sur kiuj eblas lanĉi podon surbaze de aro predikatoj (inkluzive kontroli ĉu la nodo havas sufiĉajn rimedojn por ruli la pod - PodFitsResources), kaj poste por ĉiu el ĉi tiuj nodoj, laŭ prioritatoj punktoj estas aljuĝitaj (inkluzive, ju pli da liberaj rimedoj nodo havas, des pli da punktoj ĝi estas asignita - LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation) kaj la pod estas lanĉita sur la nodo kun la plej multaj poentoj (se pluraj nodoj kontentigas tiun ĉi kondiĉon samtempe, tiam hazarda estas elektita).

Samtempe, vi devas kompreni, ke la planisto, kiam oni taksas la disponeblajn rimedojn de nodo, estas gvidata de la datumoj stokitaj en etcd - t.e. por la kvanto de la petita/lima rimedo de ĉiu pod kuranta sur ĉi tiu nodo, sed ne por la reala rimeda konsumo. Ĉi tiu informo povas esti akirita de la komanda eligo kubectl describe node $NODEekzemple:

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

Ĉi tie ni vidas ĉiujn podojn kurantajn sur specifa nodo, same kiel la rimedojn, kiujn ĉiu podoj petas. Kaj jen kiel aspektas la protokoloj de la planilo kiam la podo cronjob-cron-events-1573793820-xt6q9 estas lanĉita (ĉi tiu informo aperos en la protokolo de la planilo kiam vi agordas la 10-an protokolan nivelon en la argumentoj de la startkomando -v=10):

ŝtipo

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

Ĉi tie ni vidas, ke komence la planilo filtras kaj generas liston de 3 nodoj, sur kiuj ĝi povas esti lanĉita (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10). Poste ĝi kalkulas poentarojn surbaze de pluraj parametroj (inkluzive de BalancedResourceAllocation, LeastResourceAllocation) por ĉiu el ĉi tiuj nodoj por determini la plej taŭgan nodon. Finfine, la podo estas planita sur la nodo kun la plej alta nombro da punktoj (ĉi tie du nodoj samtempe havas la saman nombron da punktoj 100037, do hazarda estas elektita - nxs-k8s-s10).

konkludo: se nodo rulas podojn por kiuj neniuj limigoj estas fiksitaj, tiam por k8s (el la vidpunkto de konsumo de rimedoj) tio ekvivalentos al kvazaŭ tiaj podoj en ĉi tiu nodo entute ne ekzistus. Sekve, se vi, kondiĉe, havas podon kun glutema procezo (ekzemple, wowza) kaj neniuj limigoj estas fiksitaj por ĝi, tiam situacio povas ekesti kiam ĉi tiu pod efektive manĝis ĉiujn rimedojn de la nodo, sed por k8s ĉi tiu nodo. estas konsiderata malŝarĝita kaj ĝi estos aljuĝita la saman nombron da poentoj kiam vi klasifikas (precize en punktoj taksantaj disponeblajn rimedojn) kiel nodo, kiu ne havas funkciajn podojn, kio finfine povas konduki al neegala distribuo de la ŝarĝo inter nodoj.

Eldomigo de Pod

Kiel vi scias, al ĉiu podo estas asignita unu el 3 QoS-klasoj:

  1. garantiita — estas asignita kiam por ĉiu ujo en la pod peto kaj limo estas specifitaj por memoro kaj CPU, kaj ĉi tiuj valoroj devas kongrui
  2. krevebla — almenaŭ unu ujo en la podo havas peton kaj limon, kun peto < limo
  3. plej bona penado — kiam neniu ujo en la balgo estas rimedo limigita

Samtempe, kiam nodo spertas mankon de rimedoj (disko, memoro), kubelet komencas vicigi kaj forpeli podojn laŭ specifa algoritmo, kiu konsideras la prioritaton de la pod kaj ĝian QoS-klason. Ekzemple, se ni parolas pri RAM, tiam surbaze de la QoS-klaso, punktoj estas aljuĝitaj laŭ la sekva principo:

  • Garantiita: -998
  • Plej bona penado: 1000
  • Burstable: min (maksimumo (2, 1000 - (1000 * memoroPetoBytes) / maŝinoMemoryCapacityBytes), 999)

Tiuj. kun la sama prioritato, la kubelet unue elpelos podojn kun la plej bona peno QoS-klaso de la nodo.

konkludo: se vi volas redukti la verŝajnecon, ke la dezirata podo estu elpelita de la nodo okaze de manko de rimedoj sur ĝi, tiam kune kun la prioritato, vi ankaŭ devas zorgi pri agordo de la peto/limo por ĝi.

Mekanismo por horizontala aŭtoskalado de aplikaĵkapsuloj (HPA)

Kiam la tasko estas aŭtomate pliigi kaj malpliigi la nombron da podoj depende de la uzo de rimedoj (sistemo - CPU/RAM aŭ uzanto - rps), tia k8s ento kiel HPA (Horizontala Pod Autoscaler). La algoritmo de kiu estas kiel sekvas:

  1. La aktualaj legaĵoj de la observita rimedo estas determinitaj (currentMetricValue)
  2. La dezirataj valoroj por la rimedo estas determinitaj (desiredMetricValue), kiuj por sistemaj rimedoj estas fiksitaj per peto
  3. La nuna nombro da kopioj estas determinita (nunaReplicas)
  4. La sekva formulo kalkulas la deziratan nombron da kopioj (deziritajReplikoj)
    deziratajReplikoj = [ nunajReplikoj * (nunaMetricValue / dezirataMetricaValoro)]

En ĉi tiu kazo, skalo ne okazos kiam la koeficiento (currentMetricValue / dezirataMetricValue) estas proksima al 1 (en ĉi tiu kazo, ni mem povas agordi la permeseblan eraron; defaŭlte ĝi estas 0.1).

Ni rigardu kiel hpa funkcias uzante la ekzemplon de la aplikaĵo-testa aplikaĵo (priskribita kiel Deplojo), kie necesas ŝanĝi la nombron da kopioj depende de la CPU-konsumo:

  • Apliko manifesto

    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

    Tiuj. ni vidas, ke la aplikaĵo pod estas komence lanĉita en du okazoj, ĉiu el kiuj enhavas du nginx kaj nginx-exporter-ujojn, por ĉiu el kiuj specifita. petoj por CPU.

  • HPA Manifesto

    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

    Tiuj. Ni kreis hpa, kiu kontrolos la Deployment-ap-teston kaj ĝustigos la nombron da podoj kun la aplikaĵo bazita sur la cpu-indikilo (ni atendas, ke la podo devas konsumi 30% de la CPU, kiun ĝi petas), kun la nombro da kopioj enestas. la gamo de 2-10.

    Nun, ni rigardu la mekanismon de hpa operacio se ni aplikas ŝarĝon al unu el la fajrujoj:

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

Entute ni havas la jenajn:

  • La dezirata valoro (desiredMetricValue) - laŭ la agordoj de hpa, ni havas 30%
  • Nuna valoro (currentMetricValue) - por kalkulo, regilo-administranto kalkulas la averaĝan valoron de konsumo de rimedoj en %, t.e. kondiĉe faras la jenon:
    1. Ricevas absolutajn valorojn de pod-metrikoj de la metrika servilo, t.e. 101m kaj 4m
    2. Kalkulas la mezan absolutan valoron, t.e. (101m + 4m) / 2 = 53m
    3. Akiras la absolutan valoron por la dezirata konsumo de rimedoj (por tio, la petoj de ĉiuj ujoj estas resumitaj) 60m + 30m = 90m
    4. Kalkulas la mezan procenton de CPU-konsumo rilate al la petopodo, t.e. 53m / 90m * 100% = 59%

Nun ni havas ĉion, kion ni bezonas por determini ĉu ni devas ŝanĝi la nombron da kopioj; por fari tion, ni kalkulas la koeficienton:

ratio = 59% / 30% = 1.96

Tiuj. la nombro da kopioj devus esti pliigita je ~2 fojojn kaj sumiĝi al [2 * 1.96] = 4.

Konkludo: Kiel vi povas vidi, por ke ĉi tiu mekanismo funkciu, necesa kondiĉo estas la ĉeesto de petoj por ĉiuj ujoj en la observita pod.

Mekanismo por horizontala aŭtoskalado de nodoj (Cluster Autoscaler)

Por neŭtraligi la negativan efikon al la sistemo dum ŝargiĝoj, havi agordita hpa ne sufiĉas. Ekzemple, laŭ la agordoj en la administranto de hpa regilo, ĝi decidas, ke la nombro da kopioj devas esti pliigita je 2 fojojn, sed la nodoj ne havas senpagajn rimedojn por ruli tian nombron da podoj (t.e. la nodo ne povas provizi la petitaj rimedoj al la petoj pod) kaj ĉi tiuj balgoj ŝanĝas al la Atendata stato.

En ĉi tiu kazo, se la provizanto havas respondan IaaS/PaaS (ekzemple, GKE/GCE, AKS, EKS, ktp.), ilo kiel Nodo Aŭtoskaler. Ĝi ebligas al vi agordi la maksimuman kaj minimuman nombron da nodoj en la areto kaj aŭtomate ĝustigi la nunan nombron da nodoj (vokante la nuba provizanto API por ordigi/forigi nodon) kiam mankas rimedoj en la areto kaj la podoj. ne povas esti planita (estas en la Atendata stato).

Konkludo: Por povi aŭtomskali nodojn, necesas agordi petojn en la podujoj, por ke k8s povu ĝuste taksi la ŝarĝon sur la nodoj kaj sekve raporti, ke ne ekzistas rimedoj en la areto por lanĉi la sekvan podaĵon.

konkludo

Oni devas rimarki, ke agordi limojn pri ujrimedo ne estas postulo por ke la aplikaĵo rulu sukcese, sed ankoraŭ estas pli bone fari tion pro la sekvaj kialoj:

  1. Por pli preciza funkciado de la planilo laŭ ŝarĝoekvilibro inter k8s-nodoj
  2. Redukti la verŝajnecon de "pod-eldomigo-" okazaĵo okazanta
  3. Por ke horizontala aŭtoskalo de aplikaĵaj kapsuloj (HPA) funkciu
  4. Por horizontala aŭtoskalado de nodoj (Cluster Autoscaling) por nubaj provizantoj

Legu ankaŭ aliajn artikolojn en nia blogo:

fonto: www.habr.com

Aldoni komenton