Opprette en ekstra kube-planlegger med et tilpasset sett med planleggingsregler

Opprette en ekstra kube-planlegger med et tilpasset sett med planleggingsregler

Kube-scheduler er en integrert komponent av Kubernetes, som er ansvarlig for å planlegge pods på tvers av noder i samsvar med spesifiserte retningslinjer. Ofte, under driften av en Kubernetes-klynge, trenger vi ikke å tenke på hvilke policyer som brukes til å planlegge pods, siden settet med policyer til standard kube-planleggeren er egnet for de fleste dagligdagse oppgaver. Imidlertid er det situasjoner der det er viktig for oss å finjustere prosessen med å tildele pods, og det er to måter å utføre denne oppgaven på:

  1. Lag en kube-planlegger med et tilpasset sett med regler
  2. Skriv din egen planlegger og lær den å jobbe med API-serverforespørsler

I denne artikkelen vil jeg beskrive implementeringen av det første punktet for å løse problemet med ujevn planlegging av ildsteder på et av våre prosjekter.

En kort introduksjon til hvordan kube-scheduler fungerer

Det er spesielt verdt å merke seg det faktum at kube-scheduler ikke er ansvarlig for direkte planlegging av pods - den er bare ansvarlig for å bestemme noden som poden skal plasseres på. Med andre ord, resultatet av kube-schedulers arbeid er navnet på noden, som den returnerer til API-serveren for en planleggingsforespørsel, og det er der arbeidet slutter.

Først kompilerer kube-scheduler en liste over noder som poden kan planlegges på i samsvar med predikatpolicyene. Deretter mottar hver node fra denne listen et visst antall poeng i samsvar med prioriteringspolicyene. Som et resultat blir noden med maksimalt antall poeng valgt. Hvis det er noder som har samme maksimale poengsum, velges en tilfeldig. En liste og beskrivelse av policyene for predikater (filtrering) og prioriteringer (poengsum) finner du i dokumentasjon.

Beskrivelse av problemkroppen

Til tross for det store antallet forskjellige Kubernetes-klynger som vedlikeholdes hos Nixys, møtte vi først problemet med å planlegge pods først nylig, da et av prosjektene våre trengte å kjøre et stort antall periodiske oppgaver (~100 CronJob-enheter). For å forenkle beskrivelsen av problemet så mye som mulig, tar vi som eksempel en mikrotjeneste, der en cron-oppgave startes en gang i minuttet, noe som skaper en viss belastning på CPU. For å kjøre cron-oppgaven ble tre noder med helt identiske egenskaper tildelt (24 vCPUer på hver).

Samtidig er det umulig å si nøyaktig hvor lang tid CronJob vil ta å utføre, siden volumet av inndata er i konstant endring. I gjennomsnitt, under normal drift av kube-scheduler, kjører hver node 3-4 jobbforekomster, som skaper ~20-30 % av belastningen på CPU-en til hver node:

Opprette en ekstra kube-planlegger med et tilpasset sett med planleggingsregler

Selve problemet er at noen ganger sluttet cron-oppgavepoder å bli planlagt på en av de tre nodene. Det vil si at på et tidspunkt var det ikke planlagt en eneste pod for en av nodene, mens på de to andre nodene kjørte 6-8 kopier av oppgaven, noe som skapte ~40-60% av CPU-belastningen:

Opprette en ekstra kube-planlegger med et tilpasset sett med planleggingsregler

Problemet gjentok seg med absolutt tilfeldig frekvens og korrelerte av og til med øyeblikket en ny versjon av koden ble rullet ut.

Ved å øke kube-planleggerens loggingsnivå til nivå 10 (-v=10), begynte vi å registrere hvor mange poeng hver node fikk under evalueringsprosessen. Under normal planleggingsdrift kunne følgende informasjon 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. å dømme etter informasjonen hentet fra loggene, fikk hver av nodene like mange sluttpoeng og en tilfeldig ble valgt for planlegging. På tidspunktet for problematisk planlegging så loggene slik ut:

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

Av dette kan man se at en av nodene fikk færre sluttpoeng enn de andre, og derfor ble det kun utført planlegging for de to nodene som fikk maksimal poengsum. Dermed var vi definitivt overbevist om at problemet ligger nettopp i planleggingen av podene.

