Kubernetes-en bederatzi errendimendu-aholku

Kubernetes-en bederatzi errendimendu-aholku

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

Kubernetes-en bederatzi errendimendu-aholku

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.

resources:
   requests:
     memory: 2Gi
     cpu: 250m
   limits:
     memory: 4Gi
     cpu: 500m

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:

➜  ~ kubectl describe resourcequotas --namespace ops
Name:                   resource-quota
Namespace:              ops
Resource                Used          Hard
--------                ----          ----
limits.cpu              77250m        80
limits.memory           124814367488  150Gi
pods                    31            45
requests.cpu            53850m        80
requests.memory         75613234944   150Gi
services                26            50
services.loadbalancers  0             0
services.nodeports      0             0

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:

Error creating: pods "nginx-proxy-9967d8d78-nh4fs" is forbidden: exceeded quota: resource-quota, requested: limits.cpu=5,requests.cpu=5, used: limits.cpu=77250m,requests.cpu=53850m, limited: limits.cpu=10,requests.cpu=10

Antzeko arazo bat konpontzeko, tresna bat idatz dezakezu, adibidez, honela hau, komando-baliabideen egoera gorde eta konprometi dezakeena.

2. Aukeratu fitxategien biltegiratze onena

Kubernetes-en bederatzi errendimendu-aholku

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

Kubernetes-en bederatzi errendimendu-aholku

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:

  1. Sarearen karga murriztua kluster osoan.

  2. Ontzia abiarazteko denbora murriztu da.

  3. Zure Docker erregistro osoaren tamaina txikiagoa.

4. Erabili DNS cachea

Kubernetes-en bederatzi errendimendu-aholku

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

Kubernetes-en bederatzi errendimendu-aholku

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.

Kubernetes-en bederatzi errendimendu-aholkuhttps://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.

Adibidez, hona hemen pod-ezarpen tipikoak:

resources:
   requests:
     memory: 250Mi
     cpu: 200m
   limits:
     memory: 500Mi
     cpu: 350m

Gomendio-motorrak zehazten du zure aplikazioak 300m CPU eta 500Mi behar dituela behar bezala exekutatzeko. Ezarpen hauek jasoko dituzu:

resources:
   requests:
     memory: 500Mi
     cpu: 300m
   limits:
     memory: 1000Mi
     cpu: 525m

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.

Kubernetes-en bederatzi errendimendu-aholkuhttps://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

Kubernetes-en bederatzi errendimendu-aholku

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:

$ kubectl taint nodes node10 node-role.kubernetes.io/ingress=true:NoSchedule

Azpimarratzekoa da kutsadura-mekanismoak hiru efektu nagusi onartzen dituela: NoSchedule, NoExecute ΠΈ PreferNoSchedule.

  • NoSchedule esan 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:

spec:
   tolerations:
     - key: "node-role.kubernetes.io/ingress"
        operator: "Equal"
        value: "true"
        effect: "NoSchedule"

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 PriorityClass eta eremuen deskribapenak priorityClassName lekaren 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

Kubernetes-en bederatzi errendimendu-aholku

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.

Kubernetes-en bederatzi errendimendu-aholku

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:

  1. Hardware ona eduki, klusterraren tamainaren arabera (irakur dezakezu Hemen).

  2. 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.

Iturria: www.habr.com