Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis
See artikkel aitab teil mõista, kuidas Kuberneteses koormuse tasakaalustamine töötab, mis juhtub pikaealiste ühenduste skaleerimisel ja miks peaksite kaaluma kliendipoolset tasakaalustamist, kui kasutate HTTP/2, gRPC, RSocketsi, AMQP või muid pikaealisi protokolle. . 

Natuke sellest, kuidas Kubernetes liiklust ümber jagatakse 

Kubernetes pakub rakenduste juurutamiseks kahte mugavat abstraktsiooni: teenused ja juurutused.

Juurutused kirjeldavad, kuidas ja kui palju teie rakenduse eksemplare peaks igal ajahetkel töötama. Iga rakendus juurutatakse Pod-na ja sellele määratakse IP-aadress.

Teenused on funktsioonilt sarnased koormuse tasakaalustajaga. Need on loodud liikluse jaotamiseks mitme kausta vahel.

Vaatame, kuidas see välja näeb.

  1. Alloleval diagrammil näete sama rakenduse ja koormuse tasakaalustaja kolme eksemplari:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  2. Koormuse tasakaalustajat nimetatakse teenuseks ja sellele määratakse IP-aadress. Kõik sissetulevad taotlused suunatakse ümber ühte kaustadest:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  3. Juurutamise stsenaarium määrab rakenduse eksemplaride arvu. Peaaegu kunagi ei pea te otse laiendama:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  4. Igale podile määratakse oma IP-aadress:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

Kasulik on mõelda teenustele kui IP-aadresside kogumile. Iga kord, kui teenust kasutate, valitakse loendist üks IP-aadressidest ja seda kasutatakse sihtkoha aadressina.

See näeb välja selline.

  1. Teenindusele saabus curl 10.96.45.152 päring:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  2. Teenus valib sihtkohaks ühe kolmest taskuaadressist:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  3. Liiklus suunatakse ümber kindlasse kausta:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

Kui teie rakendus koosneb esi- ja taustaprogrammist, on teil mõlema jaoks nii teenus kui ka juurutus.

Kui kasutajaliides esitab taustaprogrammile päringu, ei pea ta täpselt teadma, mitut kausta taustaprogramm teenindab: neid võib olla üks, kümme või sada.

Samuti ei tea frontend midagi taustaprogrammi teenindavate kaunade aadressidest.

Kui kasutajaliides esitab taustaprogrammile päringu, kasutab see taustateenuse IP-aadressi, mis ei muutu.

Siin on, kuidas see välja.

  1. Alla 1 taotleb sisemist taustakomponenti. Selle asemel, et valida taustaprogrammi jaoks konkreetne, esitab see teenusele päringu:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  2. Teenus valib sihtkoha aadressiks ühe taustamoodulitest:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  3. Liiklus liigub Pod 1-st Pod 5-sse, mille teenus valib:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  4. Alla 1 ei tea täpselt, kui palju alla 5-ga kauneid on teenuse taga peidus:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

Aga kuidas teenus päringuid täpselt levitab? Tundub, et kasutatakse ümberringi tasakaalustamist? Selgitame välja. 

Tasakaalustamine Kubernetese teenustes

Kubernetese teenuseid pole olemas. Teenuse jaoks, millele on määratud IP-aadress ja port, pole protsessi.

Saate seda kontrollida, logides sisse klastri mis tahes sõlme ja käivitades käsu netstat -ntlp.

Te ei leia isegi teenusele eraldatud IP-aadressi.

Teenuse IP-aadress asub juhtkihis, kontrolleris ja salvestatakse andmebaasi - jne. Sama aadressi kasutab teine ​​komponent - kube-puhverserver.
Kube-puhverserver võtab vastu kõigi teenuste IP-aadresside loendi ja loob iptablesi reeglite komplekti igas klastri sõlmes.

Need reeglid ütlevad: "Kui näeme teenuse IP-aadressi, peame muutma päringu sihtkoha aadressi ja saatma selle ühte kaustadest."

Teenuse IP-aadressi kasutatakse ainult sisenemispunktina ja seda ei teeninda ükski protsess, mis kuulab seda IP-aadressi ja porti.

