Kaixo guztioi! Nire izena Oleg Sidorenkov da, DomClick-en lan egiten dut azpiegitura taldeburu gisa. Hiru urte baino gehiago daramatzagu Kuboa salgai erabiltzen, eta denbora horretan hainbat momentu interesgarri bizi izan ditugu horrekin. Gaur esango dizut nola, planteamendu egokiarekin, errendimendu handiagoa atera dezakezun Kubernetes bainila zure clusterrarentzat. Prest joan zaitez!
Denok dakizue oso ondo Kubernetes edukiontzien orkestraziorako kode irekiko sistema eskalagarria dela; beno, edo zure mikrozerbitzuen bizi-zikloa zerbitzari-ingurunean kudeatuz magia egiten duten 5 bitar. Horrez gain, nahiko tresna malgua da, Lego konstruktore bat bezala munta daitekeena, zeregin desberdinetarako pertsonalizazio handiena lortzeko.
Eta badirudi dena ondo dagoela: zerbitzariak klusterera bota, egurra su-kutxa batean bezala, eta ez dolu ezagutzen. Baina ingurumenaren alde bazaude, orduan pentsatuko duzu: βNola mantendu dezaket sua sukaldean eta basoaz damutu?β. Alegia, nola aurkitu azpiegiturak hobetzeko eta kostuak murrizteko bideak.
1. Jarrai ezazu taldearen eta aplikazioen baliabideen jarraipena
Metodo hutsal baina eraginkorrenetako bat eskaera/mugak ezartzea da. Bereizi aplikazioak izen-espazioen arabera, eta izen-eremuak garapen-taldeen arabera. Ezarri aplikazioa prozesadorearen denbora, memoria, biltegiratze iragankorra kontsumitzeko balioak zabaldu aurretik.
Esperientziaz, ondoriora iritsi ginen: ez du merezi mugetatik eskaerak bi aldiz baino gehiago puztea. Kluster-tamaina eskaeren arabera kalkulatzen da, eta aplikazioa baliabideen desberdintasuna ezartzen baduzu, adibidez, 5-10 aldiz, imajinatu zer gertatuko den zure nodoarekin lekak bete eta bat-batean karga bat jasotzen duenean. Ezer onik ez. Gutxienez, throttling, eta gehienez, agur langileari eta lortu karga zikliko bat gainontzeko nodoetan lekak mugitzen hasi ondoren.
Horrez gain, laguntzarekin limitranges Hasieran edukiontzirako baliabide-balioak ezar ditzakezu - minimoa, maximoa eta lehenetsia:
β ~ kubectl describe limitranges --namespace ops
Name: limit-range
Namespace: ops
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Container cpu 50m 10 100m 100m 2
Container ephemeral-storage 12Mi 8Gi 128Mi 4Gi -
Container memory 64Mi 40Gi 128Mi 128Mi 2
Gogoratu izen-espazioaren baliabideak mugatu behar dituzula, komando batek klusterraren baliabide guztiak hartu ezin ditzan:
Deskribapenean ikus dezakezun bezala resourcequotas, ops komandoak beste 10 CPU kontsumituko dituzten lekak zabaldu nahi baditu, orduan programatzaileak ez du baimenduko eta errore bat emango du:
Antzeko arazo bat konpontzeko, tresna bat idatz dezakezu, adibidez, honela hau, komando-baliabideen egoera gorde eta konprometi dezakeena.
2. Aukeratu fitxategien biltegiratze onena
Hemen bolumen iraunkorren gaia eta Kubernetes langile-nodoen disko azpisistema ukitu nahiko nuke. Espero dut inork ez duela HDDko "Kuboa" erabiltzen ekoizpenean, baina batzuetan SSD arrunt bat ere ez da nahikoa. Halako arazo bati aurre egin genion, non erregistroak diskoa hiltzen ari zirela I/O eragiketen bidez, eta hemen ez daude irtenbide asko:
Erabili errendimendu handiko SSDak edo aldatu NVMe-ra (zure hardwarea kudeatzen baduzu).
Erregistro-maila murriztu.
Egin diskoa bortxatzen duten lekak orekatzeko "adimentsua" (podAntiAffinity).
Goiko pantaila-argazkiak nginx-ingress-controller disko batekin zer gertatzen den erakusten du access_logs erregistroa gaituta dagoenean (~ 12k erregistro/seg). Egoera horrek, noski, nodo honetako aplikazio guztien degradazioa ekar dezake.
PVri dagokionez, ai, ez dut dena probatu. mota Bolumen iraunkorrak. Erabili egokitzen zaizun aukerarik onena. Historikoki gertatu da gurean zerbitzuen zati txiki batek RWX bolumenak behar dituela, eta aspaldi hasi ziren NFS biltegiratzea zeregin horretarako erabiltzen. Merke eta... nahikoa. Noski, kaka jan genuen berarekin - egon osasuntsu, baina sintonizatzen ikasi genuen, eta buruak jada ez dio minik ematen. Eta ahal izanez gero, aldatu S3 objektuen biltegiratzera.
3. Eraiki Optimizatutako Irudiak
Hobe da edukiontzietarako optimizatutako irudiak erabiltzea, Kubernetes-ek azkarrago eskuratu eta eraginkorrago exekuta ditzan.
Optimizazioak esan nahi du irudiak:
aplikazio bakarra eduki edo funtzio bakarra bete;
tamaina txikia, irudi handiak okerrago transmititzen direlako sarean;
Kubernetes-ek erabil ditzaketen osasun- eta prest dauden amaiera-puntuak edukitzea geldialdi-denbora gertatuz gero neurriak hartzeko;
erabili edukiontzi egokiak diren sistema eragileak (Alpine edo CoreOS bezalakoak), konfigurazio-erroreekiko erresistenteagoak direnak;
Erabili etapa anitzeko eraikuntzak, konpilatutako aplikazioak soilik zabaldu ahal izateko eta ez harekin batera dauden iturriak.
Erreminta eta zerbitzu ugari daude irudiak berehala egiaztatu eta optimizatzeko aukera ematen dutenak. Garrantzitsua da beti eguneratuta eta seguru edukitzea. Ondorioz, lortzen duzu:
Sarearen karga murriztua kluster osoan.
Ontzia abiarazteko denbora murriztu da.
Zure Docker erregistro osoaren tamaina txikiagoa.
4. Erabili DNS cachea
Karga handiei buruz hitz egiten badugu, klusterraren DNS sistema sintonizatu gabe, bizitza nahiko txarra da. Garai batean, Kuberneteseko garatzaileek kube-dns irtenbidea onartzen zuten. Gurean ere ezarri zen, baina software honek ez zuen bereziki sintonizatu eta ez zuen behar den errendimendua eman, nahiz eta, dirudienez, zeregin erraza den. Orduan coredns agertu zen, zeinetara aldatu ginen eta ez genekien dolua, geroago K8s-en DNS zerbitzu lehenetsia bihurtu zen. Noizbait, 40 mila rps-ra hazi ginen DNS sistemara, eta irtenbide hau ere ez zen nahikoa. Baina, zorionez, Nodelocaldns atera zen, nodo lokalaren cachea, aka NodeLocal DNSCache.
Zergatik erabiltzen dugu? Linux nukleoan akats bat dago, conntrack NAT bidez UDPren bidez sarbide anitzek, conntrack tauletan idazteko lasterketa-baldintza bat ekartzen dutenean, eta NAT bidezko trafikoaren zati bat galtzen da (Zerbitzuaren bidez bidaia bakoitza NAT da). Nodelocaldns-ek arazo hau konpontzen du NAT kendu eta TCP konektibitatea upstream DNSra eguneratuz, baita upstream DNS kontsultak lokalean gordeta ere (5 segundoko cache negatibo laburra barne).
5. Eskalatu lekak horizontalki eta bertikalki automatikoki
Esan al dezakezu ziurtasunez zure mikrozerbitzu guztiak karga bi edo hiru aldiz handitzeko prest daudela? Nola esleitu baliabideak behar bezala zure aplikazioei? Lan-kargaren gainetik ibiltari pare bat exekutatzen mantentzea erredundantea izan daiteke, eta bizkarrean mantentzeak trafikoaren bat-bateko igoeran zerbitzurako geldialdi-denbora dakar. Urrezko batez bestekoa biderketa ortografia bezalako zerbitzuak lortzen laguntzen du Horizontal Pod Autoscaler ΠΈ Bertikala Pod Autoscaler.
VPA zure edukiontzien eskaerak/mugak automatikoki igotzeko aukera ematen dizu pod batean, benetako erabileraren arabera. Nola izan daiteke erabilgarria? Arrazoiren batengatik horizontalki eskalatu ezin diren Pods-ak badituzu (ez da guztiz fidagarria), orduan VPA fidatzen saiatu zaitezke bere baliabideak aldatzeko. Bere ezaugarria metriko-zerbitzariaren datu historiko eta uneko datuetan oinarritutako gomendio-sistema da, beraz, eskaerak/mugak automatikoki aldatu nahi ez badituzu, zure edukiontzietarako gomendatutako baliabideak kontrolatu eta ezarpenak optimizatu ditzakezu CPU eta memoria gordetzeko. multzoan.
https://levelup.gitconnected.com/kubernetes-autoscaling-101-cluster-autoscaler-horizontal-pod-autoscaler-and-vertical-pod-2a441d9ad231-tik hartutako irudia
Kubernetes-en programatzailea eskaeretan oinarritzen da beti. Hor jartzen duzun balioa edozein dela ere, programatzaileak horretan oinarritutako nodo egoki bat bilatuko du. Kubletak behar du muga-balioa leka bat noiz zanpatu edo hil behar den jakiteko. Eta parametro garrantzitsu bakarra eskaeren balioa denez, VPAk lan egingo du. Zure aplikazioa bertikalki eskalatzen duzun bakoitzean, eskaerak zein izan behar duten definitzen duzu. Eta zer gertatuko da orduan mugekin? Parametro hori ere proportzionalki eskalatuko da.
Arestian aipatu bezala, eskaeren/mugaren ratioaren araberako eskala proportzionala da manifestuan:
CPU: 200m β 300m: ratioa 1:1.75;
Memoria: 250Mi β 500Mi: 1:2 ratioa.
Dagokionez HPa, orduan funtzionamendu mekanismoa gardenagoa da. Atalaseak prozesadorea eta memoria bezalako neurketetarako ezartzen dira, eta erreplika guztien batez bestekoak atalasea gainditzen badu, aplikazioak +1 poda eskalatzen du, balioa atalasearen azpitik jaitsi arte edo gehieneko erreplika-kopurura iritsi arte.
https://levelup.gitconnected.com/kubernetes-autoscaling-101-cluster-autoscaler-horizontal-pod-autoscaler-and-vertical-pod-2a441d9ad231-tik hartutako irudia
CPU eta Memoria bezalako ohiko neurketez gain, zure Prometheus-en neurri pertsonalizatuetan atalaseak ezar ditzakezu eta haiekin lan egin dezakezu zure aplikazioa noiz eskalatu zehazteko modurik zehatzena dela uste baduzu. Aplikazioa zehaztutako atalase metrikotik behera egonkortzen denean, HPA Pods-ak gutxieneko erreplika kopurura eskalatzen hasiko da edo kargak atalasea betetzen duen arte.
6. Ez ahaztu Node Affinity eta Pod Affinity buruz
Nodo guztiak ez dira hardware berean exekutatzen, eta pod guztiek ez dute behar konputazio intentsiboko aplikazioak exekutatu behar. Kubernetes-ek nodoen eta poden espezializazioa zehazteko aukera ematen du Nodo afinitatea ΠΈ Pod afinitatea.
Konputazio intentsiboko eragiketetarako egokiak diren nodoak badituzu, orduan eraginkortasun handiena lortzeko, hobe da aplikazioak nodo egokietara lotzea. Horretarako, erabili nodeSelector nodoaren etiketarekin.
Demagun bi nodo dituzula: batekin CPUType=HIGHFREQ eta nukleo azkar kopuru handi bat, beste batekin MemoryType=HIGHMEMORY memoria gehiago eta errendimendu azkarragoa. Modurik errazena pod inplementazioa nodo bati esleitzea da HIGHFREQatalean gehituz spec honelako hautatzailea:
β¦
nodeSelector:
CPUType: HIGHFREQ
Hori egiteko modu garestiagoa eta zehatzagoa erabiltzea da nodeAffinity eremuan affinity atala spec. Bi aukera daude:
requiredDuringSchedulingIgnoredDuringExecution: ezarpen gogorra (planifikatzaileak nodo zehatzetan bakarrik zabalduko ditu podsak (eta inon ez));
preferredDuringSchedulingIgnoredDuringExecution: ezarpen biguna (planifikatzailea nodo zehatzetara zabaltzen saiatuko da, eta huts egiten badu, hurrengo nodo erabilgarrira zabaltzen saiatuko da).
Nodoen etiketak kudeatzeko sintaxi zehatz bat zehaztu dezakezu, adibidez, In, NotIn, Exists, DoesNotExist, Gt edo Lt. Hala ere, gogoratu etiketa-zerrenda luzeetako metodo konplexuek egoera kritikoetan erabakiak hartzea motelduko dutela. Beste era batera esanda, ez gehiegi konplikatu.
Goian esan bezala, Kubernetes-ek uneko poden lotura ezartzeko aukera ematen du. Hau da, erabilgarritasun-eremu berean (hodeietarako garrantzitsuak) edo nodoekin batera funtziona dezakezun zenbait podekin.
Π podAffinity eremuak affinity atala spec kasuan bezala eremu berdinak daude eskuragarri nodeAffinity: requiredDuringSchedulingIgnoredDuringExecutionΠΈ preferredDuringSchedulingIgnoredDuringExecution. Alde bakarra hori da matchExpressions lekak lotuko ditu etiketa hori duen pod bat exekutatzen ari den nodo bati.
Kubernetes gehiago eskaintzen du eremu bat podAntiAffinity, eta horrek, aitzitik, ez du pod bat pod espezifikoak dituen nodo bati lotzen.
Esamoldeei buruz nodeAffinity Aholku bera eman daiteke: saiatu arauak sinpleak eta logikoak mantentzen, ez saiatu podaren zehaztapena arau multzo konplexu batekin gainkargatzen. Oso erraza da klusterraren baldintzekin bat ez datorren arau bat sortzea, programatzaileari karga gehigarria jarriz eta errendimendu orokorra hondatuz.
7. Taints eta Tolerazioak
Antolatzailea kudeatzeko beste modu bat dago. Ehunka nodo eta milaka mikrozerbitzu dituen kluster handi bat badaukazu, oso zaila da zenbait nodok ostatatzea saihestea.
Kutsuen mekanismoak -arauak debekatzeak- laguntzen du horretan. Esate baterako, zenbait agertokitan nodo batzuk pods exekutatzen saihestu dezakezu. Nodo jakin bati kutsadura aplikatzeko, erabili aukera taint kubectl-en. Zehaztu gakoa eta balioa eta, gero, zikindu bezala NoSchedule edo NoExecute:
Azpimarratzekoa da kutsadura-mekanismoak hiru efektu nagusi onartzen dituela: NoSchedule, NoExecute ΠΈ PreferNoSchedule.
NoScheduleesan nahi du pod zehaztapenean dagokion sarrera egon arte tolerations, ezin da nodoan zabaldu (adibide honetan node10).
PreferNoSchedule - bertsio sinplifikatua NoSchedule. Kasu honetan, programatzailea saiatuko da bat datorren sarrerarik ez duten lekak ez esleitzen. tolerations nodo bakoitzeko, baina hau ez da muga gogorra. Klusterrean baliabiderik ez badago, podak nodo honetan zabaltzen hasiko dira.
NoExecute- efektu honek sarrera bat ez duten lekak berehala ebakuatzea eragiten du tolerations.
Bitxia bada ere, portaera hori desegin daiteke tolerantzia-mekanismoa erabiliz. Hau komenigarria da "debekatuta" nodo bat dagoenean eta azpiegitura zerbitzuak soilik jarri behar dituzunean. Nola egin? Onartu tolerantzia egokia duten lekak bakarrik.
Hona hemen podaren zehaztapena nolakoa izango litzatekeen:
Horrek ez du esan nahi hurrengo birmoldatzean, podak nodo hau zehatz-mehatz joko duenik, hau ez da Node Affinity mekanismoa eta nodeSelector. Baina hainbat ezaugarri konbinatuz, programatzaileen konfigurazio oso malgua lor dezakezu.
8. Ezarri Pod inplementatzeko lehentasuna
Pod-nodo loturak konfiguratu izanak ez du esan nahi pod guztiak lehentasun berdinarekin tratatu behar direnik. Adibidez, baliteke Pod batzuk beste batzuk baino lehen zabaldu nahi izatea.
Kubernetes-ek Pod lehentasuna eta lehentasuna ezartzeko modu desberdinak eskaintzen ditu. Ezarpenak hainbat atal ditu: objektua PriorityClasseta eremuen deskribapenak priorityClassNamelekaren zehaztapenean. Demagun adibide bat:
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 99999
globalDefault: false
description: "This priority class should be used for very important pods only"
Guk sortzen dugu PriorityClass, eman izena, deskribapena eta balioa.Zenbat eta gorago value, orduan eta lehentasun handiagoa. Balioa 32 baino txikiagoa edo berdina den 1 biteko osoko edozein izan daiteke. Balio altuagoak misio kritikoko sistema-podetarako gordeta daude, normalean ezin dira aurrea hartu.Desalojoa lehentasun handiko lekak ez badu inon bueltarik eman, orduan nodo jakin bateko lekak ebakuatu egingo dira. Mekanismo hau zurrunegia bada zuretzat, orduan aukera gehi dezakezu preemptionPolicy: Never, eta orduan ez da prebentziorik izango, poda ilaran lehena izango da eta programatzaileak horretarako doako baliabideak aurkitu arte itxarongo du.
Ondoren, pod bat sortuko dugu, eta bertan izena zehaztuko dugu priorityClassName:
apiVersion: v1
kind: Pod
metadata:
name: static-web
labels:
role: myrole
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
protocol: TCP
priorityClassName: high-priority
Nahi adina lehentasunezko klase sor ditzakezu, nahiz eta honekin ez eramatea gomendatzen den (esan, lehentasun baxu, ertain eta altuera mugatu).
Horrela, beharrezkoa izanez gero, zerbitzu kritikoak zabaltzeko eraginkortasuna areagotu dezakezu, hala nola nginx-ingress-controller, coredns, etab.
9. Optimizatu zure ETCD klusterra
ETCD kluster osoaren garuna dei daiteke. Oso garrantzitsua da datu-base honen funtzionamendua maila altuan mantentzea, "Kubo"-ko eragiketen abiadura horren araberakoa baita. Nahiko estandarra, eta aldi berean, irtenbide ona izango litzateke ETCD kluster bat nodo nagusietan mantentzea, kube-apiserver-en atzerapen minimo bat izateko. Hori posible ez bada, jarri ETCDa ahalik eta hurbilen, parte-hartzaileen artean banda zabalera onarekin. Erreparatu ere ETCDko zenbat nodo erori daitezkeen klusterari kalterik egin gabe.
Kontuan izan klusterreko parte-hartzaile kopurua gehiegi handitzeak akatsen tolerantzia areagotu dezakeela errendimenduaren kaltetan, dena neurriz egon behar du.
Zerbitzua konfiguratzeaz hitz egiten badugu, gomendio gutxi daude:
Hardware ona eduki, klusterraren tamainaren arabera (irakur dezakezu Hemen).
Doitu parametro batzuk DC pare baten artean kluster bat zabaldu baduzu edo zure sare eta diskoek asko uzten badute (irakur dezakezu Hemen).
Ondorioa
Artikulu honek gure taldeak betetzen saiatzen diren puntuak deskribatzen ditu. Hau ez da ekintzen urratsez urrats deskribatzea, kluster baten gainkostua optimizatzeko erabilgarriak izan daitezkeen aukerak baizik. Argi dago kluster bakoitza bere erara bakarra dela, eta sintonizazio irtenbideak asko alda daitezkeela, beraz, interesgarria izango litzateke zure iritzia jasotzea: nola kontrolatzen duzu zure Kubernetes klusterra, nola hobetu bere errendimendua. Partekatu zure esperientzia iruzkinetan, interesgarria izango da ezagutzea.