Kubernetes: bakit napakahalagang i-configure ang pamamahala ng mapagkukunan ng system?

Bilang isang patakaran, palaging may pangangailangan na magbigay ng isang nakatuong pool ng mga mapagkukunan sa isang aplikasyon para sa tama at matatag na operasyon nito. Ngunit paano kung maraming application ang tumatakbo sa parehong kapangyarihan? Paano ibibigay ang bawat isa sa kanila ng pinakamababang kinakailangang mapagkukunan? Paano mo malimitahan ang pagkonsumo ng mapagkukunan? Paano tama na ipamahagi ang pagkarga sa pagitan ng mga node? Paano masisigurong gumagana ang horizontal scaling mechanism kung tumaas ang application load?

Kubernetes: bakit napakahalagang i-configure ang pamamahala ng mapagkukunan ng system?

Kailangan mong magsimula sa kung anong mga pangunahing uri ng mga mapagkukunan ang umiiral sa system - ito, siyempre, ay oras ng processor at RAM. Sa k8s manifests ang mga uri ng mapagkukunang ito ay sinusukat sa mga sumusunod na unit:

  • CPU - sa mga core
  • RAM - sa bytes

Bukod dito, para sa bawat mapagkukunan posible na magtakda ng dalawang uri ng mga kinakailangan - kahilingan ΠΈ mga limitasyon. Mga Kahilingan - inilalarawan ang mga minimum na kinakailangan para sa mga libreng mapagkukunan ng isang node upang magpatakbo ng isang lalagyan (at pod sa kabuuan), habang ang mga limitasyon ay nagtatakda ng isang mahigpit na limitasyon sa mga mapagkukunang magagamit sa lalagyan.

Mahalagang maunawaan na ang manifest ay hindi kailangang tahasang tukuyin ang parehong uri, ngunit ang pag-uugali ay magiging tulad ng sumusunod:

  • Kung ang mga limitasyon lamang ng isang mapagkukunan ay tahasang tinukoy, ang mga kahilingan para sa mapagkukunang ito ay awtomatikong kukuha ng isang halaga na katumbas ng mga limitasyon (maaari mong i-verify ito sa pamamagitan ng pagtawag sa mga entity ng paglalarawan). Yung. sa katunayan, ang lalagyan ay malilimitahan sa parehong halaga ng mga mapagkukunan na kinakailangan nito upang tumakbo.
  • Kung ang mga kahilingan lamang ang tahasang tinukoy para sa isang mapagkukunan, kung gayon walang mga paghihigpit sa itaas na nakatakda sa mapagkukunang ito - i.e. ang lalagyan ay limitado lamang ng mga mapagkukunan ng node mismo.

Posible ring i-configure ang pamamahala ng mapagkukunan hindi lamang sa antas ng isang partikular na lalagyan, kundi pati na rin sa antas ng namespace gamit ang mga sumusunod na entity:

  • LimitRange β€” inilalarawan ang patakaran sa paghihigpit sa antas ng lalagyan/pod sa ns at kinakailangan upang ilarawan ang mga default na limitasyon sa lalagyan/pod, pati na rin maiwasan ang paglikha ng mga halatang matatabang lalagyan/pod (o kabaliktaran), limitahan ang kanilang bilang at tukuyin ang posibleng pagkakaiba sa mga halaga sa mga limitasyon at kahilingan
  • ResourceQuotas β€” ilarawan ang patakaran sa paghihigpit sa pangkalahatan para sa lahat ng mga lalagyan sa ns at ginagamit, bilang panuntunan, upang limitahan ang mga mapagkukunan sa mga kapaligiran (kapaki-pakinabang kapag ang mga kapaligiran ay hindi mahigpit na nademarkahan sa antas ng node)

