Een extra kube-scheduler maken met een aangepaste set planningsregels

Een extra kube-scheduler maken met een aangepaste set planningsregels

Kube-scheduler is een integraal onderdeel van Kubernetes, dat verantwoordelijk is voor het plannen van pods op knooppunten in overeenstemming met gespecificeerd beleid. Vaak hoeven we tijdens de werking van een Kubernetes-cluster niet na te denken over welk beleid wordt gebruikt om pods te plannen, omdat de set beleidsregels van de standaard kube-scheduler geschikt is voor de meeste dagelijkse taken. Er zijn echter situaties waarin het belangrijk voor ons is om het proces van het toewijzen van pods te verfijnen, en er zijn twee manieren om deze taak te volbrengen:

  1. Maak een Kube-planner met een aangepaste set regels
  2. Schrijf uw eigen planner en leer deze werken met API-serververzoeken

In dit artikel zal ik de implementatie beschrijven van het eerste punt om het probleem van de ongelijke planning van haarden op een van onze projecten op te lossen.

Een korte introductie over hoe Kube-Scheduler werkt

Het is vooral de moeite waard om op te merken dat kube-scheduler niet verantwoordelijk is voor het rechtstreeks plannen van pods; het is alleen verantwoordelijk voor het bepalen van het knooppunt waarop de pod moet worden geplaatst. Met andere woorden: het resultaat van het werk van kube-scheduler is de naam van het knooppunt, dat het terugstuurt naar de API-server voor een planningsverzoek, en dat is waar zijn werk eindigt.

Eerst stelt kube-scheduler een lijst samen met knooppunten waarop de pod kan worden gepland in overeenstemming met het predicatenbeleid. Vervolgens ontvangt elk knooppunt uit deze lijst een bepaald aantal punten in overeenstemming met het prioriteitenbeleid. Als resultaat wordt het knooppunt met het maximale aantal punten geselecteerd. Als er knooppunten zijn die dezelfde maximale score hebben, wordt er een willekeurig knooppunt geselecteerd. Een lijst en beschrijving van het beleid inzake predikaten (filteren) en prioriteiten (scoren) is te vinden in documentatie.

Beschrijving van het probleemlichaam