Vaatame seda

  1. Vaatleme kolmest sõlmest koosnevat klastrit. Igal sõlmel on kaustad:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  2. Beežiks värvitud seotud kaunad on osa teenusest. Kuna teenust protsessina ei eksisteeri, kuvatakse see hallina:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  3. Esimene pod taotleb teenust ja peab minema ühte seotud kaustadest:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  4. Kuid teenust pole olemas, protsessi pole olemas. Kuidas see töötab?

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  5. Enne kui päring sõlmest lahkub, läbib see iptablesi reeglid:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  6. IPtablesi reeglid teavad, et teenust pole olemas, ja asendavad selle IP-aadressi ühe selle teenusega seotud kaustade IP-aadressidega:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  7. Päring saab sihtkoha aadressina kehtiva IP-aadressi ja seda töödeldakse tavapäraselt:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  8. Sõltuvalt võrgu topoloogiast jõuab päring lõpuks kausta:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

Kas iptables saab koormustasakaalu?

Ei, iptablesid kasutatakse filtreerimiseks ja need ei ole mõeldud tasakaalustamiseks.

Siiski on võimalik kirjutada reegleid, mis töötavad nagu pseudo-tasakaalustaja.

Ja just seda Kuberneteses rakendatakse.

Kui teil on kolm kausta, kirjutab kube-proxy järgmised reeglid:

  1. Valige esimene alam tõenäosusega 33%, vastasel juhul minge järgmise reegli juurde.
  2. Valige teine ​​50% tõenäosusega, vastasel juhul minge järgmise reegli juurde.
  3. Valige alt kolmas.

Selle süsteemi tulemusel valitakse iga kaust 33% tõenäosusega.

Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

Ja pole mingit garantiid, et Pod 2 valitakse järgmiseks pärast Pod 1.

Märkus: iptables kasutab juhusliku jaotusega statistilist moodulit. Seega põhineb tasakaalustusalgoritm juhuslikul valikul.

Nüüd, kui saate aru, kuidas teenused töötavad, vaatame huvitavamaid teenusestsenaariume.

Pikaealised ühendused Kubernetesis vaikimisi ei skaleerita

Iga HTTP-päring esiprogrammist taustaprogrammi teenindab eraldi TCP-ühendust, mis avatakse ja suletakse.

Kui kasutajaliides saadab taustaprogrammi 100 päringut sekundis, siis avatakse ja suletakse 100 erinevat TCP ühendust.

Saate vähendada päringu töötlemise aega ja koormust, avades ühe TCP-ühenduse ja kasutades seda kõigi järgnevate HTTP-päringute jaoks.

HTTP-protokollil on funktsioon, mida nimetatakse HTTP elushoidmiseks ehk ühenduse taaskasutamiseks. Sel juhul kasutatakse mitme HTTP-päringu ja vastuse saatmiseks ja vastuvõtmiseks ühte TCP-ühendust:

Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

See funktsioon ei ole vaikimisi lubatud: nii server kui ka klient peavad olema vastavalt konfigureeritud.

Seadistamine ise on lihtne ja juurdepääsetav enamiku programmeerimiskeelte ja keskkondade jaoks.

Siin on mõned lingid näidete juurde erinevates keeltes:

Mis juhtub, kui kasutame Kubernetese teenuses elushoidmist?
Oletame, et nii esi- kui ka taustaprogramm toetavad elushoidmist.

Meil on üks koopia esiosast ja kolm koopiat taustaprogrammist. Esiprogramm teeb esimese päringu ja avab TCP-ühenduse taustaprogrammiga. Päring jõuab teenuseni, sihtaadressiks valitakse üks taustamoodulitest. Taustaprogramm saadab vastuse ja esiprogramm võtab selle vastu.

Erinevalt tavapärasest olukorrast, kus TCP-ühendus suletakse pärast vastuse saamist, hoitakse see nüüd avatuna edasiste HTTP-päringute jaoks.

Mis juhtub, kui kasutajaliides saadab taustaprogrammile rohkem päringuid?

Nende päringute edastamiseks kasutatakse avatud TCP ühendust, kõik päringud suunatakse samasse taustaprogrammi, kuhu esimene päring läks.

Kas iptables ei peaks liiklust ümber jaotama?

Sel juhul mitte.

TCP-ühenduse loomisel läbib see iptablesi reegleid, mis valivad konkreetse taustaprogrammi, kuhu liiklus suunatakse.

Kuna kõik järgnevad päringud on juba avatud TCP-ühenduses, siis iptablesi reegleid enam ei kutsuta.

Vaatame, kuidas see välja näeb.

  1. Esimene pod saadab teenusele päringu:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  2. Sa juba tead, mis edasi saab. Teenust pole olemas, kuid päringu töötlemiseks on olemas iptablesi reeglid:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  3. Sihtkoha aadressiks valitakse üks taustamoodulitest:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  4. Taotlus jõuab kaunasse. Sel hetkel luuakse kahe kausta vahel püsiv TCP-ühendus:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  5. Kõik esimesest kaustast tulevad taotlused läbivad juba loodud ühenduse:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

