Kubernetes: چرا پیکربندی مدیریت منابع سیستم بسیار مهم است؟

به عنوان یک قاعده، همیشه نیاز به ارائه یک منبع اختصاصی از منابع برای یک برنامه کاربردی برای عملکرد صحیح و پایدار آن وجود دارد. اما اگر چندین برنامه با قدرت یکسان در حال اجرا باشند چه؟ چگونه می توان حداقل منابع لازم را برای هر یک از آنها فراهم کرد؟ چگونه می توانید مصرف منابع را محدود کنید؟ چگونه بار را بین گره ها به درستی توزیع کنیم؟ چگونه می توان مطمئن شد که مکانیزم پوسته پوسته شدن افقی در صورت افزایش بار برنامه کار می کند؟

Kubernetes: چرا پیکربندی مدیریت منابع سیستم بسیار مهم است؟

شما باید با انواع منابع اصلی در سیستم شروع کنید - البته این زمان پردازنده و RAM است. در مانیفست های k8s این نوع منابع در واحدهای زیر اندازه گیری می شوند:

  • CPU - در هسته ها
  • RAM - بر حسب بایت

علاوه بر این، برای هر منبع می توان دو نوع الزام را تعیین کرد - درخواست и محدودیت. درخواست‌ها - حداقل نیازمندی‌های منابع رایگان یک گره را برای اجرای یک کانتینر (و به طور کلی pod) توصیف می‌کند، در حالی که محدودیت‌ها محدودیت سختی را برای منابع در دسترس برای کانتینر تعیین می‌کنند.

درک این نکته مهم است که مانیفست نیازی به تعریف صریح هر دو نوع ندارد، اما رفتار به صورت زیر خواهد بود:

  • اگر فقط محدودیت‌های یک منبع به‌صراحت مشخص شده باشد، درخواست‌های این منبع به‌طور خودکار مقداری برابر با محدودیت‌ها می‌گیرند (شما می‌توانید با فراخوانی موجودیت‌های توصیف آن را تأیید کنید). آن ها در واقع، کانتینر به همان مقدار منابعی که برای اجرا نیاز دارد محدود خواهد شد.
  • اگر فقط درخواست ها به صراحت برای یک منبع مشخص شده باشند، هیچ محدودیت بالایی برای این منبع تعیین نمی شود - یعنی. ظرف فقط توسط منابع خود گره محدود می شود.

همچنین می توان مدیریت منابع را نه تنها در سطح یک ظرف خاص، بلکه در سطح فضای نام با استفاده از موجودیت های زیر پیکربندی کرد:

  • محدوده محدود - خط مشی محدودیت را در سطح کانتینر/غلاف در ns توصیف می کند و برای توصیف محدودیت های پیش فرض روی ظرف/غلاف و همچنین جلوگیری از ایجاد ظروف/غلاف آشکار چربی (یا برعکس)، محدود کردن تعداد آنها مورد نیاز است. و تفاوت احتمالی مقادیر در محدودیت ها و درخواست ها را تعیین کنید
  • سهمیه منابع - خط مشی محدودیت را به طور کلی برای همه کانتینرها در ns توصیف کنید و به عنوان یک قاعده برای محدود کردن منابع در بین محیط ها استفاده می شود (مفید زمانی که محیط ها به طور دقیق در سطح گره مشخص نشده باشند)

