Oprettelse af en ekstra kube-planlægger med et brugerdefineret sæt planlægningsregler

Oprettelse af en ekstra kube-planlægger med et brugerdefineret sæt planlægningsregler

Kube-scheduler er en integreret komponent af Kubernetes, som er ansvarlig for at planlægge pods på tværs af noder i overensstemmelse med specificerede politikker. Under driften af ​​en Kubernetes-klynge behøver vi ofte ikke at tænke på, hvilke politikker der bruges til at planlægge pods, da sæt af politikker i standard-kube-planlæggeren er velegnet til de fleste hverdagsopgaver. Der er dog situationer, hvor det er vigtigt for os at finjustere processen med at tildele pods, og der er to måder at udføre denne opgave på:

  1. Opret en kube-planlægger med et brugerdefineret sæt regler
  2. Skriv din egen planlægger, og lær den at arbejde med API-serveranmodninger

I denne artikel vil jeg beskrive implementeringen af ​​det første punkt for at løse problemet med ujævn planlægning af ildsteder på et af vores projekter.

En kort introduktion til, hvordan kube-scheduler fungerer

Det er især værd at bemærke det faktum, at kube-scheduler ikke er ansvarlig for direkte planlægning af pods - den er kun ansvarlig for at bestemme noden, hvorpå poden skal placeres. Med andre ord, resultatet af kube-schedulers arbejde er navnet på noden, som den returnerer til API-serveren for en planlægningsanmodning, og det er her dens arbejde slutter.

Først kompilerer kube-scheduler en liste over noder, hvor poden kan planlægges i overensstemmelse med prædikatpolitikkerne. Dernæst modtager hver node fra denne liste et vist antal point i overensstemmelse med prioritetspolitikkerne. Som et resultat vælges knudepunktet med det maksimale antal point. Hvis der er noder, der har samme maksimale score, vælges en tilfældig. En liste og beskrivelse af politikkerne for prædikater (filtrering) og prioriteter (scoring) kan findes i dokumentation.

Beskrivelse af problemlegemet

På trods af det store antal forskellige Kubernetes-klynger, der vedligeholdes hos Nixys, stødte vi først på problemet med at planlægge pods først for nylig, da et af vores projekter skulle køre et stort antal periodiske opgaver (~100 CronJob-enheder). For at forenkle beskrivelsen af ​​problemet så meget som muligt, vil vi som eksempel tage en mikrotjeneste, inden for hvilken en cron-opgave lanceres en gang i minuttet, hvilket skaber en vis belastning på CPU'en. For at køre cron-opgaven blev der tildelt tre noder med absolut identiske karakteristika (24 vCPU'er på hver).

Samtidig er det umuligt at sige med nøjagtighed, hvor lang tid CronJob vil tage at udføre, da mængden af ​​inputdata ændrer sig konstant. I gennemsnit, under normal drift af kube-scheduler, kører hver node 3-4 jobforekomster, som skaber ~20-30% af belastningen på CPU'en for hver node:

Oprettelse af en ekstra kube-planlægger med et brugerdefineret sæt planlægningsregler

Selve problemet er, at nogle gange stoppede cron-taskpods med at blive planlagt på en af ​​de tre noder. Det vil sige, at der på et tidspunkt ikke var planlagt en eneste pod for en af ​​noderne, mens der på de to andre noder kørte 6-8 kopier af opgaven, hvilket skabte ~40-60% af CPU-belastningen:

Oprettelse af en ekstra kube-planlægger med et brugerdefineret sæt planlægningsregler

Problemet gentog sig med absolut tilfældig frekvens og korrelerede af og til med det øjeblik, en ny version af koden blev rullet ud.

Ved at øge kube-scheduler-logningsniveauet til niveau 10 (-v=10), begyndte vi at registrere, hvor mange point hver node fik under evalueringsprocessen. Under normal planlægningsdrift kunne følgende oplysninger ses i loggene:

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

De der. at dømme efter informationen fra loggene, fik hver af knudepunkterne et lige antal sidste point, og et tilfældigt blev udvalgt til planlægning. På tidspunktet for problematisk planlægning så logfilerne således ud:

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

Hvoraf det kan ses, at en af ​​noderne fik færre slutpoint end de andre, og derfor blev der kun lavet planlægning for de to noder, der opnåede den maksimale score. Således var vi bestemt overbevist om, at problemet netop ligger i skemalægningen af ​​poderne.