Ang mga sumusunod ay mga halimbawa ng mga manifest na nagtatakda ng mga limitasyon sa mapagkukunan:

  • Sa partikular na antas ng container:

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

    Yung. sa kasong ito, upang magpatakbo ng isang lalagyan na may nginx, kakailanganin mo ng hindi bababa sa 1G ng libreng RAM at 0.2 CPU sa node, habang ang lalagyan ay maaaring kumonsumo ng 0.2 CPU at lahat ng magagamit na RAM sa node.

  • Sa antas ng integer ns:

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

    Yung. ang kabuuan ng lahat ng mga container ng kahilingan sa default na ns ay hindi maaaring lumampas sa 300m para sa CPU at 1G para sa OP, at ang kabuuan ng lahat ng limitasyon ay 700m para sa CPU at 2G para sa OP.

  • Mga default na limitasyon para sa mga container sa 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

    Yung. sa default na namespace para sa lahat ng container, itatakda ang kahilingan sa 100m para sa CPU at 1G para sa OP, limitasyon - 1 CPU at 2G. Kasabay nito, nakatakda rin ang limitasyon sa mga posibleng halaga sa kahilingan/limitasyon para sa CPU (50m < x < 2) at RAM (500M < x < 4G).

  • Mga paghihigpit sa antas ng pod ns:

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

    Yung. para sa bawat pod sa default ns magkakaroon ng limitasyon na 4 vCPU at 1G.

Ngayon gusto kong sabihin sa iyo kung anong mga pakinabang ang maibibigay sa amin ng pagtatakda ng mga paghihigpit na ito.

Mekanismo ng pag-load ng pagbabalanse sa pagitan ng mga node

Tulad ng alam mo, ang bahagi ng k8s ay responsable para sa pamamahagi ng mga pod sa mga node, tulad ng taga-iskedyul, na gumagana ayon sa isang partikular na algorithm. Dumadaan ang algorithm na ito sa dalawang yugto kapag pumipili ng pinakamainam na node na ilulunsad:

  1. pagsasala
  2. Ranging

Yung. ayon sa inilarawang patakaran, ang mga node ay unang pinili kung saan posibleng maglunsad ng pod batay sa isang set panaguri (kabilang ang pagsuri kung ang node ay may sapat na mapagkukunan upang patakbuhin ang pod - PodFitsResources), at pagkatapos ay para sa bawat isa sa mga node na ito, ayon sa prayoridad iginagawad ang mga puntos (kabilang ang, mas maraming libreng mapagkukunan ang mayroon ang isang node, mas maraming puntos ang itinalaga nito - LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation) at ang pod ay inilunsad sa node na may pinakamaraming puntos (kung maraming node ang nakakatugon sa kundisyong ito nang sabay-sabay, pagkatapos isang random ang napili) .

Kasabay nito, kailangan mong maunawaan na ang scheduler, kapag tinatasa ang magagamit na mga mapagkukunan ng isang node, ay ginagabayan ng data na nakaimbak sa etcd - i.e. para sa halaga ng hiniling/limitasyon ng mapagkukunan ng bawat pod na tumatakbo sa node na ito, ngunit hindi para sa aktwal na pagkonsumo ng mapagkukunan. Maaaring makuha ang impormasyong ito mula sa output ng command kubectl describe node $NODE, halimbawa:

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

Dito makikita natin ang lahat ng pod na tumatakbo sa isang partikular na node, pati na rin ang mga mapagkukunan na hinihiling ng bawat pod. At narito ang hitsura ng mga log ng scheduler kapag inilunsad ang cronjob-cron-events-1573793820-xt6q9 pod (lalabas ang impormasyong ito sa log ng scheduler kapag nakatakda ang ika-10 antas ng pag-log sa mga argumento ng command sa paglunsad -v=10 ):

log