Ondanks het grote aantal verschillende Kubernetes-clusters dat bij Nixys wordt onderhouden, kwamen we pas onlangs voor het eerst het probleem van het plannen van pods tegen, toen een van onze projecten een groot aantal periodieke taken moest uitvoeren (~100 CronJob-entiteiten). Om de beschrijving van het probleem zoveel mogelijk te vereenvoudigen, nemen we als voorbeeld één microservice, waarbinnen één keer per minuut een cron-taak wordt gestart, waardoor de CPU enigszins wordt belast. Om de cron-taak uit te voeren, werden drie knooppunten met absoluut identieke kenmerken toegewezen (elk 24 vCPU's).

Tegelijkertijd is het onmogelijk om met nauwkeurigheid te zeggen hoe lang het duurt om de CronJob uit te voeren, omdat het volume aan invoergegevens voortdurend verandert. Tijdens de normale werking van Kube-Scheduler voert elk knooppunt gemiddeld 3-4 taakinstanties uit, die ~20-30% van de belasting van de CPU van elk knooppunt creëren:

Een extra kube-scheduler maken met een aangepaste set planningsregels

Het probleem zelf is dat cron-taakpods soms niet meer gepland werden op een van de drie knooppunten. Dat wil zeggen dat er op een bepaald moment geen enkele pod was gepland voor een van de knooppunten, terwijl op de andere twee knooppunten 6-8 kopieën van de taak draaiden, wat ongeveer 40-60% van de CPU-belasting creëerde:

Een extra kube-scheduler maken met een aangepaste set planningsregels

Het probleem herhaalde zich met een absoluut willekeurige frequentie en correleerde af en toe met het moment waarop een nieuwe versie van de code werd uitgerold.

Door het logniveau van de kube-scheduler te verhogen naar niveau 10 (-v=10), begonnen we vast te leggen hoeveel punten elk knooppunt tijdens het evaluatieproces had behaald. Tijdens de normale planning kon de volgende informatie in de logboeken worden weergegeven:

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

Die. Afgaande op de informatie verkregen uit de logboeken scoorde elk van de knooppunten een gelijk aantal eindpunten en werd er een willekeurig punt geselecteerd voor de planning. Ten tijde van de problematische planning zagen de logboeken er als volgt uit:

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

Hieruit blijkt dat één van de knooppunten minder eindpunten scoorde dan de andere, en dat de planning daarom alleen werd uitgevoerd voor de twee knooppunten die de maximale score scoorden. We waren er dus absoluut van overtuigd dat het probleem juist in de planning van de pods ligt.

Het verdere algoritme voor het oplossen van het probleem lag voor ons voor de hand: analyseer de logboeken, begrijp met welke prioriteit het knooppunt geen punten kreeg en pas indien nodig het beleid van de standaard kube-scheduler aan. Hier worden we echter geconfronteerd met twee belangrijke problemen:

  1. Op het maximale logniveau (10) worden de punten die alleen voor bepaalde prioriteiten zijn behaald, weergegeven. In het bovenstaande fragment uit de logboeken kunt u zien dat voor alle prioriteiten die in de logboeken worden weerspiegeld, knooppunten hetzelfde aantal punten scoren in de normale planning en de probleemplanning, maar dat het uiteindelijke resultaat in het geval van probleemplanning anders is. We kunnen dus concluderen dat voor sommige prioriteiten de score ‘achter de schermen’ plaatsvindt, en we hebben geen manier om te begrijpen voor welke prioriteit het knooppunt geen punten heeft gekregen. We hebben dit probleem uitgebreid beschreven in kwestie Kubernetes-repository op Github. Op het moment van schrijven is er een reactie ontvangen van de ontwikkelaars dat logondersteuning zal worden toegevoegd in de Kubernetes v1.15,1.16, 1.17 en XNUMX updates.
  2. Er is geen eenvoudige manier om te begrijpen met welke specifieke set beleidsregels kube-scheduler momenteel werkt. Ja in documentatie deze lijst wordt vermeld, maar bevat geen informatie over welke specifieke gewichten aan elk van de beleidsprioriteiten worden toegekend. U kunt de gewichten alleen bekijken of het beleid van de standaardkube-planner bewerken in broncodes.

Het is vermeldenswaard dat we ooit konden vaststellen dat een knooppunt geen punten heeft ontvangen volgens het ImageLocalityPriority-beleid, dat punten toekent aan een knooppunt als het al over de afbeelding beschikt die nodig is om de applicatie uit te voeren. Dat wil zeggen, op het moment dat een nieuwe versie van de applicatie werd uitgerold, slaagde de cron-taak erin om op twee knooppunten te draaien, waarbij een nieuwe afbeelding uit het docker-register naar hen werd gedownload, en dus kregen twee knooppunten een hogere eindscore ten opzichte van de derde. .

Zoals ik hierboven schreef, zien we in de logboeken geen informatie over de evaluatie van het ImageLocalityPriority-beleid, dus om onze veronderstelling te controleren, hebben we de afbeelding met de nieuwe versie van de applicatie op het derde knooppunt gedumpt, waarna de planning correct werkte . Juist dankzij het ImageLocalityPriority-beleid werd het planningsprobleem vrij zelden waargenomen; vaker werd het met iets anders geassocieerd. Vanwege het feit dat we niet elk beleid in de lijst met prioriteiten van de standaard Kube-planner volledig konden debuggen, hadden we behoefte aan flexibel beheer van het pod-planningsbeleid.

Formulering van het probleem

We wilden dat de oplossing voor het probleem zo specifiek mogelijk zou zijn, dat wil zeggen dat de belangrijkste entiteiten van Kubernetes (hier bedoelen we de standaard Kube-planner) ongewijzigd zouden moeten blijven. We wilden niet een probleem op de ene plek oplossen en het op een andere plek creëren. Zo kwamen we tot twee opties om het probleem op te lossen, die in de inleiding van het artikel werden aangekondigd: een extra planner maken of je eigen planner schrijven. De belangrijkste vereiste voor het plannen van cron-taken is het gelijkmatig verdelen van de belasting over drie knooppunten. Aan deze vereiste kan worden voldaan door het bestaande kube-schedulerbeleid, dus om ons probleem op te lossen heeft het geen zin om uw eigen planner te schrijven.

Instructies voor het maken en implementeren van een extra kube-scheduler worden beschreven in documentatie. Het leek ons ​​echter dat de implementatie-entiteit niet genoeg was om fouttolerantie te garanderen bij de werking van een dergelijke kritieke dienst als Kube-Scheduler, dus besloten we een nieuwe Kube-Scheduler in te zetten als een statische pod, die direct zou worden gemonitord. van Kubelet. We hebben dus de volgende vereisten voor de nieuwe kube-scheduler:

  1. De service moet worden geïmplementeerd als een statische pod op alle clustermasters
  2. Er moet een fouttolerantie worden opgegeven voor het geval de actieve pod met Kube-planner niet beschikbaar is
  3. De belangrijkste prioriteit bij het plannen moet het aantal beschikbare bronnen op het knooppunt zijn (LeastRequestedPriority)

Implementatie oplossingen

Het is meteen vermeldenswaard dat we al het werk in Kubernetes v1.14.7 zullen uitvoeren, omdat Dit is de versie die in het project is gebruikt. Laten we beginnen met het schrijven van een manifest voor onze nieuwe kube-scheduler. Laten we het standaardmanifest (/etc/kubernetes/manifests/kube-scheduler.yaml) als basis nemen en het in de volgende vorm brengen:

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 over de belangrijkste wijzigingen:

  1. De naam van de pod en container gewijzigd in kube-scheduler-cron
  2. Specificeerde het gebruik van poorten 10151 en 10159 zoals de optie was gedefinieerd hostNetwork: true en we kunnen niet dezelfde poorten gebruiken als de standaard kube-scheduler (10251 en 10259)
  3. Met behulp van de parameter --config hebben we het configuratiebestand opgegeven waarmee de service moet worden gestart
  4. Geconfigureerde koppeling van het configuratiebestand (scheduler-custom.conf) en het planningsbeleidsbestand (scheduler-custom-policy-config.json) vanaf de host

Vergeet niet dat onze kube-scheduler rechten nodig heeft die vergelijkbaar zijn met de standaardrechten. Bewerk de clusterrol:

kubectl edit clusterrole system:kube-scheduler

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

Laten we het nu hebben over wat er in het configuratiebestand en het planningsbeleidsbestand moet staan:

  • Configuratiebestand (planner-custom.conf)
    Om de standaardkube-scheduler-configuratie te verkrijgen, moet u de parameter gebruiken --write-config-to van documentatie. We plaatsen de resulterende configuratie in het bestand /etc/kubernetes/scheduler-custom.conf en reduceren deze tot de volgende vorm:

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 over de belangrijkste wijzigingen:

  1. We hebben plannerName ingesteld op de naam van onze kube-scheduler-cron-service.
  2. In de parameter lockObjectName u moet ook de naam van onze service instellen en ervoor zorgen dat de parameter leaderElect ingesteld op true (als u één masternode heeft, kunt u deze instellen op false).
  3. Het pad naar het bestand opgegeven met een beschrijving van het planningsbeleid in de parameter algorithmSource.

Het is de moeite waard om het tweede punt nader te bekijken, waar we de parameters voor de sleutel bewerken leaderElection. Om fouttolerantie te garanderen, hebben we ingeschakeld (leaderElect) het proces van het selecteren van een leider (master) tussen de pods van onze kube-scheduler met behulp van een enkel eindpunt daarvoor (resourceLock) met de naam kube-scheduler-cron (lockObjectName) in de kube-systeemnaamruimte (lockObjectNamespace). Hoe Kubernetes zorgt voor een hoge beschikbaarheid van de belangrijkste componenten (inclusief kube-scheduler) kun je vinden in статье.

  • Planningsbeleidsbestand (scheduler-custom-policy-config.json)
    Zoals ik eerder schreef, kunnen we alleen achterhalen met welk specifiek beleid de standaard kube-scheduler werkt door de code ervan te analyseren. Dat wil zeggen dat we geen bestand met planningsbeleid voor de standaardkube-scheduler op dezelfde manier kunnen verkrijgen als een configuratiebestand. Laten we het planningsbeleid waarin we geïnteresseerd zijn in het bestand /etc/kubernetes/scheduler-custom-policy-config.json als volgt beschrijven:

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

Kube-scheduler stelt dus eerst een lijst samen met knooppunten waarop een pod kan worden gepland volgens het GeneralPredicates-beleid (dat een set PodFitsResources-, PodFitsHostPorts-, HostName- en MatchNodeSelector-beleid omvat). En vervolgens wordt elk knooppunt geëvalueerd in overeenstemming met de reeks beleidsregels in de prioriteitenarray. Om aan de voorwaarden van onze taak te voldoen, waren wij van mening dat een dergelijke reeks beleidsmaatregelen de optimale oplossing zou zijn. Ik wil u eraan herinneren dat een reeks beleidsregels met hun gedetailleerde beschrijvingen beschikbaar is in documentatie. Om uw taak te volbrengen, kunt u eenvoudigweg de gebruikte beleidsregels wijzigen en er de juiste gewichten aan toekennen.

Laten we het manifest van de nieuwe kube-scheduler, die we aan het begin van dit hoofdstuk hebben gemaakt, kube-scheduler-custom.yaml noemen en het in het volgende pad /etc/kubernetes/manifests op drie hoofdknooppunten plaatsen. Als alles correct is gedaan, zal Kubelet een pod op elk knooppunt starten, en in de logs van onze nieuwe kube-scheduler zullen we informatie zien dat ons beleidsbestand met succes is toegepast:

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 hoeft u alleen nog maar in de specificatie van onze CronJob aan te geven dat alle verzoeken voor het plannen van de pods moeten worden verwerkt door onze nieuwe kube-scheduler:

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

Conclusie

Uiteindelijk hebben we een extra kube-scheduler gekregen met een unieke set planningsbeleid, waarvan het werk rechtstreeks door de kubelet wordt gecontroleerd. Daarnaast hebben we de verkiezing van een nieuwe leider tussen de pods van onze kube-planner ingesteld, voor het geval de oude leider om een ​​of andere reden niet meer beschikbaar is.

Reguliere applicaties en services worden nog steeds gepland via de standaard kube-scheduler en alle cron-taken zijn volledig overgebracht naar de nieuwe. De belasting die door cron-taken wordt gecreëerd, wordt nu gelijkmatig verdeeld over alle knooppunten. Gezien het feit dat de meeste cron-taken worden uitgevoerd op dezelfde knooppunten als de hoofdapplicaties van het project, heeft dit het risico op het verplaatsen van pods vanwege een gebrek aan middelen aanzienlijk verminderd. Na de introductie van de extra kube-scheduler deden zich geen problemen meer voor met de ongelijkmatige planning van cron-taken.

Lees ook andere artikelen op onze blog:

Bron: www.habr.com

Voeg een reactie