Ustvarjanje dodatnega razporejevalnika kube z naborom pravil razporejanja po meri

Ustvarjanje dodatnega razporejevalnika kube z naborom pravil razporejanja po meri

Kube-scheduler je sestavni del Kubernetesa, ki je odgovoren za razporejanje podov po vozliščih v skladu z določenimi pravilniki. Med delovanjem gruče Kubernetes nam pogosto ni treba razmišljati o tem, katere politike se uporabljajo za razporejanje podov, saj je nabor politik privzetega kube-schedulerja primeren za večino vsakodnevnih opravil. Vendar pa obstajajo situacije, ko je za nas pomembno, da natančno prilagodimo postopek dodeljevanja podov, in to nalogo lahko opravimo na dva načina:

  1. Ustvarite kube-scheduler z naborom pravil po meri
  2. Napišite svoj načrtovalnik in ga naučite delati z zahtevami strežnika API

V tem članku bom opisal izvedbo prve točke za rešitev problema neenakomernega razporejanja kurišč na enem od naših projektov.

Kratek uvod v delovanje kube-schedulerja

Posebej velja opozoriti na dejstvo, da kube-scheduler ni odgovoren za neposredno razporejanje podov - odgovoren je samo za določitev vozlišča, na katerega naj postavi pod. Z drugimi besedami, rezultat dela kube-schedulerja je ime vozlišča, ki ga vrne strežniku API za zahtevo za razporejanje, in tu se njegovo delo konča.

Najprej kube-scheduler sestavi seznam vozlišč, na katerih je mogoče razporediti pod v skladu s pravilniki o predikatih. Nato vsako vozlišče s tega seznama prejme določeno število točk v skladu s politiko prednostnih nalog. Posledično je izbrano vozlišče z največjim številom točk. Če obstajajo vozlišča, ki imajo enako najvišjo oceno, je izbrano naključno. Seznam in opis pravilnikov o predikatih (filtriranje) in prednostnih nalogah (točkovanje) najdete v dokumentacijo.

Opis problematičnega telesa

Kljub velikemu številu različnih gruč Kubernetes, ki jih vzdržuje Nixys, smo se s problemom razporejanja podov prvič srečali šele pred kratkim, ko je moral eden od naših projektov zagnati veliko število periodičnih nalog (~100 entitet CronJob). Da bi čim bolj poenostavili opis problema, bomo za primer vzeli eno mikrostoritev, znotraj katere se enkrat na minuto zažene naloga cron, ki nekoliko obremeni CPE. Za izvajanje naloge cron so bila dodeljena tri vozlišča s popolnoma enakimi lastnostmi (24 vCPU-jev na vsakem).

Hkrati je nemogoče z natančnostjo reči, koliko časa bo trajalo izvajanje CronJob, saj se količina vhodnih podatkov nenehno spreminja. V povprečju vsako vozlišče med običajnim delovanjem kube-schedulerja zažene 3-4 primerke opravil, ki ustvarijo ~20-30 % obremenitve CPU vsakega vozlišča:

Ustvarjanje dodatnega razporejevalnika kube z naborom pravil razporejanja po meri

Težava sama je v tem, da so včasih sklopi nalog cron prenehali biti načrtovani na enem od treh vozlišč. To pomeni, da v nekem trenutku za eno od vozlišč ni bil načrtovan niti en pod, medtem ko se je na drugih dveh vozliščih izvajalo 6-8 kopij opravila, kar je ustvarilo ~40-60 % obremenitve CPU-ja:

Ustvarjanje dodatnega razporejevalnika kube z naborom pravil razporejanja po meri

Težava se je ponavljala popolnoma naključno pogosto in občasno povezana s trenutkom, ko je bila uvedena nova različica kode.

S povečanjem ravni beleženja kube-scheduler na raven 10 (-v=10) smo začeli beležiti, koliko točk je vsako vozlišče pridobilo med postopkom ocenjevanja. Med običajnim postopkom načrtovanja so lahko v dnevnikih vidni naslednji podatki:

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

Tisti. sodeč po podatkih, pridobljenih iz dnevnikov, je vsako od vozlišč doseglo enako končno število točk in naključno izbrano za načrtovanje. V času problematičnega načrtovanja so dnevniki izgledali takole:

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

Iz česar je razvidno, da je eno od vozlišč doseglo manj končnih točk od ostalih, zato je bilo načrtovanje izvedeno le za vozlišči, ki sta dosegli največjo oceno. Tako smo bili zagotovo prepričani, da je težava ravno v razporejanju strokov.