Tulemuseks on kiirem reageerimisaeg ja suurem läbilaskevõime, kuid te kaotate võimaluse taustaprogrammi skaleerida.

Isegi kui teil on taustaprogrammis kaks pideva ühendusega kausta, liigub liiklus alati ühele neist.

Kas seda saab parandada?

Kuna Kubernetes ei tea, kuidas püsivaid ühendusi tasakaalustada, langeb see ülesanne teile.

Teenused on IP-aadresside ja portide kogum, mida nimetatakse lõpp-punktideks.

Teie rakendus saab teenusest hankida lõpp-punktide loendi ja otsustada, kuidas päringuid nende vahel jagada. Saate avada püsiva ühenduse iga taskuga ja tasakaalustada nende ühenduste vahelisi taotlusi, kasutades ümberringi.

Või taotlege rohkem keerulised tasakaalustamisalgoritmid.

Tasakaalustamise eest vastutav kliendipoolne kood peaks järgima järgmist loogikat:

  1. Hankige teenusest lõpp-punktide loend.
  2. Avage iga lõpp-punkti jaoks püsiühendus.
  3. Kui on vaja taotlus esitada, kasutage ühte avatud ühendustest.
  4. Kui loend muutub, värskendage regulaarselt lõpp-punktide loendit, looge uusi või sulgege vanad püsivad ühendused.

See näeb välja selline.

  1. Selle asemel, et esimene pakett saadaks teenusele päringu, saate päringuid tasakaalustada kliendi poolel:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  2. Peate kirjutama koodi, mis küsib, millised kaustad on teenuse osa:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  3. Kui loend on olemas, salvestage see kliendi poolele ja kasutage seda kabjadega ühenduse loomiseks:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

  4. Teie vastutate koormuse tasakaalustamise algoritmi eest:

    Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

Nüüd tekib küsimus: kas see probleem kehtib ainult HTTP elushoidmise kohta?

Kliendipoolne koormuse tasakaalustamine

HTTP ei ole ainus protokoll, mis saab kasutada püsivaid TCP-ühendusi.

Kui teie rakendus kasutab andmebaasi, ei avata TCP-ühendust iga kord, kui peate tegema päringu või hankima andmebaasist dokumendi. 

Selle asemel avatakse ja kasutatakse püsivat TCP-ühendust andmebaasiga.

Kui teie andmebaas on Kubernetesis juurutatud ja juurdepääs on pakutud teenusena, ilmnevad samad probleemid, mida kirjeldati eelmises jaotises.

Üks andmebaasi koopia laaditakse rohkem kui teised. Kube-puhverserver ja Kubernetes ei aita ühendusi tasakaalustada. Peate hoolitsema päringute tasakaalustamise eest oma andmebaasiga.

Olenevalt sellest, millist teeki andmebaasiga ühenduse loomiseks kasutate, võib teil olla selle probleemi lahendamiseks erinevaid võimalusi.

Allpool on näide MySQL-i andmebaasiklastrile juurdepääsust saidilt 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

On palju teisi protokolle, mis kasutavad püsivaid TCP-ühendusi:

  • WebSockets ja turvatud WebSockets
  • HTTP / 2
  • gRPC
  • RSocketid
  • AMQP

Peaksite enamiku nendest protokollidest juba tuttav olema.

Aga kui need protokollid on nii populaarsed, siis miks pole standardiseeritud tasakaalustamislahendust? Miks on vaja kliendiloogikat muuta? Kas on olemas natiivne Kubernetese lahendus?

Kube-puhverserver ja iptables on loodud katma Kubernetesis juurutamisel kõige levinumad kasutusjuhtumid. See on mugavuse huvides.

Kui kasutate veebiteenust, mis paljastab REST API, on teil õnne – sel juhul püsivaid TCP-ühendusi ei kasutata, võite kasutada mis tahes Kubernetese teenust.

Kuid kui hakkate kasutama püsivaid TCP-ühendusi, peate välja mõtlema, kuidas koormust taustaprogrammide vahel ühtlaselt jaotada. Kubernetes ei sisalda selleks puhuks valmislahendusi.

Siiski on kindlasti võimalusi, mis võivad aidata.

Pikaealiste sidemete tasakaalustamine Kubernetes

Kubernetesis on nelja tüüpi teenuseid:

  1. KlastriIP
  2. Sõlme port
  3. Koormuse tasakaalustaja
  4. Peata

Esimesed kolm teenust põhinevad virtuaalsel IP-aadressil, mida kube-puhverserver kasutab iptablesi reeglite koostamiseks. Kuid kõigi teenuste põhialus on peata teenus.

