Luodaan ylimääräinen kube-aikataulu mukautetuilla ajoitussäännöillä

Luodaan ylimääräinen kube-aikataulu mukautetuilla ajoitussäännöillä

Kube-scheduler on Kubernetesin olennainen osa, joka vastaa podien ajoittamisesta solmujen välillä määritettyjen käytäntöjen mukaisesti. Usein Kubernetes-klusterin toiminnan aikana meidän ei tarvitse miettiä, mitä käytäntöjä podien ajoittamiseen käytetään, koska oletuskube-aikataulun käytäntösarja sopii useimpiin päivittäisiin tehtäviin. On kuitenkin tilanteita, joissa meidän on tärkeää hienosäätää podien allokointiprosessia, ja tämä tehtävä voidaan suorittaa kahdella tavalla:

  1. Luo kube-aikataulu mukautetuilla säännöillä
  2. Kirjoita oma aikataulusi ja opeta se toimimaan API-palvelinpyyntöjen kanssa

Tässä artikkelissa kuvailen ensimmäisen kohdan toteuttamista tulisijojen epätasaisen ajoituksen ongelman ratkaisemiseksi yhdessä projektissamme.

Lyhyt esittely kube-schedulerin toiminnasta

Erityisesti kannattaa huomioida se tosiasia, että kube-scheduler ei ole vastuussa podien suorasta ajoittamisesta - se on vastuussa vain sen solmun määrittämisestä, johon pod sijoitetaan. Toisin sanoen kube-schedulerin työn tulos on solmun nimi, jonka se palauttaa API-palvelimelle ajoituspyyntöä varten, ja siihen sen työ päättyy.

Ensin kube-scheduler kokoaa listan solmuista, joihin pod voidaan ajoittaa predikaattikäytäntöjen mukaisesti. Seuraavaksi jokainen tämän luettelon solmu saa tietyn määrän pisteitä prioriteettikäytäntöjen mukaisesti. Tämän seurauksena valitaan solmu, jolla on suurin määrä pisteitä. Jos solmuilla on sama maksimipistemäärä, valitaan satunnainen. Luettelo ja kuvaus predikaatti- (suodatus) ja prioriteettikäytännöistä (pisteytys) on osoitteessa dokumentointi.

Kuvaus ongelmarungosta

Huolimatta siitä, että Nixysillä ylläpidetään suurta määrää erilaisia ​​Kubernetes-klustereita, törmäsimme ensimmäisen kerran podien ajoitusongelmaan vasta äskettäin, kun yhdessä projekteistamme piti suorittaa suuri määrä säännöllisiä tehtäviä (~100 CronJob-kokonaisuutta). Yksinkertaistaaksemme ongelman kuvausta mahdollisimman paljon, otamme esimerkkinä yhden mikropalvelun, jossa cron-tehtävä käynnistetään kerran minuutissa, mikä kuormittaa prosessoria. Cron-tehtävän suorittamiseksi allokoitiin kolme solmua, joilla oli täysin identtiset ominaisuudet (24 vCPU:ta kussakin).

Samanaikaisesti on mahdotonta sanoa tarkasti, kuinka kauan CronJob kestää, koska syöttötietojen määrä muuttuu jatkuvasti. Kube-schedulerin normaalin toiminnan aikana jokainen solmu suorittaa keskimäärin 3-4 työinstanssia, jotka kuormittavat ~20-30% kunkin solmun suorittimen kuormituksesta:

Luodaan ylimääräinen kube-aikataulu mukautetuilla ajoitussäännöillä

Ongelma itsessään on, että joskus cron-tehtäväpodit lakkasivat olemasta ajoitettuja yhteen kolmesta solmusta. Eli jossain vaiheessa yhdelle solmulle ei suunniteltu ainuttakaan podia, kun taas kahdessa muussa solmussa oli käynnissä 6-8 kopiota tehtävästä, mikä tuotti ~40-60% suorittimen kuormituksesta:

Luodaan ylimääräinen kube-aikataulu mukautetuilla ajoitussäännöillä

