Kreante plian kube-planilon kun kutima aro de planaj reguloj

Kreante plian kube-planilon kun kutima aro de planaj reguloj

Kube-planilo estas integra komponanto de Kubernetes, kiu respondecas pri planado de podoj trans nodoj laŭ specifitaj politikoj. Ofte, dum funkciado de Kubernetes-areto, ni ne devas pensi pri kiuj politikoj estas uzataj por plani podojn, ĉar la aro de politikoj de la defaŭlta kube-planilo taŭgas por la plej multaj ĉiutagaj taskoj. Tamen, estas situacioj kiam gravas por ni agordi la procezon de asignado de podoj, kaj estas du manieroj plenumi ĉi tiun taskon:

  1. Kreu kube-planilon kun kutima aro de reguloj
  2. Skribu vian propran planilon kaj instruu ĝin labori kun API-servilaj petoj

En ĉi tiu artikolo, mi priskribos la efektivigon de la unua punkto por solvi la problemon de neegala planado de kamenoj en unu el niaj projektoj.

Mallonga enkonduko al kiel funkcias kube-scheduler

Indas precipe rimarki la fakton, ke kube-scheduler ne respondecas pri rekte plani podojn - ĝi nur respondecas pri determini la nodon, sur kiu meti la podojn. Alivorte, la rezulto de la laboro de kube-scheduler estas la nomo de la nodo, kiun ĝi resendas al la API-servilo por programa peto, kaj tie finiĝas ĝia laboro.

Unue, kube-scheduler kompilas liston de nodoj sur kiuj la pod povas esti planita laŭ la predikataj politikoj. Poste, ĉiu nodo de ĉi tiu listo ricevas certan nombron da poentoj konforme al la prioritataj politikoj. Kiel rezulto, la nodo kun la maksimuma nombro da punktoj estas elektita. Se estas nodoj kiuj havas la saman maksimuman poentaron, hazarda estas elektita. Listo kaj priskribo de la predikatoj (filtrado) kaj prioritatoj (poentado) politikoj troveblas en dokumentado.

Priskribo de la problemkorpo

Malgraŭ la granda nombro da malsamaj Kubernetes-aretoj konservitaj ĉe Nixys, ni unue renkontis la problemon de planado de podoj nur lastatempe, kiam unu el niaj projektoj bezonis ruli grandan nombron da periodaj taskoj (~100 CronJob-entaĵoj). Por simpligi la priskribon de la problemo kiel eble plej multe, ni prenos kiel ekzemplon unu mikroservon, ene de kiu kron-tasko estas lanĉita unufoje ĉiuminute, kreante iom da ŝarĝo sur la CPU. Por ruli la cron-taskon, tri nodoj kun absolute identaj trajtoj estis asignitaj (24 vCPUoj sur ĉiu).

Samtempe, estas neeble diri kun precizeco kiom longe la CronJob daŭros por ekzekuti, ĉar la volumo de eniga datumoj konstante ŝanĝas. Averaĝe, dum normala funkciado de kube-scheduler, ĉiu nodo kuras 3-4 laborkazojn, kiuj kreas ~20-30% de la ŝarĝo sur la CPU de ĉiu nodo:

Kreante plian kube-planilon kun kutima aro de planaj reguloj

La problemo mem estas, ke foje cron-taskaj podoj ĉesis esti planitaj sur unu el la tri nodoj. Tio estas, en iu momento, eĉ ne unu balgo estis planita por unu el la nodoj, dum sur la aliaj du nodoj funkciis 6-8 kopioj de la tasko, kreante ~40-60% de la CPU-ŝarĝo:

Kreante plian kube-planilon kun kutima aro de planaj reguloj

La problemo ripetiĝis kun absolute hazarda ofteco kaj foje korelaciis kun la momento, kiam nova versio de la kodo estis lanĉita.

Pliigante la nivelon de protokolado de kube-planisto al nivelo 10 (-v=10), ni komencis registri kiom da poentoj ĉiu nodo gajnis dum la taksada procezo. Dum normala plana operacio, la sekvaj informoj povus esti viditaj en la protokoloj:

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

Tiuj. juĝante laŭ la informoj akiritaj de la ŝtipoj, ĉiu el la nodoj gajnis egalan nombron da finaj poentoj kaj hazarda unu estis elektita por planado. En la tempo de problema planado, la protokoloj aspektis jene:

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

El kio videblas, ke unu el la nodoj gajnis malpli da finpunktoj ol la aliaj, kaj tial planado estis farita nur por la du nodoj kiuj gajnis la maksimuman poentaron. Tiel, ni certe konvinkiĝis, ke la problemo kuŝas ĝuste en la planado de la balgoj.

