Kubernetes: mengapa begitu penting untuk mengonfigurasi manajemen sumber daya sistem?

Sebagai aturan, selalu ada kebutuhan untuk menyediakan kumpulan sumber daya khusus untuk aplikasi agar dapat berfungsi dengan benar dan stabil. Namun bagaimana jika beberapa aplikasi berjalan dengan daya yang sama? Bagaimana cara menyediakan sumber daya minimum yang diperlukan masing-masing dari mereka? Bagaimana cara membatasi konsumsi sumber daya? Bagaimana cara mendistribusikan beban antar node dengan benar? Bagaimana cara memastikan mekanisme penskalaan horizontal berfungsi jika beban aplikasi meningkat?

Kubernetes: mengapa begitu penting untuk mengonfigurasi manajemen sumber daya sistem?

Anda harus mulai dengan jenis sumber daya utama apa yang ada dalam sistem - tentu saja, waktu prosesor dan RAM. Dalam manifes k8s, jenis sumber daya ini diukur dalam unit berikut:

  • CPU - dalam inti
  • RAM - dalam byte

Selain itu, untuk setiap sumber daya dimungkinkan untuk menetapkan dua jenis persyaratan - permintaan и batas. Permintaan - menjelaskan persyaratan minimum untuk sumber daya gratis dari sebuah node untuk menjalankan sebuah container (dan pod secara keseluruhan), sementara batas menetapkan batas tegas pada sumber daya yang tersedia untuk container.

Penting untuk dipahami bahwa manifes tidak harus secara eksplisit mendefinisikan kedua jenis tersebut, namun perilakunya adalah sebagai berikut:

  • Jika hanya batas sumber daya yang ditentukan secara eksplisit, maka permintaan untuk sumber daya ini secara otomatis mengambil nilai yang sama dengan batas (Anda dapat memverifikasi ini dengan memanggil entitas deskripsikan). Itu. faktanya, container akan dibatasi pada jumlah sumber daya yang sama yang dibutuhkan untuk menjalankannya.
  • Jika hanya permintaan yang ditentukan secara eksplisit untuk suatu sumber daya, maka tidak ada batasan atas yang ditetapkan pada sumber daya ini - mis. wadah hanya dibatasi oleh sumber daya dari node itu sendiri.

Dimungkinkan juga untuk mengonfigurasi manajemen sumber daya tidak hanya pada tingkat kontainer tertentu, tetapi juga pada tingkat namespace menggunakan entitas berikut:

  • Batas Jangkauan — menjelaskan kebijakan pembatasan pada level container/pod dalam ns dan diperlukan untuk menjelaskan batas default pada container/pod, serta mencegah pembuatan container/pod yang jelas-jelas gemuk (atau sebaliknya), membatasi jumlahnya dan menentukan kemungkinan perbedaan nilai batasan dan permintaan
  • ResourceQuota — menjelaskan kebijakan pembatasan secara umum untuk semua container di ns dan digunakan, sebagai aturan, untuk membatasi sumber daya antar lingkungan (berguna ketika lingkungan tidak dibatasi secara ketat pada tingkat node)

Berikut ini adalah contoh manifes yang menetapkan batas sumber daya:

  • Pada tingkat kontainer tertentu:

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

    Itu. dalam hal ini, untuk menjalankan container dengan nginx, Anda memerlukan setidaknya 1G RAM kosong dan 0.2 CPU pada node, sedangkan maksimal container dapat menggunakan 0.2 CPU dan semua RAM yang tersedia di node.

  • Pada tingkat bilangan bulat ns:

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

    Itu. jumlah semua kontainer permintaan di ns default tidak boleh melebihi 300m untuk CPU dan 1G untuk OP, dan jumlah semua batas adalah 700m untuk CPU dan 2G untuk OP.

  • Batas default untuk container di 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

    Itu. di namespace default untuk semua container, permintaan akan disetel ke 100m untuk CPU dan 1G untuk OP, batas - 1 CPU dan 2G. Pada saat yang sama, batas juga ditetapkan pada nilai yang mungkin dalam permintaan/batas untuk CPU (50m < x < 2) dan RAM (500M < x < 4G).

  • Pembatasan tingkat pod ns:

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

    Itu. untuk setiap pod di ns default akan ada batasan 4 vCPU dan 1G.

Sekarang saya ingin memberi tahu Anda keuntungan apa yang dapat diberikan oleh pengaturan pembatasan ini kepada kita.

Mekanisme penyeimbangan beban antar node

Seperti yang Anda ketahui, komponen k8s bertanggung jawab atas distribusi pod antar node, seperti scheduler, yang bekerja berdasarkan algoritma tertentu. Algoritme ini melewati dua tahap saat memilih node optimal untuk diluncurkan:

  1. penyaringan
  2. mulai

