Kubernetes. ինչու՞ է այդքան կարևոր ստեղծել համակարգի ռեսուրսների կառավարումը:

Որպես կանոն, միշտ անհրաժեշտություն կա հավելվածին տրամադրել հատուկ ռեսուրսներ՝ դրա ճիշտ և կայուն աշխատանքի համար: Բայց ինչ անել, եթե մի քանի հավելվածներ աշխատում են նույն հզորությամբ: Ինչպե՞ս ապահովել նրանցից յուրաքանչյուրին անհրաժեշտ նվազագույն ռեսուրսներով։ Ինչպե՞ս կարող եք սահմանափակել ռեսուրսների սպառումը: Ինչպե՞ս ճիշտ բաշխել բեռը հանգույցների միջև: Ինչպե՞ս ապահովել հորիզոնական մասշտաբի մեխանիզմի աշխատանքը, եթե կիրառման բեռը մեծանա:

Kubernetes. ինչու՞ է այդքան կարևոր ստեղծել համակարգի ռեսուրսների կառավարումը:

Դուք պետք է սկսեք համակարգում ռեսուրսների հիմնական տեսակներից. սա, իհարկե, պրոցեսորի ժամանակն է և RAM-ը: K8s մանիֆեստներում այս ռեսուրսների տեսակները չափվում են հետևյալ միավորներով.

  • CPU - միջուկներում
  • RAM - բայթերով

Ավելին, յուրաքանչյուր ռեսուրսի համար հնարավոր է սահմանել երկու տեսակի պահանջ. հարցումներ и սահմանափակում. Requests - նկարագրում է հանգույցի ազատ ռեսուրսների նվազագույն պահանջները կոնտեյներ գործարկելու համար (և որպես ամբողջություն), մինչդեռ սահմանափակումները սահմանում են կոնտեյների հասանելի ռեսուրսների խիստ սահմանափակում:

Կարևոր է հասկանալ, որ մանիֆեստը չպետք է հստակորեն սահմանի երկու տեսակները, բայց վարքագիծը կլինի հետևյալը.

  • Եթե ​​բացահայտորեն նշված են միայն ռեսուրսի սահմանները, ապա այս ռեսուրսի հարցումներն ինքնաբերաբար ընդունում են սահմանաչափերին հավասար արժեք (կարող եք դա հաստատել՝ զանգահարելով նկարագրող սուբյեկտներ): Նրանք. փաստորեն, կոնտեյները կսահմանափակվի նույն քանակությամբ ռեսուրսներով, որոնք պահանջվում են աշխատելու համար:
  • Եթե ​​ռեսուրսի համար բացահայտորեն նշված են միայն հարցումները, ապա այս ռեսուրսի վրա վերին սահմանափակումներ չեն սահմանվում, այսինքն. կոնտեյները սահմանափակված է միայն հանգույցի ռեսուրսներով:

Հնարավոր է նաև կարգավորել ռեսուրսների կառավարումը ոչ միայն կոնկրետ կոնտեյների մակարդակով, այլև անվանատարածքի մակարդակում՝ օգտագործելով հետևյալ սուբյեկտները.

  • Սահմանափակ տիրույթ — նկարագրում է սահմանափակման քաղաքականությունը կոնտեյների/փոդի մակարդակում ns-ում և անհրաժեշտ է կոնտեյների/փոդի լռելյայն սահմանաչափերը նկարագրելու համար, ինչպես նաև կանխելու ակնհայտ ճարպային տարաների/պատիճների ստեղծումը (կամ հակառակը), սահմանափակելու դրանց քանակը։ և որոշել արժեքների հնարավոր տարբերությունը սահմաններում և հարցումներում
  • ResourceQuotas - նկարագրել սահմանափակման քաղաքականությունը ընդհանուր առմամբ ns-ի բոլոր կոնտեյներների համար և օգտագործվում է, որպես կանոն, ռեսուրսները սահմանազատելու համար միջավայրերի միջև (օգտակար է, երբ միջավայրերը խստորեն սահմանազատված չեն հանգույցի մակարդակում)