Den yderligere algoritme til at løse problemet var indlysende for os - analyser logfilerne, forstå med hvilken prioritet noden ikke scorede point, og juster om nødvendigt politikkerne for standard kube-planlæggeren. Men her står vi over for to væsentlige vanskeligheder:

  1. Ved det maksimale logningsniveau (10) afspejles point, der kun er opnået for nogle prioriteter. I ovenstående uddrag af logfiler kan du se, at for alle prioriteter afspejlet i logfilerne, scorer noder det samme antal point i normal- og problemplanlægning, men det endelige resultat i tilfælde af problemplanlægning er anderledes. Således kan vi konkludere, at for nogle prioriteter sker scoring "bag kulisserne", og vi har ingen måde at forstå, for hvilken prioritet noden ikke fik point. Vi beskrev dette problem i detaljer i spørgsmål Kubernetes repository på Github. I skrivende stund er der modtaget et svar fra udviklerne om, at der vil blive tilføjet logføring i Kubernetes v1.15,1.16, 1.17 og XNUMX opdateringerne.
  2. Der er ingen nem måde at forstå, hvilket specifikt sæt politikker kube-scheduler arbejder med i øjeblikket. Ja, i dokumentation denne liste er opført, men den indeholder ikke oplysninger om, hvilke specifikke vægte der er tildelt hver af prioritetspolitikkerne. Du kan kun se vægtene eller redigere politikkerne for standard kube-planlæggeren i kildekoder.

Det er værd at bemærke, at vi engang var i stand til at registrere, at en node ikke modtog point i henhold til ImageLocalityPriority-politikken, som tildeler point til en node, hvis den allerede har det nødvendige billede til at køre applikationen. Det vil sige, at på det tidspunkt, hvor en ny version af applikationen blev rullet ud, lykkedes det cron-opgaven at køre på to noder, downloade et nyt billede fra docker-registret til dem, og dermed fik to noder en højere slutscore i forhold til den tredje. .

Som jeg skrev ovenfor, ser vi ikke i logfilerne information om evalueringen af ​​ImageLocalityPriority-politikken, så for at kontrollere vores antagelse dumpede vi billedet med den nye version af applikationen på den tredje node, hvorefter planlægningen fungerede korrekt . Det var netop på grund af ImageLocalityPriority-politikken, at planlægningsproblemet blev observeret ret sjældent; oftere var det forbundet med noget andet. På grund af det faktum, at vi ikke fuldt ud kunne debugge hver af politikkerne på listen over prioriteter i standard kube-planlægningsprogrammet, havde vi et behov for fleksibel styring af pod-planlægningspolitikker.

Formulering af problemet

Vi ønskede, at løsningen på problemet skulle være så specifik som muligt, det vil sige, at hovedentiteterne i Kubernetes (her mener vi standard kube-planlæggeren) skulle forblive uændrede. Vi ønskede ikke at løse et problem ét sted og skabe det et andet. Således kom vi til to muligheder for at løse problemet, som blev annonceret i introduktionen til artiklen - oprettelse af en ekstra skemalægger eller skrivning af din egen. Hovedkravet for at planlægge cron-opgaver er at fordele belastningen jævnt på tre knudepunkter. Dette krav kan opfyldes af eksisterende kube-planlægningspolitikker, så for at løse vores problem er der ingen mening i at skrive din egen planlægger.

Instruktioner til oprettelse og implementering af en ekstra kube-planlægger er beskrevet i dokumentation. Men det forekom os, at implementeringsenheden ikke var nok til at sikre fejltolerance i driften af ​​en så kritisk tjeneste som kube-scheduler, så vi besluttede at implementere en ny kube-scheduler som en statisk pod, som ville blive overvåget direkte af Kubelet. Derfor har vi følgende krav til den nye kube-planlægning:

  1. Tjenesten skal implementeres som en statisk pod på alle klyngemastere
  2. Fejltolerance skal angives i tilfælde af, at den aktive pod med kube-planlægning ikke er tilgængelig
  3. Hovedprioriteten ved planlægning bør være antallet af tilgængelige ressourcer på noden (LeastRequestedPriority)

Implementeringsløsninger

Det er værd at bemærke med det samme, at vi vil udføre alt arbejde i Kubernetes v1.14.7, fordi Dette er den version, der blev brugt i projektet. Lad os starte med at skrive et manifest til vores nye kube-planlægger. Lad os tage standardmanifestet (/etc/kubernetes/manifests/kube-scheduler.yaml) som grundlag og bringe det til følgende form:

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

Kort om de vigtigste ændringer:

  1. Ændrede navnet på poden og beholderen til kube-scheduler-cron
  2. Angiv brugen af ​​porte 10151 og 10159, som indstillingen blev defineret hostNetwork: true og vi kan ikke bruge de samme porte som standard kube-planlæggeren (10251 og 10259)
  3. Ved at bruge parameteren --config specificerede vi den konfigurationsfil, som tjenesten skulle startes med
  4. Konfigureret montering af konfigurationsfilen (scheduler-custom.conf) og planlægningspolitikfilen (scheduler-custom-policy-config.json) fra værten

