Kreiranje dodatnog kube-planera sa prilagođenim skupom pravila planiranja

Kreiranje dodatnog kube-planera sa prilagođenim skupom pravila planiranja

Kube-scheduler je integralna komponenta Kubernetesa, koja je odgovorna za raspoređivanje podova između čvorova u skladu sa specificiranim politikama. Često, tokom rada Kubernetes klastera, ne moramo da razmišljamo o tome koje politike se koriste za planiranje podova, pošto je skup politika podrazumevanog kube-planera pogodan za većinu svakodnevnih zadataka. Međutim, postoje situacije kada nam je važno da fino podesimo proces dodjeljivanja podova, a postoje dva načina za postizanje ovog zadatka:

  1. Kreirajte kube-planer sa prilagođenim skupom pravila
  2. Napišite svoj vlastiti planer i naučite ga da radi sa zahtjevima API servera

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

Kratak uvod u to kako kube-scheduler radi

Vrijedi posebno napomenuti činjenicu da kube-scheduler nije odgovoran za direktno raspoređivanje podova - on je odgovoran samo za određivanje čvora na koji će se pod postaviti. Drugim riječima, rezultat rada kube-scheduler-a je ime čvora, koje on vraća API serveru na zahtjev za raspoređivanje, i tu se njegov rad završava.

Prvo, kube-scheduler kompajlira listu čvorova na kojima se pod može rasporediti u skladu sa politikama predikata. Zatim, svaki čvor sa ove liste dobija određeni broj bodova u skladu sa politikama prioriteta. Kao rezultat, odabran je čvor sa maksimalnim brojem bodova. Ako postoje čvorovi koji imaju isti maksimalni rezultat, bira se slučajni. Spisak i opis politika predikata (filtriranje) i prioriteta (bodovanje) možete pronaći u dokumentaciju.

Opis tijela problema

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

Istovremeno, nemoguće je precizno reći koliko će vremena CronJob-u biti potrebno da se izvrši, budući da se količina ulaznih podataka stalno mijenja. U prosjeku, tokom normalnog rada kube-scheduler-a, svaki čvor pokreće 3-4 instance posla, što stvara ~20-30% opterećenja na CPU-u svakog čvora:

Kreiranje dodatnog kube-planera sa prilagođenim skupom pravila planiranja

Sam problem je u tome što ponekad cron podovi zadataka prestaju biti zakazani na jednom od tri čvora. Odnosno, u nekom trenutku nije planiran niti jedan pod za jedan od čvorova, dok je na druga dva čvora radilo 6-8 kopija zadatka, stvarajući ~40-60% opterećenja na CPU-u:

Kreiranje dodatnog kube-planera sa prilagođenim skupom pravila planiranja

Problem se ponavljao sa apsolutno nasumičnom frekvencijom i povremeno je bio u korelaciji s trenutkom uvođenja nove verzije koda.

Povećanjem nivoa evidentiranja kube-schedulera na nivo 10 (-v=10), počeli smo da bilježimo koliko je bodova svaki čvor dobio tokom procesa evaluacije. Tokom normalnog planiranja, sljedeće informacije se mogu vidjeti u zapisnicima:

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

One. Sudeći prema informacijama dobijenim iz dnevnika, svaki od čvorova je osvojio jednak broj konačnih bodova i 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 se vidi da je jedan od čvorova postigao manje konačnih bodova od ostalih, te je stoga planiranje izvršeno samo za dva čvora koja su postigla maksimalan broj bodova. Tako smo se definitivno uvjerili da je problem upravo u rasporedu mahuna.

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

  1. Na maksimalnom nivou evidentiranja (10), bodovi stečeni samo za neke prioritete se odražavaju. U gornjem izvodu dnevnika možete vidjeti da za sve prioritete reflektirane u zapisnicima čvorovi postižu isti broj bodova u normalnom i problemskom rasporedu, ali je konačni rezultat u slučaju planiranja problema drugačiji. Dakle, možemo zaključiti da se za neke prioritete bodovanje dešava „iza kulisa“, a nemamo načina da shvatimo za koji prioritet čvor nije dobio bodove. Ovaj problem smo detaljno opisali u problem Kubernetes spremište na Githubu. U vrijeme pisanja ovog teksta, primljen je odgovor od programera da će podrška za evidentiranje biti dodata u ažuriranjima Kubernetes v1.15,1.16, 1.17 i XNUMX.
  2. Ne postoji jednostavan način da se shvati s kojim specifičnim skupom politika kube-scheduler trenutno radi. Da, u dokumentaciju ova lista je navedena, ali ne sadrži informacije o tome koje su specifične težine dodijeljene svakoj od politika prioriteta. Možete vidjeti težine ili urediti politike zadanog kube-planera samo u izvorni kodovi.

Vrijedi napomenuti da smo jednom uspjeli zabilježiti da čvor nije dobio bodove prema politici ImageLocalityPriority, koja dodjeljuje bodove čvoru ako već ima sliku neophodnu za pokretanje aplikacije. Odnosno, u vrijeme kada je nova verzija aplikacije predstavljena, cron zadatak je uspio da se pokrene na dva čvora, preuzimajući im novu sliku iz docker registra, i tako su dva čvora dobila veći konačni rezultat u odnosu na treći .

Kao što sam gore napisao, u logovima ne vidimo informacije o procjeni politike ImageLocalityPriority, tako da smo kako bismo provjerili našu pretpostavku, sliku s novom verzijom aplikacije izbacili na treći čvor, nakon čega je zakazivanje funkcioniralo ispravno . Upravo zbog politike ImageLocalityPriority problem rasporeda je uočen prilično rijetko, češće se povezivao s nečim drugim. Zbog činjenice da nismo mogli u potpunosti da otklonimo greške u svakoj od politika na listi prioriteta zadanog kube-schedulera, imali smo potrebu za fleksibilnim upravljanjem politikama planiranja pod.

