Skapa en extra kube-schemaläggare med en anpassad uppsättning schemaläggningsregler

Skapa en extra kube-schemaläggare med en anpassad uppsättning schemaläggningsregler

Kube-scheduler är en integrerad komponent i Kubernetes, som ansvarar för att schemalägga pods över noder i enlighet med specificerade policyer. Under driften av ett Kubernetes-kluster behöver vi ofta inte tänka på exakt vilka policyer som används för att schemalägga poddar, eftersom standard-kube-schemaläggarens uppsättning policyer är lämpliga för de flesta vardagliga uppgifter. Det finns dock situationer när det är viktigt för oss att finjustera fördelningen av baljor, och det finns två sätt att utföra denna uppgift:

  1. Skapa kube-schemaläggare med anpassad regeluppsättning
  2. Skriv din egen schemaläggare och lär den att arbeta med API-serverförfrågningar

I den här artikeln kommer jag att beskriva genomförandet av exakt den första punkten för att lösa problemet med ojämn schemaläggning av pods på ett av våra projekt.

Kort introduktion om kube-scheduler'as arbete

Värt att notera är det faktum att kube-scheduler inte ansvarar för att schemalägga pods direkt - den ansvarar bara för att bestämma noden på vilken en pod ska placeras. Med andra ord, resultatet av kube-schedulers arbete är namnet på den nod som den returnerar till API-servern för schemaläggningsbegäran, och det är här dess arbete slutar.

Först listar kube-scheduler noderna som en Pod kan schemaläggas till enligt predikatpolicyerna. Vidare får varje nod från denna lista ett visst antal poäng i enlighet med prioritetspolicyerna. Som ett resultat väljs noden med högst poäng. Om det finns noder med samma maximala poäng väljs en slumpmässig. En lista och beskrivning av policyerna för predikat (filtrering) och prioriteringar (poängsättning) finns i dokumentation.

Beskrivning av problemkroppen

Trots det stora antalet olika Kubernetes-kluster som underhålls i Nixys, stötte vi först på problemet med att schemalägga pods först nyligen, när det för ett av våra projekt blev nödvändigt att köra ett stort antal periodiska uppgifter (~ 100 CronJob-enheter). För att förenkla beskrivningen av problemet så mycket som möjligt, låt oss som exempel ta en mikrotjänst, inom vilken en cron-uppgift lanseras en gång i minuten, vilket skapar en viss belastning på CPU:n. Tre absolut identiska noder (24 vCPUs på varje) tilldelades för arbetet med cron-uppgiften.

Samtidigt är det omöjligt att säga exakt hur länge CronJob kommer att köras, eftersom mängden indata ständigt förändras. I genomsnitt, under normal kube-scheduler-drift, kör varje nod 3-4 jobbinstanser, vilket skapar ~ 20-30% av belastningen på CPU:n för varje nod:

Skapa en extra kube-schemaläggare med en anpassad uppsättning schemaläggningsregler

Problemet i sig är att ibland slutade schemalägga cron-uppgiftspodar för en av de tre noderna. Det vill säga, någon gång i tiden var inte en enda pod planerad för en av noderna, medan 6-8 uppgiftsinstanser kördes på de andra två noderna, vilket skapade ~40-60% av belastningen på CPU:n:

Skapa en extra kube-schemaläggare med en anpassad uppsättning schemaläggningsregler

Problemet upprepades med absolut slumpmässig frekvens och korrelerade ibland med det ögonblick då en ny version av koden rullades ut.

Genom att öka loggningsnivån för kube-scheduler till nivå 10 (-v=10), började vi registrera hur många poäng varje nod får i utvärderingsprocessen. Under normal schemaläggning kunde följande information ses i loggarna:

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är. att döma av informationen som erhållits från loggarna fick var och en av noderna lika många slutpoäng och en slumpmässig en valdes för planering. Vid tidpunkten för problemplaneringen såg loggarna ut så här:

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 vilken det kan ses att en av noderna fick färre totalpoäng än de andra, och därför utfördes planering endast för två noder som fick högsta poäng. Därmed var vi säkra på att problemet ligger just i planeringen av baljor.