Ongelma toistui täysin satunnaisesti ja toisinaan korreloi koodin uuden version julkaisun kanssa.

Nostamalla kube-schedulerin lokitason tasolle 10 (-v=10), aloimme tallentaa, kuinka monta pistettä kukin solmu sai arviointiprosessin aikana. Normaalin suunnittelutoiminnan aikana lokeissa voitiin nähdä seuraavat tiedot:

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

Nuo. lokeista saaduista tiedoista päätellen kukin solmu sai yhtä paljon lopullisia pisteitä ja satunnainen valittiin suunnitteluun. Ongelmallisen suunnittelun aikana lokit näyttivät tältä:

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

Mistä voidaan nähdä, että yksi solmuista sai vähemmän loppupisteitä kuin muut, ja siksi suunnittelua tehtiin vain kahdelle maksimipistemäärän saaneelle solmulle. Näin ollen olimme ehdottomasti vakuuttuneita siitä, että ongelma piilee nimenomaan podien ajoituksessa.

Lisäalgoritmi ongelman ratkaisemiseksi oli meille ilmeinen - analysoi lokit, ymmärrä, millä prioriteetilla solmu ei saanut pisteitä ja säädä tarvittaessa oletuskube-ajoitusohjelman käytäntöjä. Tässä kohtaamme kuitenkin kaksi merkittävää vaikeutta:

  1. Suurimmalla kirjaustasolla (10) vain joistakin prioriteeteista saadut pisteet näkyvät. Yllä olevasta lokiotteesta näkyy, että kaikista lokeissa näkyvistä prioriteeteista solmut saavat saman pistemäärän normaalissa ja ongelma-ajoituksessa, mutta lopputulos ongelmasuunnittelun tapauksessa on erilainen. Siten voimme päätellä, että joidenkin prioriteettien kohdalla pisteytys tapahtuu "kulissien takana", eikä meillä ole mitään keinoa ymmärtää, mistä prioriteetista solmu ei saanut pisteitä. Kuvasimme tätä ongelmaa yksityiskohtaisesti artikkelissa kysymys Kubernetes-arkisto Githubissa. Tätä kirjoittaessa kehittäjiltä saatiin vastaus, että Kubernetes v1.15,1.16, 1.17 ja XNUMX päivityksiin lisätään lokituki.
  2. Ei ole helppoa tapaa ymmärtää, mitä tiettyä käytäntösarjaa kube-scheduler parhaillaan käyttää. Kyllä, sisään dokumentointi tämä luettelo on lueteltu, mutta se ei sisällä tietoja siitä, mitä painoarvoja kullekin prioriteettikäytännölle on määritetty. Voit nähdä painot tai muokata oletuskube-aikataulun käytäntöjä vain kohteessa lähdekoodeja.

On syytä huomata, että kun pystyimme kirjaamaan, että solmu ei saanut pisteitä ImageLocalityPriority-käytännön mukaisesti, joka antaa pisteitä solmulle, jos sillä on jo sovelluksen suorittamiseen tarvittava kuva. Eli kun sovelluksen uusi versio julkaistiin, cron-tehtävä onnistui ajamaan kahdessa solmussa, lataamalla niille uuden kuvan Docker-rekisteristä, ja siten kaksi solmua sai korkeamman lopullisen pistemäärän verrattuna kolmanteen. .

Kuten ylempänä kirjoitin, emme näe lokeissa tietoa ImageLocalityPriority-käytännön arvioinnista, joten olettamuksemme tarkistamiseksi upposimme kuvan sovelluksen uudella versiolla kolmanteen solmuun, jonka jälkeen ajoitus toimi oikein . Juuri ImageLocalityPriority-käytännön vuoksi ajoitusongelma havaittiin melko harvoin, useammin se liittyi johonkin muuhun. Koska emme pystyneet täysin virheenkorjaamaan kaikkia oletuskube-ajoitusohjelman prioriteettiluettelon käytäntöjä, tarvitsimme pod-ajoituskäytäntöjen joustavaa hallintaa.

