Xüsusi planlaşdırma qaydaları dəsti ilə əlavə kube-planlayıcının yaradılması

Xüsusi planlaşdırma qaydaları dəsti ilə əlavə kube-planlayıcının yaradılması

Kube-planlaşdırıcı Kubernetes-in ayrılmaz komponentidir və müəyyən edilmiş siyasətlərə uyğun olaraq qovşaqlar arasında podların planlaşdırılmasına cavabdehdir. Tez-tez Kubernetes klasterinin işləməsi zamanı biz podları planlaşdırmaq üçün hansı siyasətlərdən istifadə olunduğu barədə düşünmək məcburiyyətində deyilik, çünki defolt kube planlaşdırıcısının siyasətlər dəsti əksər gündəlik tapşırıqlar üçün uyğundur. Bununla belə, podların ayrılması prosesini dəqiq tənzimləməyimizin vacib olduğu vəziyyətlər var və bu tapşırığı yerinə yetirməyin iki yolu var:

  1. Xüsusi qaydalar dəsti ilə kube planlaşdırıcı yaradın
  2. Öz planlaşdırıcınızı yazın və ona API server sorğuları ilə işləməyi öyrədin

Bu yazıda layihələrimizdən birində ocaqların qeyri-bərabər planlaşdırma problemini həll etmək üçün birinci bəndin həyata keçirilməsini təsvir edəcəyəm.

Kube-planlayıcının necə işlədiyinə qısa bir giriş

Xüsusilə qeyd etmək lazımdır ki, kube-planlaşdırıcı podların birbaşa planlaşdırılmasına cavabdeh deyil - o, yalnız podun yerləşdiriləcəyi qovşağın müəyyənləşdirilməsinə cavabdehdir. Başqa sözlə, kube-planlaşdırıcının işinin nəticəsi, planlaşdırma sorğusu üçün API serverinə qaytardığı qovşağın adıdır və işinin bitdiyi yerdir.

Birincisi, kube-planlaşdırıcı, predikatlar siyasətlərinə uyğun olaraq podun planlaşdırıla biləcəyi qovşaqların siyahısını tərtib edir. Sonra, bu siyahıdan hər bir node prioritet siyasətlərinə uyğun olaraq müəyyən sayda xal alır. Nəticədə, maksimum xal sayı olan node seçilir. Eyni maksimum balı olan qovşaqlar varsa, təsadüfi biri seçilir. Predikatlar (filtrləmə) və prioritetlər (ballar) siyasətlərinin siyahısı və təsviri burada tapa bilərsiniz. sənədləşdirmə.

Problemli orqanın təsviri

Nixys-də çoxlu sayda müxtəlif Kubernetes klasterlərinin saxlanmasına baxmayaraq, biz ilk dəfə podların planlaşdırılması problemi ilə yalnız bu yaxınlarda, layihələrimizdən birinin çoxlu sayda dövri tapşırıqları (~100 CronJob obyekti) yerinə yetirmək üçün lazım olan zaman qarşılaşdıq. Problemin təsvirini mümkün qədər sadələşdirmək üçün bir mikroservisə nümunə götürəcəyik, onun daxilində dəqiqədə bir dəfə cron tapşırığı işə salınaraq CPU-da müəyyən yük yaradır. Cron tapşırığını yerinə yetirmək üçün tamamilə eyni xüsusiyyətlərə malik üç qovşaq ayrıldı (hər birində 24 vCPU).

Eyni zamanda, CronJob-un icrası üçün nə qədər vaxt lazım olduğunu dəqiq söyləmək mümkün deyil, çünki giriş məlumatlarının həcmi daim dəyişir. Orta hesabla, kube-planlayıcının normal işləməsi zamanı hər bir node 3-4 iş nümunəsini işə salır ki, bu da hər bir nodun CPU-da yükün ~20-30%-ni yaradır:

Xüsusi planlaşdırma qaydaları dəsti ilə əlavə kube-planlayıcının yaradılması