I1115 07:57:21.637791       1 scheduling_queue.go:908] About to try and schedule pod nxs-stage/cronjob-cron-events-1573793820-xt6q9                                                                                                                                           
I1115 07:57:21.637804       1 scheduler.go:453] Attempting to schedule pod: nxs-stage/cronjob-cron-events-1573793820-xt6q9                                                                                                                                                    
I1115 07:57:21.638285       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s5 is allowed, Node is running only 16 out of 110 Pods.                                                                               
I1115 07:57:21.638300       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s6 is allowed, Node is running only 20 out of 110 Pods.                                                                               
I1115 07:57:21.638322       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s3 is allowed, Node is running only 20 out of 110 Pods.                                                                               
I1115 07:57:21.638322       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s4 is allowed, Node is running only 17 out of 110 Pods.                                                                               
I1115 07:57:21.638334       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s10 is allowed, Node is running only 16 out of 110 Pods.                                                                              
I1115 07:57:21.638365       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s12 is allowed, Node is running only 9 out of 110 Pods.                                                                               
I1115 07:57:21.638334       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s11 is allowed, Node is running only 11 out of 110 Pods.                                                                              
I1115 07:57:21.638385       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s1 is allowed, Node is running only 19 out of 110 Pods.                                                                               
I1115 07:57:21.638402       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s2 is allowed, Node is running only 21 out of 110 Pods.                                                                               
I1115 07:57:21.638383       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s9 is allowed, Node is running only 16 out of 110 Pods.                                                                               
I1115 07:57:21.638335       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s8 is allowed, Node is running only 18 out of 110 Pods.                                                                               
I1115 07:57:21.638408       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s13 is allowed, Node is running only 8 out of 110 Pods.                                                                               
I1115 07:57:21.638478       1 predicates.go:1369] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s10 is allowed, existing pods anti-affinity terms satisfied.                                                                         
I1115 07:57:21.638505       1 predicates.go:1369] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s8 is allowed, existing pods anti-affinity terms satisfied.                                                                          
I1115 07:57:21.638577       1 predicates.go:1369] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s9 is allowed, existing pods anti-affinity terms satisfied.                                                                          
I1115 07:57:21.638583       1 predicates.go:829] Schedule Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 on Node nxs-k8s-s7 is allowed, Node is running only 25 out of 110 Pods.                                                                               
I1115 07:57:21.638932       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: BalancedResourceAllocation, capacity 39900 millicores 66620178432 memory bytes, total request 2343 millicores 9640186880 memory bytes, score 9        
I1115 07:57:21.638946       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: LeastResourceAllocation, capacity 39900 millicores 66620178432 memory bytes, total request 2343 millicores 9640186880 memory bytes, score 8           
I1115 07:57:21.638961       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: BalancedResourceAllocation, capacity 39900 millicores 66620170240 memory bytes, total request 4107 millicores 11307422720 memory bytes, score 9        
I1115 07:57:21.638971       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: BalancedResourceAllocation, capacity 39900 millicores 66620178432 memory bytes, total request 5847 millicores 24333637120 memory bytes, score 7        
I1115 07:57:21.638975       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: LeastResourceAllocation, capacity 39900 millicores 66620170240 memory bytes, total request 4107 millicores 11307422720 memory bytes, score 8           
I1115 07:57:21.638990       1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: LeastResourceAllocation, capacity 39900 millicores 66620178432 memory bytes, total request 5847 millicores 24333637120 memory bytes, score 7           
I1115 07:57:21.639022       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: TaintTolerationPriority, Score: (10)                                                                                                        
I1115 07:57:21.639030       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: TaintTolerationPriority, Score: (10)                                                                                                         
I1115 07:57:21.639034       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: TaintTolerationPriority, Score: (10)                                                                                                         
I1115 07:57:21.639041       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: NodeAffinityPriority, Score: (0)                                                                                                            
I1115 07:57:21.639053       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: NodeAffinityPriority, Score: (0)                                                                                                             
I1115 07:57:21.639059       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: NodeAffinityPriority, Score: (0)                                                                                                             
I1115 07:57:21.639061       1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: InterPodAffinityPriority, Score: (0)                                                                                                                   
I1115 07:57:21.639063       1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: SelectorSpreadPriority, Score: (10)                                                                                                                   
I1115 07:57:21.639073       1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: InterPodAffinityPriority, Score: (0)                                                                                                                    
I1115 07:57:21.639077       1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: SelectorSpreadPriority, Score: (10)                                                                                                                    
I1115 07:57:21.639085       1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: InterPodAffinityPriority, Score: (0)                                                                                                                    
I1115 07:57:21.639088       1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: SelectorSpreadPriority, Score: (10)                                                                                                                    
I1115 07:57:21.639103       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: SelectorSpreadPriority, Score: (10)                                                                                                         
I1115 07:57:21.639109       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: SelectorSpreadPriority, Score: (10)                                                                                                          
I1115 07:57:21.639114       1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: SelectorSpreadPriority, Score: (10)                                                                                                          
I1115 07:57:21.639127       1 generic_scheduler.go:781] Host nxs-k8s-s10 => Score 100037                                                                                                                                                                            
I1115 07:57:21.639150       1 generic_scheduler.go:781] Host nxs-k8s-s8 => Score 100034                                                                                                                                                                             
I1115 07:57:21.639154       1 generic_scheduler.go:781] Host nxs-k8s-s9 => Score 100037                                                                                                                                                                             
I1115 07:57:21.639267       1 scheduler_binder.go:269] AssumePodVolumes for pod "nxs-stage/cronjob-cron-events-1573793820-xt6q9", node "nxs-k8s-s10"                                                                                                               
I1115 07:57:21.639286       1 scheduler_binder.go:279] AssumePodVolumes for pod "nxs-stage/cronjob-cron-events-1573793820-xt6q9", node "nxs-k8s-s10": all PVCs bound and nothing to do                                                                             
I1115 07:57:21.639333       1 factory.go:733] Attempting to bind cronjob-cron-events-1573793820-xt6q9 to nxs-k8s-s10

