Kubernetes: nega tizim resurslarini boshqarishni sozlash juda muhim?

Qoidaga ko'ra, dasturning to'g'ri va barqaror ishlashi uchun har doim maxsus resurslarni taqdim etish zarurati mavjud. Ammo bir nechta ilovalar bir xil quvvatda ishlayotgan bo'lsa-chi? Ularning har birini minimal zarur resurslar bilan qanday ta'minlash mumkin? Resurs sarfini qanday cheklash mumkin? Yukni tugunlar o'rtasida qanday qilib to'g'ri taqsimlash kerak? Agar dastur yuki oshsa, gorizontal o'lchov mexanizmi ishlashini qanday ta'minlash mumkin?

Kubernetes: nega tizim resurslarini boshqarishni sozlash juda muhim?

Tizimda qanday asosiy manba turlari mavjudligidan boshlashingiz kerak - bu, albatta, protsessor vaqti va RAM. K8s manifestlarida ushbu resurs turlari quyidagi birliklarda o'lchanadi:

  • CPU - yadrolarda
  • RAM - baytlarda

Bundan tashqari, har bir resurs uchun ikki turdagi talablarni belgilash mumkin - Talablar и chegaralari. So'rovlar - konteynerni (va umuman pod) ishga tushirish uchun tugunning bepul resurslariga minimal talablarni tavsiflaydi, limitlar esa konteyner uchun mavjud resurslarga qattiq chegara qo'yadi.

Shuni tushunish kerakki, manifest ikkala turni ham aniq belgilashi shart emas, lekin xatti-harakatlar quyidagicha bo'ladi:

  • Agar faqat resurs chegaralari aniq ko'rsatilgan bo'lsa, bu resurs uchun so'rovlar avtomatik ravishda chegaralarga teng qiymatni oladi (buni tavsiflovchi ob'ektlarga qo'ng'iroq qilish orqali tekshirishingiz mumkin). Bular. aslida, konteyner ishlash uchun talab qilinadigan resurslarning bir xil miqdori bilan cheklanadi.
  • Agar resurs uchun faqat so'rovlar aniq ko'rsatilgan bo'lsa, unda bu resursda yuqori cheklovlar o'rnatilmaydi - ya'ni. konteyner faqat tugunning o'zi resurslari bilan cheklangan.

Shuningdek, resurslarni boshqarishni nafaqat ma'lum bir konteyner darajasida, balki quyidagi ob'ektlardan foydalangan holda nomlar maydoni darajasida ham sozlash mumkin:

  • LimitRange — konteyner/pod darajasida cheklash siyosatini ns-da tavsiflaydi va konteyner/poddagi standart chegaralarni tavsiflash, shuningdek, aniq yog‘li idishlar/podlar (yoki aksincha) yaratilishining oldini olish, ularning sonini cheklash uchun zarur. va chegaralar va so'rovlardagi qiymatlardagi mumkin bo'lgan farqni aniqlang
  • Resurs kvotalari — ns dagi barcha konteynerlar uchun umuman cheklash siyosatini tavsiflang va qoida tariqasida muhitlar orasidagi resurslarni chegaralash uchun ishlatiladi (muhitlar tugun darajasida qat'iy chegaralanmagan bo'lsa foydalidir)

Quyida manba chegaralarini belgilovchi manifestlarga misollar keltirilgan:

  • Maxsus konteyner darajasida:

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

    Bular. bu holda konteynerni nginx bilan ishga tushirish uchun sizga kamida 1G bepul operativ xotira va tugunga 0.2 protsessor kerak bo‘ladi, ko‘pi bilan konteyner 0.2 protsessor va tugundagi barcha mavjud operativ xotirani iste’mol qilishi mumkin.

  • ns butun soni darajasida:

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

    Bular. sukut bo'yicha ns dagi barcha so'rov konteynerlarining yig'indisi CPU uchun 300 m dan va OP uchun 1G dan oshmasligi kerak va barcha chegaralar yig'indisi CPU uchun 700 m va OP uchun 2G ni tashkil qiladi.

  • Ns dagi konteynerlar uchun standart chegaralar:

    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

    Bular. barcha konteynerlar uchun standart nomlar maydonida so'rov CPU uchun 100m va OP uchun 1G, chegara - 1 protsessor va 2G ga o'rnatiladi. Shu bilan birga, protsessor (50 m < x < 2) va RAM (500 M < x < 4G) uchun so'rov/chegarada mumkin bo'lgan qiymatlarga ham cheklov o'rnatiladi.

  • Pod darajasidagi cheklovlar:

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

    Bular. standart ns dagi har bir pod uchun 4 vCPU va 1G chegarasi bo'ladi.

