Kubernet'ler: sistem kaynak yönetimini kurmak neden bu kadar önemli?

Kural olarak, bir uygulamanın doğru ve istikrarlı çalışması için her zaman özel bir kaynak havuzunun sağlanmasına ihtiyaç vardır. Peki ya aynı güçte birden fazla uygulama çalışıyorsa? Her birine gerekli minimum kaynaklar nasıl sağlanır? Kaynak tüketimini nasıl sınırlayabilirsiniz? Yük düğümler arasında doğru şekilde nasıl dağıtılır? Uygulama yükünün artması durumunda yatay ölçeklendirme mekanizmasının çalışması nasıl sağlanır?

Kubernet'ler: sistem kaynak yönetimini kurmak neden bu kadar önemli?

Sistemde hangi ana kaynak türlerinin mevcut olduğuyla başlamanız gerekir - bu elbette işlemci zamanı ve RAM'dir. K8s bildirimlerinde bu kaynak türleri aşağıdaki birimlerle ölçülür:

  • CPU - çekirdeklerde
  • RAM - bayt cinsinden

Ayrıca her kaynak için iki tür gereksinim belirlemek mümkündür: isteklerinizi и sınırları. İstekler - bir konteyneri (ve bir bütün olarak kapsülü) çalıştırmak için bir düğümün ücretsiz kaynaklarına yönelik minimum gereksinimleri açıklar; limitler ise konteynerin kullanabileceği kaynaklara kesin bir sınır koyar.

Bildirinin her iki türü de açıkça tanımlaması gerekmediğini ancak davranışın aşağıdaki gibi olacağını anlamak önemlidir:

  • Yalnızca bir kaynağın sınırları açıkça belirtilirse, bu kaynağa yönelik istekler otomatik olarak sınırlara eşit bir değer alır (bunu, tanımlayıcı varlıkları çağırarak doğrulayabilirsiniz). Onlar. aslında konteyner, çalışması için ihtiyaç duyduğu kaynak miktarıyla sınırlı olacaktır.
  • Bir kaynak için yalnızca istekler açıkça belirtilmişse, bu kaynak üzerinde herhangi bir üst kısıtlama ayarlanmaz; kapsayıcı yalnızca düğümün kendi kaynaklarıyla sınırlıdır.

Kaynak yönetimini yalnızca belirli bir kapsayıcı düzeyinde değil aynı zamanda aşağıdaki varlıkları kullanarak ad alanı düzeyinde de yapılandırmak mümkündür:

  • SınırAralığı — ns cinsinden kap/kapsül düzeyindeki kısıtlama politikasını açıklar ve kap/kapsül üzerindeki varsayılan limitleri tanımlamak ve aynı zamanda açıkça yağ içeren kapların/kapsüllerin (veya tam tersi) oluşturulmasını önlemek ve bunların sayısını sınırlamak için gereklidir. limitler ve isteklerdeki değerlerdeki olası farkı belirlemek
  • KaynakKotaları — ns'deki tüm kapsayıcılar için genel olarak kısıtlama politikasını açıklar ve kural olarak ortamlar arasındaki kaynakları sınırlamak için kullanılır (ortamlar düğüm düzeyinde kesin olarak sınırlandırılmadığında kullanışlıdır)

Aşağıda kaynak sınırlarını belirleyen bildirim örnekleri verilmiştir:

  • Belirli konteyner düzeyinde:

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

    Onlar. bu durumda, bir konteyneri nginx ile çalıştırmak için düğümde en az 1G boş RAM ve 0.2 CPU'ya ihtiyacınız olacak, konteyner en fazla 0.2 CPU ve düğümdeki tüm kullanılabilir RAM'i tüketebilir.

  • ns tamsayı düzeyinde:

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

    Onlar. Varsayılan ns'deki tüm istek kapsayıcılarının toplamı CPU için 300 m'yi ve OP için 1G'yi geçemez ve tüm limitlerin toplamı CPU için 700 m ve OP için 2G'dir.

  • Ns cinsinden kapsayıcılar için varsayılan sınırlar:

    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

    Onlar. tüm kapsayıcılar için varsayılan ad alanında istek, CPU için 100m ve OP için 1G, limit - 1 CPU ve 2G olarak ayarlanacaktır. Aynı zamanda CPU (50m < x < 2) ve RAM (500M < x < 4G) için istek/limitteki olası değerlere de bir sınır koyulur.

  • Kapsül düzeyindeki kısıtlamalar:

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

    Onlar. varsayılan ns'deki her bölme için 4 vCPU ve 1G sınırı olacaktır.