Den ytterligare algoritmen för att lösa problemet var uppenbar för oss - att analysera loggarna, förstå med vilken prioritet noden inte fick poäng och, om nödvändigt, justera policyerna för standard kube-schemaläggaren. Men här står vi inför två betydande svårigheter:

  1. Den maximala loggningsnivån (10) återspeglar uppsättningen poäng endast för vissa prioriteringar. I ovanstående loggutdrag kan du se att för alla prioriteringar som återspeglas i loggarna får noderna samma antal poäng i normal- och problemschemaläggning, men slutresultatet vid problemschemaläggning är annorlunda. Således kan vi dra slutsatsen att för vissa prioriteringar sker poängsättningen "bakom kulisserna", och vi har inget sätt att förstå för vilken prioritet noden inte fick poäng. Vi har beskrivit denna fråga i detalj i fråga Kubernetes repository på Github. I skrivande stund mottogs ett svar från utvecklarna att loggningsstöd kommer att läggas till i Kubernetes v1.15,1.16 och 1.17 uppdateringar.
  2. Det finns inget enkelt sätt att förstå vilken speciell uppsättning policyer som kube-scheduler för närvarande arbetar med. Ja, in dokumentation denna lista är listad, men den innehåller inte information om vilka specifika vikter som är satta för var och en av prioritetspolicyerna. Du kan bara se vikterna eller redigera policyerna för standardkube-schemaläggaren i källor.

Det är värt att notera att när vi väl lyckades fixa att noden inte fick poäng enligt ImageLocalityPriority-policyn, som ger poäng till noden om den redan har den bild som krävs för att köra applikationen. Det vill säga, när den nya versionen av applikationen rullades ut, hann cron-uppgiften köras på två noder, ladda ner en ny bild från docker-registret till dem, och två noder fick därmed ett högre slutresultat i förhållande till den tredje.

Som jag skrev ovan, i loggarna ser vi inte information om utvärderingen av ImageLocalityPriority-policyn, därför, för att kontrollera vårt antagande, spolade vi bilden med den nya versionen av applikationen till den tredje noden, varefter planeringen fungerade korrekt. Det var just på grund av ImageLocalityPriority-policyn som schemaläggningsproblemet observerades ganska sällan, oftare var det förknippat med något annat. På grund av det faktum att vi inte helt kunde felsöka var och en av principerna i prioriteringslistan för standard kube-schemaläggaren, hade vi ett behov av flexibel hantering av pod-schemaläggningspolicyer.

Problem uttalande

Vi ville att lösningen på problemet skulle vara så målinriktad som möjligt, det vill säga att huvudenheterna i Kubernetes (här menar vi standard kube-schemaläggaren) ska förbli oförändrade. Vi ville inte lösa ett problem på ett ställe och skapa det på ett annat. Således kom vi till två alternativ för att lösa problemet som tillkännagavs i inledningen till artikeln - skapa en extra schemaläggare eller skriva din egen. Huvudkravet för att schemalägga cron-uppgifter är att jämnt fördela belastningen över de tre noderna. Detta krav kan uppfyllas av befintliga kube-scheduler-policyer, så det är ingen mening att skriva vår egen schemaläggare för vår uppgift.

Instruktioner för att skapa och distribuera ytterligare en kube-schemaläggare beskrivs i dokumentation. Det verkade dock för oss som att implementeringsenheten inte räcker för att säkerställa feltolerans i driften av en så kritisk tjänst som kube-scheduler, så vi bestämde oss för att distribuera den nya kube-schedulern som en statisk pod, som Kubelet kommer att övervaka direkt. . Därför har vi följande krav för den nya kube-schemaläggaren:

  1. Tjänsten måste distribueras som en statisk pod på alla klustermaster
  2. Failover bör tillhandahållas om den aktiva podden med kube-scheduler inte är tillgänglig
  3. Huvudprioriteten vid planering bör vara mängden tillgängliga resurser på noden (LeastRequestedPriority)

Implementeringslösningar

Det bör noteras omedelbart att vi kommer att utföra allt arbete i Kubernetes v1.14.7, eftersom denna version användes i projektet. Låt oss börja med att skriva ett manifest för vår nya kube-schemaläggare. Låt oss ta standardmanifestet (/etc/kubernetes/manifests/kube-scheduler.yaml) som grund och föra det till följande 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 viktigaste förändringarna:

  1. Ändrade pod- och containernamn till kube-scheduler-cron
  2. Specificerad för att använda portarna 10151 och 10159 när alternativet är definierat hostNetwork: true och vi kan inte använda samma portar som standard kube-scheduler (10251 och 10259)
  3. Använd parametern --config, ange den konfigurationsfil som tjänsten ska starta med
  4. Konfigurerad för att montera konfigurationsfilen (scheduler-custom.conf) och schemaläggningspolicyfilen (scheduler-custom-policy-config.json) från värden