Ongelma

Halusimme ongelman ratkaisun olevan mahdollisimman tarkka eli Kubernetesin (tässä tarkoitamme oletuskube-ajoitusohjelma) pääolioiden tulisi pysyä ennallaan. Emme halunneet ratkaista ongelmaa yhdessä paikassa ja luoda sitä toisessa. Näin ollen päädyimme kahteen vaihtoehtoon ongelman ratkaisemiseksi, joista ilmoitettiin artikkelin johdannossa - lisäaikataulun luominen tai oman kirjoittaminen. Päävaatimus cron-tehtävien ajoituksessa on jakaa kuorma tasaisesti kolmen solmun välillä. Tämä vaatimus voidaan täyttää olemassa olevilla kube-scheduler-käytännöillä, joten ongelmamme ratkaisemiseksi ei ole mitään järkeä kirjoittaa omaa ajastinta.

Ohjeet ylimääräisen kube-aikataulun luomiseen ja käyttöönottoon on kuvattu dokumentointi. Meistä kuitenkin vaikutti siltä, ​​että Deployment-entiteetti ei riittänyt varmistamaan vikasietoisuutta niin kriittisen palvelun kuin kube-scheduler toiminnassa, joten päätimme ottaa käyttöön uuden kube-schedulerin Static Podina, jota valvottaisiin suoraan. kirjoittanut Kubelet. Näin ollen meillä on seuraavat vaatimukset uudelle kube-aikataululle:

  1. Palvelu on otettava käyttöön staattisena kotelona kaikissa klusterin pääkoneissa
  2. Vikasietoisuus on annettava, jos aktiivinen pod kube-schedulerilla ei ole käytettävissä
  3. Suunnittelun pääprioriteetti tulee olla solmun käytettävissä olevien resurssien määrä (LeastRequestedPriority)

Toteutusratkaisut

Heti kannattaa huomioida, että teemme kaikki työt Kubernetes v1.14.7:ssä, koska Tämä on versio, jota käytettiin projektissa. Aloitetaan kirjoittamalla manifesti uudelle kube-schedulerillemme. Otetaan oletusluettelo (/etc/kubernetes/manifests/kube-scheduler.yaml) pohjaksi ja tuodaan se seuraavaan muotoon:

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

Lyhyesti tärkeimmistä muutoksista:

  1. Podin ja säilön nimi muutettiin muotoon kube-scheduler-cron
  2. Määritettiin porttien 10151 ja 10159 käyttö vaihtoehdoksi hostNetwork: true emmekä voi käyttää samoja portteja kuin oletuskube-aikataulu (10251 ja 10259)
  3. Määritimme parametrin --config avulla määritystiedoston, jolla palvelu käynnistetään
  4. Konfigurointitiedoston (scheduler-custom.conf) ja ajoituskäytäntötiedoston (scheduler-custom-policy-config.json) liittäminen isännästä

Älä unohda, että kube-scheduler tarvitsee oletusarvon kaltaiset oikeudet. Muokkaa sen klusterin roolia:

kubectl edit clusterrole system:kube-scheduler

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

Puhutaan nyt siitä, mitä määritystiedoston ja ajoituskäytäntötiedoston pitäisi sisältää:

  • Asetustiedosto (scheduler-custom.conf)
    Käytä parametria saadaksesi oletusarvoisen kube-scheduler-kokoonpanon --write-config-to ja dokumentointi. Sijoitamme tuloksena saadut asetukset tiedostoon /etc/kubernetes/scheduler-custom.conf ja muokkaamme sen seuraavaan muotoon:

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"

Lyhyesti tärkeimmistä muutoksista:

  1. Asetamme schedulerName:n kube-scheduler-cron-palvelumme nimeksi.
  2. Parametrissa lockObjectName sinun on myös asetettava palvelumme nimi ja varmistettava, että parametri leaderElect aseta arvoksi tosi (jos sinulla on yksi pääsolmu, voit asettaa sen arvoon false).
  3. Määritti polun tiedostoon, jossa on parametrin aikataulutuskäytäntöjen kuvaus algorithmSource.