Dito makikita natin na sa simula ang scheduler ay nagsasala at bumubuo ng isang listahan ng 3 node kung saan maaari itong ilunsad (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10). Pagkatapos ay kinakalkula nito ang mga marka batay sa ilang mga parameter (kabilang ang BalancedResourceAllocation, LeastResourceAllocation) para sa bawat isa sa mga node na ito upang matukoy ang pinakaangkop na node. Sa huli, ang pod ay naka-iskedyul sa node na may pinakamataas na bilang ng mga puntos (dito ang dalawang node nang sabay-sabay ay may parehong bilang ng mga puntos na 100037, kaya isang random ang napili - nxs-k8s-s10).

Pagbubuhos: kung ang isang node ay nagpapatakbo ng mga pod kung saan walang mga paghihigpit na itinakda, kung gayon para sa mga k8 (mula sa punto ng view ng pagkonsumo ng mapagkukunan) ito ay katumbas ng parang walang ganoong mga pod sa node na ito. Samakatuwid, kung ikaw, sa kondisyon, ay may isang pod na may matakaw na proseso (halimbawa, wowza) at walang mga paghihigpit na itinakda para dito, kung gayon ang isang sitwasyon ay maaaring lumitaw kapag ang pod na ito ay aktwal na kumain ng lahat ng mga mapagkukunan ng node, ngunit para sa mga k8 ang node na ito ay itinuturing na na-unload at ito ay bibigyan ng parehong bilang ng mga puntos kapag nagra-rank (tiyak sa mga puntos na sinusuri ang mga magagamit na mapagkukunan) bilang isang node na walang gumaganang pods, na sa huli ay maaaring humantong sa hindi pantay na pamamahagi ng load sa pagitan ng mga node.

Ang pagpapaalis ni Pod

Tulad ng alam mo, ang bawat pod ay itinalaga ng isa sa 3 klase ng QoS:

  1. garantisado β€” ay itinalaga kapag para sa bawat lalagyan sa pod ang isang kahilingan at limitasyon ay tinukoy para sa memorya at cpu, at ang mga halagang ito ay dapat tumugma
  2. maputok β€” kahit isang lalagyan sa pod ay may kahilingan at limitasyon, na may kahilingan < limitasyon
  3. pinakamahusay na pagsisikap β€” kapag walang isang lalagyan sa pod ang limitadong mapagkukunan