Problemin özü ondadır ki, bəzən cron tapşırıq podları üç qovşaqdan birində planlaşdırılmağı dayandırır. Yəni, müəyyən bir vaxtda, qovşaqlardan biri üçün heç bir pod planlaşdırılmadı, digər iki qovşaqda isə 6-8 nüsxə tapşırığın işlədiyi halda CPU yükünün ~ 40-60% -ni yaratdı:

Xüsusi planlaşdırma qaydaları dəsti ilə əlavə kube-planlayıcının yaradılması

Problem tamamilə təsadüfi tezliklə təkrarlanır və bəzən kodun yeni versiyasının buraxılması ilə əlaqələndirilirdi.

Kube-planlaşdırıcının qeyd səviyyəsini 10-cu səviyyəyə (-v=10) yüksəltməklə, qiymətləndirmə prosesi zamanı hər bir qovşağın neçə xal qazandığını qeyd etməyə başladıq. Normal planlaşdırma əməliyyatı zamanı jurnallarda aşağıdakı məlumatlar görünə bilər:

resource_allocation.go:78] cronjob-1574828880-mn7m4 -> Node03: BalancedResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 1387 millicores 4161694720 memory bytes, score 9
resource_allocation.go:78] cronjob-1574828880-mn7m4 -> Node02: BalancedResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 1347 millicores 4444810240 memory bytes, score 9
resource_allocation.go:78] cronjob-1574828880-mn7m4 -> Node03: LeastResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 1387 millicores 4161694720 memory bytes, score 9
resource_allocation.go:78] cronjob-1574828880-mn7m4 -> Node01: BalancedResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 1687 millicores 4790840320 memory bytes, score 9
resource_allocation.go:78] cronjob-1574828880-mn7m4 -> Node02: LeastResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 1347 millicores 4444810240 memory bytes, score 9
resource_allocation.go:78] cronjob-1574828880-mn7m4 -> Node01: LeastResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 1687 millicores 4790840320 memory bytes, score 9
generic_scheduler.go:726] cronjob-1574828880-mn7m4_project-stage -> Node01: NodeAffinityPriority, Score: (0)                                                                                       
generic_scheduler.go:726] cronjob-1574828880-mn7m4_project-stage -> Node02: NodeAffinityPriority, Score: (0)                                                                                       
generic_scheduler.go:726] cronjob-1574828880-mn7m4_project-stage -> Node03: NodeAffinityPriority, Score: (0)                                                                                       
interpod_affinity.go:237] cronjob-1574828880-mn7m4 -> Node01: InterPodAffinityPriority, Score: (0)                                                                                                        
generic_scheduler.go:726] cronjob-1574828880-mn7m4_project-stage -> Node01: TaintTolerationPriority, Score: (10)                                                                                   
interpod_affinity.go:237] cronjob-1574828880-mn7m4 -> Node02: InterPodAffinityPriority, Score: (0)                                                                                                        
generic_scheduler.go:726] cronjob-1574828880-mn7m4_project-stage -> Node02: TaintTolerationPriority, Score: (10)                                                                                   
selector_spreading.go:146] cronjob-1574828880-mn7m4 -> Node01: SelectorSpreadPriority, Score: (10)                                                                                                        
interpod_affinity.go:237] cronjob-1574828880-mn7m4 -> Node03: InterPodAffinityPriority, Score: (0)                                                                                                        
generic_scheduler.go:726] cronjob-1574828880-mn7m4_project-stage -> Node03: TaintTolerationPriority, Score: (10)                                                                                   
selector_spreading.go:146] cronjob-1574828880-mn7m4 -> Node02: SelectorSpreadPriority, Score: (10)                                                                                                        
selector_spreading.go:146] cronjob-1574828880-mn7m4 -> Node03: SelectorSpreadPriority, Score: (10)                                                                                                        
generic_scheduler.go:726] cronjob-1574828880-mn7m4_project-stage -> Node01: SelectorSpreadPriority, Score: (10)                                                                                    
generic_scheduler.go:726] cronjob-1574828880-mn7m4_project-stage -> Node02: SelectorSpreadPriority, Score: (10)                                                                                    
generic_scheduler.go:726] cronjob-1574828880-mn7m4_project-stage -> Node03: SelectorSpreadPriority, Score: (10)                                                                                    
generic_scheduler.go:781] Host Node01 => Score 100043                                                                                                                                                                        
generic_scheduler.go:781] Host Node02 => Score 100043                                                                                                                                                                        
generic_scheduler.go:781] Host Node03 => Score 100043

