Kubernetes: система ресурстарын башкарууну конфигурациялоо эмне үчүн абдан маанилүү?

Эреже катары, анын туура жана туруктуу иштеши үчүн ар дайым ресурстардын атайын пулун берүү зарылчылыгы бар. Бирок бир эле кубаттуулукта бир нече тиркемелер иштеп жатсачы? Алардын ар бирин минималдуу зарыл ресурстар менен кантип камсыз кылуу керек? Ресурстарды керектөөнү кантип чектөөгө болот? Түйүндөр ортосунда жүктү кантип туура бөлүштүрүү керек? Тиркеме жүктөмү көбөйсө, горизонталдуу масштабдоо механизминин иштешин кантип камсыз кылуу керек?

Kubernetes: система ресурстарын башкарууну конфигурациялоо эмне үчүн абдан маанилүү?

Системада ресурстардын кандай негизги түрлөрү бар экенинен баштоо керек - бул, албетте, процессордун убактысы жана RAM. k8s манифесттеринде бул ресурстардын түрлөрү төмөнкү бирдиктер менен өлчөнөт:

  • CPU - өзөктө
  • RAM - байт менен

Мындан тышкары, ар бир ресурс үчүн талаптардын эки түрүн коюуга болот - суроо-талаптар и чектери. Сурамдар - контейнерди иштетүү үчүн түйүндүн бош ресурстарына минималдуу талаптарды сүрөттөйт (жана бүтүндөй подъезд), ал эми чектөөлөр контейнерге жеткиликтүү ресурстарга катуу чектөө коёт.

Манифесттин эки түрүн тең так аныктоого тийиш эмес экенин түшүнүү маанилүү, бирок жүрүм-турум төмөнкүдөй болот:

  • Эгерде ресурстун чектери гана ачык көрсөтүлсө, анда бул ресурска суроо-талаптар автоматтык түрдө чектерге барабар маанини алат (сиз муну сүрөттөгөн объекттерге чалуу менен текшерсеңиз болот). Ошол. чындыгында, контейнер иштетүү үчүн талап кылынган ресурстардын бирдей көлөмү менен чектелет.
  • Эгерде ресурс үчүн суроо-талаптар гана ачык көрсөтүлсө, анда бул ресурста эч кандай жогорку чектөөлөр коюлбайт - б.а. контейнер түйүнүнүн ресурстары менен гана чектелет.

Ресурстарды башкарууну белгилүү бир контейнердин деңгээлинде гана эмес, ошондой эле төмөнкү объекттерди колдонуу менен аттар мейкиндигинин деңгээлинде конфигурациялоого болот:

  • LimitRange — ns менен контейнер/под деңгээлинде чектөө саясатын сүрөттөйт жана контейнер/под боюнча демейки чектөөлөрдү сүрөттөө, ошондой эле ачык майлуу идиштерди/поддорду (же тескерисинче) түзүүгө жол бербөө, алардын санын чектөө үчүн керек. жана чектерде жана суроо-талаптардагы баалуулуктардагы мүмкүн болгон айырманы аныктаңыз
  • Ресурстук квоталар — ns ичиндеги бардык контейнерлер үчүн жалпысынан чектөө саясатын сүрөттөйт жана, эреже катары, чөйрөлөр арасында ресурстарды чектөө үчүн колдонулат (чөйрө түйүн деңгээлинде так чектелбеген учурда пайдалуу)

Төмөндө ресурстук чектөөлөрдү койгон манифесттердин мисалдары келтирилген:

  • Контейнердин конкреттүү деңгээлинде:

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

    Ошол. бул учурда, nginx менен контейнерди иштетүү үчүн сизге кеминде 1G бош RAM жана түйүндө 0.2 CPU керек болот, ал эми контейнер эң көп дегенде 0.2 CPU жана түйүндөгү бардык жеткиликтүү оперативдүү эстутумду керектей алат.

  • Бүтүн сан деңгээлинде ns:

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

    Ошол. демейки ns ичиндеги бардык суроо контейнерлеринин суммасы CPU үчүн 300мден жана ОП үчүн 1Gден ашпашы керек, ал эми бардык чектин суммасы CPU үчүн 700м жана ОП үчүн 2G.

  • 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

    Ошол. бардык контейнерлер үчүн демейки аталыш мейкиндигинде сурам CPU үчүн 100м жана OP үчүн 1G, чек - 1 CPU жана 2G деп коюлат. Ошол эле учурда, CPU (50m < x < 2) жана RAM (500M < x < 4G) үчүн суроо-талап/лимитте мүмкүн болгон маанилерге да чек коюлган.

  • Под деңгээлиндеги чектөөлөр:

    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. Рангинг