Ստորև բերված են ռեսուրսների սահմանաչափեր սահմանող մանիֆեստների օրինակներ.

  • Հատուկ կոնտեյների մակարդակում.

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

    Նրանք. Այս դեպքում, nginx-ով կոնտեյներ գործարկելու համար ձեզ հարկավոր է առնվազն 1 Գ ազատ օպերատիվ հիշողություն և 0.2 պրոցեսոր հանգույցի վրա, մինչդեռ կոնտեյները առավելագույնը կարող է սպառել 0.2 պրոցեսոր և հանգույցի վրա առկա բոլոր առկա օպերատիվ հիշողություն:

  • Ամբողջական մակարդակում ns:

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

    Նրանք. լռելյայն ns-ում բոլոր հարցումների բեռնարկղերի գումարը չի կարող գերազանցել 300 մ-ը CPU-ի համար և 1G-ը՝ OP-ի համար, և բոլոր սահմանաչափերի գումարը 700 մ է CPU-ի համար և 2G-ը՝ OP-ի համար:

  • 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

    Նրանք. Բոլոր կոնտեյներների համար լռելյայն անվանատարածքում հարցումը կսահմանվի 100 մ CPU-ի համար և 1G՝ OP-ի համար, սահմանը՝ 1 CPU և 2G: Միևնույն ժամանակ, սահմանվում է նաև CPU-ի (50m <x<2) և RAM-ի (500M <x<4G) հարցում/սահմանաչափի հնարավոր արժեքների սահմանափակում:

  • Pod-մակարդակի սահմանափակումներ ns.

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

    Նրանք. լռելյայն ns-ի յուրաքանչյուր պատի համար կլինի 4 vCPU և 1G սահմանաչափ:

Այժմ ես կցանկանայի ձեզ ասել, թե ինչ առավելություններ կարող է տալ մեզ այս սահմանափակումների սահմանումը:

Հանգույցների միջև բեռի հավասարակշռման մեխանիզմը

Ինչպես գիտեք, k8s բաղադրիչը պատասխանատու է հանգույցների միջև բաշխման համար, ինչպիսիք են ժամանակացույց, որն աշխատում է կոնկրետ ալգորիթմի համաձայն։ Այս ալգորիթմը մեկնարկելու համար օպտիմալ հանգույց ընտրելիս անցնում է երկու փուլով.

  1. զտման
  2. Տարածություն

Նրանք. համաձայն նկարագրված քաղաքականության, սկզբնապես ընտրվում են հանգույցներ, որոնց վրա հնարավոր է գործարկել մի փաթեթ՝ հիմնված հավաքածուի վրա պրեդիկատներ (ներառյալ ստուգել, ​​թե արդյոք հանգույցն ունի բավարար ռեսուրսներ pod-ը գործարկելու համար - PodFitsResources), այնուհետև այս հանգույցներից յուրաքանչյուրի համար՝ ըստ առաջնահերթությունները միավորներ են շնորհվում (ներառյալ՝ որքան շատ ազատ ռեսուրսներ ունի հանգույցը, այնքան ավելի շատ միավոր է հատկացվում՝ LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation) և բլոկը գործարկվում է ամենաշատ միավոր ունեցող հանգույցի վրա (եթե մի քանի հանգույցներ բավարարում են այս պայմանը միանգամից, ապա ընտրված է պատահական մեկը):