Bunlar. jurnallardan əldə edilən məlumatlara əsasən, qovşaqların hər biri bərabər sayda yekun xal topladı və planlaşdırma üçün təsadüfi biri seçildi. Problemli planlaşdırma zamanı qeydlər belə görünürdü:

resource_allocation.go:78] cronjob-1574211360-bzfkr -> Node02: BalancedResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 1587 millicores 4581125120 memory bytes, score 9
resource_allocation.go:78] cronjob-1574211360-bzfkr -> Node03: BalancedResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 1087 millicores 3532549120 memory bytes, score 9
resource_allocation.go:78] cronjob-1574211360-bzfkr -> Node02: LeastResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 1587 millicores 4581125120 memory bytes, score 9
resource_allocation.go:78] cronjob-1574211360-bzfkr -> Node01: BalancedResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 987 millicores 3322833920 memory bytes, score 9
resource_allocation.go:78] cronjob-1574211360-bzfkr -> Node01: LeastResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 987 millicores 3322833920 memory bytes, score 9 
resource_allocation.go:78] cronjob-1574211360-bzfkr -> Node03: LeastResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 1087 millicores 3532549120 memory bytes, score 9
interpod_affinity.go:237] cronjob-1574211360-bzfkr -> Node03: InterPodAffinityPriority, Score: (0)                                                                                                        
interpod_affinity.go:237] cronjob-1574211360-bzfkr -> Node02: InterPodAffinityPriority, Score: (0)                                                                                                        
interpod_affinity.go:237] cronjob-1574211360-bzfkr -> Node01: InterPodAffinityPriority, Score: (0)                                                                                                        
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node03: TaintTolerationPriority, Score: (10)                                                                                   
selector_spreading.go:146] cronjob-1574211360-bzfkr -> Node03: SelectorSpreadPriority, Score: (10)                                                                                                        
selector_spreading.go:146] cronjob-1574211360-bzfkr -> Node02: SelectorSpreadPriority, Score: (10)                                                                                                        
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node02: TaintTolerationPriority, Score: (10)                                                                                   
selector_spreading.go:146] cronjob-1574211360-bzfkr -> Node01: SelectorSpreadPriority, Score: (10)                                                                                                        
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node03: NodeAffinityPriority, Score: (0)                                                                                       
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node03: SelectorSpreadPriority, Score: (10)                                                                                    
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node02: SelectorSpreadPriority, Score: (10)                                                                                    
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node01: TaintTolerationPriority, Score: (10)                                                                                   
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node02: NodeAffinityPriority, Score: (0)                                                                                       
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node01: NodeAffinityPriority, Score: (0)                                                                                       
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node01: SelectorSpreadPriority, Score: (10)                                                                                    
generic_scheduler.go:781] Host Node03 => Score 100041                                                                                                                                                                        
generic_scheduler.go:781] Host Node02 => Score 100041                                                                                                                                                                        
generic_scheduler.go:781] Host Node01 => Score 100038

Buradan görünə bilər ki, qovşaqlardan biri digərlərinə nisbətən daha az yekun xal toplayıb və buna görə də planlaşdırma yalnız maksimum xal toplayan iki qovşaq üçün aparılıb. Beləliklə, biz əmin olduq ki, problem məhz podların planlaşdırılmasındadır.