Izjava o problemu

Željeli smo da rješenje problema bude što konkretnije, odnosno da glavni entiteti Kubernetesa (ovdje mislimo na default kube-scheduler) trebaju ostati 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 - kreiranje dodatnog planera ili pisanje vlastitog. Glavni zahtjev za raspoređivanje cron zadataka je ravnomjerna raspodjela opterećenja na tri čvora. Ovaj zahtjev može biti zadovoljen postojećim kube-scheduler politikama, tako da za rješavanje našeg problema nema smisla pisati vlastiti planer.

Upute za kreiranje i postavljanje dodatnog kube-planera opisane su u dokumentaciju. Međutim, činilo nam se da entitet Deployment nije dovoljan da osigura toleranciju grešaka u radu tako kritične usluge kao što je kube-scheduler, pa smo odlučili da implementiramo novi kube-scheduler kao statički pod, koji bi se direktno nadgledao. by Kubelet. Dakle, imamo sljedeće zahtjeve za novi kube-scheduler:

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

Implementacija rješenja

Vrijedi odmah napomenuti da ćemo sve radove izvoditi u Kubernetes v1.14.7, jer Ovo je verzija koja je korištena u projektu. Počnimo s pisanjem manifesta za naš novi kube-scheduler. Uzmimo zadani manifest (/etc/kubernetes/manifests/kube-scheduler.yaml) kao osnovu i dovedemo 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. Promijenjeno ime modula i kontejnera u kube-scheduler-cron
  2. Navedeno korištenje portova 10151 i 10159 kao opcija definirana hostNetwork: true i ne možemo koristiti iste portove kao zadani kube-scheduler (10251 i 10259)
  3. Koristeći --config parametar, specificirali smo konfiguracijsku datoteku s kojom bi se servis trebao pokrenuti
  4. Konfigurirano montiranje konfiguracijske datoteke (scheduler-custom.conf) i datoteke politike rasporeda (scheduler-custom-policy-config.json) sa hosta

Ne zaboravite da će našem kube-planeru trebati prava slična zadanom. 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 politike planiranja:

  • Konfiguracijski fajl (scheduler-custom.conf)
    Da biste dobili zadanu konfiguraciju kube-schedulera, morate koristiti parametar --write-config-to из dokumentaciju. Dobivenu konfiguraciju ćemo smjestiti 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. Postavili smo schedulerName na ime našeg kube-scheduler-cron servisa.
  2. U parametru lockObjectName također morate podesiti naziv naše usluge i uvjeriti se da je parametar leaderElect postavite na true (ako imate jedan glavni čvor, možete ga postaviti na false).
  3. Naveli stazu do datoteke s opisom politika planiranja u parametru algorithmSource.

Vrijedi pobliže pogledati drugu točku, gdje uređujemo parametre za ključ leaderElection. Kako bismo osigurali toleranciju grešaka, omogućili smo (leaderElect) proces odabira lidera (mastera) između podova našeg kube-planera koristeći jednu krajnju tačku za njih (resourceLock) pod nazivom kube-scheduler-cron (lockObjectName) u imenskom prostoru kube-system (lockObjectNamespace). Kako Kubernetes osigurava visoku dostupnost glavnih komponenti (uključujući kube-scheduler) možete pronaći u članak.

  • Datoteka politike planiranja (scheduler-custom-policy-config.json)
    Kao što sam ranije napisao, možemo saznati s kojim specifičnim politikama radi zadani kube-scheduler samo analizom njegovog koda. Odnosno, ne možemo dobiti datoteku s politikama planiranja za zadani kube-scheduler na isti način kao konfiguracijski fajl. Hajde da opišemo politike planiranja koje 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
}

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

Nazovimo manifest novog kube-schedulera, koji smo kreirali na početku poglavlja, kube-scheduler-custom.yaml i smjestimo ga na sljedeću stazu /etc/kubernetes/manifests na tri glavna čvora. Ako je sve urađeno kako treba, Kubelet će pokrenuti pod na svakom čvoru, a u zapisima našeg novog kube-planera vidjet ćemo informaciju da je naša datoteka politike 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 ostaje je da naznačimo u specifikaciji našeg CronJob-a da sve zahtjeve za zakazivanje njegovih podova treba obraditi naš novi kube-scheduler:

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

zaključak

Na kraju, dobili smo dodatni kube-planer sa jedinstvenim skupom politika planiranja, čiji rad direktno nadgleda kubelet. Osim toga, postavili smo izbor novog vođe između podova našeg kube-schedulera u slučaju da stari lider iz nekog razloga postane nedostupan.

Redovne aplikacije i servisi nastavljaju da se zakazuju preko podrazumevanog kube-rasporednika, a svi cron zadaci su u potpunosti prebačeni na novi. Opterećenje koje stvaraju cron zadaci sada je ravnomjerno raspoređeno na sve čvorove. S obzirom da se većina cron zadataka izvršava na istim čvorovima kao i glavne aplikacije projekta, ovo je značajno smanjilo rizik od pomjeranja podova zbog nedostatka resursa. Nakon uvođenja dodatnog kube-planera, problemi s neujednačenim rasporedom cron zadataka više se nisu javljali.

Pročitajte i druge članke na našem blogu:

izvor: www.habr.com

Dodajte komentar