Endi men sizga ushbu cheklovlarni o'rnatish bizga qanday afzalliklarni berishi mumkinligini aytmoqchiman.

Tugunlar orasidagi yukni muvozanatlash mexanizmi

Ma'lumki, k8s komponenti tugunlar o'rtasida podkalarni taqsimlash uchun javobgardir, masalan rejalashtiruvchi, bu ma'lum bir algoritmga muvofiq ishlaydi. Ushbu algoritm ishga tushirish uchun optimal tugunni tanlashda ikki bosqichdan o'tadi:

  1. filtrlash
  2. Rangli

Bular. tasvirlangan siyosatga ko'ra, dastlab tugunlar tanlanadi, ularda to'plam asosida podkastni ishga tushirish mumkin predikatlar (jumladan, tugunning podni ishga tushirish uchun yetarli resurslari mavjudligini tekshirish - PodFitsResources), so'ngra ushbu tugunlarning har biri uchun ustuvorliklar ball beriladi (jumladan, tugun qancha bo'sh resurslarga ega bo'lsa, shuncha ko'p ball beriladi - LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation) va pod eng ko'p ball to'plagan tugunda ishga tushiriladi (agar bir nechta tugunlar bir vaqtning o'zida ushbu shartni qondirsa, u holda tasodifiy tanlanadi).

Shu bilan birga, rejalashtiruvchi tugunning mavjud resurslarini baholashda etcd-da saqlanadigan ma'lumotlarga asoslanishini tushunishingiz kerak - ya'ni. ushbu tugunda ishlaydigan har bir podning so'ralgan/cheklangan resursi miqdori uchun, lekin haqiqiy resurs iste'moli uchun emas. Ushbu ma'lumotni buyruq chiqishidan olish mumkin kubectl describe node $NODE, masalan:

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

Bu erda biz ma'lum bir tugunda ishlaydigan barcha podslarni, shuningdek, har bir pod so'ragan resurslarni ko'ramiz. Va cronjob-cron-events-1573793820-xt6q9 pod ishga tushirilganda rejalashtirish jurnallari qanday ko'rinishga ega bo'ladi (bu ma'lumot ishga tushirish buyrug'i argumentlarida -v=10 ro'yxatga olishning 10-darajasini o'rnatganingizda rejalashtiruvchi jurnalida paydo bo'ladi):

jurnal

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

Bu erda biz ko'ramizki, rejalashtiruvchi dastlab ishga tushirilishi mumkin bo'lgan 3 ta tugun ro'yxatini filtrlaydi va yaratadi (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10). Keyin u eng mos tugunni aniqlash uchun ushbu tugunlarning har biri uchun bir nechta parametrlar (shu jumladan BalancedResourceAllocation, LeastResourceAllocation) asosida ballarni hisoblab chiqadi. Oxir-oqibat, pod eng ko'p ball to'plagan tugunga rejalashtirilgan (bu erda bir vaqtning o'zida ikkita tugun bir xil sonli 100037 nuqtaga ega, shuning uchun tasodifiy biri tanlanadi - nxs-k8s-s10).

xulosa: agar tugun hech qanday cheklovlar o'rnatilmagan podlarni ishga tushirsa, u holda k8lar uchun (resurs iste'moli nuqtai nazaridan) bu tugunda umuman bunday podalar yo'qligiga teng bo'ladi. Shuning uchun, agar sizda shartli ravishda ochko'z jarayonga ega bo'lgan pod bo'lsa (masalan, wowza) va u uchun hech qanday cheklovlar o'rnatilmagan bo'lsa, unda bu pod aslida tugunning barcha resurslarini yeganida vaziyat yuzaga kelishi mumkin, ammo k8s uchun bu tugun. yuklanmagan deb hisoblanadi va u ish podkastlari bo'lmagan tugun sifatida (aniq mavjud resurslarni baholash ballarida) reytingda bir xil miqdordagi ballga ega bo'ladi, bu oxir-oqibatda tugunlar o'rtasida yukning notekis taqsimlanishiga olib kelishi mumkin.

Podning quvilishi