در زیر نمونه‌هایی از مانیفست‌هایی هستند که محدودیت‌های منابع را تعیین می‌کنند:

  • در سطح ظرف خاص:

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

    آن ها در این حالت، برای اجرای یک کانتینر با nginx، به حداقل 1G رم رایگان و 0.2 CPU روی گره نیاز دارید، در حالی که حداکثر کانتینر می تواند 0.2 CPU و تمام RAM موجود در گره را مصرف کند.

  • در سطح عدد صحیح 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 بیشتر باشد و مجموع تمام محدودیت ها برای CPU 700 متر و برای OP 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

    آن ها در فضای نام پیش‌فرض برای همه کانتینرها، درخواست روی 100 متر برای CPU و 1G برای OP، محدود - 1 CPU و 2G تنظیم می‌شود. در همان زمان، محدودیتی نیز بر روی مقادیر ممکن در درخواست/محدودیت برای CPU (50m < x < 2) و RAM (500M < x < 4G) تنظیم شده است.

  • محدودیت‌های سطح پاد ns:

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

    آن ها برای هر pod در 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، گزارش‌های زمان‌بندی چگونه به نظر می‌رسند (این اطلاعات در گزارش زمان‌بندی ظاهر می‌شوند زمانی که دهمین سطح گزارش‌گیری در آرگومان‌های دستور راه‌اندازی -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. تضمین شده است - زمانی تخصیص داده می شود که برای هر کانتینر در pod یک درخواست و محدودیت برای حافظه و cpu مشخص شود و این مقادیر باید مطابقت داشته باشند.
  2. قابل ترکیدن - حداقل یک ظرف در غلاف دارای یک درخواست و یک محدودیت، با درخواست < محدودیت است
  3. بهترین تلاش - زمانی که حتی یک ظرف در غلاف منبع محدودی ندارد

در همان زمان، هنگامی که یک گره کمبود منابع (دیسک، حافظه) را تجربه می‌کند، Kubelet شروع به رتبه‌بندی و حذف پادها بر اساس الگوریتم خاصی می‌کند که اولویت pod و کلاس QoS آن را در نظر می‌گیرد. به عنوان مثال، اگر ما در مورد RAM صحبت می کنیم، بر اساس کلاس QoS، امتیاز طبق اصل زیر تعلق می گیرد:

  • تضمین:-998
  • بهترین تلاش: 1000
  • قابل ترکیدن: حداقل (حداکثر (2، 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes)، 999)

آن ها با همان اولویت، kubelet ابتدا پادها را با بهترین تلاش کلاس QoS از گره خارج می کند.

نتیجه: اگر می خواهید احتمال خروج پاد مورد نظر از گره را در صورت کمبود منابع روی آن کاهش دهید، در کنار اولویت، باید به تنظیم درخواست/محدودیت برای آن نیز توجه کنید.

مکانیزم برای مقیاس خودکار افقی غلاف های کاربردی (HPA)

هنگامی که وظیفه افزایش و کاهش خودکار تعداد پادها بسته به استفاده از منابع (سیستم - CPU/RAM یا کاربر - rps) است، یک موجودیت k8s مانند HPA (Autoscaler Pod Horizontal). که الگوریتم آن به شرح زیر است:

  1. قرائت های فعلی منبع مشاهده شده تعیین می شود (currentMetricValue)
  2. مقادیر مورد نظر برای منبع تعیین می شود (desiredMetricValue) که برای منابع سیستم با استفاده از درخواست تنظیم می شود.
  3. تعداد نسخه‌های فعلی مشخص شده است (currentReplicas)
  4. فرمول زیر تعداد مورد نظر ماکت (DesiredReplicas) را محاسبه می کند.
    دلخواه Replicas = [Replicas فعلی * (currentMetricValue / dëshiruarMetricValue)]

در این حالت، زمانی که ضریب (currentMetricValue / dëshiruarMetricValue) نزدیک به 1 باشد، مقیاس بندی رخ نمی دهد (در این حالت، خودمان می توانیم خطای مجاز را تنظیم کنیم؛ به طور پیش فرض 0.1 است).

بیایید به نحوه عملکرد hpa با استفاده از مثال برنامه app-test (معروف به Deployment) نگاه کنیم، جایی که لازم است تعداد تکرارها را بسته به مصرف 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-exporter است که برای هر کدام یک مشخص شده است. درخواست برای 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 ایجاد کردیم که تست برنامه Deployment را نظارت می کند و تعداد پادها را با برنامه بر اساس نشانگر cpu تنظیم می کند (ما انتظار داریم که پاد باید 30٪ از CPU درخواستی خود را مصرف کند)، با تعداد کپی های موجود در آن. محدوده 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، و غیره)، ابزاری مانند خودکار مقیاس گره. این به شما امکان می دهد حداکثر و حداقل تعداد گره ها را در خوشه تنظیم کنید و به طور خودکار تعداد فعلی گره ها را تنظیم کنید (با فراخوانی API ارائه دهنده ابر برای سفارش/حذف یک گره) در صورت کمبود منابع در خوشه و پادها. نمی توان برنامه ریزی کرد (در حالت معلق هستند).

نتیجه گیری: برای اینکه بتوان گره ها را مقیاس خودکار کرد، باید درخواست ها را در کانتینرهای پاد تنظیم کرد تا k8s بتوانند به درستی بار روی گره ها را ارزیابی کنند و بر این اساس گزارش دهند که هیچ منبعی در خوشه برای راه اندازی pod بعدی وجود ندارد.

نتیجه

لازم به ذکر است که تنظیم محدودیت منابع کانتینر برای اجرای موفقیت آمیز برنامه الزامی نیست، اما به دلایل زیر بهتر است این کار انجام شود:

  1. برای عملکرد دقیق تر زمانبند از نظر تعادل بار بین گره های k8s
  2. برای کاهش احتمال وقوع یک رویداد "اخراج غلاف".
  3. برای اینکه مقیاس خودکار افقی غلاف های کاربردی (HPA) کار کند
  4. برای مقیاس خودکار افقی گره ها (Cluster Autoscaling) برای ارائه دهندگان ابر

همچنین سایر مقالات وبلاگ ما را بخوانید:

منبع: www.habr.com

اضافه کردن نظر