
Kube-scheduler është një komponent themelor i Kubernetes që merret me planifikimin e pod-eve në nodo duke u bazuar në politikën e caktuar. Shpesh, gjatë përdorimit të klasterit Kubernetes, ne nuk e mendojmë se sipas cilave politikash ndodh planifikimi i pod-eve, pasi grupi i politikave të kube-scheduler-it përkojnë me shumicën e detyrave të përditshme. Megjithatë, ka situata kur është e rëndësishme të menaxhohet me shumë kujdes procesi i shpërndarjes së pod-eve, dhe për të realizuar këtë, ka dy rrugë:
- Krijimi i një kube-scheduler me një grup rregullash të personalizuara
- Shkrimi i një scheduler-i të vet dhe mësimi i tij për të punuar me kërkesat e serverit API
Në këtë artikull, unë do të përshkruaj zbatimin e pikës së parë për të zgjidhur problemin e planifikimit të pabarabartë të pod-eve në një nga projektet tona.
Një hyrje e shkurtër rreth punës së kube-scheduler-it
ĂshtĂ« e rĂ«ndĂ«sishme tĂ« theksohet se kube-scheduler nuk merret me planifikimin e drejtpĂ«rdrejtĂ« tĂ« pod-eve â ai Ă«shtĂ« pĂ«rgjegjĂ«s vetĂ«m pĂ«r pĂ«rcaktimin e nodĂ«s ku duhet tĂ« vendoset pod-i. Me fjalĂ« tĂ« tjera, rezultati i punĂ«s sĂ« kube-scheduler-it Ă«shtĂ« emri i nodĂ«s qĂ« ai i kthen serverit API nĂ« pĂ«rgjigje tĂ« kĂ«rkesĂ«s pĂ«r planifikim, dhe kĂ«tu pĂ«rfundon puna e tij.
Fillimisht, kube-scheduler krijon një listë nodash ku mund të planifikohet pod-i sipas politikave të predikateve. Më pas, secila nodë nga kjo listë merr një numër të caktuar pikësh sipas politikave prioritete. Si rezultat, zgjidhet nodi që ka grumbulluar numrin maksimal të pikëve. Nëse ka nodo me të njëjtin maksimum, zgjidhet njëra rastësisht. Me listën dhe përshkrimin e politikave të predikateve (filtrimi) dhe prioriteteve (vlerësimi) mund të njiheni në .
Përshkrimi i problemit
Megjithëse kemi një numër të madh klasteresh Kubernetes në shërbim në Nixys, për herë të parë me problemin e planifikimit të pod-eve u përballëm vetëm së fundmi, kur për një nga projektet tona u shfaq nevoja për të nisur një numër të madh detyrash periodike (~100 entitete CronJob). Për të thjeshtuar sa më shumë përshkrimin e problemit, do të marrim si shembull një mikroshërbim, në kuadër të cilit një herë në minutë fillohet një detyrë cron që krijon një ngarkesë të caktuar në CPU. Për operimin e detyrës cron, u ndanë tri nodo krejtësisht të njëjta nga ana e karakteristikave (24 vCPU në secilën).
Megjithatë, nuk është e mundur të ecet me saktësi se sa kohë do të marrë ekzekutimi i CronJob-it, pasi volumi i të dhënave hyrëse ndalon të jetë konstant. Në mesatare, gjatë funksionimit normal të kube-scheduler-it, në çdo nodë punojnë 3-4 kopje të detyrës, të cilat krijojnë ~20-30% ngarkesë në CPU-në e secilës nodë:

Problemi qëndron në faktin se ndonjëherë pod-et e detyrave cron ndalonin së planifikuari në një nga tre nodat. Kështu, në një moment, në një nga nodat nuk planifikohej asnjë pod, ndërsa dy nodat e tjera kishin 6-8 kopje të detyrës, duke krijuar ~40-60% ngarkesë në CPU:

Problemi përsëritej me një rastësi të plotë në periudha dhe ndonjëherë ishte i lidhur me momentin e lëshimit të një versioni të ri të kodit.
Duke rritur nivelin e regjistrimit të kube-scheduler-it në nivelin 10 (-v=10), filluam të regjistronim se sa pikë merrte çdo nodë gjatë vlerësimit. Gjatë funksionimi normal të planifikimit, në regjistra mund të shihnim informacionin e mëposhtëm:
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 100043Kjo do të thotë se, sipas informacionit të marrë nga logët, çdo nod kishte një numër të barabartë pikësh përfundimtar dhe për planifikimin zgjidhej një rastësore. Në momentin e planifikimit problematik, logët duken si më poshtë:
resource_allocation.go:78] cronjob-1574211360-bzfkr -> Node02: BalancedResourceAllocation, kapacitet 23900 millicores 67167186944 bytes memorie, kërkesa totale 1587 millicores 4581125120 bytes memorie, skori 9
resource_allocation.go:78] cronjob-1574211360-bzfkr -> Node03: BalancedResourceAllocation, kapacitet 23900 millicores 67167186944 bytes memorie, kërkesa totale 1087 millicores 3532549120 bytes memorie, skori 9
resource_allocation.go:78] cronjob-1574211360-bzfkr -> Node02: LeastResourceAllocation, kapacitet 23900 millicores 67167186944 bytes memorie, kërkesa totale 1587 millicores 4581125120 bytes memorie, skori 9
resource_allocation.go:78] cronjob-1574211360-bzfkr -> Node01: BalancedResourceAllocation, kapacitet 23900 millicores 67167186944 bytes memorie, kërkesa totale 987 millicores 3322833920 bytes memorie, skori 9
resource_allocation.go:78] cronjob-1574211360-bzfkr -> Node01: LeastResourceAllocation, kapacitet 23900 millicores 67167186944 bytes memorie, kërkesa totale 987 millicores 3322833920 bytes memorie, skori 9
resource_allocation.go:78] cronjob-1574211360-bzfkr -> Node03: LeastResourceAllocation, kapacitet 23900 millicores 67167186944 bytes memorie, kërkesa totale 1087 millicores 3532549120 bytes memorie, skori 9
interpod_affinity.go:237] cronjob-1574211360-bzfkr -> Node03: InterPodAffinityPriority, Skori: (0)
interpod_affinity.go:237] cronjob-1574211360-bzfkr -> Node02: InterPodAffinityPriority, Skori: (0)
interpod_affinity.go:237] cronjob-1574211360-bzfkr -> Node01: InterPodAffinityPriority, Skori: (0)
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node03: TaintTolerationPriority, Skori: (10)
selector_spreading.go:146] cronjob-1574211360-bzfkr -> Node03: SelectorSpreadPriority, Skori: (10)
selector_spreading.go:146] cronjob-1574211360-bzfkr -> Node02: SelectorSpreadPriority, Skori: (10)
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node02: TaintTolerationPriority, Skori: (10)
selector_spreading.go:146] cronjob-1574211360-bzfkr -> Node01: SelectorSpreadPriority, Skori: (10)
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node03: NodeAffinityPriority, Skori: (0)
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node03: SelectorSpreadPriority, Skori: (10)
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node02: SelectorSpreadPriority, Skori: (10)
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node01: TaintTolerationPriority, Skori: (10)
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node02: NodeAffinityPriority, Skori: (0)
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node01: NodeAffinityPriority, Skori: (0)
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node01: SelectorSpreadPriority, Skori: (10)
generic_scheduler.go:781] Host Node03 -> Skori 100041
generic_scheduler.go:781] Host Node02 -> Skori 100041
generic_scheduler.go:781] Host Node01 -> Skori 100038Nga e cila është e qartë që një nga nodet kishte grumbulluar më pak pikë përfundimtare se të tjerat, dhe për këtë arsye, planifikimi u realizua vetëm në dy nodet që fituan pikun maksimal. Kështu ne u siguruam që problemi ishte pikërisht në planifikimin e podëve.
Algoritmi i mĂ«tejshĂ«m pĂ«r zgjidhjen e problemit ishte i qartĂ« pĂ«r ne â tĂ« analizojmĂ« log-et, tĂ« kuptojmĂ« se pĂ«r cilin prioritet konkret node nuk grumbulloi pikĂ« dhe, nĂ«se Ă«shtĂ« e nevojshme, tĂ« korrektojmĂ« politikat e kube-scheduler default. MegjithatĂ«, kĂ«tu u pĂ«rballĂ«m me dy vĂ«shtirĂ«si tĂ« rĂ«ndĂ«sishme:
- Në nivelin maksimal të log-imit (10) reflektohet një grup pikësh vetëm për disa prioritete. Në fragmentin e mësipërm të log-eve mund të vërehet se për të gjitha prioritetet e pasqyruara në log, nodet grumbullojnë të njëjtin numër pikësh në planifikimin normal dhe atë problematik, megjithatë rezultati përfundimtar në rastin e planifikimit problematik ndryshon. Kështu, mund të përfundohet se për disa prioritete, llogaritja e pikëve ndodh "në prapaskenë", dhe nuk kemi asnjë mundësi për të kuptuar se për cilin prioritet konkret node nuk grumbulloi pikë. Ky problem e kemi përshkruar në detaje në repozitorin Kubernetes në Github. Në momentin e shkrimit të artikullit është marrë një përgjigje nga zhvilluesit, se mbështetje për log-imin do të shtohet në përditësimet e Kubernetes v1.15, 1.16 dhe 1.17.
- Nuk ka një mënyrë të thjeshtë për të kuptuar me cilin grup politik konkret aktualisht punon kube-scheduler. Po, në këtë listë është përfshirë, por në të nuk ka informacion se cilat konkretisht peshë janë vendosur për secilën nga politikat prioritet. Të shohësh peshat ose të editosh politikat e kube-scheduler default mund të bëhet vetëm në .
ĂshtĂ« e rĂ«ndĂ«sishme tĂ« theksohet se njĂ« herĂ« arritĂ«m tĂ« dokumentojmĂ« se nodi nuk merrte pikĂ« sipas politikĂ«s ImageLocalityPriority, e cila akordon pikĂ« nodit nĂ«se njĂ« imazh i nevojshĂ«m pĂ«r funksionimin e aplikacionit Ă«shtĂ« tashmĂ« i pranishĂ«m atje. Pra, nĂ« momentin e lansimit tĂ« versionit tĂ« ri tĂ« aplikacionit, detyra cron arrinte tĂ« ekzekutohej nĂ« dy node, duke i shkarkuar ato me njĂ« imazh tĂ« ri nga docker registry, dhe kĂ«shtu dy node merrnin njĂ« rezultat mĂ« tĂ« lartĂ« nĂ« krahasim me tĂ« tretin.
Siç e kam përmendur më lart, në logjet tona nuk shohim informacion rreth vlerësimit të politikës ImageLocalityPriority, prandaj, për të verifikuar supozimin tim, shkarkuam imazhin me versionin e ri të aplikacionit në nodin e tretë, pas së cilës planifikimi filloi të funksiononte siç duhet. Problemi i planifikimit u vu re mjaft rrallë për shkak të politikës ImageLocalityPriority; më shpesh ishte i lidhur me diçka tjetër. Për shkak se nuk mund të debaguam plotësisht çdo politikë në listën e prioriteteve të kube-scheduler-it standard, na nevojitej një menaxhim më fleksibël të politikave të planifikimit të pods.
Vendosja e detyrës
DĂ«shironim qĂ« zgjidhja e problemit tĂ« ishte sa mĂ« e saktĂ«, pra entitetet kryesore tĂ« Kubernetes (kĂ«tu kam parasysh kube-scheduler-in standard) duhet tĂ« mbeten tĂ« pandryshuara. Nuk donim tĂ« zgjidhnim njĂ« problem nĂ« njĂ« vend dhe ta krijonim atĂ« nĂ« njĂ« tjetĂ«r. KĂ«shtu, arritĂ«m nĂ« dy opsione pĂ«r zgjidhjen e problemit, tĂ« cilat u pĂ«rmendĂ«n nĂ« hyrjen e artikullit â krijimi i njĂ« scheduler-i shtesĂ« ose shkruarja e njĂ« tĂ« vetĂ«. KĂ«rkesa kryesore pĂ«r planifikimin e detyrave cron Ă«shtĂ« shpĂ«rndarja e barabartĂ« e ngarkesĂ«s mbi tre node. Kjo kĂ«rkesĂ« mund tĂ« pĂ«rmbushet me politikat ekzistuese tĂ« kube-scheduler-it, prandaj nuk ka kuptim tĂ« shkruajmĂ« njĂ« scheduler tĂ« vetin pĂ«r tĂ« zgjidhur problemin tonĂ«.
Udhëzimi për krijimin dhe Deployment-in e kube-scheduler-it shtesë është përshkruar në . Megjithatë, ne mendojmë se entitetet e Deployment-it nuk janë të mjaftueshme për të garantuar qëndrueshmërinë e një shërbimi kaq kritik si kube-scheduler, prandaj vendosëm të vendosim një kube-scheduler të ri si Static Pod, i cili do të monitorohej drejtpërdrejt nga Kubelet. kështu, ne kishim kërkesat e mëposhtme për kube-scheduler-in e ri:
- Shërbimi duhet të jetë i vendosur si Static Pod në të gjithë masterat e klasterit
- Duhet të sigurohet qëndrueshmëria në rast se pod-i aktiv me kube-scheduler është i paqasshëm
- Prioriteti kryesor gjatë planifikimit duhet të jetë sasia e të dhënave të disponueshme në nod (LeastRequestedPriority)
Implementimi i zgjidhjes
Duhet të theksohet se të gjitha punët do t'i bëjmë në Kubernetes v1.14.7, pasi pikërisht kjo version është përdorur në projekt. Të fillojmë me hartimin e manifestit për kube-scheduler-in tonë të ri. Do të marrim si bazë manifestin e kube-scheduler-it standard (/etc/kubernetes/manifests/kube-scheduler.yaml) dhe do ta sjellim në formën e mëposhtme:
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-configPërmbledhje mbi ndryshimet kryesore:
- Ndryshuam emrin e pod-it dhe konteinerit në kube-scheduler-cron
- Specifikuam përdorimin e porteve 10151 dhe 10159 pasi është përcaktuar opsioni
hostNetwork: truedhe nuk mund tĂ« pĂ«rdorim tĂ« njĂ«jtat porte si kube-scheduler standard (10251 dhe 10259) - Me parametrin âconfig specifikuam skedarin e konfigurimit me tĂ« cilin duhet tĂ« fillojĂ« shĂ«rbimi
- Konfiguruam montimin e skedarit të konfigurimit (scheduler-custom.conf) dhe skedarit të politikave të planifikimit (scheduler-custom-policy-config.json) nga hosti
Mos harrojmë se kube-scheduler-i ynë do të kërkojë privilegje të ngjashme me ato të kështjellës. Redaktojmë rolin e tij të klasterit:
kubectl edit clusterrole system:kube-scheduler...
resourceNames:
- kube-scheduler
- kube-scheduler-cron
...Tani le të flasim mbi përmbajtjen që duhet të ketë skedari i konfigurimit dhe skedari me politikat e planifikimit:
- Skedari i konfigurimit (scheduler-custom.conf)
Për të marrë konfigurimin e kube-scheduler default, duhet të përdorim parametrin--write-config-tonga . Konfigurimin e marrë do ta vendosim në skedarin /etc/kubernetes/scheduler-custom.conf dhe do ta formojmë si më poshtë:
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"Përmbledhje mbi ndryshimet kryesore:
- Ne vendosëm në schedulerName emrin e shërbimit tonë kube-scheduler-cron.
- NĂ« parametrin
lockObjectNameduhet gjithashtu të vendosim emrin e shërbimit tonë dhe të sigurohemi se parametrileaderElectështë vendosur në vlerën true (nëse keni vetëm një master-node, mund ta vendosni në false). - Caktojmë rrugën e skedarit me përshkrimin e politikave të planifikimit në parametrin
algorithmSource.
Duhet të ndalemi më në detaje te pika e dytë, ku redaktojmë parametrat për çelësin leaderElection. Për të siguruar disponueshmëri të lartë, aktivizuam (leaderElect) procesin e zgjedhjes së liderit (master) ndërmjet pod-ëve të kube-scheduler tonë duke përdorur një endpoint të vetëm për ta (resourceLock) me emrin kube-scheduler-cron (lockObjectName) në hapësirën e emrave kube-system (lockObjectNamespace). Për informacion në lidhje me si Kubernetes siguron disponueshmërinë e lartë të komponentëve kryesorë (përfshirë kube-scheduler), mund të referoheni tek .
- Skedari i politikave të planifikimit (scheduler-custom-policy-config.json)
Siç e pĂ«rmenda mĂ« parĂ« â duke analizuar kodin e kube-scheduler default, mund tĂ« kuptojmĂ« se cilat politika tĂ« sakta pĂ«rdor. Pra, nuk mund tĂ« marrim njĂ« skedar me politikat e planifikimit tĂ« kube-scheduler default ashtu si me skedarin e konfigurimit. Do t'i pĂ«rshkruajmĂ« politikat e interesit nĂ« skedarin /etc/kubernetes/scheduler-custom-policy-config.json si mĂ« poshtĂ«:
{
"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
}Në këtë mënyrë, kube-scheduler fillimisht krijon një listë nodash, ku mund të planifikohet pod-i sipas politikës GeneralPredicates (e cila përfshin një grup politikash si PodFitsResources, PodFitsHostPorts, HostName dhe MatchNodeSelector). Më pas, çdo nodë vlerësohet sipas grupit të politikave në arrayn prioritetet. Për të arritur qëllimet tona, menduam se ky grup politikash do të ishte zgjidhja më optimale. Kujtojmë se grupi i politikave me përshkrimet e tyre është në dispozicion në . Për të përmbushur qëllimin tuaj, thjesht mund të ndryshoni grupin e politikave të përdorur dhe t'u caktoni atyre pesha përkatëse.
Manifesti i kube-scheduler të ri, të cilin e krijuam në fillim të kapitullit, do ta quajmë kube-scheduler-custom.yaml dhe do ta vendosim në rrugën /etc/kubernetes/manifests në tre master-nodes. Nëse gjithçka është bërë siç duhet, Kubelet në çdo nodë do të niste pod-in, dhe në log-et e kube-scheduler të ri do të shohim informacionin se skedari ynë me politikat u aplikua me sukses:
Creating scheduler from configuration: {{ } [{GeneralPredicates }]{[ServiceSpreadingPriority 1 } {EqualPriority 1 } {LeastRequestedPriority 1 } {NodePreferAvoidPodsPriority 10000 } {NodeAffinityPriority 1 }]} [] 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:{}]'Tani mbetet vetëm të caktosh në specifikën e CronJob-së sonë, që të gjitha kërkesat për planifikimin e pod-eve të saj duhet të trajtohen nga kube-scheduler i ri:
...
jobTemplate:
spec:
template:
spec:
schedulerName: kube-scheduler-cron
...Përfundimi
Në fund, kemi marrë kube-scheduler të shtuar me një grup unik politikash planifikimi, të cilin e monitoron direkt kubelet. Përveç kësaj, kemi rregulluar zgjedhjen e një lideri të ri ndërmjet pod-eve të kube-scheduler tonë në rast se lideri i vjetër bëhet i paqasshëm për ndonjë arsyes.
Aplikacionet dhe shërbimet e zakonshme vazhdojnë të planifikohen përmes kube-scheduler të paracaktuar, ndërsa të gjitha detyrat cron janë transferuar plotësisht në të riun. Ngarkesa e krijuar nga detyrat cron tani shpërndahet baras mbi të gjitha nodet. Të konsiderojmë se pjesa më e madhe e detyrave cron ekzekutohen në të njëjtat node si aplikacionet kryesore të projektit, kjo ka lejuar një ulje të dukshme të rrezikut të kalimit të podëve për shkak të mungesës së burimeve. Pas zbatimit të kube-scheduler të shtuar, nuk ka pasur më probleme me planifikimin jo të barabartë të detyrave cron.
Shihni gjithashtu artikuj të tjerë në blogun tonë:
Burimi: habr.com