Kasabay nito, kapag ang isang node ay nakakaranas ng kakulangan ng mga mapagkukunan (disk, memorya), ang kubelet ay magsisimulang mag-rank at mag-evict ng mga pod ayon sa isang partikular na algorithm na isinasaalang-alang ang priyoridad ng pod at ang klase ng QoS nito. Halimbawa, kung pinag-uusapan natin ang tungkol sa RAM, pagkatapos ay batay sa klase ng QoS, ang mga puntos ay iginawad ayon sa sumusunod na prinsipyo:

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

Yung. na may parehong priyoridad, aalisin muna ng kubelet ang mga pod na may pinakamahusay na pagsisikap na klase ng QoS mula sa node.

Pagbubuhos: kung gusto mong bawasan ang posibilidad na maalis ang nais na pod mula sa node kung sakaling magkaroon ng kakulangan ng mga mapagkukunan dito, pagkatapos kasama ang priyoridad, kailangan mo ring alagaan ang pagtatakda ng kahilingan/limitasyon para dito.

Mekanismo para sa pahalang na autoscaling ng mga application pod (HPA)

Kapag ang gawain ay awtomatikong dagdagan at bawasan ang bilang ng mga pod depende sa paggamit ng mga mapagkukunan (system - CPU/RAM o user - rps), tulad ng k8s entity bilang HPA (Horizontal Pod Autoscaler). Ang algorithm kung saan ay ang mga sumusunod:

  1. Ang kasalukuyang mga pagbabasa ng naobserbahang mapagkukunan ay tinutukoy (currentMetricValue)
  2. Ang mga nais na halaga para sa mapagkukunan ay tinutukoy (desiredMetricValue), na para sa mga mapagkukunan ng system ay itinakda gamit ang kahilingan
  3. Ang kasalukuyang bilang ng mga replicas ay tinutukoy (currentReplicas)
  4. Kinakalkula ng sumusunod na formula ang nais na bilang ng mga replika (desiredReplicas)
    desiredReplicas = [ currentReplicas * ( currentMetricValue / desiredMetricValue )]

Sa kasong ito, hindi magaganap ang pag-scale kapag ang coefficient (currentMetricValue / desiredMetricValue) ay malapit sa 1 (sa kasong ito, maaari naming itakda ang pinahihintulutang error sa aming sarili; bilang default, ito ay 0.1).

Tingnan natin kung paano gumagana ang hpa gamit ang halimbawa ng app-test application (inilalarawan bilang Deployment), kung saan kinakailangang baguhin ang bilang ng mga replika depende sa pagkonsumo ng CPU:

  • Manifest ng aplikasyon

    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

    Yung. nakita namin na ang application pod ay unang inilunsad sa dalawang pagkakataon, ang bawat isa ay naglalaman ng dalawang nginx at nginx-exporter na lalagyan, para sa bawat isa kung saan isang tinukoy kahilingan para sa CPU.

  • Manipesto ng HPA

    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

    Yung. Gumawa kami ng hpa na susubaybayan ang Deployment app-test at isasaayos ang bilang ng mga pod sa application batay sa cpu indicator (inaasahan namin na dapat kumonsumo ang pod ng 30% ng CPU na hinihiling nito), kasama ang bilang ng mga replika na nasa ang hanay ng 2-10.

    Ngayon, tingnan natin ang mekanismo ng pagpapatakbo ng hpa kung maglalapat tayo ng load sa isa sa mga apuyan:

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

