Stvaranje dodatnog kube-planera s prilagođenim skupom pravila zakazivanja

Stvaranje dodatnog kube-planera s prilagođenim skupom pravila zakazivanja

Kube-scheduler sastavna je komponenta Kubernetesa, koja je odgovorna za raspoređivanje podova po čvorovima u skladu s navedenim pravilima. Često, tijekom rada Kubernetes klastera, ne moramo razmišljati o tome koje se politike koriste za raspoređivanje podova, budući da je skup politika zadanog kube-schedulera prikladan za većinu svakodnevnih zadataka. Međutim, postoje situacije kada nam je važno fino podesiti proces dodjele podova, a postoje dva načina za postizanje ovog zadatka:

  1. Napravite kube-planer s prilagođenim skupom pravila
  2. Napišite vlastiti planer i naučite ga da radi sa zahtjevima API poslužitelja

U ovom članku opisat ću implementaciju prve točke za rješavanje problema neravnomjernog rasporeda ognjišta na jednom od naših projekata.

Kratak uvod u način rada kube-schedulera

Posebno je vrijedno istaknuti činjenicu da kube-scheduler nije odgovoran za izravno raspoređivanje podova - odgovoran je samo za određivanje čvora na koji će se postaviti podovi. Drugim riječima, rezultat rada kube-schedulera je naziv čvora, koji on vraća API poslužitelju za zahtjev za raspoređivanjem i tu njegov rad završava.

Prvo, kube-scheduler sastavlja popis čvorova na kojima se pod može rasporediti u skladu s pravilima predikata. Dalje, svaki čvor s ove liste dobiva određeni broj bodova u skladu s politikom prioriteta. Kao rezultat, odabire se čvor s maksimalnim brojem bodova. Ako postoje čvorovi koji imaju isti maksimalni rezultat, odabire se slučajni čvor. Popis i opis politika predikata (filtriranje) i prioriteta (bodovanje) mogu se pronaći u dokumentacija.

Opis problematičnog tijela

Unatoč velikom broju različitih Kubernetes klastera koji se održavaju u Nixysu, prvi put smo se susreli s problemom raspoređivanja podova tek nedavno, kada je jedan od naših projekata trebao pokrenuti veliki broj periodičnih zadataka (~100 CronJob entiteta). Kako bismo što više pojednostavili opis problema, uzet ćemo kao primjer jedan mikroservis unutar kojeg se jednom u minuti pokreće cron task koji stvara određeno opterećenje CPU-a. Za izvođenje cron zadatka dodijeljena su tri čvora s apsolutno identičnim karakteristikama (24 vCPU-a na svakom).

Istodobno, nemoguće je s točnošću reći koliko će CronJob-u trebati da se izvrši, jer se količina ulaznih podataka stalno mijenja. U prosjeku, tijekom normalnog rada kube-schedulera, svaki čvor pokreće 3-4 instance posla, što stvara ~20-30% opterećenja CPU-a svakog čvora:

Stvaranje dodatnog kube-planera s prilagođenim skupom pravila zakazivanja

Sam problem je u tome što se ponekad cron task podovi prestaju planirati na jednom od tri čvora. To jest, u nekom trenutku u vremenu niti jedan modul nije bio planiran za jedan od čvorova, dok je na druga dva čvora bilo pokrenuto 6-8 kopija zadatka, stvarajući ~40-60% CPU opterećenja:

Stvaranje dodatnog kube-planera s prilagođenim skupom pravila zakazivanja

Problem se ponavljao s apsolutno nasumičnom učestalošću i povremeno u korelaciji s trenutkom uvođenja nove verzije koda.

Povećanjem razine zapisivanja kube-schedulera na razinu 10 (-v=10), počeli smo bilježiti koliko je bodova svaki čvor dobio tijekom procesa evaluacije. Tijekom normalnog rada planiranja, sljedeće informacije mogu se vidjeti u zapisima:

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

Oni. sudeći prema informacijama dobivenim iz logova, svaki od čvorova dobio je jednak broj konačnih bodova, a za planiranje je odabran slučajni. U vrijeme problematičnog planiranja dnevnici su izgledali ovako:

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

Iz čega je vidljivo da je jedan od čvorova postigao manje konačnih bodova od ostalih, te je stoga planiranje provedeno samo za dva čvora koja su osvojila maksimalnu ocjenu. Tako smo se definitivno uvjerili da je problem upravo u rasporedu mahuna.

