Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes
Šis raksts palīdzēs jums saprast, kā Kubernetes darbojas slodzes līdzsvarošana, kas notiek, mērogojot ilgstošus savienojumus un kāpēc jums vajadzētu apsvērt klienta puses līdzsvarošanu, ja izmantojat HTTP/2, gRPC, RSockets, AMQP vai citus ilgstošas ​​darbības protokolus. . 

Mazliet par to, kā notiek satiksmes pārdale Kubernetes 

Kubernetes nodrošina divas ērtas abstrakcijas lietojumprogrammu izvietošanai: pakalpojumi un izvietošana.

Izvietojumos ir aprakstīts, kā un cik daudzām jūsu lietojumprogrammas kopijām ir jādarbojas jebkurā laikā. Katra lietojumprogramma tiek izvietota kā Pod, un tai tiek piešķirta IP adrese.

Pakalpojumi pēc funkcijām ir līdzīgi slodzes līdzsvarotājam. Tie ir paredzēti, lai sadalītu trafiku vairākos apvidos.

Paskatīsimies, kā tas izskatās.

  1. Zemāk esošajā diagrammā var redzēt trīs vienas un tās pašas lietojumprogrammas un slodzes līdzsvarotāja gadījumus:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  2. Slodzes balansētāju sauc par pakalpojumu, un tam tiek piešķirta IP adrese. Jebkurš ienākošais pieprasījums tiek novirzīts uz vienu no aplikācijām:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  3. Izvietošanas scenārijs nosaka lietojumprogrammas gadījumu skaitu. Jums gandrīz nekad nebūs jāizvēršas tieši zem:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  4. Katram podam ir piešķirta sava IP adrese:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

Ir lietderīgi uzskatīt pakalpojumus kā IP adrešu kolekciju. Katru reizi, kad piekļūstat pakalpojumam, viena no IP adresēm tiek atlasīta no saraksta un tiek izmantota kā galamērķa adrese.

Tas izskatās šādi.

  1. Dienestā saņemts čokurošanās 10.96.45.152 pieprasījums:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  2. Pakalpojums kā galamērķi izvēlas vienu no trim podadresēm:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  3. Satiksme tiek novirzīta uz noteiktu aplikumu:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

Ja jūsu lietojumprogramma sastāv no priekšgala un aizmugursistēmas, jums būs gan pakalpojums, gan izvietošana.

Kad priekšgals iesniedz pieprasījumu aizmugursistēmai, tai nav precīzi jāzina, cik aplikāciju aizmugursistēma apkalpo: var būt viens, desmit vai simts.

Tāpat priekšgals neko nezina par aizmugursistēmu apkalpojošo podiņu adresēm.

Kad priekšgals veic pieprasījumu aizmugursistēmai, tā izmanto aizmugursistēmas pakalpojuma IP adresi, kas nemainās.

Tas izskatās šādi.

  1. Zem 1 pieprasa iekšējo aizmugursistēmas komponentu. Tā vietā, lai aizmugursistēmai atlasītu konkrētu, tas pakalpojumam veic pieprasījumu:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  2. Pakalpojums kā galamērķa adresi atlasa vienu no aizmugursistēmas podiem:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  3. Satiksme notiek no Pod 1 uz Pod 5, ko izvēlējies pakalpojums:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  4. Jaunāks par 1 — precīzi nezina, cik daudz podiņu, piemēram, zem 5, ir paslēpti aiz pakalpojuma:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

Bet kā tieši pakalpojums izplata pieprasījumus? Šķiet, ka tiek izmantota apļveida balansēšana? Izdomāsim. 

Balansēšana Kubernetes pakalpojumos

Kubernetes pakalpojumi nepastāv. Pakalpojumam, kuram ir piešķirta IP adrese un ports, nav procesa.

To var pārbaudīt, piesakoties jebkurā klastera mezglā un palaižot komandu netstat -ntlp.

Jūs pat nevarēsit atrast pakalpojumam piešķirto IP adresi.

Pakalpojuma IP adrese atrodas vadības slānī, kontrolierī un ierakstīta datu bāzē - utt. To pašu adresi izmanto cits komponents - kube-proxy.
Kube starpniekserveris saņem visu pakalpojumu IP adrešu sarakstu un ģenerē iptables kārtulu kopu katrā klastera mezglā.

