Konteineriai, mikroservisai ir aptarnavimo tinkleliai

Internete krūva straipsniai о aptarnavimo tinklelis (serviso tinklelis), o štai dar vienas. Sveika! Bet kodėl? Tada noriu išreikšti savo nuomonę, kad būtų buvę geriau, jei paslaugų tinkleliai būtų atsiradę prieš 10 metų, prieš atsirandant konteinerių platformoms, tokioms kaip Docker ir Kubernetes. Nesakau, kad mano požiūris geresnis ar blogesnis nei kitų, bet kadangi tarnybiniai tinkleliai yra gana sudėtingi gyvūnai, juos geriau suprasti padės keli požiūriai.

Kalbėsiu apie „dotCloud“ platformą, kuri buvo sukurta remiantis daugiau nei šimtu mikro paslaugų ir palaikė tūkstančius konteinerinių programų. Paaiškinsiu, su kokiais iššūkiais susidūrėme kurdami ir paleisdami, ir kaip paslaugų tinkleliai galėtų (arba negalėjo) padėti.

„DotCloud“ istorija

Esu rašęs apie „dotCloud“ istoriją ir šios platformos architektūros pasirinkimus, bet apie tinklo sluoksnį daug nekalbėjau. Jei nenorite pasinerti į skaitymą paskutinis straipsnis Trumpai apie „dotCloud“ pateikiame esmę: tai „PaaS“ platforma kaip paslauga, leidžianti klientams paleisti įvairias programas (Java, PHP, Python...), palaikanti daugybę duomenų. paslaugas (MongoDB, MySQL, Redis...) ir darbo eigą, pvz., Heroku: įkeliate savo kodą į platformą, ji sukuria konteinerio vaizdus ir juos diegia.

Aš jums pasakysiu, kaip srautas buvo nukreiptas į „dotCloud“ platformą. Ne todėl, kad tai buvo ypač šaunu (nors sistema savo laiku veikė puikiai!), o pirmiausia dėl to, kad su moderniais įrankiais tokį dizainą per trumpą laiką gali lengvai įgyvendinti kukli komanda, jei reikia būdo nukreipti eismą tarp būrio. mikropaslaugų ar daugybės programų. Tokiu būdu galite palyginti galimybes: kas atsitiks, jei viską sukursite patys arba naudosite esamą paslaugų tinklelį. Standartinis pasirinkimas – pasigaminti patiems arba nusipirkti.

Priglobtų programų srauto nukreipimas

„DotCloud“ programos gali atskleisti HTTP ir TCP galinius taškus.

HTTP galutiniai taškai dinamiškai pridedamas prie apkrovos balansavimo grupės konfigūracijos Hipache. Tai panašu į tai, ką ištekliai daro šiandien Įėjimas „Kubernetes“ ir apkrovos balansavimo priemonė Traefik.

Klientai prisijungia prie HTTP galinių taškų per atitinkamus domenus, jei domeno pavadinimas nurodo į dotCloud apkrovos balansavimo priemones. Nieko ypatingo.

TCP galutiniai taškai susietas su prievado numeriu, kuris per aplinkos kintamuosius perduodamas visiems tos dėklo konteineriams.

Klientai gali prisijungti prie TCP galinių taškų naudodami atitinkamą pagrindinio kompiuterio pavadinimą (pvz., gateway-X.dotcloud.com) ir prievado numerį.

Šis pagrindinio kompiuterio pavadinimas yra „nats“ serverio klasteris (nesusijęs su NATS), kuris nukreips gaunamus TCP ryšius į tinkamą konteinerį (arba, jei teikiamos apkrovos subalansuotos paslaugos, į tinkamus konteinerius).

Jei esate susipažinę su Kubernetes, tai tikriausiai primins apie Paslaugas „NodePort“.

„DotCloud“ platformoje nebuvo lygiaverčių paslaugų „ClusterIP“: Paprastumo dėlei paslaugos buvo pasiekiamos vienodai tiek iš platformos vidaus, tiek iš išorės.

Viskas buvo organizuota gana paprastai: pradiniai HTTP ir TCP maršruto parinkimo tinklų diegimai tikriausiai buvo tik keli šimtai Python eilučių. Paprasti (sakyčiau naivūs) algoritmai, kurie tobulėjo platformai augant ir atsirandant papildomiems reikalavimams.