Միևնույն ժամանակ, դուք պետք է հասկանաք, որ ժամանակացույցը հանգույցի առկա ռեսուրսները գնահատելիս առաջնորդվում է այն տվյալներով, որոնք պահվում են etcd-ում, այսինքն. Այս հանգույցի վրա աշխատող յուրաքանչյուր պատի պահանջվող/սահմանափակ ռեսուրսի քանակի համար, բայց ոչ ռեսուրսի իրական սպառման համար: Այս տեղեկատվությունը կարելի է ստանալ հրամանի ելքից kubectl describe node $NODE, օրինակ `

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

Այստեղ մենք տեսնում ենք բոլոր պատիճները, որոնք աշխատում են որոշակի հանգույցի վրա, ինչպես նաև այն ռեսուրսները, որոնք պահանջում է յուրաքանչյուր pod: Եվ ահա, թե ինչ տեսք ունեն ժամանակացույցի մատյանները, երբ գործարկվում է cronjob-cron-events-1573793820-xt6q9 pod (այս տեղեկատվությունը կհայտնվի ժամանակացույցի մատյանում, երբ գրանցման 10-րդ մակարդակը սահմանվի գործարկման հրամանի արգումենտներում -v=10): ):

գերան

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

Այստեղ մենք տեսնում ենք, որ սկզբում ժամանակացույցը զտում և ստեղծում է 3 հանգույցների ցանկ, որոնց վրա այն կարող է գործարկվել (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10): Այնուհետև այն հաշվարկում է միավորները՝ հիմնվելով մի քանի պարամետրերի վրա (ներառյալ BalancedResourceAllocation, LeastResourceAllocation) այս հանգույցներից յուրաքանչյուրի համար, որպեսզի որոշի ամենահարմար հանգույցը: Ի վերջո, պատիճը նախատեսված է ամենաշատ միավորներ ունեցող հանգույցի վրա (այստեղ միանգամից երկու հանգույց ունեն նույն թվով կետերը 100037, ուստի ընտրվում է պատահական մեկը՝ nxs-k8s-s10):

ԱրտադրողականությունԵթե ​​հանգույցը գործարկում է պատյաններ, որոնց համար սահմանափակումներ չեն դրված, ապա k8-ների համար (ռեսուրսների սպառման տեսանկյունից) դա համարժեք կլինի, կարծես այս հանգույցում ընդհանրապես այդպիսի հանգույցներ չլինեն: Հետևաբար, եթե դուք, պայմանականորեն, ունեք շատակեր պրոցեսով պատիճ (օրինակ՝ wowza) և դրա համար սահմանափակումներ չեն դրված, ապա կարող է իրավիճակ առաջանալ, երբ այս պատիճն իրականում կերել է հանգույցի բոլոր ռեսուրսները, բայց k8-ների համար այս հանգույցը համարվում է բեռնաթափված, և այն կշնորհվի նույնքան միավորներ, երբ դասակարգվում է (ճշգրիտ՝ առկա ռեսուրսները գնահատող միավորներով) որպես հանգույց, որը չունի աշխատանքային հանգույցներ, ինչը, ի վերջո, կարող է հանգեցնել հանգույցների միջև բեռի անհավասար բաշխմանը:

Պոդի վտարումը

Ինչպես գիտեք, յուրաքանչյուր pod-ին հատկացվում է QoS 3 դասերից մեկը.

  1. երաշխավորված - նշանակվում է, երբ պատիճում գտնվող յուրաքանչյուր կոնտեյների համար հիշողության և պրոցեսորի համար սահմանված է հարցում և սահմանափակում, և այդ արժեքները պետք է համապատասխանեն
  2. պայթող — պատիճում առնվազն մեկ կոնտեյներ ունի հարցում և սահմանաչափ, խնդրանքով < սահմանաչափով
  3. լավագույն ջանք — երբ պատիճում ոչ մի կոնտեյներ ռեսուրս սահմանափակ չէ

Միևնույն ժամանակ, երբ հանգույցը զգում է ռեսուրսների (սկավառակ, հիշողություն) պակաս, kubelet-ը սկսում է դասավորել և դուրս հանել բլոկները՝ ըստ հատուկ ալգորիթմի, որը հաշվի է առնում pod-ի և նրա QoS դասի առաջնահերթությունը: Օրինակ, եթե խոսքը RAM-ի մասին է, ապա QoS դասի հիման վրա միավորները շնորհվում են հետևյալ սկզբունքով.

  • Երաշխավորված: -998
  • Լավագույն ջանք: 1000
  • Պայթող: min (առավելագույնը (2, 1000 - (1000 * հիշողություն RequestBytes) / մեքենաՀիշողության հզորություն բայթ), 999)

Նրանք. Նույն առաջնահերթությամբ, kubelet-ը սկզբում կվտարի պատերը՝ լավագույն ջանքերով QoS դասը հանգույցից:

ԱրտադրողականությունԵթե ​​ցանկանում եք նվազեցնել ցանկալի pod-ի հանգույցից վտարվելու հավանականությունը դրա վրա ռեսուրսների բացակայության դեպքում, ապա առաջնահերթության հետ մեկտեղ պետք է հոգ տանել նաև դրա հարցումը/սահմանը սահմանելու մասին:

Կիրառական պատյանների հորիզոնական ավտոմատ մասշտաբավորման մեխանիզմ (HPA)

Երբ խնդիր է դրված ինքնաբերաբար ավելացնել և նվազեցնել pods-ների քանակը՝ կախված ռեսուրսների օգտագործումից (համակարգ - CPU/RAM կամ օգտագործող - rps), k8s կազմվածքը, ինչպիսին է. HPA (Horizontal Pod Autoscaler): Որի ալգորիթմը հետևյալն է.

  1. Դիտարկվող ռեսուրսի ընթացիկ ընթերցումները որոշված ​​են (currentMetricValue)
  2. Որոշվում են ռեսուրսի համար ցանկալի արժեքները (ցանկալի MetricValue), որոնք համակարգի ռեսուրսների համար սահմանվում են՝ օգտագործելով հարցումը
  3. Որոշված ​​է կրկնօրինակների ընթացիկ թիվը (currentReplicas)
  4. Հետևյալ բանաձևը հաշվարկում է կրկնօրինակների ցանկալի թիվը (ցանկալի կրկնօրինակներ)
    ցանկալի կրկնօրինակներ = [ներկայիս կրկնօրինակներ * (ընթացիկՄետրական արժեք / ցանկալի մետրիկ արժեք)]

Այս դեպքում մասշտաբավորում չի առաջանա, երբ գործակիցը (currentMetricValue / ցանկալիMetricValue) մոտ է 1-ին (այս դեպքում մենք կարող ենք ինքներս սահմանել թույլատրելի սխալը. լռելյայն այն 0.1 է):

Եկեք նայենք, թե ինչպես է աշխատում hpa-ն՝ օգտագործելով app-test հավելվածի օրինակը (նկարագրված է որպես Deployment), որտեղ անհրաժեշտ է փոխել կրկնօրինակների քանակը՝ կախված պրոցեսորի սպառումից.

  • Դիմումի մանիֆեստ

    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

    Նրանք. մենք տեսնում ենք, որ հավելվածի pod սկզբնապես գործարկվում է երկու օրինակով, որոնցից յուրաքանչյուրը պարունակում է երկու nginx և nginx-արտահանող կոնտեյներ, որոնցից յուրաքանչյուրի համար նշված է. հարցումներ պրոցեսորի համար:

  • 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

    Նրանք. Մենք ստեղծեցինք hpa, որը կվերահսկի Deployment հավելվածի թեստը և կկարգավորի փոդերի քանակը հավելվածի հետ՝ հիմնվելով պրոցեսորի ցուցիչի վրա (ակնկալում ենք, որ pod-ը պետք է սպառի իր պահանջած պրոցեսորի 30%-ը), ընդ որում կրկնօրինակների քանակը կլինի: 2-10 միջակայքը:

    Հիմա եկեք նայենք hpa-ի գործարկման մեխանիզմին, եթե օջախներից մեկի վրա բեռ կիրառենք.

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

Ընդհանուր առմամբ մենք ունենք հետևյալը.

  • Ցանկալի արժեքը (ցանկալի MetricValue) - ըստ hpa պարամետրերի, մենք ունենք 30%
  • Ընթացիկ արժեք (currentMetricValue) - հաշվարկի համար վերահսկիչ-կառավարիչը հաշվարկում է ռեսուրսների սպառման միջին արժեքը %-ով, այսինքն. պայմանականորեն կատարում է հետևյալը.
    1. Ստանում է pod չափումների բացարձակ արժեքներ մետրային սերվերից, այսինքն. 101մ և 4մ
    2. Հաշվում է միջին բացարձակ արժեքը, այսինքն. (101 մ + 4 մ) / 2 = 53 մ
    3. Ստանում է բացարձակ արժեքը ցանկալի ռեսուրսի սպառման համար (դրա համար ամփոփվում են բոլոր բեռնարկղերի հարցումները) 60 մ + 30 մ = 90 մ
    4. Հաշվում է պրոցեսորի սպառման միջին տոկոսը հարցման պատի համեմատ, այսինքն. 53 մ / 90 մ * 100% = 59%

Այժմ մենք ունենք այն ամենը, ինչ անհրաժեշտ է որոշելու համար, թե արդյոք մեզ անհրաժեշտ է փոխել կրկնօրինակների քանակը, դա անելու համար մենք հաշվարկում ենք գործակիցը.

ratio = 59% / 30% = 1.96

Նրանք. կրկնօրինակների թիվը պետք է ավելացվի ~2 անգամ և կազմի [2 * 1.96] = 4:

Եզրակացություն. Ինչպես տեսնում եք, այս մեխանիզմը գործելու համար անհրաժեշտ պայման է դիտարկվող պատիճում բոլոր բեռնարկղերի հարցումների առկայությունը։

Հանգույցների հորիզոնական ավտոմատ մասշտաբավորման մեխանիզմ (Cluster Autoscaler)

Բեռի բարձրացումների ժամանակ համակարգի վրա բացասական ազդեցությունը չեզոքացնելու համար կազմաձևված hpa ունենալը բավարար չէ: Օրինակ, ըստ hpa վերահսկիչի մենեջերի կարգավորումների, նա որոշում է, որ կրկնօրինակների թիվը պետք է ավելացվի 2 անգամ, սակայն հանգույցները չունեն ազատ ռեսուրսներ՝ նման քանակի բլոկներ գործարկելու համար (այսինքն՝ հանգույցը չի կարող ապահովել պահանջվող ռեսուրսներ հարցումների պատիճ) և այս բլոկները անցնում են Սպասող վիճակի:

Այս դեպքում, եթե մատակարարն ունի համապատասխան IaaS/PaaS (օրինակ՝ GKE/GCE, AKS, EKS և այլն), նման գործիք. Հանգույցի Autoscaler. Այն թույլ է տալիս սահմանել հանգույցների առավելագույն և նվազագույն քանակը կլաստերի մեջ և ավտոմատ կերպով կարգավորել հանգույցների ընթացիկ թիվը (զանգահարելով ամպային մատակարարի API՝ հանգույց պատվիրելու/հեռացնելու համար), երբ կլաստերում և բլոկներում ռեսուրսների պակաս կա: չի կարող պլանավորվել (կանխող վիճակում են):

Եզրակացություն. Հանգույցների ավտոմատ մասշտաբավորման հնարավորության համար անհրաժեշտ է հարցումներ սահմանել պատիճ կոնտեյներներում, որպեսզի k8-ները կարողանան ճիշտ գնահատել բեռը հանգույցների վրա և համապատասխանաբար զեկուցել, որ կլաստերում ռեսուրսներ չկան հաջորդ pod գործարկելու համար:

Ամփոփում

Հարկ է նշել, որ կոնտեյներային ռեսուրսների սահմանաչափերի սահմանումը հավելվածի հաջող աշխատանքի համար պարտադիր չէ, բայց դեռ ավելի լավ է դա անել հետևյալ պատճառներով.

  1. Ժամանակացույցի ավելի ճշգրիտ աշխատանքի համար k8s հանգույցների միջև բեռի հավասարակշռման առումով
  2. Նվազեցնել «ջարդի վտարման» իրադարձության հավանականությունը
  3. Հավելվածի պատյանների (HPA) հորիզոնական ավտոմատ մասշտաբավորման համար աշխատելու համար
  4. Ամպային պրովայդերների համար հանգույցների հորիզոնական ավտոմատ մասշտաբավորման համար (Cluster Autoscaling):

Կարդացեք նաև մեր բլոգի այլ հոդվածներ.

Source: www.habr.com

Добавить комментарий