Nadaljnji algoritem za rešitev težave nam je bil očiten - analizirajte dnevnike, razumejte, s kakšno prioriteto vozlišče ni doseglo točk, in po potrebi prilagodite politike privzetega razporejevalnika kube. Vendar se tu soočamo z dvema velikima težavama:

  1. Pri najvišji ravni beleženja (10) se odražajo točke, pridobljene samo za nekatere prioritete. V zgornjem izvlečku dnevnikov lahko vidite, da za vse prioritete, odražene v dnevnikih, vozlišča dosežejo enako število točk pri običajnem in problemskem razporejanju, vendar je končni rezultat v primeru načrtovanja problemov drugačen. Tako lahko sklepamo, da se za nekatere prioritete točkovanje dogaja "v ozadju" in ne moremo razumeti, za katero prioriteto vozlišče ni dobilo točk. To težavo smo podrobno opisali v vprašanje Repozitorij Kubernetes na Githubu. V času pisanja so od razvijalcev prejeli odgovor, da bo podpora za beleženje dodana v posodobitvah Kubernetes v1.15,1.16, 1.17 in XNUMX.
  2. Ni preprostega načina, da bi razumeli, s katerim naborom pravilnikov trenutno deluje kube-scheduler. Da, v dokumentacijo ta seznam je naveden, vendar ne vsebuje informacij o tem, katere specifične uteži so dodeljene posameznim prednostnim politikam. Ogledate si lahko uteži ali uredite pravilnike privzetega razporejevalnika kube samo v izvorne kode.

Omeniti velja, da smo enkrat uspeli zabeležiti, da vozlišče ni prejelo točk v skladu s pravilnikom ImageLocalityPriority, ki vozlišču dodeli točke, če že ima sliko, potrebno za zagon aplikacije. To pomeni, da je v času, ko je bila uvedena nova različica aplikacije, opravilo cron uspelo zagnati na dveh vozliščih in vanje prenesti novo sliko iz registra dockerjev, zato sta dve vozlišči prejeli višjo končno oceno glede na tretje .

Kot sem zapisal zgoraj, v dnevnikih ne vidimo informacij o vrednotenju pravilnika ImageLocalityPriority, zato smo, da bi preverili našo domnevo, odvrgli sliko z novo različico aplikacije na tretje vozlišče, po katerem je razporejanje delovalo pravilno . Ravno zaradi pravilnika ImageLocalityPriority je bila težava z razporejanjem opažena precej redko, pogosteje je bila povezana z nečim drugim. Zaradi dejstva, da nismo mogli v celoti odpraviti napak v vsaki politiki na seznamu prednostnih nalog privzetega razporejevalnika kube, smo potrebovali prilagodljivo upravljanje politik razporejanja podov.

Izjava o težavah

Želeli smo, da je rešitev problema čim bolj specifična, to pomeni, da glavne entitete Kubernetesa (tu mislimo na privzeti kube-scheduler) ostanejo nespremenjene. Nismo želeli rešiti problema na enem mestu in ga ustvariti na drugem. Tako smo prišli do dveh možnosti rešitve problema, ki sta bili napovedani v uvodu članka - ustvarjanje dodatnega razporejevalnika ali pisanje svojega. Glavna zahteva za razporejanje nalog cron je enakomerna porazdelitev obremenitve na tri vozlišča. To zahtevo je mogoče izpolniti z obstoječimi pravilniki kube-scheduler, zato za rešitev našega problema nima smisla pisati lastnega razporejevalnika.

Navodila za ustvarjanje in namestitev dodatnega razporejevalnika kube so opisana v dokumentacijo. Vendar se nam je zdelo, da entiteta Deployment ni dovolj za zagotavljanje tolerance napak pri delovanju tako kritične storitve, kot je kube-scheduler, zato smo se odločili, da uvedemo nov kube-scheduler kot Static Pod, ki bi bil neposredno nadzorovan. od Kubelet. Tako imamo naslednje zahteve za novi razporejevalnik kube:

  1. Storitev mora biti nameščena kot Static Pod na vseh glavnih gruč
  2. Zagotovljena mora biti toleranca napak, če aktivni pod s kube-schedulerjem ni na voljo
  3. Glavna prioriteta pri načrtovanju mora biti število razpoložljivih virov na vozlišču (LeastRequestedPriority)

Izvedbene rešitve

Takoj je treba omeniti, da bomo vse delo izvajali v Kubernetes v1.14.7, ker To je različica, ki je bila uporabljena v projektu. Začnimo s pisanjem manifesta za naš novi razporejevalnik kube. Vzemimo za osnovo privzeti manifest (/etc/kubernetes/manifests/kube-scheduler.yaml) in ga pripeljimo v naslednjo obliko:

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

Na kratko o glavnih spremembah:

  1. Spremenjeno ime sklopa in vsebnika v kube-scheduler-cron
  2. Podala je uporabo vrat 10151 in 10159, kot je bila definirana možnost hostNetwork: true in ne moremo uporabiti istih vrat kot privzeti kube-scheduler (10251 in 10259)
  3. S parametrom --config smo določili konfiguracijsko datoteko, s katero naj se storitev zažene
  4. Konfigurirana namestitev konfiguracijske datoteke (scheduler-custom.conf) in datoteke pravilnika o načrtovanju (scheduler-custom-policy-config.json) iz gostitelja

