Paglikha ng karagdagang kube-scheduler na may custom na hanay ng mga panuntunan sa pag-iiskedyul

Paglikha ng karagdagang kube-scheduler na may custom na hanay ng mga panuntunan sa pag-iiskedyul

Ang Kube-scheduler ay isang mahalagang bahagi ng Kubernetes, na responsable para sa pag-iskedyul ng mga pod sa mga node alinsunod sa mga tinukoy na patakaran. Kadalasan, sa panahon ng pagpapatakbo ng isang Kubernetes cluster, hindi namin kailangang isipin kung aling mga patakaran ang ginagamit upang mag-iskedyul ng mga pod, dahil ang hanay ng mga patakaran ng default na kube-scheduler ay angkop para sa karamihan ng mga pang-araw-araw na gawain. Gayunpaman, may mga sitwasyon kung kailan mahalaga para sa amin na ayusin ang proseso ng paglalaan ng mga pod, at may dalawang paraan para magawa ang gawaing ito:

  1. Gumawa ng kube-scheduler na may custom na hanay ng mga panuntunan
  2. Sumulat ng iyong sariling scheduler at turuan itong gumana sa mga kahilingan ng server ng API

Sa artikulong ito, ilalarawan ko ang pagpapatupad ng unang punto upang malutas ang problema ng hindi pantay na pag-iskedyul ng mga apuyan sa isa sa aming mga proyekto.

Isang maikling panimula sa kung paano gumagana ang kube-scheduler

Ito ay nagkakahalaga lalo na ang pagpuna sa katotohanan na ang kube-scheduler ay hindi mananagot para sa direktang pag-iskedyul ng mga pod - ito ay responsable lamang sa pagtukoy sa node kung saan ilalagay ang pod. Sa madaling salita, ang resulta ng trabaho ng kube-scheduler ay ang pangalan ng node, na ibinabalik nito sa API server para sa isang kahilingan sa pag-iiskedyul, at doon nagtatapos ang trabaho nito.

Una, ang kube-scheduler ay nag-compile ng isang listahan ng mga node kung saan maaaring iiskedyul ang pod alinsunod sa mga patakaran ng predicates. Susunod, ang bawat node mula sa listahang ito ay tumatanggap ng isang tiyak na bilang ng mga puntos alinsunod sa mga patakarang priyoridad. Bilang resulta, ang node na may pinakamataas na bilang ng mga puntos ay napili. Kung may mga node na may parehong maximum na marka, isang random ang pipiliin. Ang isang listahan at paglalarawan ng mga patakaran (pag-filter) at mga priyoridad (pagmamarka) ay matatagpuan sa dokumentasyon.

Paglalarawan ng katawan ng problema

Sa kabila ng malaking bilang ng iba't ibang kumpol ng Kubernetes na pinapanatili sa Nixys, una naming naranasan ang problema sa pag-iskedyul ng mga pod kamakailan lamang, nang ang isa sa aming mga proyekto ay kailangang magpatakbo ng maraming pana-panahong gawain (~100 CronJob entity). Upang gawing simple ang paglalarawan ng problema hangga't maaari, kukuha kami bilang isang halimbawa ng isang microservice, kung saan ang isang gawain ng cron ay inilunsad isang beses sa isang minuto, na lumilikha ng ilang pagkarga sa CPU. Para patakbuhin ang cron task, tatlong node na may ganap na magkaparehong katangian ang inilaan (24 vCPU sa bawat isa).

Kasabay nito, imposibleng sabihin nang may katumpakan kung gaano katagal bago maisagawa ang CronJob, dahil patuloy na nagbabago ang dami ng input data. Sa karaniwan, sa normal na operasyon ng kube-scheduler, ang bawat node ay nagpapatakbo ng 3-4 na pagkakataon ng trabaho, na lumilikha ng ~20-30% ng load sa CPU ng bawat node:

Paglikha ng karagdagang kube-scheduler na may custom na hanay ng mga panuntunan sa pag-iiskedyul

Ang problema mismo ay kung minsan ang mga cron task pod ay huminto sa pag-iskedyul sa isa sa tatlong node. Iyon ay, sa ilang mga punto sa oras, hindi isang solong pod ang binalak para sa isa sa mga node, habang sa iba pang dalawang node ay tumatakbo ang 6-8 na kopya ng gawain, na lumilikha ng ~40-60% ng pag-load ng CPU:

Paglikha ng karagdagang kube-scheduler na may custom na hanay ng mga panuntunan sa pag-iiskedyul