Problemin həlli üçün sonrakı alqoritm bizə aydın idi - qeydləri təhlil edin, düyünün hansı prioritetlə xal toplamadığını anlayın və lazım olduqda standart kube planlaşdırıcısının siyasətini tənzimləyin. Ancaq burada iki mühüm çətinliklə üzləşirik:

  1. Maksimum giriş səviyyəsində (10) yalnız bəzi prioritetlər üçün toplanmış xallar əks olunur. Yuxarıdakı qeydlərdən çıxarışda, qeydlərdə əks olunan bütün prioritetlər üçün qovşaqların normal və problem planlaşdırmasında eyni sayda xal topladığını, lakin problemin planlaşdırılması zamanı yekun nəticənin fərqli olduğunu görə bilərsiniz. Beləliklə, belə nəticəyə gələ bilərik ki, bəzi prioritetlər üçün xal toplama "pərdə arxasında" baş verir və düyünün hansı prioritet üçün xal almadığını başa düşmək üçün heç bir yolumuz yoxdur. Bu problemi ətraflı təsvir etdik buraxılış Github-da Kubernetes deposu. Yazı zamanı tərtibatçılardan Kubernetes v1.15,1.16, 1.17 və XNUMX yeniləmələrinə giriş dəstəyinin əlavə ediləcəyinə dair cavab alındı.
  2. Kube-planlayıcının hazırda hansı xüsusi siyasət dəsti ilə işlədiyini başa düşməyin asan yolu yoxdur. Bəli, in sənədləşdirmə bu siyahı verilmişdir, lakin bu, prioritet siyasətlərin hər birinə hansı xüsusi çəkilərin təyin edildiyi barədə məlumatı ehtiva etmir. Defolt kube planlaşdırıcısının çəkilərini görə və ya siyasətlərini yalnız burada redaktə edə bilərsiniz mənbə kodları.

Qeyd etmək lazımdır ki, bir dəfə biz tətbiqi işə salmaq üçün lazım olan təsvirə malik olan node-a xal verən ImageLocalityPriority siyasətinə uyğun olaraq qovşağın xal almadığını qeyd edə bildik. Yəni, tətbiqin yeni versiyası yayılan zaman cron tapşırığı iki qovşaqda işləməyi bacardı, onlara docker reyestrindən yeni bir şəkil endirdi və beləliklə, iki qovşaq üçüncü ilə müqayisədə daha yüksək yekun xal aldı. .

Yuxarıda yazdığım kimi, loglarda ImageLocalityPriority siyasətinin qiymətləndirilməsi ilə bağlı məlumat görmürük, buna görə də fərziyyəmizi yoxlamaq üçün tətbiqin yeni versiyası ilə şəkli üçüncü node üzərinə atdıq, bundan sonra planlaşdırma düzgün işlədi. . Məhz ImageLocalityPriority siyasətinə görə planlaşdırma problemi olduqca nadir hallarda müşahidə olunurdu; daha tez-tez başqa bir şeylə əlaqələndirilirdi. Defolt kube planlaşdırıcısının prioritetləri siyahısındakı siyasətlərin hər birini tam olaraq sazlaya bilmədiyimizə görə, pod planlaşdırma siyasətlərinin çevik idarə edilməsinə ehtiyacımız var idi.

Problem problemi

Problemin həllinin mümkün qədər konkret olmasını istədik, yəni Kubernetes-in əsas qurumları (burada defolt kube-planlaşdırıcını nəzərdə tuturuq) dəyişməz qalmalıdır. Bir yerdə problemi həll edib, başqa yerdə yaratmaq istəmədik. Beləliklə, məqalənin girişində elan edilən problemin həlli üçün iki varianta gəldik - əlavə bir planlaşdırıcı yaratmaq və ya özünüz yazmaq. Cron tapşırıqlarını planlaşdırmaq üçün əsas tələb yükü üç qovşaqda bərabər paylamaqdır. Bu tələb mövcud kube planlaşdırıcı siyasətləri ilə təmin edilə bilər, buna görə də problemimizi həll etmək üçün öz planlaşdırıcınızı yazmağın mənası yoxdur.

Əlavə kube planlaşdırıcı yaratmaq və yerləşdirmək üçün təlimatlar təsvir edilmişdir sənədləşdirmə. Bununla belə, bizə elə gəldi ki, Yerləşdirmə obyekti kube-planlaşdırıcı kimi kritik bir xidmətin işində nasazlığa dözümlülüyünü təmin etmək üçün kifayət deyil, ona görə də biz birbaşa izləniləcək Statik Pod kimi yeni kube planlaşdırıcısını yerləşdirməyə qərar verdik. Kubelet tərəfindən. Beləliklə, yeni kube planlaşdırıcı üçün aşağıdakı tələblərimiz var:

  1. Xidmət bütün klaster ustalarında Statik Pod kimi yerləşdirilməlidir
  2. Kube-planlaşdırıcısı olan aktiv pod əlçatan olmadıqda xətaya dözümlülük təmin edilməlidir
  3. Planlaşdırma zamanı əsas prioritet qovşaqdakı mövcud resursların sayı olmalıdır (LeastRequestedPriority)