Ne pozabite, da bo naš kube-scheduler potreboval pravice, podobne privzetim. Uredite vlogo gruče:

kubectl edit clusterrole system:kube-scheduler

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

Zdaj pa se pogovorimo o tem, kaj mora vsebovati konfiguracijska datoteka in datoteka pravilnika o načrtovanju:

  • Konfiguracijska datoteka (scheduler-custom.conf)
    Če želite pridobiti privzeto konfiguracijo kube-scheduler, morate uporabiti parameter --write-config-to z dne dokumentacijo. Nastalo konfiguracijo bomo postavili v datoteko /etc/kubernetes/scheduler-custom.conf in jo reducirali v naslednjo obliko:

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"

Na kratko o glavnih spremembah:

  1. Nastavimo schedulerName na ime naše storitve kube-scheduler-cron.
  2. V parametru lockObjectName prav tako morate nastaviti ime naše storitve in se prepričati, da parameter leaderElect nastavite na true (če imate eno glavno vozlišče, ga lahko nastavite na false).
  3. Podal je pot do datoteke z opisom politik razporejanja v parametru algorithmSource.

Vredno si je podrobneje ogledati drugo točko, kjer urejamo parametre za ključ leaderElection. Da bi zagotovili odpornost na napake, smo omogočili (leaderElect) postopek izbire vodje (glavnega) med sklopi našega razporejevalnika kube z uporabo ene končne točke zanje (resourceLock) z imenom kube-scheduler-cron (lockObjectName) v imenskem prostoru sistema kube (lockObjectNamespace). Kako Kubernetes zagotavlja visoko razpoložljivost glavnih komponent (vključno s kube-schedulerjem), lahko najdete v članek.

  • Datoteka pravilnika o načrtovanju (scheduler-custom-policy-config.json)
    Kot sem že zapisal, lahko ugotovimo, s katerimi posebnimi politikami deluje privzeti razporejevalnik kube samo z analizo njegove kode. To pomeni, da ne moremo pridobiti datoteke s pravilniki o razporejanju za privzeti načrtovalnik kube na enak način kot konfiguracijsko datoteko. Opišimo politike razporejanja, ki nas zanimajo v datoteki /etc/kubernetes/scheduler-custom-policy-config.json, kot sledi:

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

Tako kube-scheduler najprej sestavi seznam vozlišč, za katera je mogoče razporediti pod v skladu s pravilnikom GeneralPredicates (ki vključuje nabor pravilnikov PodFitsResources, PodFitsHostPorts, HostName in MatchNodeSelector pravilnikov). Nato se vsako vozlišče ovrednoti v skladu z naborom pravilnikov v matriki prioritet. Za izpolnjevanje pogojev naše naloge smo menili, da bi bil tak sklop pravilnikov optimalna rešitev. Naj vas spomnim, da je niz pravilnikov z njihovimi podrobnimi opisi na voljo v dokumentacijo. Če želite izpolniti svojo nalogo, lahko preprosto spremenite nabor uporabljenih pravilnikov in jim dodelite ustrezne uteži.

Poimenujmo manifest novega kube-schedulerja, ki smo ga ustvarili na začetku poglavja, kube-scheduler-custom.yaml in ga postavimo na naslednjo pot /etc/kubernetes/manifests na treh glavnih vozliščih. Če je vse opravljeno pravilno, bo Kubelet zagnal pod na vsakem vozlišču in v dnevnikih našega novega kube-schedulerja bomo videli informacije, da je bila naša datoteka pravilnika uspešno uporabljena:

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

Zdaj ostane le še, da v specifikaciji našega CronJoba navedemo, da mora vse zahteve za razporejanje njegovih podov obdelati naš novi kube-scheduler:

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

Zaključek

Končno smo dobili dodaten kube-scheduler z edinstvenim naborom pravilnikov o razporejanju, katerega delo nadzira neposredno kubelet. Poleg tega smo nastavili volitve novega vodje med podoma našega kube-schedulerja, če stari vodja iz nekega razloga postane nedosegljiv.

Običajne aplikacije in storitve so še naprej načrtovane prek privzetega kube-schedulerja, vsa opravila cron pa so bila v celoti prenesena v novega. Obremenitev, ki jo ustvarijo naloge cron, je zdaj enakomerno porazdeljena po vseh vozliščih. Glede na to, da se večina opravil cron izvaja na istih vozliščih kot glavne aplikacije projekta, je to znatno zmanjšalo tveganje premikanja podov zaradi pomanjkanja virov. Po uvedbi dodatnega kube-schedulerja se težave z neenakomernim razporejanjem cron opravil niso več pojavljale.

Preberite tudi druge članke na našem blogu:

Vir: www.habr.com

Dodaj komentar