Şimdi size bu kısıtlamaları koymanın bize ne gibi avantajlar sağlayabileceğini anlatmak istiyorum.

Düğümler arasında yük dengeleme mekanizması

Bildiğiniz gibi k8s bileşeni, pod'ların düğümler arasındaki dağıtımından sorumludur; Zamanlayıcıbelirli bir algoritmaya göre çalışır. Bu algoritma, başlatılacak en uygun düğümü seçerken iki aşamadan geçer:

  1. süzme
  2. değişen

Onlar. açıklanan politikaya göre, başlangıçta bir diziye dayalı olarak bir bölmeyi başlatmanın mümkün olduğu düğümler seçilir. yüklemler (düğümün bölmeyi çalıştırmak için yeterli kaynağa sahip olup olmadığının kontrol edilmesi dahil - PodFitsResources) ve ardından bu düğümlerin her biri için, aşağıdakilere göre öncelikleri puanlar verilir (bir düğüm ne kadar çok boş kaynağa sahip olursa, ona o kadar çok puan atanır - En Az Kaynak Tahsisi/En Az Talep Edilen Öncelik/Dengeli Kaynak Tahsisi dahil) ve bölme en çok puana sahip düğümde başlatılır (birden fazla düğüm bu koşulu aynı anda karşılıyorsa, o zaman rastgele bir tanesi seçilir).

Aynı zamanda, bir düğümün mevcut kaynaklarını değerlendirirken zamanlayıcının, vbd'de depolanan veriler tarafından yönlendirildiğini anlamalısınız - yani. bu düğümde çalışan her bölmenin talep edilen/sınırlı kaynak miktarı için, ancak gerçek kaynak tüketimi için değil. Bu bilgi komut çıktısından elde edilebilir. kubectl describe node $NODEÖrneğin:

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

Burada belirli bir düğümde çalışan tüm bölmelerin yanı sıra her bölmenin talep ettiği kaynakları görüyoruz. Cronjob-cron-events-1573793820-xt6q9 bölmesi başlatıldığında zamanlayıcı günlükleri şu şekilde görünür (bu bilgi, başlangıç ​​komutu argümanlarında -v=10 10. günlük kaydını ayarladığınızda zamanlayıcı günlüğünde görünecektir):

geniş martı

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

Burada, başlangıçta zamanlayıcının filtrelediğini ve başlatılabileceği 3 düğümden oluşan bir liste oluşturduğunu görüyoruz (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10). Daha sonra, en uygun düğümü belirlemek amacıyla bu düğümlerin her biri için çeşitli parametrelere (BalancedResourceAllocation, LeastResourceAllocation dahil) dayalı olarak puanları hesaplar. Sonuçta bölme, en yüksek puan sayısına sahip düğümde planlanır (burada iki düğüm aynı anda aynı sayıda 100037 noktasına sahiptir, dolayısıyla rastgele bir tane seçilir - nxs-k8s-s10).

Aviator apk: Bir düğüm, hiçbir kısıtlamanın ayarlanmadığı bölmeleri çalıştırıyorsa, o zaman k8'ler için (kaynak tüketimi açısından) bu, bu düğümde hiç böyle bölmeler yokmuş gibi eşdeğer olacaktır. Bu nedenle, şartlı olarak obur bir sürece sahip bir bölmeniz varsa (örneğin, wowza) ve bunun için herhangi bir kısıtlama ayarlanmamışsa, bu bölmenin aslında düğümün tüm kaynaklarını yediği, ancak k8'ler için bu düğümün olduğu bir durum ortaya çıkabilir. yüksüz olarak kabul edilir ve çalışan bölmelere sahip olmayan bir düğüm olarak sıralanırken (tam olarak mevcut kaynakları değerlendiren puanlarda) aynı sayıda puanla ödüllendirilir; bu da sonuçta yükün düğümler arasında eşit olmayan bir şekilde dağılmasına yol açabilir.