Nereikėjo didelio esamo kodo pertvarkymo. Visų pirma, 12 faktorių programos gali tiesiogiai naudoti adresą, gautą per aplinkos kintamuosius.

Kuo tai skiriasi nuo šiuolaikinių paslaugų tinklelio?

Ribotas matomumas. Mes neturėjome jokios TCP maršruto parinkimo tinklelio metrikos. Kalbant apie HTTP maršruto parinkimą, vėlesnėse versijose buvo pateikta išsami HTTP metrika su klaidų kodais ir atsako laiku, tačiau šiuolaikiniai paslaugų tinkleliai yra dar toliau, suteikdami integraciją su metrikų rinkimo sistemomis, pvz., Prometheus.

Matomumas svarbus ne tik eksploataciniu požiūriu (kad būtų lengviau šalinti triktis), bet ir išleidžiant naujas funkcijas. Tai apie saugumą mėlynai žalias dislokavimas и Kanarų dislokavimas.

Maršruto efektyvumas taip pat yra ribotas. „DotCloud“ maršruto tinkle visas srautas turėjo eiti per tam skirtų maršruto mazgų grupę. Tai reiškė, kad buvo galima peržengti kelias AZ (prieinamumo zonos) ribas ir žymiai padidinti delsą. Prisimenu trikčių šalinimo kodą, kuris kiekviename puslapyje pateikdavo daugiau nei šimtą SQL užklausų ir kiekvienai užklausai atidarydavo naują ryšį su SQL serveriu. Kai veikia lokaliai, puslapis įkeliamas akimirksniu, tačiau „dotCloud“ įkeliamas kelias sekundes, nes kiekvienas TCP ryšys (ir vėlesnė SQL užklausa) užtrunka dešimtis milisekundžių. Šiuo konkrečiu atveju nuolatiniai ryšiai išsprendė problemą.

Šiuolaikiniai aptarnavimo tinkleliai geriau sprendžia tokias problemas. Pirmiausia jie patikrina, ar ryšiai nukreipti šaltinyje. Loginė eiga yra tokia pati: клиент → меш → сервис, bet dabar tinklelis veikia lokaliai, o ne nuotoliniuose mazguose, todėl ryšys клиент → меш yra vietinis ir labai greitas (mikrosekundės, o ne milisekundės).

Šiuolaikiniai paslaugų tinkleliai taip pat įgyvendina išmanesnius apkrovos balansavimo algoritmus. Stebėdami užpakalinių sistemų būklę, jos gali siųsti daugiau srauto į greitesnes pagrindines programas, todėl pagerėja bendras našumas.

saugumas irgi geriau. „DotCloud“ maršruto parinkimo tinklelis veikė tik „EC2 Classic“ ir nešifravo srauto (remiantis prielaida, kad jei kas nors sugebėjo užuosti EC2 tinklo srautą, jūs jau turėjote didelių problemų). Šiuolaikinės paslaugos tinkleliai skaidriai apsaugo visą mūsų srautą, pavyzdžiui, su abipusiu TLS autentifikavimu ir vėlesniu šifravimu.

Srauto nukreipimas platformos paslaugoms

Gerai, aptarėme srautą tarp programų, bet kaip apie pačią „dotCloud“ platformą?

Pati platforma susidėjo iš maždaug šimto mikro paslaugų, atsakingų už įvairias funkcijas. Kai kurie priėmė kitų užklausas, o kai kurie buvo foniniai darbuotojai, prisijungę prie kitų paslaugų, bet patys nepriėmė prisijungimų. Bet kokiu atveju kiekviena tarnyba turi žinoti adresų, prie kurių reikia prisijungti, galinius taškus.

Daugelis aukšto lygio paslaugų gali naudoti aukščiau aprašytą maršruto tinklelį. Tiesą sakant, daugelis iš daugiau nei šimto „dotCloud“ mikro paslaugų buvo įdiegtos kaip įprastos programos pačioje „dotCloud“ platformoje. Tačiau nedaugeliui žemo lygio paslaugų (ypač tų, kurios įdiegia šį maršruto parinkimo tinklelį) reikėjo kažko paprastesnio, su mažiau priklausomybių (kadangi jos negalėjo pasikliauti savimi – sena gera vištienos ir kiaušinių problema).

