Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes
Þessi grein mun hjálpa þér að skilja hvernig álagsjöfnun virkar í Kubernetes, hvað gerist þegar langvarandi tengingar eru stækkaðar og hvers vegna þú ættir að íhuga jafnvægi viðskiptavinar ef þú notar HTTP/2, gRPC, RSockets, AMQP eða aðrar langlífar samskiptareglur . 

Smá um hvernig umferð er endurdreifð í Kubernetes 

Kubernetes býður upp á tvær þægilegar útdrættir til að dreifa forritum: Þjónusta og dreifing.

Dreifingar lýsa því hvernig og hversu mörg eintök af forritinu þínu ættu að vera í gangi hverju sinni. Hvert forrit er notað sem Pod og er úthlutað IP tölu.

Þjónusta er svipuð í virkni og álagsjafnari. Þau eru hönnuð til að dreifa umferð um marga belg.

Við skulum sjá hvernig það lítur út.

  1. Í skýringarmyndinni hér að neðan geturðu séð þrjú tilvik af sama forriti og álagsjafnara:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  2. Álagsjafnarinn er kallaður þjónusta og er úthlutað IP tölu. Allar beiðnir sem berast er vísað á einn af belgjunum:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  3. Dreifingarsviðið ákvarðar fjölda tilvika forritsins. Þú þarft næstum aldrei að stækka beint undir:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  4. Hver belg er úthlutað eigin IP tölu:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

Það er gagnlegt að hugsa um þjónustu sem safn af IP-tölum. Í hvert skipti sem þú opnar þjónustuna er ein af IP tölunum valin af listanum og notuð sem áfangastaður.

Þetta lítur svona út.

  1. Beiðni um krullu 10.96.45.152 er móttekin til þjónustunnar:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  2. Þjónustan velur eitt af þremur netföngum sem áfangastaður:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  3. Umferð er vísað á tiltekið hólf:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

Ef forritið þitt samanstendur af framenda og bakenda, þá muntu hafa bæði þjónustu og dreifingu fyrir hvert.

Þegar framhliðin leggur fram beiðni til bakendans þarf hann ekki að vita nákvæmlega hversu marga belg hann þjónar: það gæti verið einn, tíu eða hundrað.

Einnig veit framendinn ekkert um heimilisföng belganna sem þjóna bakendanum.

Þegar framhliðin gerir beiðni til bakendans notar hann IP tölu bakendaþjónustunnar, sem breytist ekki.

Svona lítur það út.

  1. Undir 1 biður um innri bakendahlutann. Í stað þess að velja ákveðna fyrir bakendann, leggur það fram beiðni til þjónustunnar:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  2. Þjónustan velur einn af bakendunum sem áfangastað:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  3. Umferð fer frá Pod 1 til Pod 5, valinn af þjónustunni:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  4. Undir 1 veit ekki nákvæmlega hversu margir belg eins og undir 5 eru falin á bak við þjónustuna:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

En hvernig nákvæmlega dreifir þjónustan beiðnum? Það virðist sem round-robin jafnvægi sé notað? Við skulum reikna það út. 

Jafnvægi í Kubernetes þjónustu

Kubernetes þjónusta er ekki til. Það er ekkert ferli fyrir þjónustuna sem er úthlutað IP tölu og gátt.

Þú getur staðfest þetta með því að skrá þig inn á hvaða hnút sem er í klasanum og keyra netstat -ntlp skipunina.

Þú munt ekki einu sinni geta fundið IP töluna sem þjónustunni er úthlutað.

IP-tala þjónustunnar er staðsett í stjórnlaginu, í stjórnandanum og skráð í gagnagrunninn - osfrv. Sama heimilisfang er notað af öðrum íhlut - kube-proxy.
Kube-proxy fær lista yfir IP vistföng fyrir alla þjónustu og býr til sett af iptables reglum á hverjum hnút í klasanum.