Peata teenusel ei ole sellega seotud ühtegi IP-aadressi ja see pakub ainult mehhanismi IP-aadresside loendi ja sellega seotud kaustade (otspunktide) portide hankimiseks.

Kõik teenused põhinevad peata teenusel.

ClusterIP teenus on peata teenus, millel on mõned täiendused: 

  1. Halduskiht määrab sellele IP-aadressi.
  2. Kube-puhverserver genereerib vajalikud iptablesi reeglid.

Nii saate kube-puhverserverit ignoreerida ja oma rakenduse koormuse tasakaalustamiseks kasutada otse peata teenusest saadud lõpp-punktide loendit.

Kuid kuidas saame lisada sarnase loogika kõigile klastris juurutatud rakendustele?

Kui teie rakendus on juba juurutatud, võib see ülesanne tunduda võimatu. Siiski on alternatiivne võimalus.

Service Mesh aitab teid

Tõenäoliselt olete juba märganud, et kliendipoolne koormuse tasakaalustamise strateegia on üsna tavaline.

Kui rakendus käivitub, siis:

  1. Hangi teenusest IP-aadresside loendi.
  2. Avab ja hooldab ühendusbasseini.
  3. Värskendab perioodiliselt basseini lõpp-punkte lisades või eemaldades.

Kui rakendus soovib taotlust esitada, siis:

  1. Valib saadaoleva ühenduse, kasutades mingit loogikat (nt round-robin).
  2. Täidab taotluse.

Need sammud toimivad nii WebSocketsi, gRPC kui ka AMQP ühenduste puhul.

Saate selle loogika eraldada eraldi teegiks ja kasutada seda oma rakendustes.

Selle asemel saate siiski kasutada teenindusvõrke, nagu Istio või Linkerd.

Service Mesh täiendab teie rakendust protsessiga, mis:

  1. Otsib automaatselt teenuse IP-aadresse.
  2. Testib ühendusi, nagu WebSockets ja gRPC.
  3. Tasakaalustab päringud õige protokolli abil.

Service Mesh aitab hallata liiklust klastri sees, kuid see on üsna ressursimahukas. Muud võimalused on kasutada kolmandate osapoolte teeke, nagu Netflix Ribbon, või programmeeritavaid puhverservereid, nagu Envoy.

Mis juhtub, kui te eirate tasakaalustamise probleeme?

Saate koormuse tasakaalustamist mitte kasutada ja siiski ei märka muudatusi. Vaatame mõnda tööstsenaariumi.

Kui teil on rohkem kliente kui servereid, pole see nii suur probleem.

Oletame, et on viis klienti, mis loovad ühenduse kahe serveriga. Isegi kui tasakaalustamist pole, kasutatakse mõlemat serverit:

Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

Ühendused ei pruugi olla ühtlaselt jaotunud: võib-olla neli klienti on ühendatud sama serveriga, kuid on suur võimalus, et mõlemat serverit kasutatakse.

Probleemsem on vastupidine stsenaarium.

Kui teil on vähem kliente ja rohkem servereid, võivad teie ressursid olla alakasutatud ja ilmneda potentsiaalne kitsaskoht.

Oletame, et seal on kaks klienti ja viis serverit. Parimal juhul tekib kaks püsiühendust kahe serveriga viiest.

Ülejäänud serverid on jõude:

Koormuse tasakaalustamine ja pikaealiste ühenduste skaleerimine Kubernetesis

Kui need kaks serverit ei saa hakkama kliendi taotlustega, ei aita horisontaalne skaleerimine.

Järeldus

Kubernetese teenused on loodud töötama enamiku standardsete veebirakenduste stsenaariumide puhul.

Kui aga hakkate töötama püsivaid TCP-ühendusi kasutavate rakendusprotokollidega, nagu andmebaasid, gRPC või WebSockets, ei ole teenused enam sobivad. Kubernetes ei paku püsivate TCP-ühenduste tasakaalustamiseks sisemisi mehhanisme.

See tähendab, et peate rakendusi kirjutama kliendipoolset tasakaalustamist silmas pidades.

Tõlke on koostanud meeskond Kubernetes aaS saidilt Mail.ru.

Mida muud selle teema kohta lugeda:

  1. Kolm automaatse skaleerimise taset Kubernetes ja kuidas neid tõhusalt kasutada
  2. Kubernetes piraatluse vaimus koos rakenduse malliga.
  3. Meie telegrammi kanal digitaalse transformatsiooni kohta.

Allikas: www.habr.com

Lisa kommentaar