Den videre algoritmen for å løse problemet var åpenbar for oss - analyser loggene, forstå ved hvilken prioritet noden ikke fikk poeng og, om nødvendig, juster retningslinjene til standard kube-planleggeren. Men her står vi overfor to betydelige vanskeligheter:

  1. På det maksimale loggingsnivået (10) gjenspeiles poeng oppnådd kun for noen prioriteringer. I det ovennevnte utdraget av logger kan du se at for alle prioriteringer som gjenspeiles i loggene, får noder samme antall poeng i normal- og problemplanlegging, men det endelige resultatet i tilfelle problemplanlegging er annerledes. Dermed kan vi konkludere med at for noen prioriteringer skjer scoring "bak kulissene", og vi har ingen måte å forstå hvilken prioritet noden ikke fikk poeng for. Vi beskrev dette problemet i detalj i utstedelse Kubernetes-depot på Github. I skrivende stund ble det mottatt svar fra utviklerne om at loggstøtte vil bli lagt til i Kubernetes v1.15,1.16, 1.17 og XNUMX oppdateringene.
  2. Det er ingen enkel måte å forstå hvilket spesifikt sett med retningslinjer kube-scheduler jobber med for øyeblikket. Ja, inn dokumentasjon denne listen er oppført, men den inneholder ikke informasjon om hvilke spesifikke vekter som er tildelt hver av prioriteringspolicyene. Du kan se vektene eller redigere retningslinjene til standard kube-planleggeren bare i kildekoder.

Det er verdt å merke seg at når vi var i stand til å registrere at en node ikke mottok poeng i henhold til ImageLocalityPriority-policyen, som tildeler poeng til en node hvis den allerede har bildet som er nødvendig for å kjøre applikasjonen. Det vil si at på det tidspunktet en ny versjon av applikasjonen ble rullet ut, klarte cron-oppgaven å kjøre på to noder, lastet ned et nytt bilde fra docker-registeret til dem, og dermed fikk to noder en høyere sluttpoengsum i forhold til den tredje. .

Som jeg skrev ovenfor, i loggene ser vi ikke informasjon om evalueringen av ImageLocalityPriority-policyen, så for å sjekke antagelsen vår, dumpet vi bildet med den nye versjonen av applikasjonen til den tredje noden, hvoretter planleggingen fungerte riktig . Det var nettopp på grunn av ImageLocalityPriority-policyen at planleggingsproblemet ble observert ganske sjelden; oftere var det assosiert med noe annet. På grunn av det faktum at vi ikke helt kunne feilsøke hver av policyene i listen over prioriteringer til standard kube-planleggeren, hadde vi et behov for fleksibel administrasjon av pod-planleggingspolicyer.

Formulering av problemet

Vi ønsket at løsningen på problemet skulle være så spesifikk som mulig, det vil si at hovedenhetene til Kubernetes (her mener vi standard kube-planlegger) skulle forbli uendret. Vi ønsket ikke å løse et problem ett sted og skape det et annet. Dermed kom vi til to alternativer for å løse problemet, som ble annonsert i introduksjonen til artikkelen - å lage en ekstra planlegger eller skrive din egen. Hovedkravet for å planlegge cron-oppgaver er å fordele belastningen jevnt over tre noder. Dette kravet kan tilfredsstilles av eksisterende kube-planlegger-policyer, så for å løse problemet vårt er det ingen vits i å skrive din egen planlegger.

Instruksjoner for å opprette og distribuere en ekstra kube-planlegger er beskrevet i dokumentasjon. Det virket imidlertid for oss som om distribusjonsenheten ikke var nok til å sikre feiltoleranse i driften av en så kritisk tjeneste som kube-scheduler, så vi bestemte oss for å distribuere en ny kube-scheduler som en statisk pod, som ville bli overvåket direkte av Kubelet. Derfor har vi følgende krav til den nye kube-planleggeren:

  1. Tjenesten må distribueres som en statisk pod på alle klyngemastere
  2. Feiltoleranse må gis i tilfelle den aktive poden med kube-planlegger er utilgjengelig
  3. Hovedprioriteten ved planlegging bør være antall tilgjengelige ressurser på noden (LeastRequestedPriority)

Løsningsimplementering

Det er verdt å merke seg med en gang at vi vil utføre alt arbeid i Kubernetes v1.14.7, fordi Dette er versjonen som ble brukt i prosjektet. La oss starte med å skrive et manifest for vår nye kube-planlegger. La oss ta standardmanifestet (/etc/kubernetes/manifests/kube-scheduler.yaml) som grunnlag 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 viktigste endringene:

  1. Endret navnet på poden og beholderen til kube-scheduler-cron
  2. Spesifiserte bruken av portene 10151 og 10159 slik alternativet ble definert hostNetwork: true og vi kan ikke bruke de samme portene som standard kube-planlegger (10251 og 10259)
  3. Ved å bruke --config-parameteren spesifiserte vi konfigurasjonsfilen som tjenesten skulle startes med
  4. Konfigurert montering av konfigurasjonsfilen (scheduler-custom.conf) og planleggingspolicyfilen (scheduler-custom-policy-config.json) fra verten