Šios žemo lygio, itin svarbios paslaugos buvo įdiegtos naudojant konteinerius tiesiai keliuose pagrindiniuose mazguose. Šiuo atveju nebuvo naudojamos standartinės platformos paslaugos: linkeris, planuotojas ir bėgikas. Jei norite palyginti su šiuolaikinėmis konteinerių platformomis, tai panašu į valdymo plokštumos valdymą docker run tiesiogiai mazguose, o ne deleguoti užduotį Kubernetes. Tai gana panaši koncepcija statiniai moduliai (pods), kurią naudoja kubeadm arba bootkube paleidžiant atskirą klasterį.

Šios paslaugos buvo atskleistos paprastai ir neapdorotai: YAML faile buvo išvardyti jų vardai ir adresai; ir kiekvienas klientas turėjo pasiimti šio YAML failo kopiją diegti.

Viena vertus, jis itin patikimas, nes nereikalauja išorinės raktų/reikšmių saugyklos, pvz., Zookeeper, palaikymo (atminkite, etcd arba Consul tuo metu dar nebuvo). Kita vertus, tai apsunkino paslaugų perkėlimą. Kiekvieną kartą, kai buvo atliktas judėjimas, visi klientai gaus atnaujintą YAML failą (ir galbūt paleis iš naujo). Nelabai patogu!

Vėliau pradėjome diegti naują schemą, kai kiekvienas klientas prisijungdavo prie vietinio tarpinio serverio. Vietoj adreso ir prievado jam tereikia žinoti paslaugos prievado numerį ir prisijungti per localhost. Vietinis tarpinis serveris tvarko šį ryšį ir persiunčia jį į tikrąjį serverį. Dabar, kai perkeliate užpakalinę programą į kitą kompiuterį arba keičiate mastelį, užuot atnaujinę visus klientus, tereikia atnaujinti visus šiuos vietinius tarpinius serverius; ir perkrauti nebereikia.

(Taip pat buvo planuojama įtraukti srautą į TLS ryšius ir įdėti kitą tarpinį serverį į priėmimo pusę, taip pat patikrinti TLS sertifikatus nedalyvaujant priimančiajai tarnybai, kuri sukonfigūruota priimti ryšius tik localhost. Daugiau apie tai vėliau).

Tai labai panašu į „SmartStack“ iš „Airbnb“, tačiau reikšmingas skirtumas yra tas, kad „SmartStack“ yra įdiegtas ir įdiegtas gamyboje, o „dotCloud“ vidinė maršruto parinkimo sistema buvo sustabdyta, kai „dotCloud“ tapo „Docker“.

Aš asmeniškai laikau „SmartStack“ vienu iš tokių sistemų kaip „Istio“, „Linkerd“ ir „Consul Connect“ pirmtakų, nes visos jos laikosi to paties modelio:

  • Paleiskite tarpinį serverį kiekviename mazge.
  • Klientai prisijungia prie tarpinio serverio.
  • Valdymo plokštuma atnaujina tarpinio serverio konfigūraciją, kai pasikeičia užpakalinės programos.
  • ... Pelnas!

Šiuolaikinis paslaugų tinklelio įgyvendinimas

Jei šiandien reikėtų įdiegti panašų tinklelį, galėtume naudoti panašius principus. Pavyzdžiui, sukonfigūruokite vidinę DNS zoną susiedami paslaugų pavadinimus su erdvėje esančiais adresais 127.0.0.0/8. Tada paleiskite HAProxy kiekviename klasterio mazge, priimdami ryšius kiekvienu paslaugų adresu (tame potinklyje 127.0.0.0/8) ir nukreipti / subalansuoti apkrovą į atitinkamas užpakalines programas. HAProxy konfigūraciją galima valdyti confd, leidžiančią saugoti pagrindinę informaciją etcd arba Consul ir prireikus automatiškai perkelti atnaujintą konfigūraciją į HAProxy.