Ang problema ay naulit na may ganap na random na dalas at paminsan-minsan ay nauugnay sa sandali ng isang bagong bersyon ng code ay inilunsad.

Sa pamamagitan ng pagtaas ng antas ng pag-log ng kube-scheduler sa antas 10 (-v=10), sinimulan naming itala kung gaano karaming puntos ang natamo ng bawat node sa panahon ng proseso ng pagsusuri. Sa panahon ng normal na pagpapatakbo ng pagpaplano, ang sumusunod na impormasyon ay makikita sa mga log:

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

Yung. sa paghusga sa impormasyong nakuha mula sa mga log, ang bawat isa sa mga node ay nakakuha ng pantay na bilang ng mga huling puntos at isang random na isa ang napili para sa pagpaplano. Sa oras ng problemang pagpaplano, ang mga log ay ganito ang hitsura:

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

Mula sa kung saan makikita na ang isa sa mga node ay nakakuha ng mas kaunting mga huling puntos kaysa sa iba, at samakatuwid ang pagpaplano ay isinagawa lamang para sa dalawang node na nakakuha ng pinakamataas na marka. Kaya, tiyak na kumbinsido kami na ang problema ay tiyak na nakasalalay sa pag-iiskedyul ng mga pod.

Ang karagdagang algorithm para sa paglutas ng problema ay halata sa amin - pag-aralan ang mga log, maunawaan kung anong priyoridad ang hindi nakakuha ng mga puntos ng node at, kung kinakailangan, ayusin ang mga patakaran ng default na kube-scheduler. Gayunpaman, narito tayo ay nahaharap sa dalawang makabuluhang paghihirap:

  1. Sa pinakamataas na antas ng pag-log (10), ang mga puntos na nakuha lamang para sa ilang mga priyoridad ay makikita. Sa itaas na sipi ng mga log, makikita mo na para sa lahat ng priyoridad na makikita sa mga log, ang mga node ay nakakuha ng parehong bilang ng mga puntos sa normal at pag-iiskedyul ng problema, ngunit ang huling resulta sa kaso ng pagpaplano ng problema ay iba. Kaya, maaari naming tapusin na para sa ilang mga priyoridad, ang pagmamarka ay nangyayari "sa likod ng mga eksena", at wala kaming paraan upang maunawaan kung aling priyoridad ang node ay hindi nakakuha ng mga puntos. Inilarawan namin ang problemang ito nang detalyado sa problema Kubernetes repository sa Github. Sa oras ng pagsulat, isang tugon ang natanggap mula sa mga developer na ang suporta sa pag-log ay idaragdag sa mga update sa Kubernetes v1.15,1.16, 1.17 at XNUMX.
  2. Walang madaling paraan upang maunawaan kung aling partikular na hanay ng mga patakaran ang kasalukuyang ginagamit ng kube-scheduler. Oo, sa dokumentasyon nakalista ang listahang ito, ngunit hindi ito naglalaman ng impormasyon tungkol sa kung anong mga partikular na timbang ang itinalaga sa bawat isa sa mga patakarang priyoridad. Maaari mong makita ang mga timbang o i-edit ang mga patakaran ng default na kube-scheduler lamang sa source code.

Kapansin-pansin na sa sandaling naitala namin na ang isang node ay hindi nakatanggap ng mga puntos ayon sa patakaran ng ImageLocalityPriority, na nagbibigay ng mga puntos sa isang node kung mayroon na itong larawang kinakailangan upang patakbuhin ang application. Iyon ay, sa oras na ang isang bagong bersyon ng application ay inilunsad, ang gawain ng cron ay pinamamahalaang tumakbo sa dalawang node, na nag-download ng isang bagong imahe mula sa docker registry sa kanila, at sa gayon ang dalawang node ay nakatanggap ng isang mas mataas na pangwakas na marka na may kaugnayan sa pangatlo .

Tulad ng isinulat ko sa itaas, sa mga log ay wala kaming nakikitang impormasyon tungkol sa pagsusuri ng patakaran ng ImageLocalityPriority, kaya para masuri ang aming palagay, itinapon namin ang imahe gamit ang bagong bersyon ng application sa ikatlong node, pagkatapos kung saan gumana nang tama ang pag-iskedyul . Dahil mismo sa patakaran ng ImageLocalityPriority na ang problema sa pag-iiskedyul ay bihirang naobserbahan; mas madalas na nauugnay ito sa ibang bagay. Dahil sa katotohanang hindi namin ganap na ma-debug ang bawat isa sa mga patakaran sa listahan ng mga priyoridad ng default na kube-scheduler, kailangan namin ng flexible na pamamahala ng mga patakaran sa pag-iskedyul ng pod.

