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 и цялата налична 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 по подразбиране не може да надвишава 300m за процесора и 1G за OP, а сборът от всички ограничения е 700m за 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

    Тези. в пространството на имената по подразбиране за всички контейнери, заявката ще бъде зададена на 100m за CPU и 1G за OP, ограничение - 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

    Тези. за всеки pod в ns по подразбиране ще има ограничение от 4 vCPU и 1G.

Сега бих искал да ви кажа какви предимства може да ни даде поставянето на тези ограничения.

Механизъм за балансиране на натоварването между възлите

Както знаете, компонентът k8s е отговорен за разпределението на pods между възли, като напр Scheduler, който работи по определен алгоритъм. Този алгоритъм преминава през два етапа при избора на оптималния възел за стартиране:

  1. филтриране
  2. Обхват

Тези. съгласно описаната политика, първоначално се избират възли, на които е възможно да се стартира pod въз основа на набор предикати (включително проверка дали възелът има достатъчно ресурси, за да стартира pod - PodFitsResources), и след това за всеки от тези възли, според приоритети се присъждат точки (включително колкото повече свободни ресурси има даден възел, толкова повече точки му се присвояват - LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation) и подът се стартира на възела с най-много точки (ако няколко възела отговарят на това условие наведнъж, тогава избран е случаен) .

В същото време трябва да разберете, че планировчикът, когато оценява наличните ресурси на възел, се ръководи от данните, които се съхраняват в etcd - т.е. за количеството заявен/ограничен ресурс на всеки pod, работещ на този възел, но не и за действителното потребление на ресурси. Тази информация може да бъде получена от изхода на командата 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. гарантирано — се присвоява, когато за всеки контейнер в pod са посочени заявка и лимит за памет и процесор и тези стойности трябва да съвпадат
  2. разрушаващ се — поне един контейнер в групата има заявка и ограничение, с искане < ограничение
  3. най-добри усилия — когато нито един контейнер в групата не е с ограничен ресурс

В същото време, когато даден възел изпита липса на ресурси (диск, памет), kubelet започва да класира и изгонва pods според специфичен алгоритъм, който взема предвид приоритета на pod и неговия QoS клас. Например, ако говорим за RAM, тогава въз основа на класа QoS точките се присъждат съгласно следния принцип:

  • Гарантирано: -998
  • Най-доброто усилие: 1000
  • Разрушим: min(max(2, 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)

Тези. със същия приоритет, kubelet първо ще изгони подове с най-добрия QoS клас от възела.

Продукция: ако искате да намалите вероятността желаният под да бъде изгонен от възела в случай на липса на ресурси в него, тогава заедно с приоритета трябва да се погрижите и за задаването на заявката/лимита за него.

Механизъм за хоризонтално автоматично мащабиране на пакети приложения (HPA)

Когато задачата е автоматично да се увеличава и намалява броят на подовете в зависимост от използването на ресурси (система - CPU/RAM или потребител - rps), такъв k8s обект като HPA (Horizontal Pod Autoscaler). Алгоритъмът на което е както следва:

  1. Определят се текущите показания на наблюдавания ресурс (currentMetricValue)
  2. Определят се желаните стойности за ресурса (desiredMetricValue), които за системните ресурси се задават с помощта на заявка
  3. Определя се текущият брой реплики (currentReplicas)
  4. Следната формула изчислява желания брой реплики (desiredReplicas)
    желани реплики = [ текущи реплики * ( текуща метрична стойност / желана метрична стойност )]

В този случай няма да настъпи мащабиране, когато коефициентът (currentMetricValue / desireMetricValue) е близо до 1 (в този случай можем сами да зададем допустимата грешка; по подразбиране тя е 0.1).

Нека да разгледаме как работи hpa, използвайки примера на приложението за тестване на приложения (описано като разполагане), където е необходимо да промените броя на репликите в зависимост от потреблението на процесора:

  • Манифест на приложението

    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, който ще наблюдава теста на приложението за внедряване и ще коригира броя на подовете с приложението въз основа на индикатора за процесора (очакваме, че подът трябва да консумира 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. Получава абсолютни стойности на показателите на pod от сървъра на показателите, т.е. 101м и 4м
    2. Изчислява средната абсолютна стойност, т.е. (101m + 4m) / 2 = 53m
    3. Получава абсолютната стойност за желаното потребление на ресурси (за това заявките на всички контейнери се сумират) 60m + 30m = 90m
    4. Изчислява средния процент на потребление на процесора по отношение на заявката, т.е. 53m / 90m * 100% = 59%

Сега имаме всичко необходимо, за да определим дали трябва да променим броя на репликите; за да направим това, изчисляваме коефициента:

ratio = 59% / 30% = 1.96

Тези. броят на репликите трябва да се увеличи ~2 пъти и да възлиза на [2 * 1.96] = 4.

Заключение: Както можете да видите, за да работи този механизъм, необходимо условие е наличието на заявки за всички контейнери в наблюдавания pod.

Механизъм за хоризонтално автоматично мащабиране на възли (Cluster Autoscaler)

За да се неутрализира отрицателното въздействие върху системата по време на скокове на натоварване, не е достатъчно да имате конфигуриран hpa. Например, според настройките в мениджъра на контролера на hpa, той решава, че броят на репликите трябва да се увеличи 2 пъти, но възлите нямат свободни ресурси, за да стартират такъв брой подове (т.е. възелът не може да осигури поискани ресурси към групата заявки) и тези групи превключват в състояние на чакане.

В този случай, ако доставчикът има съответен IaaS/PaaS (например GKE/GCE, AKS, EKS и т.н.), инструмент като Възел Autoscaler. Позволява ви да зададете максималния и минималния брой възли в клъстера и автоматично да коригирате текущия брой възли (чрез извикване на API на доставчика на облак, за да поръчате/премахнете възел), когато има липса на ресурси в клъстера и подовете не могат да бъдат планирани (са в състояние на изчакване).

Заключение: За да можете автоматично да мащабирате възлите, е необходимо да зададете заявки в контейнерите на pod, така че k8s да може правилно да оцени натоварването на възлите и съответно да докладва, че няма ресурси в клъстера за стартиране на следващия pod.

Заключение

Трябва да се отбележи, че задаването на ограничения на ресурсите на контейнера не е изискване за успешното изпълнение на приложението, но все пак е по-добре да го направите поради следните причини:

  1. За по-точна работа на планировчика по отношение на балансирането на натоварването между k8s възлите
  2. За да се намали вероятността от възникване на събитие „изгонване на капсула“.
  3. За работа с хоризонтално автоматично мащабиране на пакети приложения (HPA).
  4. За хоризонтално автоматично мащабиране на възли (Cluster Autoscaling) за облачни доставчици

Прочетете и други статии в нашия блог:

Източник: www.habr.com

Добавяне на нов коментар