Šajos noteikumos teikts: "Ja mēs redzam pakalpojuma IP adresi, mums ir jāmaina pieprasījuma galamērķa adrese un jānosūta tā uz vienu no podiem."

Pakalpojuma IP adrese tiek izmantota tikai kā ieejas punkts, un to neapkalpo neviens process, kas klausās šo IP adresi un portu.

Apskatīsim šo

  1. Apsveriet trīs mezglu kopu. Katram mezglam ir podi:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  2. Piesietas pākstis, kas krāsotas bēšā krāsā, ir daļa no pakalpojuma. Tā kā pakalpojums neeksistē kā process, tas tiek parādīts pelēkā krāsā:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  3. Pirmais aplikums pieprasa pakalpojumu, un tam ir jāiet uz kādu no saistītajiem aplikatoriem:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  4. Bet pakalpojums neeksistē, process neeksistē. Kā tas darbojas?

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  5. Pirms pieprasījums atstāj mezglu, tas iziet cauri iptables noteikumiem:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  6. Iptables noteikumi zina, ka pakalpojums neeksistē, un aizstāj tā IP adresi ar vienu no ar šo pakalpojumu saistīto podziņu IP adresēm:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  7. Pieprasījums saņem derīgu IP adresi kā galamērķa adresi un tiek apstrādāts kā parasti:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  8. Atkarībā no tīkla topoloģijas pieprasījums galu galā sasniedz podziņu:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

Vai iptables var slodzes līdzsvaru?

Nē, iptables tiek izmantotas filtrēšanai, un tās nav paredzētas balansēšanai.

Tomēr ir iespējams uzrakstīt noteikumu kopumu, kas darbojas līdzīgi pseidobalansētājs.

Un tas ir tieši tas, kas tiek īstenots Kubernetes.

Ja jums ir trīs podi, kube-proxy ierakstīs šādus noteikumus:

  1. Atlasiet pirmo apakšdaļu ar varbūtību 33%, pretējā gadījumā pārejiet uz nākamo noteikumu.
  2. Izvēlieties otro ar 50% varbūtību, pretējā gadījumā pārejiet uz nākamo noteikumu.
  3. Zemāk atlasiet trešo.

Šīs sistēmas rezultātā katrs pods tiek atlasīts ar 33% varbūtību.

Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

Un nav garantijas, ka Pod 2 tiks izvēlēts nākamais pēc Pod 1.

Piezīme: iptables izmanto statistikas moduli ar nejaušu sadalījumu. Tādējādi balansēšanas algoritms ir balstīts uz nejaušu atlasi.

Tagad, kad esat sapratis, kā pakalpojumi darbojas, apskatīsim interesantākus pakalpojumu scenārijus.

Ilgstoši savienojumi pakalpojumā Kubernetes pēc noklusējuma netiek mērogoti

Katru HTTP pieprasījumu no priekšgala uz aizmuguri apkalpo atsevišķs TCP savienojums, kas tiek atvērts un aizvērts.

Ja priekšgals nosūta 100 pieprasījumus sekundē uz aizmuguri, tad tiek atvērti un aizvērti 100 dažādi TCP savienojumi.

Varat samazināt pieprasījumu apstrādes laiku un slodzi, atverot vienu TCP savienojumu un izmantojot to visiem nākamajiem HTTP pieprasījumiem.

HTTP protokolam ir funkcija, ko sauc par HTTP saglabāšanu vai savienojuma atkārtotu izmantošanu. Šajā gadījumā vienu TCP savienojumu izmanto, lai nosūtītu un saņemtu vairākus HTTP pieprasījumus un atbildes:

Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

Šī funkcija pēc noklusējuma nav iespējota: attiecīgi jākonfigurē gan serveris, gan klients.

Pati iestatīšana ir vienkārša un pieejama lielākajai daļai programmēšanas valodu un vidi.

Šeit ir dažas saites uz piemēriem dažādās valodās:

Kas notiek, ja Kubernetes pakalpojumā izmantosim saglabāšanu dzīvajā?
Pieņemsim, ka gan priekšgals, gan aizmugure atbalsta saglabāšanu dzīvā.

Mums ir viena priekšgala kopija un trīs aizmugursistēmas kopijas. Priekšgals veic pirmo pieprasījumu un atver TCP savienojumu ar aizmuguri. Pieprasījums sasniedz pakalpojumu, viens no aizmugursistēmas podiem tiek atlasīts kā mērķa adrese. Aizmugursistēma nosūta atbildi, un priekšgals to saņem.

Atšķirībā no parastās situācijas, kad TCP savienojums tiek aizvērts pēc atbildes saņemšanas, tagad tas ir atvērts turpmākiem HTTP pieprasījumiem.

Kas notiek, ja priekšgals nosūta vairāk pieprasījumu aizmugursistēmai?

Lai pārsūtītu šos pieprasījumus, tiks izmantots atvērts TCP savienojums, visi pieprasījumi tiks nosūtīti uz to pašu aizmugursistēmu, kur tika nosūtīts pirmais pieprasījums.

Vai iptables nevajadzētu pārdalīt trafiku?

Ne šajā gadījumā.

Kad tiek izveidots TCP savienojums, tas iziet cauri iptables kārtulām, kas atlasa noteiktu aizmugursistēmu, uz kuru tiks novirzīts trafiks.

Tā kā visi nākamie pieprasījumi ir jau atvērtā TCP savienojumā, iptables noteikumi vairs netiek izsaukti.

Paskatīsimies, kā tas izskatās.

  1. Pirmais pods nosūta pakalpojumam pieprasījumu:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  2. Jūs jau zināt, kas notiks tālāk. Pakalpojums neeksistē, taču ir iptables noteikumi, kas apstrādās pieprasījumu:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  3. Viens no aizmugursistēmas podiem tiks atlasīts kā galamērķa adrese:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  4. Pieprasījums sasniedz podziņu. Šajā brīdī starp diviem podiem tiks izveidots pastāvīgs TCP savienojums:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  5. Jebkurš nākamais pieprasījums no pirmā podziņa tiks veikts, izmantojot jau izveidoto savienojumu:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

Rezultāts ir ātrāks reakcijas laiks un lielāka caurlaidspēja, taču jūs zaudējat iespēju mērogot aizmugursistēmu.

Pat ja jums ir divi podi aizmugursistēmā, ar pastāvīgu savienojumu, satiksme vienmēr tiks novirzīta uz vienu no tiem.

Vai to var labot?

Tā kā Kubernetes nezina, kā līdzsvarot pastāvīgus savienojumus, šis uzdevums ir jums.

Pakalpojumi ir IP adrešu un portu kolekcija, ko sauc par galapunktiem.

Jūsu lietojumprogramma var iegūt galapunktu sarakstu no pakalpojuma un izlemt, kā sadalīt pieprasījumus starp tiem. Varat atvērt pastāvīgu savienojumu ar katru podziņu un līdzsvarot pieprasījumus starp šiem savienojumiem, izmantojot apļveida metodi.

Vai arī piesakieties vairāk sarežģīti balansēšanas algoritmi.

Klienta puses kodam, kas ir atbildīgs par līdzsvarošanu, ir jāievēro šāda loģika:

  1. Iegūstiet galapunktu sarakstu no pakalpojuma.
  2. Atveriet pastāvīgu savienojumu katram galapunktam.
  3. Kad ir nepieciešams pieprasījums, izmantojiet kādu no atvērtajiem savienojumiem.
  4. Regulāri atjauniniet galapunktu sarakstu, izveidojiet jaunus vai aizveriet vecos pastāvīgos savienojumus, ja saraksts mainās.

Tā tas izskatīsies.

  1. Tā vietā, lai pirmais pods nosūtītu pieprasījumu pakalpojumam, varat līdzsvarot pieprasījumus klienta pusē:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  2. Jums ir jāraksta kods, kas jautā, kuri podi ir daļa no pakalpojuma:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  3. Kad saraksts ir izveidots, saglabājiet to klienta pusē un izmantojiet to, lai izveidotu savienojumu ar podiem:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

  4. Jūs esat atbildīgs par slodzes līdzsvarošanas algoritmu:

    Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