Þessar reglur segja: „Ef við sjáum IP-tölu þjónustunnar verðum við að breyta áfangastað beiðninnar og senda það á einn af belgjunum.

IP-tölu þjónustunnar er aðeins notuð sem inngangsstaður og er ekki þjónað af neinu ferli sem hlustar á þá IP tölu og höfn.

Við skulum skoða þetta

  1. Lítum á þyrping þriggja hnúta. Hver hnút hefur belg:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  2. Bundnir beljur málaðar drapplitaðar eru hluti af þjónustunni. Þar sem þjónustan er ekki til sem ferli er hún sýnd með gráu:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  3. Fyrsti belgurinn biður um þjónustu og verður að fara í einn af tengdum belgjum:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  4. En þjónustan er ekki til, ferlið er ekki til. Hvernig virkar það?

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  5. Áður en beiðnin yfirgefur hnútinn fer hún í gegnum iptables reglurnar:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  6. Iptables reglurnar vita að þjónustan er ekki til og skipta út IP tölu hennar fyrir eina af IP tölum belgjanna sem tengjast þeirri þjónustu:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  7. Beiðnin fær gilt IP-tölu sem áfangastaðfang og er unnið venjulega:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  8. Það fer eftir staðfræði netkerfisins, beiðnin berst að lokum til belgsins:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

Getur iptables hleðslujafnvægi?

Nei, iptables eru notuð til að sía og voru ekki hönnuð fyrir jafnvægi.

Hins vegar er hægt að skrifa sett af reglum sem virka eins og gervijafnvægi.

Og þetta er nákvæmlega það sem er útfært í Kubernetes.

Ef þú ert með þrjá belg, mun kube-proxy skrifa eftirfarandi reglur:

  1. Veldu fyrsta undirlið með 33% líkum, annars farðu í næstu reglu.
  2. Veldu þann seinni með 50% líkur, annars farðu í næstu reglu.
  3. Veldu þriðja undir.

Þetta kerfi leiðir til þess að hver fræbelgur er valinn með 33% líkum.

Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

Og það er engin trygging fyrir því að Pod 2 verði valinn næst á eftir Pod 1.

Athugið: iptables notar tölfræðieiningu með handahófskenndri dreifingu. Þannig er jafnvægisreikniritið byggt á handahófsvali.

Nú þegar þú skilur hvernig þjónusta virkar skulum við skoða áhugaverðari þjónustusviðsmyndir.

Langlífar tengingar í Kubernetes stækka ekki sjálfgefið

Hver HTTP beiðni frá framenda til bakenda er þjónað af sérstakri TCP tengingu, sem er opnuð og lokuð.

Ef framhliðin sendir 100 beiðnir á sekúndu til bakendans, þá eru 100 mismunandi TCP tengingar opnaðar og lokaðar.

Þú getur dregið úr vinnslutíma og álagi beiðna með því að opna eina TCP tengingu og nota hana fyrir allar síðari HTTP beiðnir.

HTTP samskiptareglur eru með eiginleika sem kallast HTTP keep-alive, eða endurnotkun tenginga. Í þessu tilviki er ein TCP tenging notuð til að senda og taka á móti mörgum HTTP beiðnum og svörum:

Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

Þessi eiginleiki er ekki virkur sjálfgefið: bæði þjónninn og viðskiptavinurinn verða að vera stilltir í samræmi við það.

Uppsetningin sjálf er einföld og aðgengileg fyrir flest forritunarmál og umhverfi.

Hér eru nokkrir tenglar á dæmi á mismunandi tungumálum:

Hvað gerist ef við notum Keep-alive í Kubernetes þjónustu?
Gerum ráð fyrir að bæði framendinn og bakendinn styðji við að halda lífi.

Við höfum eitt eintak af framendanum og þrjú eintök af bakendanum. Framendinn gerir fyrstu beiðnina og opnar TCP tengingu við bakendann. Beiðnin berst til þjónustunnar, einn af bakendabelgjunum er valinn sem áfangastaður. Bakendinn sendir svar og framendinn fær það.