Beveik taip veikia Istio! Tačiau su tam tikrais skirtumais:

  • Naudoja Pasiuntinio įgaliotinis vietoj HAProxy.
  • Saugo bazinės sistemos konfigūraciją per Kubernetes API, o ne etcd arba Consul.
  • Paslaugoms priskiriami adresai vidiniame potinklyje (Kubernetes ClusterIP adresai), o ne 127.0.0.0/8.
  • Turi papildomą komponentą (Citadelę), skirtą pridėti abipusį TLS autentifikavimą tarp kliento ir serverių.
  • Palaiko naujas funkcijas, tokias kaip grandinės pertraukimas, paskirstytas sekimas, kanarėlių diegimas ir kt.

Greitai pažvelkime į kai kuriuos skirtumus.

Pasiuntinio įgaliotinis

Envoy Proxy parašė Lyft [Uber konkurentas taksi rinkoje – apytiksl. juosta]. Daugeliu atžvilgių jis panašus į kitus tarpinius serverius (pvz., HAProxy, Nginx, Traefik...), tačiau Lyft parašė savo, nes jiems reikėjo funkcijų, kurių trūko kitiems tarpiniams serveriams, ir atrodė protingiau sukurti naują, o ne išplėsti esamą.

Pasiuntinį galima naudoti atskirai. Jei turiu konkrečią paslaugą, kuriai reikia prisijungti prie kitų paslaugų, galiu ją sukonfigūruoti, kad prisijungtų prie „Envoy“, tada dinamiškai sukonfigūruoti ir iš naujo sukonfigūruoti „Envoy“ pagal kitų tarnybų vietą ir gauti daug puikių papildomų funkcijų, tokių kaip matomumas. Užuot naudoję tinkintą kliento biblioteką arba į kodą įvedę skambučių pėdsakus, srautą siunčiame į Envoy, o jis už mus renka metrikas.

Tačiau pasiuntinys taip pat gali dirbti kaip duomenų plokštuma (duomenų plokštuma) paslaugų tinkleliui. Tai reiškia, kad pasiuntinys dabar sukonfigūruotas šiam paslaugų tinklui valdymo plokštuma (valdymo plokštuma).

Valdymo plokštuma

Valdymo plokštumoje Istio remiasi Kubernetes API. Tai nelabai skiriasi nuo confd naudojimo, kuri remiasi etcd arba Consul, kad peržiūrėtų raktų rinkinį duomenų saugykloje. „Istio“ naudoja „Kubernetes“ API, kad peržiūrėtų „Kubernetes“ išteklių rinkinį.

Tarp to ir tada: Man asmeniškai tai buvo naudinga Kubernetes API aprašaskuriame rašoma:

Kubernetes API serveris yra „kvailas serveris“, siūlantis API išteklių saugyklą, versijų nustatymą, patvirtinimą, atnaujinimą ir semantiką.

Istio sukurtas darbui su Kubernetes; ir jei norite jį naudoti už Kubernetes ribų, turite paleisti Kubernetes API serverio egzempliorių (ir etcd Helper paslaugą).

Paslaugų adresai

Istio remiasi ClusterIP adresais, kuriuos skiria Kubernetes, todėl Istio paslaugos gauna vidinį adresą (ne diapazone 127.0.0.0/8).

Konkrečios paslaugos „Kubernetes“ klasteryje be „Istio“ srautą „ClusterIP“ adresu perima „kube-proxy“ ir siunčia į to tarpinio serverio vidinę sistemą. Jei jus domina techninės detalės, kube-proxy nustato iptables taisykles (arba IPVS apkrovos balansavimo priemones, priklausomai nuo to, kaip ji sukonfigūruota), kad perrašytų jungčių, nukreipiančių į ClusterIP adresą, paskirties IP adresus.

Įdiegus „Istio“ „Kubernetes“ klasteryje, niekas nepasikeičia, kol jis nėra aiškiai įjungtas tam tikram vartotojui ar net visai vardų erdvei, įvedant konteinerį. sidecar į pasirinktines ankštis. Šis konteineris sukurs „Envoy“ egzempliorių ir nustatys „iptables“ taisyklių rinkinį, kad perimtų srautą, nukreiptą į kitas paslaugas, ir nukreiptų tą srautą į „Envoy“.