Tagad rodas jautājums: vai šī problēma attiecas tikai uz HTTP saglabāšanu?

Klienta puses slodzes balansēšana

HTTP nav vienīgais protokols, kas var izmantot pastāvīgus TCP savienojumus.

Ja jūsu lietojumprogramma izmanto datu bāzi, TCP savienojums netiek atvērts katru reizi, kad jums ir nepieciešams veikt pieprasījumu vai izgūt dokumentu no datu bāzes. 

Tā vietā tiek atvērts un izmantots pastāvīgs TCP savienojums ar datu bāzi.

Ja jūsu datu bāze ir izvietota Kubernetes un piekļuve tiek nodrošināta kā pakalpojums, jūs saskarsities ar tām pašām problēmām, kas aprakstītas iepriekšējā sadaļā.

Viena datu bāzes kopija būs vairāk ielādēta nekā pārējās. Kube-proxy un Kubernetes nepalīdzēs līdzsvarot savienojumus. Jums ir jārūpējas, lai vaicājumi būtu līdzsvaroti jūsu datubāzē.

Atkarībā no tā, kuru bibliotēku izmantojat, lai izveidotu savienojumu ar datu bāzi, šīs problēmas risināšanai var būt dažādas iespējas.

Tālāk ir sniegts piemērs, kā piekļūt MySQL datu bāzes klasterim no 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

Ir daudzi citi protokoli, kas izmanto pastāvīgus TCP savienojumus:

  • WebSockets un nodrošinātās WebSockets
  • HTTP / 2
  • grRPC
  • RSockets
  • AMQP

Jums jau vajadzētu būt pazīstamam ar lielāko daļu šo protokolu.

Bet, ja šie protokoli ir tik populāri, kāpēc nav standartizēta balansēšanas risinājuma? Kāpēc ir jāmaina klienta loģika? Vai ir vietējais Kubernetes risinājums?

Kube starpniekserveris un iptables ir paredzēti, lai aptvertu visbiežāk sastopamos lietošanas gadījumus, izvietojot Kubernetes. Tas ir ērtībai.

Ja izmantojat tīmekļa pakalpojumu, kas atklāj REST API, jums ir paveicies — šajā gadījumā netiek izmantoti pastāvīgi TCP savienojumi, varat izmantot jebkuru Kubernetes pakalpojumu.

Bet, kad sākat izmantot pastāvīgus TCP savienojumus, jums būs jāizdomā, kā vienmērīgi sadalīt slodzi starp aizmugursistēmām. Kubernetes nesatur gatavus risinājumus šim gadījumam.

Tomēr noteikti ir iespējas, kas var palīdzēt.

Līdzsvarojot ilgstošus sakarus Kubernetes

Kubernetes ir četri pakalpojumu veidi:

  1. ClusterIP
  2. Mezglu ports
  3. LoadBalancer
  4. Bez galvas

Pirmie trīs pakalpojumi darbojas, pamatojoties uz virtuālo IP adresi, ko izmanto kube-proxy, lai izveidotu iptables noteikumus. Bet visu pakalpojumu pamats ir bezgalvīgs pakalpojums.

Pakalpojumam bez galvas nav saistīta neviena IP adrese, un tas nodrošina tikai mehānismu IP adrešu un ar to saistīto podziņu (galapunktu) portu saraksta izgūšanai.

Visi pakalpojumi ir balstīti uz pakalpojumu bez galvas.

ClusterIP pakalpojums ir bezgalīgs pakalpojums ar dažiem papildinājumiem: 

  1. Pārvaldības slānis tam piešķir IP adresi.
  2. Kube-proxy ģenerē nepieciešamos iptables noteikumus.

Tādā veidā jūs varat ignorēt kube-proxy un tieši izmantot galapunktu sarakstu, kas iegūts no pakalpojuma bez galvas, lai līdzsvarotu lietojumprogrammu.

Bet kā mēs varam pievienot līdzīgu loģiku visām klasterī izvietotajām lietojumprogrammām?