Ólíkt venjulegum aðstæðum þar sem TCP tengingin er lokuð eftir að hafa fengið svar, er henni nú haldið opnu fyrir frekari HTTP beiðnir.

Hvað gerist ef framhliðin sendir fleiri beiðnir til bakendans?

Til að framsenda þessar beiðnir verður notuð opin TCP tenging, allar beiðnir fara í sama bakenda þar sem fyrsta beiðnin fór.

Ætti iptables ekki að dreifa umferðinni aftur?

Ekki í þessu tilfelli.

Þegar TCP tenging er búin til fer hún í gegnum iptables reglur sem velja ákveðna bakenda þar sem umferðin fer.

Þar sem allar síðari beiðnir eru á þegar opinni TCP tengingu, eru iptables reglurnar ekki lengur kallaðar.

Við skulum sjá hvernig það lítur út.

  1. Fyrsta hólfið sendir beiðni til þjónustunnar:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  2. Þú veist nú þegar hvað mun gerast næst. Þjónustan er ekki til, en það eru iptables reglur sem munu vinna úr beiðninni:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  3. Einn af bakendabelgjunum verður valinn sem áfangastaður:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  4. Beiðnin berst í belg. Á þessum tímapunkti verður viðvarandi TCP tenging milli belgjanna tveggja komið á:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  5. Allar síðari beiðnir frá fyrsta hólfinu munu fara í gegnum tenginguna sem þegar hefur verið komið á:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

Niðurstaðan er hraðari viðbragðstími og meiri afköst, en þú missir getu til að skala bakendann.

Jafnvel ef þú ert með tvo belg í bakendanum, með stöðugri tengingu, mun umferð alltaf fara í annan þeirra.

Er hægt að laga þetta?

Þar sem Kubernetes veit ekki hvernig á að halda jafnvægi á viðvarandi tengingum, þá er þetta verkefni þitt.

Þjónusta er safn af IP tölum og höfnum sem kallast endapunktar.

Forritið þitt getur fengið lista yfir endapunkta frá þjónustunni og ákveðið hvernig á að dreifa beiðnum á milli þeirra. Þú getur opnað viðvarandi tengingu við hvert hólf og jafnvægisbeiðnir milli þessara tenginga með því að nota hringrás.

Eða sækja um meira flókin jafnvægisreiknirit.

Kóðinn við viðskiptavininn sem ber ábyrgð á jafnvægi ætti að fylgja þessari rökfræði:

  1. Fáðu lista yfir endapunkta frá þjónustunni.
  2. Opnaðu viðvarandi tengingu fyrir hvern endapunkt.
  3. Þegar beiðni þarf að gera skaltu nota eina af opnu tengingunum.
  4. Uppfærðu listann yfir endapunkta reglulega, búðu til nýja eða lokaðu gömlum viðvarandi tengingum ef listinn breytist.

Svona mun það líta út.

  1. Í stað þess að fyrsta belgurinn sendi beiðnina til þjónustunnar, geturðu jafnvægisbeiðnir viðskiptavinarhliðar:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  2. Þú þarft að skrifa kóða sem spyr hvaða belg eru hluti af þjónustunni:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  3. Þegar þú hefur listann skaltu vista hann á biðlarahlið og nota hann til að tengjast belgunum:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

  4. Þú ert ábyrgur fyrir álagsjöfnunaralgríminu:

    Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

Nú vaknar spurningin: á þetta vandamál aðeins við um HTTP keep-alive?

Álagsjöfnun viðskiptavinarhliðar

HTTP er ekki eina samskiptareglan sem getur notað viðvarandi TCP tengingar.

Ef forritið þitt notar gagnagrunn, þá er TCP tenging ekki opnuð í hvert skipti sem þú þarft að gera beiðni eða sækja skjal úr gagnagrunninum. 