Ikke glem at vår kube-planlegger vil trenge rettigheter som ligner standarden. Rediger klyngerollen:

kubectl edit clusterrole system:kube-scheduler

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

La oss nå snakke om hva som skal være i konfigurasjonsfilen og planleggingspolicyfilen:

  • Konfigurasjonsfil (scheduler-custom.conf)
    For å få standard kube-planleggerkonfigurasjon, må du bruke parameteren --write-config-to av dokumentasjon. Vi vil plassere den resulterende konfigurasjonen i filen /etc/kubernetes/scheduler-custom.conf og redusere 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 viktigste endringene:

  1. Vi setter schedulerName til navnet på vår kube-scheduler-cron-tjeneste.
  2. I parameteren lockObjectName du må også angi navnet på tjenesten vår og sørge for at parameteren leaderElect satt til sann (hvis du har én hovednode, kan du sette den til usann).
  3. Spesifiserte banen til filen med en beskrivelse av planleggingspolicyene i parameteren algorithmSource.

Det er verdt å se nærmere på det andre punktet, der vi redigerer parameterne for nøkkelen leaderElection. For å sikre feiltoleranse har vi aktivert (leaderElect) prosessen med å velge en leder (master) mellom podene til kube-planleggeren vår ved å bruke et enkelt endepunkt for dem (resourceLock) kalt kube-scheduler-cron (lockObjectName) i kube-systemets navneområde (lockObjectNamespace). Hvordan Kubernetes sikrer høy tilgjengelighet av hovedkomponentene (inkludert kube-scheduler) kan finnes i artikkel.

  • Planleggingspolicyfil (scheduler-custom-policy-config.json)
    Som jeg skrev tidligere, kan vi finne ut hvilke spesifikke retningslinjer standard kube-planleggeren fungerer med bare ved å analysere koden. Det vil si at vi ikke kan få tak i en fil med planleggingspolicyer for standard kube-planlegger på samme måte som en konfigurasjonsfil. La oss beskrive planleggingspolicyene vi er interessert 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
}

Dermed kompilerer kube-scheduler først en liste over noder som en pod kan planlegges til i henhold til GeneralPredicates-policyen (som inkluderer et sett med PodFitsResources, PodFitsHostPorts, HostName og MatchNodeSelector-policyer). Og så blir hver node evaluert i samsvar med settet med policyer i prioritetsmatrisen. For å oppfylle betingelsene for vår oppgave, vurderte vi at et slikt sett med retningslinjer ville være den optimale løsningen. La meg minne deg på at et sett med retningslinjer med detaljerte beskrivelser er tilgjengelig i dokumentasjon. For å utføre oppgaven din kan du ganske enkelt endre settet med policyer som brukes og tildele passende vekter til dem.

La oss kalle manifestet til den nye kube-planleggeren, som vi opprettet i begynnelsen av kapittelet, kube-scheduler-custom.yaml og plassere den i den følgende banen /etc/kubernetes/manifests på tre hovednoder. Hvis alt er gjort riktig, vil Kubelet starte en pod på hver node, og i loggene til vår nye kube-planlegger vil vi se informasjon om at policyfilen vår ble brukt:

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

Nå gjenstår det bare å indikere i spesifikasjonen til vår CronJob at alle forespørsler om planlegging av pods skal behandles av vår nye kube-planlegger:

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

Konklusjon

Til slutt fikk vi en ekstra kube-planlegger med et unikt sett med planleggingspolicyer, hvis arbeid overvåkes direkte av kubelet. I tillegg har vi satt opp valget av en ny leder mellom podene til kube-planleggeren vår i tilfelle den gamle lederen blir utilgjengelig av en eller annen grunn.

Vanlige applikasjoner og tjenester fortsetter å planlegges gjennom standard kube-planleggeren, og alle cron-oppgaver er fullstendig overført til den nye. Belastningen skapt av cron-oppgaver er nå jevnt fordelt over alle noder. Tatt i betraktning at de fleste av cron-oppgavene utføres på de samme nodene som hovedapplikasjonene i prosjektet, har dette betydelig redusert risikoen for å flytte pods på grunn av mangel på ressurser. Etter å ha introdusert den ekstra kube-planleggeren, oppsto det ikke lenger problemer med ujevn planlegging av cron-oppgaver.

Les også andre artikler på bloggen vår:

Kilde: www.habr.com

Legg til en kommentar