Pod'un tahliyesi

Bildiğiniz gibi her pod'a 3 QoS sınıfından biri atanır:

  1. garantili — bölmedeki her konteyner için bellek ve işlemci için bir istek ve limit belirlendiğinde ve bu değerlerin eşleşmesi gerektiğinde atanır
  2. patlayabilir — bölmedeki en az bir kapsayıcının bir isteği ve bir sınırı vardır; istek < limit ile
  3. en iyi çaba — bölmedeki tek bir konteynerin kaynağı sınırlı olmadığında

Aynı zamanda, bir düğüm kaynak eksikliği (disk, bellek) yaşadığında kubelet, pod'un önceliğini ve QoS sınıfını dikkate alan belirli bir algoritmaya göre pod'ları sıralamaya ve çıkarmaya başlar. Örneğin RAM'den bahsediyorsak, QoS sınıfına göre puanlar aşağıdaki prensibe göre verilir:

  • Garantili:-998
  • En iyi çaba: 1000
  • patlayabilir: min(max(2, 1000 - (1000 *memoryRequestBytes) / machineMemoryCapacityBytes), 999)

Onlar. Aynı önceliğe sahip olan kubelet, ilk önce QoS sınıfının en iyi çabasına sahip bölmeleri düğümden çıkaracaktır.

Aviator apk: Kaynak eksikliği durumunda istenen bölmenin düğümden çıkarılma olasılığını azaltmak istiyorsanız önceliğin yanı sıra, bunun için istek/sınır ayarlamaya da dikkat etmeniz gerekir.

Uygulama bölmelerinin (HPA) yatay otomatik ölçeklendirme mekanizması

Görev, kaynakların (sistem - CPU/RAM veya kullanıcı - rps) kullanımına bağlı olarak bölme sayısını otomatik olarak artırmak veya azaltmak olduğunda, aşağıdaki gibi bir k8s varlığı HPA (Yatay Pod Otomatik Ölçekleyici). Algoritması aşağıdaki gibidir:

  1. Gözlemlenen kaynağın mevcut okumaları belirlenir (currentMetricValue)
  2. Kaynak için istenen değerler belirlenir (desiredMetricValue), sistem kaynakları için istek kullanılarak ayarlanır
  3. Mevcut kopya sayısı belirlenir (currentReplicas)
  4. Aşağıdaki formül istenen kopya sayısını (desiredReplicas) hesaplar
    arzu edilenKopyalar = [ currentReplicas * ( currentMetricValue / istenilenMetricValue )]

Bu durumda katsayı (currentMetricValue / istenilenMetricValue) 1'e yakın olduğunda ölçeklendirme yapılmayacaktır (bu durumda izin verilen hatayı kendimiz ayarlayabiliriz; varsayılan olarak 0.1'dir).

CPU tüketimine bağlı olarak kopya sayısını değiştirmenin gerekli olduğu uygulama testi uygulaması (Dağıtım olarak tanımlanır) örneğini kullanarak hpa'nın nasıl çalıştığına bakalım:

  • Uygulama bildirimi

    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

    Onlar. uygulama bölmesinin başlangıçta her biri iki nginx ve nginx-exporter kapsayıcısı içeren iki durumda başlatıldığını görüyoruz; isteklerinizi CPU için.

  • HPA Manifestosu

    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

    Onlar. Dağıtım uygulaması testini izleyecek ve cpu göstergesine dayalı olarak uygulamadaki pod sayısını ayarlayacak bir hpa oluşturduk (podun talep ettiği CPU'nun %30'unu tüketmesini bekliyoruz), kopya sayısı da mevcut. 2-10 aralığı.

    Şimdi ocaklardan birine yük uyguladığımızda hpa işleminin mekanizmasına bakalım:

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