Þess í stað er viðvarandi TCP tenging við gagnagrunninn opnuð og notuð.

Ef gagnagrunnurinn þinn er settur á Kubernetes og aðgangur er veittur sem þjónusta, muntu lenda í sömu vandamálum og lýst er í fyrri hlutanum.

Ein gagnagrunnseftirmynd verður meira hlaðin en hinar. Kube-proxy og Kubernetes munu ekki hjálpa til við að koma jafnvægi á tengingar. Þú verður að gæta þess að koma jafnvægi á fyrirspurnirnar í gagnagrunninn þinn.

Það fer eftir því hvaða bókasafn þú notar til að tengjast gagnagrunninum, þú gætir haft mismunandi möguleika til að leysa þetta vandamál.

Hér að neðan er dæmi um aðgang að MySQL gagnagrunnsklasa frá Node.js:

var mysql = require('mysql');
var poolCluster = mysql.createPoolCluster();

var endpoints = /* retrieve endpoints from the Service */

for (var [index, endpoint] of endpoints) {
  poolCluster.add(`mysql-replica-${index}`, endpoint);
}

// Make queries to the clustered MySQL database

Það eru margar aðrar samskiptareglur sem nota viðvarandi TCP tengingar:

  • WebSockets og öruggar WebSockets
  • HTTP / 2
  • gRPC
  • RSokkar
  • AMQP

Þú ættir nú þegar að kannast við flestar þessar samskiptareglur.

En ef þessar samskiptareglur eru svona vinsælar, hvers vegna er þá ekki til staðlað jafnvægislausn? Hvers vegna þarf rökfræði viðskiptavinarins að breytast? Er til innfædd Kubernetes lausn?

Kube-proxy og iptables eru hönnuð til að ná yfir algengustu notkunartilvik þegar þeir eru dreifðir á Kubernetes. Þetta er til þæginda.

Ef þú ert að nota vefþjónustu sem afhjúpar REST API, ertu heppinn - í þessu tilfelli eru viðvarandi TCP tengingar ekki notaðar, þú getur notað hvaða Kubernetes þjónustu sem er.

En þegar þú byrjar að nota viðvarandi TCP tengingar þarftu að finna út hvernig á að dreifa álaginu jafnt yfir bakenda. Kubernetes inniheldur ekki tilbúnar lausnir fyrir þetta mál.

Hins vegar eru vissulega valkostir sem geta hjálpað.

Jafnvægi á langlífum tengingum í Kubernetes

Það eru fjórar tegundir þjónustu í Kubernetes:

  1. ClusterIP
  2. NodePort
  3. LoadBalancer
  4. Höfuðlaus

Fyrstu þrjár þjónusturnar starfa á grundvelli sýndar IP tölu, sem er notað af kube-proxy til að byggja upp iptables reglur. En grundvallargrundvöllur allrar þjónustu er höfuðlaus þjónusta.

Höfuðlausa þjónustan hefur enga IP-tölu tengda sér og veitir aðeins kerfi til að sækja lista yfir IP-tölur og tengi fyrir belg (endapunkta) sem tengjast henni.

Öll þjónusta byggir á hauslausu þjónustunni.

ClusterIP þjónustan er höfuðlaus þjónusta með nokkrum viðbótum: 

  1. Stjórnunarlagið úthlutar því IP tölu.
  2. Kube-proxy býr til nauðsynlegar iptables reglur.

Þannig geturðu hunsað kube-proxy og notað beint listann yfir endapunkta sem fæst frá höfuðlausu þjónustunni til að hlaða jafnvægi á forritið þitt.

En hvernig getum við bætt sambærilegri rökfræði við öll forrit sem notuð eru í klasanum?

Ef forritið þitt er þegar komið í notkun gæti þetta verkefni virst ómögulegt. Hins vegar er annar valkostur.