La plia algoritmo por solvi la problemon estis evidenta por ni - analizu la protokolojn, komprenu laŭ kia prioritato la nodo ne gajnis poentojn kaj, se necese, ĝustigu la politikojn de la defaŭlta kube-planilo. Tamen, ĉi tie ni alfrontas du gravajn malfacilaĵojn:

  1. Ĉe la maksimuma registra nivelo (10), punktoj akiritaj nur por iuj prioritatoj estas reflektitaj. En la supra eltiraĵo de protokoloj, vi povas vidi, ke por ĉiuj prioritatoj reflektitaj en la protokoloj, nodoj gajnas la saman nombron da poentoj en normala kaj problemplanado, sed la fina rezulto en la kazo de problemplanado estas malsama. Tiel, ni povas konkludi, ke por iuj prioritatoj, poentado okazas "malantaŭ la scenoj", kaj ni ne havas manieron kompreni por kiu prioritato la nodo ne ricevis poentojn. Ni priskribis ĉi tiun problemon detale en temo Kubernetes-deponejo sur Github. En la momento de la skribado, oni ricevis respondon de la programistoj, ke registra subteno estos aldonita en la ĝisdatigoj de Kubernetes v1.15,1.16, 1.17 kaj XNUMX.
  2. Ne estas facila maniero kompreni, kun kiu specifa aro de politikoj kube-scheduler nuntempe laboras. Jes, en dokumentado ĉi tiu listo estas listigita, sed ĝi ne enhavas informojn pri kiaj specifaj pezoj estas asignitaj al ĉiu el la prioritataj politikoj. Vi povas vidi la pezojn aŭ redakti la politikojn de la defaŭlta kube-planilo nur en fontoj.

Indas noti, ke iam ni povis registri, ke nodo ne ricevis poentojn laŭ la politiko ImageLocalityPriority, kiu aljuĝas poentojn al nodo se ĝi jam havas la bildon necesan por ruli la aplikaĵon. Tio estas, kiam nova versio de la aplikaĵo estis lanĉita, la cron-tasko sukcesis funkcii sur du nodoj, elŝutante novan bildon de la docker-registro al ili, kaj tiel du nodoj ricevis pli altan finan poentaron rilate al la tria. .

Kiel mi skribis supre, en la protokoloj ni ne vidas informojn pri la taksado de la politiko ImageLocalityPriority, do por kontroli nian supozon, ni forĵetis la bildon kun la nova versio de la aplikaĵo sur la trian nodon, post kiu planado funkciis ĝuste. . Ĝuste pro la politiko ImageLocalityPriority la planproblemo estis observita sufiĉe malofte; pli ofte ĝi estis asociita kun io alia. Pro la fakto, ke ni ne povis plene sencimigi ĉiun el la politikoj en la listo de prioritatoj de la defaŭlta kube-scheduler, ni havis bezonon por fleksebla administrado de pod-planadpolitikoj.

Formulado de la problemo

Ni volis, ke la solvo de la problemo estu kiel eble plej specifa, tio estas, ke la ĉefaj estaĵoj de Kubernetes (ĉi tie ni volas diri la defaŭltan kube-planilon) restu senŝanĝaj. Ni ne volis solvi problemon en unu loko kaj krei ĝin en alia. Tiel, ni venis al du ebloj por solvi la problemon, kiuj estis anoncitaj en la enkonduko al la artikolo - krei plian planilon aŭ skribi vian propran. La ĉefa postulo por plani cron-taskojn estas distribui la ŝarĝon egale tra tri nodoj. Ĉi tiu postulo povas esti kontentigita per ekzistantaj kube-scheduler-politikoj, do por solvi nian problemon ne utilas skribi vian propran planilon.

Instrukcioj por krei kaj Deploji plian kube-planilon estas priskribitaj en dokumentado. Tamen, ŝajnis al ni, ke la Deploja ento ne sufiĉas por certigi misfunkciadon en la funkciado de tia kritika servo kiel kube-scheduler, do ni decidis deploji novan kube-scheduler kiel Static Pod, kiu estus rekte monitorita. de Kubelet. Tiel, ni havas la jenajn postulojn por la nova kube-planilo:

  1. La servo devas esti deplojita kiel Static Pod sur ĉiuj cluster-majstroj
  2. Toleremo al misfunkciadoj devas esti provizita se la aktiva pod kun kube-scheduler ne estas disponebla
  3. La ĉefa prioritato dum planado devus esti la nombro da disponeblaj rimedoj sur la nodo (LeastRequestedPriority)

Solvoj de efektivigo

Indas tuj rimarki, ke ni plenumos ĉiujn laborojn en Kubernetes v1.14.7, ĉar Ĉi tiu estas la versio, kiu estis uzata en la projekto. Ni komencu verkante manifeston por nia nova kube-planilo. Ni prenu la defaŭltan manifeston (/etc/kubernetes/manifests/kube-scheduler.yaml) kiel bazon kaj alportu ĝin al la sekva formo:

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

Mallonge pri la ĉefaj ŝanĝoj:

  1. Ŝanĝis la nomon de la pod kaj ujo al kube-scheduler-cron
  2. Precis la uzon de havenoj 10151 kaj 10159 kiel la opcio estis difinita hostNetwork: true kaj ni ne povas uzi la samajn havenojn kiel la defaŭlta kube-planilo (10251 kaj 10259)
  3. Uzante la parametron --config, ni specifis la agordan dosieron per kiu la servo devus esti komencita
  4. Agordita muntado de la agorda dosiero (scheduler-custom.conf) kaj planada politika dosiero (scheduler-custom-policy-config.json) de la gastiganto