Daljnji algoritam za rješavanje problema bio nam je očit - analizirajte zapise, shvatite po kojem prioritetu čvor nije dobio bodove i, ako je potrebno, prilagodite pravila zadanog kube-planera. Međutim, ovdje se susrećemo s dvije značajne poteškoće:

  1. Na najvećoj razini zapisivanja (10) odražavaju se bodovi dobiveni samo za neke prioritete. U gornjem izvatku dnevnika možete vidjeti da za sve prioritete prikazane u zapisnicima čvorovi postižu isti broj bodova u normalnom i problemskom rasporedu, ali je konačni rezultat u slučaju problemskog planiranja drugačiji. Dakle, možemo zaključiti da se za neke prioritete bodovanje događa “iza kulisa” i ne možemo razumjeti za koji prioritet čvor nije dobio bodove. Ovaj problem smo detaljno opisali u izdanje Kubernetes spremište na Githubu. U vrijeme pisanja, od programera je primljen odgovor da će podrška za bilježenje biti dodana u ažuriranjima Kubernetes v1.15,1.16, 1.17 i XNUMX.
  2. Ne postoji jednostavan način da shvatite s kojim određenim skupom pravila kube-scheduler trenutno radi. Da, unutra dokumentacija ovaj je popis naveden, ali ne sadrži informacije o tome koji su specifični ponderi dodijeljeni svakoj od politika prioriteta. Možete vidjeti težine ili urediti pravila zadanog kube-schedulera samo u izvorni kodovi.

Vrijedno je napomenuti da smo jednom uspjeli zabilježiti da čvor nije dobio bodove prema politici ImageLocalityPriority, koja dodjeljuje bodove čvoru ako već ima sliku potrebnu za pokretanje aplikacije. To jest, u vrijeme kada je nova verzija aplikacije izbačena, cron zadatak uspio se pokrenuti na dva čvora, preuzimajući novu sliku iz docker registra na njih, i stoga su dva čvora dobila višu konačnu ocjenu u odnosu na treći .

Kao što sam gore napisao, u zapisnicima ne vidimo informacije o procjeni politike ImageLocalityPriority, pa smo, kako bismo provjerili našu pretpostavku, bacili sliku s novom verzijom aplikacije na treći čvor, nakon čega je zakazivanje radilo ispravno . Upravo zbog politike ImageLocalityPriority problem zakazivanja je rijetko uočen, češće je bio povezan s nečim drugim. Zbog činjenice da nismo mogli u potpunosti otkloniti pogreške u svakoj politici na popisu prioriteta zadanog kube-planera, imali smo potrebu za fleksibilnim upravljanjem politikama raspoređivanja podova.

Formuliranje problema

Htjeli smo da rješenje problema bude što specifičnije, odnosno da glavni entiteti Kubernetesa (ovdje mislimo na zadani kube-scheduler) ostanu nepromijenjeni. Nismo htjeli riješiti problem na jednom mjestu, a stvoriti ga na drugom. Tako smo došli do dvije opcije za rješavanje problema, koje su najavljene u uvodu članka - stvaranje dodatnog planera ili pisanje vlastitog. Glavni zahtjev za raspoređivanje cron zadataka je ravnomjerna raspodjela opterećenja na tri čvora. Ovaj zahtjev se može zadovoljiti postojećim pravilima kube-planera, tako da za rješavanje našeg problema nema smisla pisati vlastiti planer.

Upute za stvaranje i postavljanje dodatnog kube-planera opisane su u dokumentacija. Međutim, činilo nam se da Deployment entitet nije dovoljan da osigura toleranciju na pogreške u radu tako kritične usluge kao što je kube-scheduler, pa smo odlučili implementirati novi kube-scheduler kao Static Pod, koji bi se izravno nadzirao od strane Kubeleta. Dakle, imamo sljedeće zahtjeve za novi kube-planer:

  1. Usluga mora biti postavljena kao Static Pod na svim masterima klastera
  2. Tolerancija grešaka mora biti osigurana u slučaju da aktivni modul s kube-planerom nije dostupan
  3. Glavni prioritet pri planiranju trebao bi biti broj dostupnih resursa na čvoru (LeastRequestedPriority)

Implementacija rješenja

Odmah je vrijedno napomenuti da ćemo sav posao obaviti u Kubernetes v1.14.7, jer Ovo je verzija koja je korištena u projektu. Počnimo s pisanjem manifesta za naš novi kube-planer. Uzmimo zadani manifest (/etc/kubernetes/manifests/kube-scheduler.yaml) kao osnovu i dovedimo ga u sljedeći oblik:

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

Ukratko o glavnim promjenama:

  1. Promijenio je naziv modula i spremnika u kube-scheduler-cron
  2. Navedena je upotreba portova 10151 i 10159 jer je opcija definirana hostNetwork: true i ne možemo koristiti iste portove kao zadani kube-planer (10251 i 10259)
  3. Pomoću parametra --config odredili smo konfiguracijsku datoteku s kojom se servis treba pokrenuti
  4. Konfigurirano montiranje konfiguracijske datoteke (scheduler-custom.conf) i datoteke pravila zakazivanja (scheduler-custom-policy-config.json) s glavnog računala