Ma'lumki, har bir podka 3 ta QoS sinfidan biriga tayinlangan:

  1. kafolatlangan - podkastdagi har bir konteyner uchun xotira va protsessor uchun so'rov va cheklov ko'rsatilganda tayinlanadi va bu qiymatlar mos kelishi kerak
  2. portlash mumkin — poddagi kamida bitta konteynerda so‘rov va limit mavjud, so‘rov < limiti bilan
  3. eng yaxshi harakat — podda bitta konteyner ham resurs cheklangan bo'lsa

Shu bilan birga, tugun resurslarning (disk, xotira) etishmasligini boshdan kechirganda, kubelet podning ustuvorligi va uning QoS klassini hisobga oladigan aniq algoritmga muvofiq podlarni tartiblashni va chiqarib tashlashni boshlaydi. Masalan, agar biz operativ xotira haqida gapiradigan bo'lsak, unda QoS sinfiga asoslanib, ballar quyidagi printsipga muvofiq beriladi:

  • Kafolatlangan:-998
  • BestEffort: 1000
  • Burstable: min (maksimal (2, 1000 - (1000 * xotiraRequestBytes) / machineMemoryCapacityBytes), 999)

Bular. Xuddi shu ustuvorlik bilan kubelet birinchi navbatda tugundan QoS sinfining eng yaxshi kuchlari bilan podlarni chiqarib tashlaydi.

xulosa: agar siz kerakli podani tugundan undagi resurslar yetishmasa, chiqarib yuborish ehtimolini kamaytirmoqchi bo'lsangiz, u holda ustuvorlik bilan bir qatorda unga so'rov/cheklovni o'rnatish haqida ham g'amxo'rlik qilishingiz kerak.

Ilova podslarini gorizontal avtomatik masshtablash mexanizmi (HPA)

Vazifa resurslardan foydalanishga (tizim - CPU/RAM yoki foydalanuvchi - rps) qarab podalar sonini avtomatik ravishda oshirish va kamaytirish bo'lsa, k8s ob'ekti kabi. HPA (Gorizontal Pod Autoscaler). Uning algoritmi quyidagicha:

  1. Kuzatilgan resursning joriy ko'rsatkichlari aniqlanadi (currentMetricValue)
  2. Resurs uchun kerakli qiymatlar aniqlanadi (desiredMetricValue), ular tizim resurslari uchun so'rov yordamida o'rnatiladi.
  3. Joriy nusxalar soni aniqlandi (joriy replikalar)
  4. Quyidagi formula replikalarning kerakli sonini hisoblab chiqadi (desiredReplicas)
    wantdReplicas = [ currentReplicas * ( currentMetricValue / desiredMetricValue )]

Bunday holda, koeffitsient (currentMetricValue / desiredMetricValue) 1 ga yaqin bo'lganda masshtablash sodir bo'lmaydi (bu holda biz ruxsat etilgan xatoni o'zimiz belgilashimiz mumkin; sukut bo'yicha u 0.1).

Keling, hpa qanday ishlashini ilova-test ilovasi misolida ko'rib chiqaylik (tartibga solish deb ta'riflangan), bu erda protsessor iste'moliga qarab replikalar sonini o'zgartirish kerak:

  • Ilova manifest

    kind: Deployment
    apiVersion: apps/v1beta2
    metadata:
    name: app-test
    spec:
    selector:
    matchLabels:
    app: app-test
    replicas: 2
    template:
    metadata:
    labels:
    app: app-test
    spec:
    containers:
    - name: nginx
    image: registry.nixys.ru/generic-images/nginx
    imagePullPolicy: Always
    resources:
    requests:
    cpu: 60m
    ports:
    - name: http
    containerPort: 80
    - name: nginx-exporter
    image: nginx/nginx-prometheus-exporter
    resources:
    requests:
    cpu: 30m
    ports:
    - name: nginx-exporter
    containerPort: 9113
    args:
    - -nginx.scrape-uri
    - http://127.0.0.1:80/nginx-status

    Bular. Ilova podasi dastlab ikkita holatda ishga tushirilganligini ko'ramiz, ularning har birida ikkita nginx va nginx-eksport konteynerlari mavjud bo'lib, ularning har biri uchun belgilangan Talablar CPU uchun.

  • HPA manifesti

    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

    Bular. Biz hpa-ni yaratdik, u Deployment ilova-testini kuzatib boradi va protsessor ko'rsatkichi (biz protsessor so'ragan protsessorning 30 foizini iste'mol qilishi kerak deb kutamiz) asosida dastur bilan bo'laklar sonini moslashtiradi, replikalar soni esa 2-10 oralig'ida.

    Endi, agar biz o'choqlardan biriga yuk qo'llasak, hpa ishlash mexanizmini ko'rib chiqamiz:

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