Integravus su Kubernetes DNS, tai reiškia, kad mūsų kodas gali prisijungti pagal paslaugos pavadinimą ir viskas „tiesiog veikia“. Kitaip tariant, mūsų kodas pateikia tokias užklausas kaip http://api/v1/users/4242tada api išspręsti prašymą 10.97.105.48, iptables taisyklės perims ryšius nuo 10.97.105.48 ir perduos juos vietiniam pasiuntinio įgaliotajam serveriui, o tas vietinis įgaliotasis serveris perduos užklausą į tikrąjį užpakalinės programos API. Fu!

Papildomi maivymasis

„Istio“ taip pat teikia visišką šifravimą ir autentifikavimą per mTLS (abipusį TLS). Komponentas vadinamas Citadelė.

Taip pat yra komponentas Maišytuvas, kurio pasiuntinys gali paprašyti kiekvienas prašymas priimti specialų sprendimą dėl tos užklausos, atsižvelgiant į įvairius veiksnius, pvz., antraštes, užpakalinę apkrovą ir kt... (nesijaudinkite: yra daug būdų, kaip išlaikyti maišytuvą, ir net jei jis sugenda, Envoy dirbs toliau gerai kaip įgaliotinis).

Ir, žinoma, paminėjome matomumą: „Envoy“ renka didžiulį kiekį metrikų, teikdamas paskirstytą sekimą. Mikropaslaugų architektūroje, jei viena API užklausa turi būti perduota per mikropaslaugas A, B, C ir D, tada prisijungus paskirstytasis sekimas prie užklausos pridės unikalų identifikatorių ir išsaugos šį identifikatorių per antrinius užklausas visoms šioms mikropaslaugoms. visi susiję skambučiai turi būti užfiksuoti, vėlavimai ir pan.

Kurti arba pirkti

Istio garsėja kaip sudėtingas. Priešingai, sukurti maršruto tinklelį, kurį aprašiau šio įrašo pradžioje, naudojant esamus įrankius yra gana paprasta. Taigi, ar prasminga vietoj to sukurti savo paslaugų tinklą?

Jei turime nedidelių poreikių (nereikia matomumo, grandinės pertraukiklio ir kitų subtilybių), tada kyla minčių kurti savo įrankį. Bet jei naudosime Kubernetes, jo gali net neprireikti, nes Kubernetes jau teikia pagrindinius įrankius paslaugų atradimui ir apkrovos balansavimui.

Bet jei turime išplėstinius reikalavimus, tada „įsigyti“ paslaugų tinklelį atrodo daug geresnis pasirinkimas. (Tai ne visada yra „pirkimas“, nes „Istio“ yra atvirojo kodo, bet vis tiek turime investuoti inžinerinio laiko, kad jį suprastume, įdiegtume ir valdytume.)

Ar turėčiau rinktis „Istio“, „Linkerd“ ar „Consul Connect“?

Kol kas kalbėjome tik apie Istio, bet tai ne vienintelis paslaugų tinklelis. Populiari alternatyva - Linkerd, ir yra daugiau Consul Connect.

Ką pasirinkti?

Sąžiningai, aš nežinau. Šiuo metu nemanau, kad esu pakankamai kompetentingas atsakyti į šį klausimą. Yra keli įdomus straipsniai su šių priemonių palyginimu ir net etalonų.

Vienas iš perspektyvių būdų yra naudoti tokį įrankį kaip SuperGloo. Jis įgyvendina abstrakcijos sluoksnį, kad supaprastintų ir suvienodintų API, kurias rodo paslaugų tinkleliai. Užuot išmokę specifinių (ir, mano nuomone, gana sudėtingų) skirtingų paslaugų tinklelio API, galime naudoti paprastesnes SuperGloo konstrukcijas ir lengvai pereiti iš vienos į kitą, tarsi turėtume tarpinį konfigūracijos formatą, apibūdinantį HTTP sąsajas ir galimus pagrindinius įrenginius. sugeneruoti tikrąją Nginx, HAProxy, Traefik, Apache...

Šiek tiek papasakojau apie Istio ir SuperGloo, o kitame straipsnyje noriu parodyti, kaip naudojant SuperGloo pridėti Istio arba Linkerd prie esamo klasterio ir kaip pastarasis atlieka darbą, ty leidžia jums pereiti nuo vienas paslaugų tinklelis į kitą neperrašant konfigūracijų.

Šaltinis: www.habr.com

Добавить комментарий