Ошол. сүрөттөлгөн саясатка ылайык, алгач түйүндөр тандалып алынат, аларда топтомдун негизинде подводду ишке киргизүүгө болот предикаттар (анын ичинде түйүндүн подкатты иштетүү үчүн жетиштүү ресурстары бар-жоктугун текшерүү - 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%)

Бул жерде биз белгилүү бир түйүндө иштеген бардык поддондорду, ошондой эле ар бир поддон сураган ресурстарды көрөбүз. Жана бул жерде cronjob-cron-events-1573793820-xt6q9 подъезди ишке киргизилгенде пландаштыргыч журналдары кандай болот (бул маалымат пландоочу журналда сиз баштоо буйругунун аргументтерине 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).

жыйынтыктоо: эгерде түйүн эч кандай чектөөлөр коюлбаган подкасттарды иштетсе, анда k8s үчүн (ресурстарды керектөө көз карашынан алганда) бул түйүндө мындай подкектер такыр жок болгонго барабар болот. Ошондуктан, эгерде сизде шарттуу түрдө ашказан процесси бар подколь (мисалы, wowza) болсо жана ага эч кандай чектөөлөр коюлбаса, анда бул поддон чындыгында түйүндүн бардык ресурстарын жеп койгондо кырдаал келип чыгышы мүмкүн, бирок k8s үчүн бул түйүн. түшүрүлгөн деп эсептелинет жана ага (так колдо болгон ресурстарды баалоочу упайларда) рейтингде иштеген түйүн катары бирдей сандагы упай ыйгарылат, бул акыр аягында түйүндөрдүн ортосунда жүктүн бирдей эмес бөлүштүрүлүшүнө алып келиши мүмкүн.

Поддун чыгарылышы

Белгилүү болгондой, ар бир подрядга 3 QoS класстарынын бири ыйгарылган:

  1. гарантияланган - подкасттагы ар бир контейнер үчүн эстутум жана процессор үчүн суроо-талап жана чек көрсөтүлгөндө дайындалат жана бул маанилер дал келиши керек
  2. жарылуучу — капчыктагы жок дегенде бир контейнерде суроо-талап жана чектөө бар, өтүнүч < чек менен
  3. жакшы аракет — капчыктагы бир дагы контейнер ресурс чектелбегенде