Ja jūsu lietojumprogramma jau ir izvietota, šis uzdevums var šķist neiespējams. Tomēr ir alternatīva iespēja.

Service Mesh jums palīdzēs

Jūs droši vien jau esat pamanījis, ka klienta puses slodzes līdzsvarošanas stratēģija ir diezgan standarta.

Kad lietojumprogramma tiek startēta, tā:

  1. Iegūst IP adrešu sarakstu no pakalpojuma.
  2. Atver un uztur savienojumu baseinu.
  3. Periodiski atjaunina pūlu, pievienojot vai noņemot galapunktus.

Kad lietojumprogramma vēlas iesniegt pieprasījumu, tā:

  1. Atlasa pieejamo savienojumu, izmantojot kādu loģiku (piem., round-robin).
  2. Izpilda pieprasījumu.

Šīs darbības darbojas gan WebSockets, gan gRPC un AMQP savienojumiem.

Varat sadalīt šo loģiku atsevišķā bibliotēkā un izmantot to savās lietojumprogrammās.

Tomēr tā vietā varat izmantot pakalpojumu tīklus, piemēram, Istio vai Linkerd.

Service Mesh papildina jūsu lietojumprogrammu ar procesu, kas:

  1. Automātiski meklē pakalpojumu IP adreses.
  2. Pārbauda savienojumus, piemēram, WebSockets un gRPC.
  3. Līdzsvaro pieprasījumus, izmantojot pareizo protokolu.

Service Mesh palīdz pārvaldīt trafiku klasterī, taču tas ir diezgan resursietilpīgs. Citas iespējas ir izmantot trešo pušu bibliotēkas, piemēram, Netflix lenti, vai programmējamus starpniekserverus, piemēram, Envoy.

Kas notiek, ja ignorējat līdzsvarošanas problēmas?

Varat izvēlēties neizmantot slodzes līdzsvarošanu un joprojām nepamanīt nekādas izmaiņas. Apskatīsim dažus darba scenārijus.

Ja jums ir vairāk klientu nekā serveru, tā nav tik liela problēma.

Pieņemsim, ka ir pieci klienti, kas savienojas ar diviem serveriem. Pat ja nav balansēšanas, tiks izmantoti abi serveri:

Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

Savienojumi var nebūt vienmērīgi sadalīti: iespējams, četri klienti ir savienoti ar vienu un to pašu serveri, taču pastāv liela iespēja, ka tiks izmantoti abi serveri.

Problemātiskāks ir pretējais scenārijs.

Ja jums ir mazāk klientu un vairāk serveru, jūsu resursi var būt nepietiekami izmantoti un parādīsies potenciāls sastrēgums.

Pieņemsim, ka ir divi klienti un pieci serveri. Labākajā gadījumā būs divi pastāvīgi savienojumi ar diviem serveriem no pieciem.

Atlikušie serveri būs dīkstāvē:

Slodzes līdzsvarošana un ilgtermiņa savienojumu mērogošana Kubernetes

Ja šie divi serveri nevar apstrādāt klientu pieprasījumus, horizontālā mērogošana nepalīdzēs.

Secinājums

Kubernetes pakalpojumi ir paredzēti darbam lielākajā daļā standarta tīmekļa lietojumprogrammu scenāriju.

Tomēr, tiklīdz sākat strādāt ar lietojumprogrammu protokoliem, kas izmanto pastāvīgus TCP savienojumus, piemēram, datu bāzes, gRPC vai WebSockets, pakalpojumi vairs nav piemēroti. Kubernetes nenodrošina iekšējos mehānismus pastāvīgu TCP savienojumu līdzsvarošanai.

Tas nozīmē, ka jums ir jāraksta lietojumprogrammas, paturot prātā klienta puses līdzsvarošanu.

Tulkojumu sagatavojusi komanda Kubernetes aaS no Mail.ru.

Ko vēl lasīt par tēmu:

  1. Trīs automātiskās mērogošanas līmeņi programmā Kubernetes un to efektīva izmantošana
  2. Kubernetes pirātisma garā ar veidni ieviešanai.
  3. Mūsu telegrammas kanāls par digitālo transformāciju.

Avots: www.habr.com

Pievieno komentāru