İcra həlləri

Dərhal qeyd etmək lazımdır ki, biz bütün işləri Kubernetes v1.14.7-də yerinə yetirəcəyik, çünki Bu layihədə istifadə olunan versiyadır. Yeni kube planlaşdırıcımız üçün manifest yazmaqla başlayaq. Defolt manifesti (/etc/kubernetes/manifests/kube-scheduler.yaml) əsas götürək və onu aşağıdakı formaya gətirək:

kind: Pod
metadata:
  labels:
    component: scheduler
    tier: control-plane
  name: kube-scheduler-cron
  namespace: kube-system
spec:
      containers:
      - command:
        - /usr/local/bin/kube-scheduler
        - --address=0.0.0.0
        - --port=10151
        - --secure-port=10159
        - --config=/etc/kubernetes/scheduler-custom.conf
        - --authentication-kubeconfig=/etc/kubernetes/scheduler.conf
        - --authorization-kubeconfig=/etc/kubernetes/scheduler.conf
        - --v=2
        image: gcr.io/google-containers/kube-scheduler:v1.14.7
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 8
          httpGet:
            host: 127.0.0.1
            path: /healthz
            port: 10151
            scheme: HTTP
          initialDelaySeconds: 15
          timeoutSeconds: 15
        name: kube-scheduler-cron-container
        resources:
          requests:
            cpu: '0.1'
        volumeMounts:
        - mountPath: /etc/kubernetes/scheduler.conf
          name: kube-config
          readOnly: true
        - mountPath: /etc/localtime
          name: localtime
          readOnly: true
        - mountPath: /etc/kubernetes/scheduler-custom.conf
          name: scheduler-config
          readOnly: true
        - mountPath: /etc/kubernetes/scheduler-custom-policy-config.json
          name: policy-config
          readOnly: true
      hostNetwork: true
      priorityClassName: system-cluster-critical
      volumes:
      - hostPath:
          path: /etc/kubernetes/scheduler.conf
          type: FileOrCreate
        name: kube-config
      - hostPath:
          path: /etc/localtime
        name: localtime
      - hostPath:
          path: /etc/kubernetes/scheduler-custom.conf
          type: FileOrCreate
        name: scheduler-config
      - hostPath:
          path: /etc/kubernetes/scheduler-custom-policy-config.json
          type: FileOrCreate
        name: policy-config

Əsas dəyişikliklər haqqında qısaca:

  1. Pod və konteynerin adı kube-scheduler-cron olaraq dəyişdirildi
  2. Seçim müəyyən edildiyi üçün 10151 və 10159 portlarının istifadəsini göstərdi hostNetwork: true və biz standart kube planlaşdırıcı ilə eyni portlardan istifadə edə bilmərik (10251 və 10259)
  3. --config parametrindən istifadə edərək xidmətin başlamalı olduğu konfiqurasiya faylını təyin etdik
  4. Konfiqurasiya faylının (scheduler-custom.conf) və planlaşdırma siyasəti faylının (scheduler-custom-policy-config.json) hostdan konfiqurasiya edilmiş montajı

Unutmayın ki, kube planlaşdırıcımız standart hüquqlara bənzər hüquqlara ehtiyac duyur. Onun klaster rolunu redaktə edin:

kubectl edit clusterrole system:kube-scheduler

...
   resourceNames:
    - kube-scheduler
    - kube-scheduler-cron
...

İndi konfiqurasiya faylında və planlaşdırma siyasəti faylında nələrin olması lazım olduğundan danışaq:

  • Konfiqurasiya faylı (scheduler-custom.conf)
    Standart kube planlaşdırıcı konfiqurasiyasını əldə etmək üçün parametrdən istifadə etməlisiniz --write-config-to haqqında sənədləşdirmə. Yaranan konfiqurasiyanı /etc/kubernetes/scheduler-custom.conf faylına yerləşdirəcəyik və onu aşağıdakı formaya endirərik:

apiVersion: kubescheduler.config.k8s.io/v1alpha1
kind: KubeSchedulerConfiguration
schedulerName: kube-scheduler-cron
bindTimeoutSeconds: 600
clientConnection:
  acceptContentTypes: ""
  burst: 100
  contentType: application/vnd.kubernetes.protobuf
  kubeconfig: /etc/kubernetes/scheduler.conf
  qps: 50
disablePreemption: false
enableContentionProfiling: false
enableProfiling: false
failureDomains: kubernetes.io/hostname,failure-domain.beta.kubernetes.io/zone,failure-domain.beta.kubernetes.io/region
hardPodAffinitySymmetricWeight: 1
healthzBindAddress: 0.0.0.0:10151
leaderElection:
  leaderElect: true
  leaseDuration: 15s
  lockObjectName: kube-scheduler-cron
  lockObjectNamespace: kube-system
  renewDeadline: 10s
  resourceLock: endpoints
  retryPeriod: 2s
metricsBindAddress: 0.0.0.0:10151
percentageOfNodesToScore: 0
algorithmSource:
   policy:
     file:
       path: "/etc/kubernetes/scheduler-custom-policy-config.json"

Əsas dəyişikliklər haqqında qısaca:

  1. Biz planlayıcının adını kube-planlaşdırıcı-cron xidmətimizin adına təyin etdik.
  2. Parametrdə lockObjectName siz də xidmətimizin adını təyin etməli və parametrin olduğundan əmin olmalısınız leaderElect doğru olaraq təyin edin (bir master node varsa, onu yalana təyin edə bilərsiniz).
  3. Parametrdə planlaşdırma siyasətlərinin təsviri ilə fayla gedən yol göstərildi algorithmSource.

Açarın parametrlərini redaktə etdiyimiz ikinci nöqtəni daha yaxından nəzərdən keçirməyə dəyər leaderElection. Arızaya dözümlülüyünü təmin etmək üçün biz (leaderElect) kube planlaşdırıcımızın podları arasında onlar üçün tək son nöqtədən istifadə edərək liderin (master) seçilməsi prosesi (resourceLock) adlı kube-planlaşdırıcı-cron (lockObjectName) kube sisteminin ad məkanında (lockObjectNamespace). Kubernetes-in əsas komponentlərin (o cümlədən kube planlayıcısı) yüksək əlçatanlığını necə təmin etdiyini burada tapa bilərsiniz. məqalə.

  • Planlaşdırma siyasəti faylı (scheduler-custom-policy-config.json)
    Daha əvvəl yazdığım kimi, standart kube planlaşdırıcısının hansı xüsusi siyasətlərlə işlədiyini yalnız kodunu təhlil etməklə öyrənə bilərik. Yəni, konfiqurasiya faylı ilə eyni şəkildə standart kube-planlaşdırıcı üçün planlaşdırma siyasətləri olan fayl əldə edə bilmirik. /etc/kubernetes/scheduler-custom-policy-config.json faylında bizi maraqlandıran planlaşdırma siyasətlərini aşağıdakı kimi təsvir edək:

{
  "kind": "Policy",
  "apiVersion": "v1",
  "predicates": [
    {
      "name": "GeneralPredicates"
    }
  ],
  "priorities": [
    {
      "name": "ServiceSpreadingPriority",
      "weight": 1
    },
    {
      "name": "EqualPriority",
      "weight": 1
    },
    {
      "name": "LeastRequestedPriority",
      "weight": 1
    },
    {
      "name": "NodePreferAvoidPodsPriority",
      "weight": 10000
    },
    {
      "name": "NodeAffinityPriority",
      "weight": 1
    }
  ],
  "hardPodAffinitySymmetricWeight" : 10,
  "alwaysCheckAllPredicates" : false
}