Itu. sesuai dengan kebijakan yang dijelaskan, node pada awalnya dipilih yang memungkinkan untuk meluncurkan pod berdasarkan kumpulan predikat (termasuk memeriksa apakah node memiliki sumber daya yang cukup untuk menjalankan pod - PodFitsResources), dan kemudian untuk masing-masing node tersebut, menurut prioritas poin diberikan (termasuk, semakin banyak sumber daya gratis yang dimiliki sebuah node, semakin banyak poin yang diberikan - LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation) dan pod diluncurkan pada node dengan poin terbanyak (jika beberapa node memenuhi kondisi ini sekaligus, maka dipilih secara acak).

Pada saat yang sama, Anda perlu memahami bahwa penjadwal, ketika menilai sumber daya yang tersedia dari sebuah node, dipandu oleh data yang disimpan di etcd - mis. untuk jumlah sumber daya yang diminta/dibatasi dari setiap pod yang berjalan pada node ini, namun tidak untuk konsumsi sumber daya sebenarnya. Informasi ini dapat diperoleh dari output perintah kubectl describe node $NODE, misalnya:

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

Di sini kita melihat semua pod berjalan pada node tertentu, serta sumber daya yang diminta oleh setiap pod. Dan inilah tampilan log penjadwal saat pod cronjob-cron-events-1573793820-xt6q9 diluncurkan (informasi ini akan muncul di log penjadwal saat Anda menyetel level logging ke-10 di argumen perintah startup -v=10):

catatan

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

Di sini kita melihat bahwa pada awalnya penjadwal memfilter dan menghasilkan daftar 3 node yang dapat diluncurkan (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10). Kemudian menghitung skor berdasarkan beberapa parameter (termasuk BalancedResourceAllocation, LeastResourceAllocation) untuk masing-masing node tersebut guna menentukan node yang paling sesuai. Pada akhirnya, pod dijadwalkan pada node dengan jumlah poin terbanyak (di sini dua node sekaligus memiliki jumlah poin yang sama 100037, jadi dipilih secara acak - nxs-k8s-s10).

Keluaran: jika sebuah node menjalankan pod yang tidak ada batasannya, maka untuk k8 (dari sudut pandang konsumsi sumber daya) hal ini akan sama dengan seolah-olah tidak ada pod seperti itu pada node ini sama sekali. Oleh karena itu, jika Anda, secara kondisional, memiliki pod dengan proses yang rakus (misalnya, wowza) dan tidak ada batasan yang ditetapkan untuknya, maka situasi mungkin muncul ketika pod ini sebenarnya memakan semua sumber daya dari node tersebut, tetapi untuk k8s node ini dianggap tidak dimuat dan akan diberikan jumlah poin yang sama saat memberi peringkat (tepatnya dalam poin menilai sumber daya yang tersedia) sebagai node yang tidak memiliki pod yang berfungsi, yang pada akhirnya dapat menyebabkan distribusi beban antar node tidak merata.

Penggusuran Pod

Seperti yang Anda ketahui, setiap pod diberi salah satu dari 3 kelas QoS:

  1. terjamin — ditetapkan ketika untuk setiap kontainer di pod, permintaan dan batas ditentukan untuk memori dan cpu, dan nilai-nilai ini harus cocok
  2. mudah meledak — setidaknya satu container di pod memiliki permintaan dan batasan, dengan request < limit
  3. upaya terbaik — ketika tidak ada satu pun container di dalam pod yang sumber dayanya terbatas