On syytä tarkastella lähemmin toista kohtaa, jossa muokkaamme avaimen parametreja leaderElection. Vikasietokyvyn varmistamiseksi olemme ottaneet käyttöön (leaderElect) prosessi, jossa valitaan johtaja (master) kube-schedulerimme podien välillä käyttämällä niille yhtä päätepistettä (resourceLock) nimeltä kube-scheduler-cron (lockObjectName) kube-järjestelmän nimiavaruudessa (lockObjectNamespace). Miten Kubernetes varmistaa pääkomponenttien (mukaan lukien kube-scheduler) korkean käytettävyyden, löydät osoitteesta статье.

  • Ajoituskäytäntötiedosto (scheduler-custom-policy-config.json)
    Kuten aiemmin kirjoitin, voimme selvittää, millä erityisillä käytännöillä oletuskube-scheduler toimii, vain analysoimalla sen koodia. Toisin sanoen emme voi saada tiedostoa, jossa on ajoituskäytännöt oletuskube-aikataululle, samalla tavalla kuin asetustiedostoa. Kuvataan aikataulutuskäytännöt, joista olemme kiinnostuneita /etc/kubernetes/scheduler-custom-policy-config.json-tiedostossa seuraavasti:

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

Siten kube-scheduler kokoaa ensin luettelon solmuista, joihin pod voidaan ajoittaa GeneralPredicates-käytännön mukaisesti (joka sisältää joukon PodFitsResources-, PodFitsHostPorts-, HostName- ja MatchNodeSelector-käytäntöjä). Ja sitten jokainen solmu arvioidaan prioriteettitaulukon käytäntöjen joukon mukaisesti. Täyttääksemme tehtävämme ehdot katsoimme, että tällainen toimintalinja olisi optimaalinen ratkaisu. Haluan muistuttaa, että joukko käytäntöjä ja niiden yksityiskohtaiset kuvaukset ovat saatavilla dokumentointi. Suorittaaksesi tehtäväsi, voit yksinkertaisesti muuttaa käytettyjä käytäntöjä ja määrittää niille sopivat painotukset.

Kutsutaan luvun alussa luomamme uuden kube-schedulerin manifestiksi kube-scheduler-custom.yaml ja sijoitetaan se seuraavaan polkuun /etc/kubernetes/manifests kolmeen pääsolmuun. Jos kaikki on tehty oikein, Kubelet käynnistää podin jokaisessa solmussa, ja uuden kube-schedulerimme lokeissa näemme tiedon siitä, että käytäntötiedostomme on otettu käyttöön:

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

Nyt ei jää muuta kuin ilmoittaa CronJobimme spesifikaatioissa, että uuden kube-schedulerimme tulee käsitellä kaikki podien ajoituspyynnöt:

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

Johtopäätös

Lopulta saimme ylimääräisen kube-schedulerin ainutlaatuisella aikataulutuskäytännöllä, jonka toimintaa valvoo suoraan kubelet. Lisäksi olemme asettaneet uuden johtajan valinnan kube-schedulerimme väliin siltä varalta, että vanha johtaja ei jostain syystä ole tavoitettavissa.

Säännölliset sovellukset ja palvelut ajoitetaan edelleen oletuskube-aikataulun kautta, ja kaikki cron-tehtävät on siirretty kokonaan uuteen. cron-tehtävien luoma kuorma on nyt jakautunut tasaisesti kaikille solmuille. Ottaen huomioon, että suurin osa cron-tehtävistä suoritetaan samoissa solmuissa kuin projektin pääsovellukset, tämä on vähentänyt merkittävästi podien liikkumisen riskiä resurssien puutteen vuoksi. Lisäkube-aikataulun käyttöönoton jälkeen cron-tehtävien epätasaisen ajoituksen ongelmia ei enää ilmennyt.

Lue myös muut artikkelit blogistamme:

Lähde: will.com

Lisää kommentti