Ошол эле учурда, түйүн ресурстардын (диск, эс тутум) жетишсиздигин сезгенде, kubelet поддондун приоритеттүүлүгүн жана анын QoS классын эске алган белгилүү бир алгоритм боюнча подряддарды рейтингге келтирип, чыгара баштайт. Мисалы, RAM жөнүндө сөз болсо, анда QoS классынын негизинде упайлар төмөнкү принцип боюнча ыйгарылат:

  • кепилденген:-998
  • BestEffort: 1000
  • Burstable: мин(макс(2, 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)

Ошол. ошол эле артыкчылык менен, kubelet адегенде түйүндөн QoS классынын эң жакшы аракети менен поддондорду чыгарат.

жыйынтыктоо: эгер сиз керектүү поддондун түйүнүндө ресурстардын жетишсиздигинен чыгарылып кетүү ыктымалдыгын азайтууну кааласаңыз, анда артыкчылык менен бирге, ага суроо-талапты/лимитти коюуга да кам көрүшүңүз керек.

Колдонмо подкасттарын горизонталдуу автоскалдаштыруу механизми (HPA)

Милдет ресурстардын колдонулушуна жараша (система - CPU/RAM же колдонуучу - rps) поддондордун санын автоматтык түрдө көбөйтүү жана азайтуу болгондо, мындай k8s объектиси мбар (Горизонталдык Pod Autoscaler). Анын алгоритми төмөнкүдөй:

  1. Байкоочу ресурстун учурдагы көрсөткүчтөрү аныкталат (currentMetricValue)
  2. Ресурс үчүн керектүү маанилер аныкталат (desiredMetricValue), алар системалык ресурстар үчүн суроо-талаптын жардамы менен орнотулат
  3. Репликалардын учурдагы саны аныкталды (currentReplicas)
  4. Төмөнкү формула репликалардын керектүү санын эсептейт (desiredReplicas)
    wantdReplicas = [CurrentReplicas * (CurrentMetricValue / desiredMetricValue)]

Бул учурда, коэффицент (currentMetricValue / wantdMetricValue) 1ге жакын болгондо масштабдоо болбойт (бул учурда биз жол берилген катаны өзүбүз орното алабыз; демейки боюнча 0.1).

Келгиле, hpa кантип иштээрин колдонмо-сынак тиркемесинин (Орнотуу катары сүрөттөлгөн) мисалында карап көрөлү, мында CPU керектөөсүнө жараша репликалардын санын өзгөртүү керек:

  • Колдонмо манифести

    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

    Ошол. биз тиркеме подъезди алгач эки инстанцияда ишке киргизилгенин көрүп жатабыз, алардын ар бири эки nginx жана nginx-экспорттоочу контейнерлерди камтыйт, алардын ар бири үчүн белгиленген суроо-талаптар CPU үчүн.

  • 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 түздүк, ал Жайгаштыруу колдонмо-сынагына көз салып, приложение менен поддондордун санын cpu индикаторунун негизинде тууралайт (под сураган CPUнин 30% керектешет деп күтөбүз), репликалардын саны диапазону 2-10.

    Эми, эгерде биз очоктордун бирине жүк берсек, hpa иштөө механизмин карап көрөлү:

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

Жалпысынан бизде төмөнкүлөр бар:

  • Керектүү маани (desiredMetricValue) - hpa жөндөөлөрүнө ылайык, бизде 30%
  • Учурдагы маани (currentMetricValue) - эсептөө үчүн контроллер-менеджер ресурстарды керектөөнүн орточо маанисин % менен эсептейт, б.а. шарттуу түрдө төмөнкүлөрдү аткарат:
    1. Метрикалык серверден под метрикалардын абсолюттук маанилерин алат, б.а. 101м жана 4м
    2. Орточо абсолюттук маанини эсептейт, б.а. (101м + 4м) / 2 = 53м
    3. Керектүү ресурс керектөө үчүн абсолюттук маанини алат (бул үчүн бардык контейнерлердин суроо-талаптары жыйынтыкталган) 60м + 30м = 90м
    4. Сурам подготкусуна салыштырмалуу CPU керектөөнүн орточо пайызын эсептейт, б.а. 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 ж.б.) бар болсо, төмөнкүдөй курал Node Autoscaler. Ал кластердеги түйүндөрдүн максималдуу жана минималдуу санын коюуга жана кластерде жана подкасттарда ресурстар жетишсиз болгондо түйүндөрдүн учурдагы санын автоматтык түрдө жөнгө салууга мүмкүндүк берет (түйүнгө буйрутма берүү/алып салуу үчүн булут провайдеринин API'син чакыруу менен). пландаштырууга болбойт (Күтүүдө).

корутундусу: Түйүндөрдү автоматтык түрдө масштабдай алуу үчүн, k8s түйүндөрдөгү жүктөмдү туура баалоосу үчүн жана тиешелүү түрдө кластерде кийинки подкукту ишке киргизүү үчүн ресурстар жок деп кабарлашы үчүн поддон контейнерлерине суроо-талаптарды коюу керек.

жыйынтыктоо

Белгилей кетчү нерсе, контейнер ресурстарынын чектерин коюу колдонмонун ийгиликтүү иштеши үчүн талап эмес, бирок төмөнкү себептерден улам муну кылган жакшы:

  1. k8s түйүндөрүнүн ортосундагы жүк балансы жагынан пландаштыргычтын так иштеши үчүн
  2. "Подок чыгаруу" окуясынын пайда болуу ыктымалдыгын азайтуу үчүн
  3. Колдонмо подкасттарын (HPA) горизонталдуу авто масштабдоо үчүн
  4. Булут провайдерлери үчүн түйүндөрдү горизонталдуу автоскалдаштыруу үчүн (Cluster Autoscaling).

Биздин блогдогу башка макалаларды да окуңуз:

Source: www.habr.com

Комментарий кошуу