Ne forgesu, ke nia kube-planilo bezonos rajtojn similajn al la defaŭlta. Redaktu ĝian gruprolon:

kubectl edit clusterrole system:kube-scheduler

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

Nun ni parolu pri tio, kio devus esti enhavita en la agorda dosiero kaj la planada politika dosiero:

  • Agorda dosiero (scheduler-custom.conf)
    Por akiri la defaŭltan agordon de kube-scheduler, vi devas uzi la parametron --write-config-to el dokumentado. Ni metos la rezultan agordon en la dosieron /etc/kubernetes/scheduler-custom.conf kaj reduktos ĝin al la sekva formo:

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"

Mallonge pri la ĉefaj ŝanĝoj:

  1. Ni agordas schedulerName al la nomo de nia kube-scheduler-cron servo.
  2. En la parametro lockObjectName vi ankaŭ devas agordi la nomon de nia servo kaj certigi ke la parametro leaderElect agordu al vera (se vi havas unu majstran nodon, vi povas agordi ĝin al falsa).
  3. Specis la vojon al la dosiero kun priskribo de la planaj politikoj en la parametro algorithmSource.

Indas rigardi pli detale la duan punkton, kie ni redaktas la parametrojn por la ŝlosilo leaderElection. Por certigi misfunkciadon, ni ebligis (leaderElect) la procezo de elektado de gvidanto (majstro) inter la balgoj de nia kube-planilo uzante ununuran finpunkton por ili (resourceLock) nomita kube-scheduler-cron (lockObjectName) en la kube-sistema nomspaco (lockObjectNamespace). Kiel Kubernetes certigas altan haveblecon de la ĉefaj komponentoj (inkluzive de kube-planilo) troveblas en artikolo.

  • Planada politika dosiero (scheduler-custom-policy-config.json)
    Kiel mi skribis pli frue, ni povas ekscii kun kiuj specifaj politikoj funkcias la defaŭlta kube-planilo nur analizante ĝian kodon. Tio estas, ni ne povas akiri dosieron kun planaj politikoj por la defaŭlta kube-scheduler same kiel agorda dosiero. Ni priskribu la planadpolitikojn pri kiuj ni interesiĝas en la /etc/kubernetes/scheduler-custom-policy-config.json-dosiero jene:

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

Tiel, kube-scheduler unue kompilas liston de nodoj al kiuj pod povas esti planita laŭ la politiko GeneralPredicates (kiu inkluzivas aron de politikoj PodFitsResources, PodFitsHostPorts, HostName kaj MatchNodeSelector). Kaj tiam ĉiu nodo estas taksita laŭ la aro de politikoj en la prioritata tabelo. Por plenumi la kondiĉojn de nia tasko, ni konsideris, ke tia aro de politikoj estus la optimuma solvo. Mi memorigu vin, ke aro da politikoj kun iliaj detalaj priskriboj estas disponeblaj en dokumentado. Por plenumi vian taskon, vi povas simple ŝanĝi la aron da politikoj uzataj kaj atribui taŭgajn pezojn al ili.

Ni nomos la manifeston de la nova kube-scheduler, kiun ni kreis komence de la ĉapitro, kube-scheduler-custom.yaml kaj metos ĝin en la sekvan vojon /etc/kubernetes/manifests sur tri ĉefaj nodoj. Se ĉio estas farita ĝuste, Kubelet lanĉos podon sur ĉiu nodo, kaj en la protokoloj de nia nova kube-planilo ni vidos informojn, ke nia politika dosiero estis sukcese aplikita:

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

Nun restas nur indiki en la specifo de nia CronJob, ke ĉiuj petoj por plani ĝiajn podojn devas esti procesitaj de nia nova kube-planilo:

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

konkludo

Finfine, ni ricevis plian kube-planilon kun unika aro de planaj politikoj, kies laboro estas kontrolita rekte de la kubelet. Krome, ni starigis la elekton de nova gvidanto inter la balgoj de nia kube-planisto, se la malnova gvidanto ial ne disponeblas.

Regulaj aplikoj kaj servoj daŭre estas planitaj per la defaŭlta kube-planilo, kaj ĉiuj cron-taskoj estis tute translokigitaj al la nova. La ŝarĝo kreita de cron-taskoj nun estas egale distribuita tra ĉiuj nodoj. Konsiderante, ke la plej multaj el la cron-taskoj estas ekzekutitaj sur la samaj nodoj kiel la ĉefaj aplikoj de la projekto, ĉi tio signife reduktis la riskon de movi podojn pro manko de rimedoj. Post enkonduko de plia kube-planilo, problemoj kun neegala planado de cron-taskoj ne plu aperis.

Legu ankaŭ aliajn artikolojn en nia blogo:

fonto: www.habr.com

Aldoni komenton