Toplamda aşağıdakilere sahibiz:

  • İstenilen değer (desiredMetricValue) - hpa ayarlarına göre %30'a sahibiz
  • Geçerli değer (currentMetricValue) - hesaplama için denetleyici-yönetici, kaynak tüketiminin ortalama değerini % cinsinden hesaplar; şartlı olarak aşağıdakileri yapar:
    1. Metrik sunucudan pod metriklerinin mutlak değerlerini alır, yani. 101m ve 4m
    2. Ortalama mutlak değeri hesaplar; (101m + 4m) / 2 = 53m
    3. İstenilen kaynak tüketiminin mutlak değerini alır (bunun için tüm konteynerlerin istekleri toplanır) 60m + 30m = 90m
    4. İstek bölmesine göre CPU tüketiminin ortalama yüzdesini hesaplar; 53m / 90m * %100 = %59

Artık kopya sayısını değiştirmemiz gerekip gerekmediğini belirlemek için ihtiyacımız olan her şeye sahibiz; bunu yapmak için katsayıyı hesaplıyoruz:

ratio = 59% / 30% = 1.96

Onlar. kopya sayısı ~2 kat artırılmalı ve [2 * 1.96] = 4 olmalıdır.

Sonuç: Gördüğünüz gibi bu mekanizmanın çalışması için gerekli bir koşul, gözlemlenen bölmedeki tüm konteynerlere yönelik isteklerin bulunmasıdır.

Düğümlerin yatay otomatik ölçeklendirme mekanizması (Küme Otomatik Ölçekleyici)

Yük dalgalanmaları sırasında sistem üzerindeki olumsuz etkiyi nötralize etmek için yapılandırılmış bir hpa'ya sahip olmak yeterli değildir. Örneğin, hpa denetleyici yöneticisindeki ayarlara göre replika sayısının 2 kat arttırılması gerektiğine karar verir, ancak düğümlerin bu kadar sayıda pod'u çalıştıracak boş kaynakları yoktur (yani düğüm, gerekli veriyi sağlayamaz). istenen kaynaklar istek bölmesine gönderilir) ve bu bölmeler Beklemede durumuna geçer.

Bu durumda, sağlayıcının karşılık gelen bir IaaS/PaaS'si varsa (örneğin, GKE/GCE, AKS, EKS vb.), şöyle bir araç: Düğüm Otomatik Ölçekleyicisi. Kümedeki maksimum ve minimum düğüm sayısını ayarlamanıza ve kümede ve bölmelerde kaynak eksikliği olduğunda mevcut düğüm sayısını otomatik olarak ayarlamanıza (bir düğümü sipariş etmek/kaldırmak için bulut sağlayıcı API'sini çağırarak) olanak tanır. planlanamıyor (Bekleme durumunda).

Sonuç: Düğümleri otomatik olarak ölçeklendirebilmek için, k8'lerin düğümlerdeki yükü doğru bir şekilde değerlendirebilmesi ve buna göre kümede bir sonraki bölmeyi başlatacak kaynak olmadığını bildirebilmesi için bölme kapsayıcılarındaki istekleri ayarlamak gerekir.

Sonuç

Uygulamanın başarıyla çalışması için kapsayıcı kaynak sınırlarını ayarlamanın bir gereklilik olmadığı, ancak aşağıdaki nedenlerden dolayı bunu yapmanın yine de daha iyi olduğu unutulmamalıdır:

  1. K8s düğümleri arasında yük dengeleme açısından zamanlayıcının daha doğru çalışması için
  2. Bir "kapsül tahliyesi" olayının meydana gelme olasılığını azaltmak için
  3. Uygulama bölmelerinin (HPA) yatay otomatik ölçeklendirmesinin çalışması için
  4. Bulut sağlayıcıları için düğümlerin yatay otomatik ölçeklendirilmesi (Küme Otomatik Ölçeklendirme) için

Ayrıca blogumuzdaki diğer makaleleri de okuyun:

Kaynak: habr.com

Yorum ekle