Pahayag ng problema

Nais naming maging tiyak ang solusyon sa problema hangga't maaari, iyon ay, ang mga pangunahing entity ng Kubernetes (dito ang ibig naming sabihin ay ang default na kube-scheduler) ay dapat manatiling hindi nagbabago. Hindi namin gustong lutasin ang isang problema sa isang lugar at gawin ito sa isa pa. Kaya, nakarating kami sa dalawang pagpipilian para sa paglutas ng problema, na inihayag sa panimula sa artikulo - ang paglikha ng isang karagdagang scheduler o pagsulat ng iyong sarili. Ang pangunahing kinakailangan para sa pag-iskedyul ng mga gawain ng cron ay upang pantay-pantay na ipamahagi ang load sa tatlong node. Ang pangangailangang ito ay maaaring matugunan ng umiiral na mga patakaran ng kube-scheduler, kaya upang malutas ang aming problema ay walang saysay na isulat ang iyong sariling scheduler.

Ang mga tagubilin para sa paggawa at Pag-deploy ng karagdagang kube-scheduler ay inilalarawan sa dokumentasyon. Gayunpaman, sa tingin namin ay hindi sapat ang Deployment entity para matiyak ang fault tolerance sa pagpapatakbo ng naturang kritikal na serbisyo bilang kube-scheduler, kaya nagpasya kaming mag-deploy ng bagong kube-scheduler bilang Static Pod, na direktang susubaybayan. ni Kubelet. Kaya, mayroon kaming mga sumusunod na kinakailangan para sa bagong kube-scheduler:

  1. Dapat i-deploy ang serbisyo bilang Static Pod sa lahat ng cluster masters
  2. Dapat ibigay ang fault tolerance kung sakaling hindi available ang aktibong pod na may kube-scheduler
  3. Ang pangunahing priyoridad kapag nagpaplano ay ang bilang ng mga magagamit na mapagkukunan sa node (LeastRequestedPriority)

Mga solusyon sa pagpapatupad

Kapansin-pansin kaagad na isasagawa namin ang lahat ng gawain sa Kubernetes v1.14.7, dahil Ito ang bersyon na ginamit sa proyekto. Magsimula tayo sa pagsulat ng manifesto para sa ating bagong kube-scheduler. Gawin natin ang default na manifest (/etc/kubernetes/manifests/kube-scheduler.yaml) bilang batayan at dalhin ito sa sumusunod na 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

Maikling tungkol sa mga pangunahing pagbabago:

  1. Pinalitan ang pangalan ng pod at container sa kube-scheduler-cron
  2. Tinukoy ang paggamit ng mga port 10151 at 10159 bilang ang opsyon ay tinukoy hostNetwork: true at hindi namin magagamit ang parehong mga port bilang default na kube-scheduler (10251 at 10259)
  3. Gamit ang --config parameter, tinukoy namin ang configuration file kung saan dapat simulan ang serbisyo
  4. Naka-configure na pag-mount ng configuration file (scheduler-custom.conf) at scheduling policy file (scheduler-custom-policy-config.json) mula sa host

Huwag kalimutan na ang aming kube-scheduler ay mangangailangan ng mga karapatan na katulad ng default. I-edit ang cluster role nito:

kubectl edit clusterrole system:kube-scheduler

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

Ngayon pag-usapan natin kung ano ang dapat na nilalaman sa file ng pagsasaayos at sa file ng patakaran sa pag-iiskedyul:

  • Configuration file (scheduler-custom.conf)
    Upang makuha ang default na configuration ng kube-scheduler, dapat mong gamitin ang parameter --write-config-to ng dokumentasyon. Ilalagay namin ang resultang configuration sa file /etc/kubernetes/scheduler-custom.conf at babawasan ito sa sumusunod na 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"

Maikling tungkol sa mga pangunahing pagbabago:

  1. Itinakda namin ang schedulerName sa pangalan ng aming serbisyong kube-scheduler-cron.
  2. Sa parameter lockObjectName kailangan mo ring itakda ang pangalan ng aming serbisyo at siguraduhin na ang parameter leaderElect itakda sa true (kung mayroon kang isang master node, maaari mo itong itakda sa false).
  3. Tinukoy ang path sa file na may paglalarawan ng mga patakaran sa pag-iiskedyul sa parameter algorithmSource.