Ne zaboravite da će naš kube-planer trebati prava slična zadanim. Uredite njegovu ulogu klastera:

kubectl edit clusterrole system:kube-scheduler

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

Sada razgovarajmo o tome što bi trebalo biti sadržano u konfiguracijskoj datoteci i datoteci pravila zakazivanja:

  • Konfiguracijska datoteka (scheduler-custom.conf)
    Da biste dobili zadanu konfiguraciju kube-planera, morate koristiti parametar --write-config-to od dokumentacija. Dobivenu konfiguraciju smjestit ćemo u datoteku /etc/kubernetes/scheduler-custom.conf i svesti je na sljedeći oblik:

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"

Ukratko o glavnim promjenama:

  1. PlanerName postavljamo na naziv naše kube-scheduler-cron usluge.
  2. U parametru lockObjectName također morate postaviti naziv naše usluge i provjeriti da li je parametar leaderElect postaviti na true (ako imate jedan glavni čvor, možete ga postaviti na false).
  3. Naveden je put do datoteke s opisom pravila zakazivanja u parametru algorithmSource.

Vrijedi pobliže pogledati drugu točku, gdje uređujemo parametre za ključ leaderElection. Kako bismo osigurali toleranciju na pogreške, omogućili smo (leaderElect) proces odabira predvodnika (glavnog) između grupa našeg kube-planera koristeći jednu krajnju točku za njih (resourceLock) pod nazivom kube-scheduler-cron (lockObjectName) u prostoru imena kube-sustava (lockObjectNamespace). Kako Kubernetes osigurava visoku dostupnost glavnih komponenti (uključujući kube-scheduler) može se pronaći u članak.

  • Datoteka pravila zakazivanja (scheduler-custom-policy-config.json)
    Kao što sam ranije napisao, možemo saznati s kojim specifičnim pravilima zadani kube-planer radi samo analizom njegovog koda. To jest, ne možemo dobiti datoteku s pravilima zakazivanja za zadani kube-planer na isti način kao konfiguracijsku datoteku. Opišimo pravila zakazivanja koja nas zanimaju u datoteci /etc/kubernetes/scheduler-custom-policy-config.json na sljedeći način:

{
  "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
}

Stoga kube-scheduler prvo kompilira popis čvorova za koje se pod može rasporediti prema politici GeneralPredicates (koja uključuje skup pravila PodFitsResources, PodFitsHostPorts, HostName i MatchNodeSelector pravila). Zatim se svaki čvor procjenjuje u skladu sa skupom pravila u nizu prioriteta. Za ispunjenje uvjeta našeg zadatka smatrali smo da bi takav skup politika bio optimalno rješenje. Dopustite mi da vas podsjetim da je skup pravila s njihovim detaljnim opisima dostupan u dokumentacija. Da biste izvršili svoj zadatak, možete jednostavno promijeniti skup korištenih pravila i dodijeliti im odgovarajuće težine.

Nazvat ćemo manifest novog kube-schedulera, koji smo stvorili na početku poglavlja, kube-scheduler-custom.yaml i smjestiti ga na sljedeću stazu /etc/kubernetes/manifests na tri glavna čvora. Ako je sve učinjeno ispravno, Kubelet će pokrenuti pod na svakom čvoru, au zapisima našeg novog kube-planera vidjet ćemo informaciju da je naša datoteka pravila uspješno primijenjena:

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:{}]'

Sada sve što preostaje je naznačiti u specifikaciji našeg CronJoba da sve zahtjeve za raspoređivanje njegovih podova treba obraditi naš novi kube-planer:

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

Zaključak

U konačnici, dobili smo dodatni kube-scheduler s jedinstvenim skupom pravila raspoređivanja, čiji rad nadzire izravno kubelet. Osim toga, postavili smo izbor novog voditelja između grupa našeg kube-schedulera u slučaju da stari voditelj iz nekog razloga postane nedostupan.

Redovne aplikacije i usluge nastavljaju se raspoređivati ​​kroz zadani kube-scheduler, a svi cron zadaci u potpunosti su prebačeni u novi. Opterećenje koje stvaraju cron zadaci sada je ravnomjerno raspoređeno po svim čvorovima. Uzimajući u obzir da se većina cron zadataka izvršava na istim čvorovima kao i glavne aplikacije projekta, to je značajno smanjilo rizik premještanja podova zbog nedostatka resursa. Nakon uvođenja dodatnog kube-schedulera više se nisu javljali problemi s neravnomjernim raspoređivanjem cron zadataka.

Također pročitajte ostale članke na našem blogu:

Izvor: www.habr.com

Dodajte komentar