Service Mesh mun hjálpa þér

Þú hefur sennilega þegar tekið eftir því að álagsjafnvægisstefna viðskiptavinarhliðar er nokkuð staðlað.

Þegar forritið byrjar, það:

  1. Fær lista yfir IP tölur frá þjónustunni.
  2. Opnar og viðheldur tengilaug.
  3. Uppfærir laugina reglulega með því að bæta við eða fjarlægja endapunkta.

Þegar forritið vill leggja fram beiðni, þá:

  1. Velur tiltæka tengingu með því að nota einhverja rökfræði (td round-robin).
  2. Framkvæmir beiðnina.

Þessi skref virka fyrir bæði WebSockets, gRPC og AMQP tengingar.

Þú getur aðskilið þessa rökfræði í sérstakt bókasafn og notað það í forritunum þínum.

Hins vegar geturðu notað þjónustunet eins og Istio eða Linkerd í staðinn.

Service Mesh eykur umsókn þína með ferli sem:

  1. Leitar sjálfkrafa að IP tölum þjónustunnar.
  2. Prófar tengingar eins og WebSockets og gRPC.
  3. Jafnar beiðnir með því að nota rétta samskiptareglur.

Service Mesh hjálpar til við að stjórna umferð innan klasans, en það er frekar auðlindafrekt. Aðrir valkostir eru að nota þriðja aðila bókasöfn eins og Netflix Ribbon eða forritanleg umboð eins og Envoy.

Hvað gerist ef þú hunsar jafnvægisvandamál?

Þú getur valið að nota ekki álagsjafnvægi og samt ekki tekið eftir neinum breytingum. Við skulum skoða nokkrar vinnusviðsmyndir.

Ef þú ert með fleiri viðskiptavini en netþjóna er þetta ekki svo stórt vandamál.

Segjum að það séu fimm viðskiptavinir sem tengjast tveimur netþjónum. Jafnvel þótt það sé ekkert jafnvægi, verða báðir netþjónarnir notaðir:

Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

Tengingar eru kannski ekki jafndreifðar: kannski fjórir viðskiptavinir tengdir sama netþjóni, en það eru góðar líkur á að báðir netþjónarnir verði notaðir.

Það sem er erfiðara er hið gagnstæða atburðarás.

Ef þú ert með færri viðskiptavini og fleiri netþjóna gætu auðlindir þínar verið vannýttar og hugsanlegur flöskuháls mun birtast.

Segjum að það séu tveir viðskiptavinir og fimm netþjónar. Í besta falli verða tvær varanlegar tengingar við tvo netþjóna af fimm.

Þeir netþjónar sem eftir eru verða aðgerðalausir:

Álagsjafnvægi og stækkandi langlífar tengingar í Kubernetes

Ef þessir tveir netþjónar geta ekki séð um beiðnir viðskiptavina, mun lárétt stærðarstærð ekki hjálpa.

Ályktun

Kubernetes þjónusta er hönnuð til að virka í flestum venjulegum vefforritum.

Hins vegar, þegar þú byrjar að vinna með samskiptareglur forrita sem nota viðvarandi TCP tengingar, eins og gagnagrunna, gRPC eða WebSockets, hentar þjónusta ekki lengur. Kubernetes býður ekki upp á innra kerfi til að koma jafnvægi á viðvarandi TCP tengingar.

Þetta þýðir að þú verður að skrifa forrit með jafnvægi viðskiptavinar í huga.

Þýðing unnin af teyminu Kubernetes aaS frá Mail.ru.

Hvað annað að lesa um efnið:

  1. Þrjú stig sjálfvirkrar mælingar í Kubernetes og hvernig á að nota þau á áhrifaríkan hátt
  2. Kubernetes í anda sjóræningjastarfsemi með sniðmáti fyrir útfærslu.
  3. Telegram rás okkar um stafræna umbreytingu.

Heimild: www.habr.com

Bæta við athugasemd