Glöm inte att vår kube-schemaläggare kommer att behöva rättigheter som liknar standarden. Redigera dess klusterroll:

kubectl edit clusterrole system:kube-scheduler

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

Låt oss nu prata om vad som ska finnas i konfigurationsfilen och schemaläggningspolicyfilen:

  • Konfigurationsfil (scheduler-custom.conf)
    För att få konfigurationen av standard kube-schemaläggaren måste du använda parametern --write-config-to av dokumentation. Vi kommer att placera den resulterande konfigurationen i filen /etc/kubernetes/scheduler-custom.conf och föra den till följande 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 viktigaste förändringarna:

  1. Ställ in schedulerName till namnet på vår tjänst kube-scheduler-cron.
  2. I parametern lockObjectName vi måste också ställa in namnet på vår tjänst och se till att parametern leaderElect satt till true (om du har en huvudnod kan du ställa in värdet på false).
  3. Angav sökvägen till filen med beskrivningen av schemaläggningsprinciper i parametern algorithmSource.

Det är värt att uppehålla sig mer i detalj vid andra stycket, där vi redigerar parametrarna för nyckeln leaderElection. För feltolerans har vi aktiverat (leaderElect) processen att välja en ledare (master) mellan poddarna i vår kube-schemaläggare genom att använda en enda slutpunkt för dem (resourceLock) heter kube-scheduler-cron (lockObjectName) i kube-systemets namnutrymme (lockObjectNamespace). Hur Kubernetes säkerställer hög tillgänglighet för huvudkomponenterna (inklusive kube-scheduler) finns i artikeln.

  • Schemaläggningspolicyfil (scheduler-custom-policy-config.json)
    Som jag skrev tidigare kan vi bara ta reda på vilka specifika policyer som standard kube-schemaläggaren arbetar med genom att analysera dess kod. Det vill säga, vi kan inte få filen med standard kube-schedulers schemaläggningspolicyer, analogt med konfigurationsfilen. Låt oss beskriva de schemaläggningspolicyer som är intressanta för oss i filen /etc/kubernetes/scheduler-custom-policy-config.json enligt följande:

{
  "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å kube-scheduler listar först noderna som en Pod kan schemaläggas till enligt GeneralPredicates-policyn (som inkluderar policyuppsättningen PodFitsResources, PodFitsHostPorts, HostName och MatchNodeSelector). Och sedan utvärderas varje nod i enlighet med uppsättningen policyer i prioritetsmatrisen. För att uppfylla villkoren för vår uppgift ansåg vi att en sådan uppsättning policyer skulle vara den bästa lösningen. Låt mig påminna dig om att en uppsättning policyer med deras detaljerade beskrivning finns tillgänglig i dokumentation. För att utföra din uppgift kan du helt enkelt ändra uppsättningen av policyer som används och tilldela lämpliga vikter till dem.

Det nya kube-scheduler-manifestet som vi skapade i början av kapitlet kommer att kallas kube-scheduler-custom.yaml och placeras i /etc/kubernetes/manifests på de tre huvudnoderna. Om allt görs korrekt kommer Kubelet att starta podden på varje nod, och i loggarna för vår nya kube-schemaläggare kommer vi att se information om att vår policyfil har tillämpats framgångsrikt:

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 återstår det bara att ange i specen för vår CronJob att alla förfrågningar om att schemalägga dess pods ska behandlas av vår nya kube-scheduler:

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

Slutsats

Till slut fick vi en extra kube-schemaläggare med en unik uppsättning schemaläggningspolicyer, som övervakas direkt av kubelet. Dessutom ställer vi in ​​valet av en ny ledare mellan poddarna på vår kube-schemaläggare ifall den gamla ledaren blir otillgänglig av någon anledning.

Normala applikationer och tjänster fortsätter att schemaläggas genom standard kube-scheduler, och alla cron-uppgifter har överförts helt till den nya. Belastningen som skapas av cron-uppgifter är nu jämnt fördelad över alla noder. Med tanke på att de flesta av cron-uppgifterna utförs på samma noder som projektets huvudapplikationer, minskade detta avsevärt risken för att pods flyttar på grund av brist på resurser. Efter introduktionen av den extra kube-schemaläggaren fanns det inga fler problem med ojämn schemaläggning av cron-jobb.

Läs även andra artiklar på vår blogg:

Källa: will.com

Lägg en kommentar