Hammasi bo'lib bizda quyidagilar mavjud:

  • Istalgan qiymat (desiredMetricValue) - hpa sozlamalariga ko'ra, bizda 30% bor
  • Joriy qiymat (currentMetricValue) - hisoblash uchun boshqaruvchi-menejer resurs iste'molining o'rtacha qiymatini %da hisoblab chiqadi, ya'ni. shartli ravishda quyidagilarni bajaradi:
    1. Metrik serverdan pod ko'rsatkichlarining mutlaq qiymatlarini oladi, ya'ni. 101 m va 4 m
    2. O'rtacha mutlaq qiymatni hisoblaydi, ya'ni. (101m + 4m) / 2 = 53m
    3. Kerakli resurs iste'moli uchun mutlaq qiymatni oladi (buning uchun barcha konteynerlarning so'rovlari umumlashtiriladi) 60m + 30m = 90m
    4. So'rov podiga nisbatan CPU iste'molining o'rtacha foizini hisoblab chiqadi, ya'ni. 53m / 90m * 100% = 59%

Endi bizda replikalar sonini o'zgartirish kerakmi yoki yo'qligini aniqlash uchun kerak bo'lgan hamma narsa bor, buning uchun koeffitsientni hisoblaymiz:

ratio = 59% / 30% = 1.96

Bular. replikalar soni ~ 2 marta ko'paytirilishi va [2 * 1.96] = 4 ga teng bo'lishi kerak.

xulosa: Ko'rib turganingizdek, ushbu mexanizmning ishlashi uchun zarur shart - bu kuzatilgan podada barcha konteynerlar uchun so'rovlarning mavjudligi.

Tugunlarni gorizontal avtomatik masshtablash mexanizmi (Cluster Autoscaler)

Yuk ko'tarilishi paytida tizimga salbiy ta'sirni bartaraf etish uchun sozlangan hpa ga ega bo'lish etarli emas. Masalan, hpa kontroller menejeridagi sozlamalarga ko'ra, u replikatsiyalar sonini 2 baravar oshirish kerak, deb qaror qiladi, lekin tugunlarda bunday sonli podkastlarni ishga tushirish uchun bepul resurslar yo'q (ya'ni, tugun o'z-o'zidan foydalanishni ta'minlay olmaydi). so'ralgan manbalar so'rovlar podasiga) va bu podlar Kutish holatiga o'tadi.

Bunday holda, agar provayderda mos keladigan IaaS/PaaS bo'lsa (masalan, GKE/GCE, AKS, EKS va boshqalar), shunga o'xshash vosita Tugunni avtomatik o'lchovchi. Bu sizga klasterdagi tugunlarning maksimal va minimal sonini belgilash va klaster va podkastlarda resurslar yetishmaganda joriy tugunlar sonini avtomatik ravishda sozlash imkonini beradi (tugunga buyurtma berish/oʻchirish uchun bulut provayderi APIsiga qoʻngʻiroq qilish orqali). rejalashtirish mumkin emas (kutish holatida).

xulosa: Tugunlarni avtomatik o'lchash imkoniyatiga ega bo'lish uchun pod konteynerlarida so'rovlarni o'rnatish kerak, shunda k8s tugunlarga yukni to'g'ri baholay oladi va shunga mos ravishda keyingi podni ishga tushirish uchun klasterda resurslar yo'qligi haqida xabar beradi.

xulosa

Shuni ta'kidlash kerakki, konteyner resurslari chegaralarini belgilash dasturning muvaffaqiyatli ishlashi uchun shart emas, lekin quyidagi sabablarga ko'ra buni qilish yaxshiroqdir:

  1. K8s tugunlari orasidagi yukni muvozanatlash nuqtai nazaridan rejalashtiruvchining aniqroq ishlashi uchun
  2. "Podni ko'chirish" hodisasining yuzaga kelishi ehtimolini kamaytirish uchun
  3. Ishlash uchun dastur podslarini (HPA) gorizontal avtomatik masshtablash uchun
  4. Bulutli provayderlar uchun tugunlarning gorizontal avtomatik o'lchamlari uchun (Cluster Autoscaling).

Shuningdek, bizning blogimizdagi boshqa maqolalarni o'qing:

Manba: www.habr.com

a Izoh qo'shish