Sa kabuuan mayroon kaming mga sumusunod:

  • Ang nais na halaga (desiredMetricValue) - ayon sa mga setting ng hpa, mayroon kaming 30%
  • Kasalukuyang halaga (currentMetricValue) - para sa pagkalkula, kinakalkula ng controller-manager ang average na halaga ng pagkonsumo ng mapagkukunan sa %, i.e. may kondisyong ginagawa ang sumusunod:
    1. Tumatanggap ng mga ganap na halaga ng mga sukatan ng pod mula sa server ng sukatan, i.e. 101m at 4m
    2. Kinakalkula ang average na ganap na halaga, i.e. (101m + 4m) / 2 = 53m
    3. Nakukuha ang ganap na halaga para sa nais na pagkonsumo ng mapagkukunan (para dito, ang mga kahilingan ng lahat ng mga lalagyan ay buod) 60m + 30m = 90m
    4. Kinakalkula ang average na porsyento ng pagkonsumo ng CPU na may kaugnayan sa request pod, i.e. 53m / 90m * 100% = 59%

Ngayon mayroon kaming lahat ng kailangan namin upang matukoy kung kailangan naming baguhin ang bilang ng mga replika; upang gawin ito, kinakalkula namin ang koepisyent:

ratio = 59% / 30% = 1.96

Yung. ang bilang ng mga replika ay dapat dagdagan ng ~2 beses at halaga sa [2 * 1.96] = 4.

Konklusyon: Tulad ng nakikita mo, upang gumana ang mekanismong ito, ang isang kinakailangang kondisyon ay ang pagkakaroon ng mga kahilingan para sa lahat ng mga lalagyan sa naobserbahang pod.

Mekanismo para sa pahalang na autoscaling ng mga node (Cluster Autoscaler)

Para ma-neutralize ang negatibong epekto sa system sa panahon ng load surges, hindi sapat ang pagkakaroon ng naka-configure na hpa. Halimbawa, ayon sa mga setting sa hpa controller manager, napagpasyahan nito na ang bilang ng mga replika ay kailangang dagdagan ng 2 beses, ngunit ang mga node ay walang libreng mapagkukunan upang magpatakbo ng ganoong bilang ng mga pod (ibig sabihin, ang node ay hindi maaaring magbigay ng humiling ng mga mapagkukunan sa requests pod) at ang mga pod na ito ay lumipat sa Nakabinbing estado.

Sa kasong ito, kung ang provider ay may katumbas na IaaS/PaaS (halimbawa, GKE/GCE, AKS, EKS, atbp.), isang tool tulad ng Node Autoscaler. Binibigyang-daan ka nitong itakda ang maximum at minimum na bilang ng mga node sa cluster at awtomatikong isaayos ang kasalukuyang bilang ng mga node (sa pamamagitan ng pagtawag sa cloud provider API para mag-order/mag-alis ng node) kapag may kakulangan ng mga mapagkukunan sa cluster at mga pod hindi maiiskedyul (nasa Nakabinbing estado).

Konklusyon: Upang makapag-autoscale ng mga node, kinakailangang magtakda ng mga kahilingan sa mga container ng pod para ma-assess nang tama ng mga k8 ang load sa mga node at nang naaayon ay iulat na walang mga mapagkukunan sa cluster para ilunsad ang susunod na pod.

Konklusyon

Dapat tandaan na ang pagtatakda ng mga limitasyon sa mapagkukunan ng lalagyan ay hindi kinakailangan para matagumpay na tumakbo ang application, ngunit mas mahusay pa ring gawin ito para sa mga sumusunod na dahilan:

  1. Para sa mas tumpak na operasyon ng scheduler sa mga tuntunin ng load balancing sa pagitan ng mga k8s node
  2. Upang bawasan ang posibilidad na magkaroon ng kaganapang "pagpapalayas ng pod".
  3. Para gumana ang horizontal autoscaling ng mga application pod (HPA).
  4. Para sa pahalang na autoscaling ng mga node (Cluster Autoscaling) para sa mga cloud provider

Basahin din ang iba pang mga artikulo sa aming blog:

Pinagmulan: www.habr.com

Magdagdag ng komento