Pada saat yang sama, ketika sebuah node mengalami kekurangan sumber daya (disk, memori), kubelet mulai memberi peringkat dan mengeluarkan pod berdasarkan algoritma tertentu yang memperhitungkan prioritas pod dan kelas QoS-nya. Misalnya, jika kita berbicara tentang RAM, maka berdasarkan kelas QoS, poin diberikan sesuai dengan prinsip berikut:

  • Terjamin: -998
  • Usaha terbaik: 1000
  • meledak: min(maks(2, 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)

Itu. dengan prioritas yang sama, kubelet pertama-tama akan mengeluarkan pod dengan kelas QoS upaya terbaik dari node.

Keluaran: jika Anda ingin mengurangi kemungkinan pod yang diinginkan dikeluarkan dari node jika terjadi kekurangan sumber daya, maka selain prioritasnya, Anda juga perlu mengatur permintaan/batasnya.

Mekanisme penskalaan otomatis pod aplikasi (HPA) secara horizontal

Ketika tugasnya adalah menambah dan mengurangi jumlah pod secara otomatis tergantung pada penggunaan sumber daya (sistem - CPU/RAM atau pengguna - rps), entitas k8s seperti HPA (Penskala Pod Horizontal). Algoritmanya adalah sebagai berikut:

  1. Pembacaan saat ini dari sumber daya yang diamati ditentukan (currentMetricValue)
  2. Nilai yang diinginkan untuk sumber daya ditentukan (desiredMetricValue), yang untuk sumber daya sistem ditetapkan menggunakan permintaan
  3. Jumlah replika saat ini ditentukan (Replika saat ini)
  4. Rumus berikut menghitung jumlah replika yang diinginkan (Replika yang diinginkan)
    Replika yang diinginkan = [Replika saat ini * ( NilaiMetrik Saat Ini / NilaiMetrik yang diinginkan )]

Dalam hal ini, penskalaan tidak akan terjadi ketika koefisien (currentMetricValue/desiredMetricValue) mendekati 1 (dalam hal ini, kita dapat mengatur sendiri kesalahan yang diizinkan; secara default adalah 0.1).

Mari kita lihat cara kerja hpa menggunakan contoh aplikasi app-test (digambarkan sebagai Deployment), di mana jumlah replika perlu diubah tergantung pada konsumsi CPU:

  • Manifes aplikasi

    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

    Itu. kita melihat bahwa pod aplikasi pada awalnya diluncurkan dalam dua instance, yang masing-masing berisi dua container nginx dan nginx-exporter, yang masing-masing memiliki spesifikasi tertentu permintaan untuk CPU.

  • Manifesto 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

    Itu. Kami membuat hpa yang akan memantau pengujian aplikasi Deployment dan menyesuaikan jumlah pod dengan aplikasi berdasarkan indikator cpu (kami memperkirakan pod akan menggunakan 30% CPU yang diminta), dengan jumlah replika berada di kisaran 2-10.

    Sekarang, mari kita lihat mekanisme pengoperasian hpa jika kita memberikan beban pada salah satu perapian:

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

Secara total kami memiliki yang berikut:

  • Nilai yang diinginkan (desiredMetricValue) - sesuai dengan pengaturan hpa, kami memiliki 30%
  • Nilai saat ini (currentMetricValue) - untuk penghitungan, pengontrol-manajer menghitung nilai rata-rata konsumsi sumber daya dalam %, yaitu. secara kondisional melakukan hal berikut:
    1. Menerima nilai absolut metrik pod dari server metrik, mis. 101m dan 4m
    2. Menghitung nilai absolut rata-rata, mis. (101m + 4m) / 2 = 53m
    3. Mendapat nilai absolut untuk konsumsi sumber daya yang diinginkan (untuk ini, permintaan semua kontainer dijumlahkan) 60m + 30m = 90m
    4. Menghitung persentase rata-rata konsumsi CPU relatif terhadap pod permintaan, mis. 53m / 90m * 100% = 59%

Sekarang kita memiliki semua yang kita perlukan untuk menentukan apakah kita perlu mengubah jumlah replika; untuk melakukan ini, kita menghitung koefisiennya:

ratio = 59% / 30% = 1.96

Itu. jumlah replika harus ditingkatkan ~2 kali lipat dan jumlahnya menjadi [2 * 1.96] = 4.

Kesimpulan: Seperti yang Anda lihat, agar mekanisme ini berfungsi, kondisi yang diperlukan adalah adanya permintaan untuk semua container di pod yang diamati.

Mekanisme penskalaan otomatis node secara horizontal (Cluster Autoscaler)

Untuk menetralisir dampak negatif pada sistem selama lonjakan beban, memiliki hpa yang dikonfigurasi saja tidak cukup. Misalnya, menurut pengaturan di manajer pengontrol hpa, diputuskan bahwa jumlah replika perlu ditingkatkan sebanyak 2 kali lipat, namun node tidak memiliki sumber daya bebas untuk menjalankan sejumlah pod (yaitu node tidak dapat menyediakan sumber daya yang diminta ke pod permintaan) dan pod ini beralih ke status Tertunda.

Dalam hal ini, jika penyedia memiliki IaaS/PaaS yang sesuai (misalnya, GKE/GCE, AKS, EKS, dll.), alat seperti Penskala Otomatis Node. Hal ini memungkinkan Anda untuk mengatur jumlah maksimum dan minimum node dalam cluster dan secara otomatis menyesuaikan jumlah node saat ini (dengan memanggil API penyedia cloud untuk memesan/menghapus sebuah node) ketika ada kekurangan sumber daya di cluster dan pod. tidak dapat dijadwalkan (berada dalam status Tertunda).

Kesimpulan: Untuk dapat melakukan penskalaan otomatis pada node, perlu untuk mengatur permintaan dalam kontainer pod sehingga k8s dapat menilai beban pada node dengan benar dan melaporkan bahwa tidak ada sumber daya di cluster untuk meluncurkan pod berikutnya.

Kesimpulan

Perlu dicatat bahwa menetapkan batas sumber daya kontainer bukan merupakan persyaratan agar aplikasi dapat berjalan dengan sukses, namun tetap lebih baik melakukannya karena alasan berikut:

  1. Untuk pengoperasian penjadwal yang lebih akurat dalam hal penyeimbangan beban antar node k8s
  2. Untuk mengurangi kemungkinan terjadinya peristiwa “penggusuran pod”.
  3. Agar penskalaan otomatis pod aplikasi (HPA) horizontal berfungsi
  4. Untuk penskalaan otomatis node secara horizontal (Cluster Autoscaling) untuk penyedia cloud

Baca juga artikel lainnya di blog kami:

Sumber: www.habr.com

Tambah komentar