Ito ay nagkakahalaga ng pagtingin sa pangalawang punto, kung saan ine-edit namin ang mga parameter para sa susi leaderElection. Para matiyak ang fault tolerance, pinagana namin (leaderElect) ang proseso ng pagpili ng pinuno (master) sa pagitan ng mga pod ng aming kube-scheduler gamit ang isang endpoint para sa kanila (resourceLock) pinangalanang kube-scheduler-cron (lockObjectName) sa kube-system namespace (lockObjectNamespace). Paano tinitiyak ng Kubernetes ang mataas na kakayahang magamit ng mga pangunahing bahagi (kabilang ang kube-scheduler) ay makikita sa Artikulo.

  • Pag-iiskedyul ng file ng patakaran (scheduler-custom-policy-config.json)
    Gaya ng isinulat ko kanina, malalaman natin kung aling mga partikular na patakaran ang gumagana sa default na kube-scheduler sa pamamagitan lamang ng pagsusuri sa code nito. Ibig sabihin, hindi kami makakakuha ng file na may mga patakaran sa pag-iiskedyul para sa default na kube-scheduler sa parehong paraan tulad ng configuration file. Ilarawan natin ang mga patakaran sa pag-iiskedyul kung saan interesado tayo sa /etc/kubernetes/scheduler-custom-policy-config.json file tulad ng sumusunod:

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

Kaya, ang kube-scheduler ay unang nag-compile ng isang listahan ng mga node kung saan maaaring iiskedyul ang isang pod ayon sa patakaran ng GeneralPredicates (na kinabibilangan ng isang set ng PodFitsResources, PodFitsHostPorts, HostName, at MatchNodeSelector na mga patakaran). At pagkatapos ay sinusuri ang bawat node alinsunod sa hanay ng mga patakaran sa hanay ng mga priyoridad. Upang matupad ang mga kondisyon ng aming gawain, isinasaalang-alang namin na ang gayong hanay ng mga patakaran ang magiging pinakamainam na solusyon. Ipaalala ko sa iyo na available ang isang hanay ng mga patakaran kasama ang mga detalyadong paglalarawan ng mga ito dokumentasyon. Upang magawa ang iyong gawain, maaari mo lamang baguhin ang hanay ng mga patakarang ginamit at magtalaga ng mga naaangkop na timbang sa kanila.

Tawagan natin ang manifest ng bagong kube-scheduler, na ginawa namin sa simula ng chapter, kube-scheduler-custom.yaml at ilagay ito sa sumusunod na path /etc/kubernetes/manifests sa tatlong master node. Kung gagawin nang tama ang lahat, maglulunsad ang Kubelet ng pod sa bawat node, at sa mga log ng aming bagong kube-scheduler makikita namin ang impormasyon na matagumpay na nailapat ang aming file ng patakaran:

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

Ngayon ang natitira na lang ay ipahiwatig sa spec ng aming CronJob na ang lahat ng kahilingan para sa pag-iskedyul ng mga pod nito ay dapat iproseso ng aming bagong kube-scheduler:

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

Konklusyon

Sa huli, nakakuha kami ng karagdagang kube-scheduler na may natatanging hanay ng mga patakaran sa pag-iiskedyul, na ang gawain ay direktang sinusubaybayan ng kubelet. Bilang karagdagan, nag-set up kami ng halalan ng bagong pinuno sa pagitan ng mga pod ng aming kube-scheduler kung sakaling maging hindi available ang lumang pinuno sa ilang kadahilanan.

Ang mga regular na application at serbisyo ay patuloy na nakaiskedyul sa pamamagitan ng default na kube-scheduler, at lahat ng mga gawain sa cron ay ganap na nailipat sa bago. Ang pag-load na nilikha ng mga gawain ng cron ay pantay na ipinamahagi sa lahat ng mga node. Isinasaalang-alang na ang karamihan sa mga gawain ng cron ay isinasagawa sa parehong mga node bilang mga pangunahing aplikasyon ng proyekto, ito ay makabuluhang nabawasan ang panganib ng paglipat ng mga pod dahil sa kakulangan ng mga mapagkukunan. Matapos ipakilala ang karagdagang kube-scheduler, hindi na lumitaw ang mga problema sa hindi pantay na pag-iiskedyul ng mga gawain sa cron.

Basahin din ang iba pang mga artikulo sa aming blog:

Pinagmulan: www.habr.com

Magdagdag ng komento