Beləliklə, kube-planlaşdırıcı əvvəlcə GeneralPredicates siyasətinə (buraya PodFitsResources, PodFitsHostPorts, HostName və MatchNodeSelector siyasətləri daxildir) uyğun olaraq podun planlaşdırıla biləcəyi qovşaqların siyahısını tərtib edir. Və sonra hər bir node prioritetlər massivindəki siyasətlər dəstinə uyğun olaraq qiymətləndirilir. Tapşırığımızın şərtlərini yerinə yetirmək üçün biz hesab etdik ki, belə bir siyasət kompleksi optimal həll yolu olacaqdır. Nəzərinizə çatdırım ki, ətraflı təsviri olan bir sıra siyasətlər burada mövcuddur sənədləşdirmə. Tapşırığınızı yerinə yetirmək üçün sadəcə olaraq istifadə olunan siyasətlər toplusunu dəyişdirə və onlara müvafiq çəkilər təyin edə bilərsiniz.

Gəlin, fəslin əvvəlində yaratdığımız yeni kube-planlayıcının manifestini kube-scheduler-custom.yaml adlandıraq və onu aşağıdakı /etc/kubernetes/manifests yolunda üç master node üzərində yerləşdirək. Hər şey düzgün aparılırsa, Kubelet hər bir qovşaqda bir pod işə salacaq və yeni kube planlaşdırıcımızın qeydlərində siyasət faylımızın uğurla tətbiq edildiyi barədə məlumat görəcəyik:

Creating scheduler from configuration: {{ } [{GeneralPredicates <nil>}] [{ServiceSpreadingPriority 1 <nil>} {EqualPriority 1 <nil>} {LeastRequestedPriority 1 <nil>} {NodePreferAvoidPodsPriority 10000 <nil>} {NodeAffinityPriority 1 <nil>}] [] 10 false}
Registering predicate: GeneralPredicates
Predicate type GeneralPredicates already registered, reusing.
Registering priority: ServiceSpreadingPriority
Priority type ServiceSpreadingPriority already registered, reusing.
Registering priority: EqualPriority
Priority type EqualPriority already registered, reusing.
Registering priority: LeastRequestedPriority
Priority type LeastRequestedPriority already registered, reusing.
Registering priority: NodePreferAvoidPodsPriority
Priority type NodePreferAvoidPodsPriority already registered, reusing.
Registering priority: NodeAffinityPriority
Priority type NodeAffinityPriority already registered, reusing.
Creating scheduler with fit predicates 'map[GeneralPredicates:{}]' and priority functions 'map[EqualPriority:{} LeastRequestedPriority:{} NodeAffinityPriority:{} NodePreferAvoidPodsPriority:{} ServiceSpreadingPriority:{}]'

İndi qalan yalnız CronJob-un spesifikasiyasında qeyd etməkdir ki, onun podlarını planlaşdırmaq üçün bütün sorğular yeni kube planlaşdırıcımız tərəfindən işlənməlidir:

...
 jobTemplate:
    spec:
      template:
        spec:
          schedulerName: kube-scheduler-cron
...

Nəticə

Nəhayət, işinə birbaşa kubelet tərəfindən nəzarət edilən unikal planlaşdırma siyasətləri dəsti olan əlavə kube-planlaşdırıcı əldə etdik. Bundan əlavə, köhnə lider nədənsə əlçatmaz olarsa, kube planlaşdırıcımızın podları arasında yeni liderin seçilməsini qurmuşuq.

Daimi tətbiqlər və xidmətlər standart kube planlaşdırıcı vasitəsilə planlaşdırılmağa davam edir və bütün cron tapşırıqları tamamilə yenisinə köçürüldü. Cron tapşırıqlarının yaratdığı yük indi bütün qovşaqlarda bərabər paylanır. Cron tapşırıqlarının əksəriyyətinin layihənin əsas tətbiqləri ilə eyni qovşaqlarda yerinə yetirildiyini nəzərə alsaq, bu, resursların olmaması səbəbindən podların hərəkət riskini əhəmiyyətli dərəcədə azaldıb. Əlavə kube planlaşdırıcısını təqdim etdikdən sonra cron tapşırıqlarının qeyri-bərabər planlaşdırılması ilə bağlı problemlər artıq yaranmadı.

Bloqumuzdakı digər məqalələri də oxuyun:

Mənbə: www.habr.com

Добавить комментарий