Glem ikke, at vores kube-planlægger har brug for rettigheder svarende til standarden. Rediger dens klyngerolle:

kubectl edit clusterrole system:kube-scheduler

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

Lad os nu tale om, hvad der skal være indeholdt i konfigurationsfilen og planlægningspolitikfilen:

  • Konfigurationsfil (scheduler-custom.conf)
    For at opnå standard kube-scheduler-konfigurationen skal du bruge parameteren --write-config-to af dokumentation. Vi placerer den resulterende konfiguration i filen /etc/kubernetes/scheduler-custom.conf og reducerer den til følgende form:

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"

Kort om de vigtigste ændringer:

  1. Vi indstiller schedulerName til navnet på vores kube-scheduler-cron-tjeneste.
  2. I parameteren lockObjectName du skal også angive navnet på vores tjeneste og sørge for, at parameteren leaderElect sat til sand (hvis du har én masterknude, kan du indstille den til falsk).
  3. Angiv stien til filen med en beskrivelse af planlægningspolitikkerne i parameteren algorithmSource.

Det er værd at se nærmere på det andet punkt, hvor vi redigerer parametrene for nøglen leaderElection. For at sikre fejltolerance har vi aktiveret (leaderElect) processen med at vælge en leder (master) mellem pods af vores kube-planlægger ved hjælp af et enkelt slutpunkt for dem (resourceLock) med navnet kube-scheduler-cron (lockObjectName) i kube-systemets navneområde (lockObjectNamespace). Hvordan Kubernetes sikrer høj tilgængelighed af hovedkomponenterne (inklusive kube-scheduler) kan findes i artiklen.

  • Planlægningspolitikfil (scheduler-custom-policy-config.json)
    Som jeg skrev tidligere, kan vi kun finde ud af, hvilke specifikke politikker standard kube-planlæggeren arbejder med ved at analysere dens kode. Det vil sige, at vi ikke kan få en fil med planlægningspolitikker for standard kube-planlæggeren på samme måde som en konfigurationsfil. Lad os beskrive de planlægningspolitikker, vi er interesserede i i filen /etc/kubernetes/scheduler-custom-policy-config.json som følger:

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

Således kompilerer kube-scheduler først en liste over noder, som en pod kan planlægges til i henhold til GeneralPredicates-politikken (som inkluderer et sæt PodFitsResources, PodFitsHostPorts, HostName og MatchNodeSelector-politikker). Og derefter evalueres hver node i overensstemmelse med sættet af politikker i prioritetsarrayet. For at opfylde betingelserne for vores opgave anså vi, at et sådant sæt politikker ville være den optimale løsning. Lad mig minde dig om, at et sæt politikker med deres detaljerede beskrivelser er tilgængeligt i dokumentation. For at udføre din opgave kan du blot ændre det anvendte sæt af politikker og tildele passende vægte til dem.

Lad os kalde manifestet af den nye kube-scheduler, som vi oprettede i begyndelsen af ​​kapitlet, kube-scheduler-custom.yaml og placere det i den følgende sti /etc/kubernetes/manifests på tre hovedknudepunkter. Hvis alt er gjort korrekt, vil Kubelet starte en pod på hver node, og i logfilerne for vores nye kube-planlægger vil vi se oplysninger om, at vores politikfil blev anvendt med succes:

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

Nu er der kun tilbage at angive i specifikationerne for vores CronJob, at alle anmodninger om planlægning af dens pods skal behandles af vores nye kube-planlægger:

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

Konklusion

I sidste ende fik vi en ekstra kube-planlægger med et unikt sæt af planlægningspolitikker, hvis arbejde overvåges direkte af kubelet. Derudover har vi oprettet valget af en ny leder mellem pods af vores kube-planlægger, hvis den gamle leder bliver utilgængelig af en eller anden grund.

Regelmæssige applikationer og tjenester planlægges fortsat gennem standard kube-planlægningsprogrammet, og alle cron-opgaver er blevet fuldstændigt overført til den nye. Belastningen skabt af cron-opgaver er nu jævnt fordelt på alle noder. I betragtning af, at de fleste af cron-opgaverne udføres på de samme noder som projektets hovedapplikationer, har dette reduceret risikoen for at flytte pods betydeligt på grund af manglende ressourcer. Efter at have introduceret den ekstra kube-planlægning, opstod der ikke længere problemer med ujævn planlægning af cron-opgaver.

Læs også andre artikler på vores blog:

Kilde: www.habr.com

Tilføj en kommentar