Vsebniki, mikrostoritve in storitvene mreže

Na internetu kup članki о servisne mreže (servisna mreža), in tukaj je še ena. Hura! Ampak zakaj? Nato želim izraziti svoje mnenje, da bi bila storitvena omrežja boljša pred 10 leti, pred pojavom vsebniških platform, kot sta Docker in Kubernetes. Ne trdim, da je moje stališče boljše ali slabše od drugih, a ker so storitvene mreže precej zapletene živali, jih bo več zornih kotov pomagalo bolje razumeti.

Govoril bom o platformi dotCloud, ki je bila zgrajena na več kot sto mikrostoritvah in je podpirala na tisoče aplikacij v kontejnerjih. Pojasnil bom izzive, na katere smo naleteli pri razvoju in lansiranju, in kako bi lahko (ali ne) pomagala mrežna omrežja storitev.

zgodovina dotcloud

O zgodovini dotCloud in izbiri arhitekture za to platformo sem že pisal, nisem pa veliko govoril o omrežni plasti. Če nočeš brati zadnji članek o dotCloudu je bistvo: to je platforma PaaS kot storitev, ki strankam omogoča izvajanje širokega nabora aplikacij (Java, PHP, Python ...), s podporo za širok nabor podatkovnih storitev ( MongoDB, MySQL, Redis ...) in potek dela, kot je Heroku: naložite svojo kodo na platformo, ta zgradi slike vsebnika in jih razmesti.

Povedal vam bom, kako je bil promet poslan na platformo dotCloud. Pa ne zato, ker je bilo posebno kul (čeprav je sistem za svoj čas dobro deloval!), ampak predvsem zato, ker lahko s pomočjo sodobnih orodij takšen dizajn enostavno implementira v kratkem času skromna ekipa, če potrebuje način za usmerjanje prometa med kupom mikrostoritev ali kupom aplikacij. Tako lahko primerjate možnosti: kaj se zgodi, če vse razvijete sami ali uporabite obstoječo servisno mrežo. Standardna izbira: naredite sami ali kupite.

Usmerjanje prometa za gostujoče aplikacije

Aplikacije na dotCloud lahko izpostavijo končne točke HTTP in TCP.

končne točke HTTP dinamično dodan v konfiguracijo gruče izravnalnika obremenitve Hipache. To je podobno temu, kar viri počnejo danes Vstop v Kubernetesu in uravnalniku obremenitve, podobnem Traefik.

Odjemalci se povežejo s končnimi točkami HTTP prek ustreznih domen, pod pogojem, da ime domene kaže na izravnalnike obremenitve dotCloud. Nič posebnega.

končne točke TCP povezana s številko vrat, ki se nato prek spremenljivk okolja posreduje vsem vsebnikom v tem skladu.

Odjemalci se lahko povežejo s končnimi točkami TCP z uporabo ustreznega imena gostitelja (nekaj podobnega kot prehod-X.dotcloud.com) in številke vrat.

To ime gostitelja se razreši v gručo strežnikov "nats" (ni povezano z NATS), ki bo dohodne povezave TCP usmeril v pravi vsebnik (ali v primeru storitev z uravnoteženo obremenitvijo v pravilne vsebnike).

Če poznate Kubernetes, vas bo to verjetno spomnilo na storitve Node Port.

Na platformi dotCloud ni bilo enakovrednih storitev GrozdIP: zaradi poenostavitve je dostop do storitev potekal na enak način tako znotraj kot zunaj platforme.

Vse je bilo organizirano precej preprosto: prvotne izvedbe usmerjevalnih omrežij HTTP in TCP so bile verjetno le nekaj sto vrstic Pythona. Preprosti (rekel bi, naivni) algoritmi, ki so bili izpopolnjeni z rastjo platforme in pojavom dodatnih zahtev.

Obsežno preoblikovanje obstoječe kode ni bilo potrebno. Še posebej, 12 Factor Apps lahko neposredno uporabi naslov, pridobljen s spremenljivkami okolja.

Kako se to razlikuje od sodobne storitvene mreže?

Omejeno vidljivost. Sploh nismo imeli metrik za usmerjevalno mrežo TCP. Ko gre za usmerjanje HTTP, imajo novejše različice podrobne metrike HTTP s kodami napak in odzivnimi časi, vendar sodobna storitvena omrežja gredo še dlje in zagotavljajo integracijo s sistemi za zbiranje metrik, kot je na primer Prometheus.

Vidnost ni pomembna le z operativnega vidika (za pomoč pri odpravljanju težav), temveč tudi ob izdaji novih funkcij. Govorimo o varnem modro-zelena razporeditev и razporeditev kanarčkov.

Učinkovitost usmerjanja je tudi omejena. V usmerjevalni mreži dotCloud je moral ves promet potekati skozi gručo namenskih usmerjevalnih vozlišč. To je pomenilo potencialno prečkanje več meja AZ (območja razpoložljivosti) in znatno povečanje zakasnitve. Spomnim se kode za odpravljanje težav, ki je naredila več kot sto poizvedb SQL na stran in za vsako poizvedbo odprla novo povezavo s strežnikom SQL. Pri lokalnem zagonu se stran naloži takoj, na dotCloud pa nalaganje traja nekaj sekund, ker vsaka povezava TCP (in poznejša poizvedba SQL) traja več deset milisekund. V tem primeru so težavo rešile trajne povezave.

Sodobne storitvene mreže se bolje spopadajo s takšnimi težavami. Najprej preverijo, ali so povezave speljane v viru. Logični potek je enak: клиент → меш → сервис, zdaj pa mreža deluje lokalno in ne na oddaljenih vozliščih, zato povezava клиент → меш je lokalno in zelo hitro (mikrosekunde namesto milisekund).

Sodobna storitvena omrežja izvajajo tudi pametnejše algoritme za uravnoteženje obremenitve. S spremljanjem zdravja ozadij lahko pošljejo več prometa hitrejšim ozadjem, kar ima za posledico boljšo splošno zmogljivost.

varnost je tudi boljši. Usmerjevalna mreža dotCloud je v celoti delovala na EC2 Classic in ni šifrirala prometa (pod predpostavko, da če je nekomu uspelo namestiti vohljanje na omrežni promet EC2, ste že v velikih težavah). Sodobna mrežna omrežja pregledno ščitijo ves naš promet, na primer z medsebojno avtentikacijo TLS in kasnejšim šifriranjem.

Usmerjanje prometa za storitve platforme

V redu, razpravljali smo o prometu med aplikacijami, kaj pa sama platforma dotCloud?

Sama platforma je bila sestavljena iz približno sto mikroservisov, odgovornih za različne funkcije. Nekateri so sprejemali zahteve drugih, nekateri pa so bili delavci v ozadju, ki so se povezovali z drugimi storitvami, vendar sami niso sprejemali povezav. V obeh primerih mora vsaka storitev poznati končne točke naslovov, s katerimi se mora povezati.

Številne storitve na visoki ravni lahko uporabljajo zgoraj opisano usmerjevalno mrežo. Pravzaprav je bilo veliko od več kot XNUMX mikrostoritev dotCloud razporejenih kot redne aplikacije na sami platformi dotCloud. Toda majhno število nizkonivojskih storitev (zlasti tistih, ki izvajajo to usmerjevalno mrežo) je potrebovalo nekaj enostavnejšega, z manj odvisnostmi (ker se pri delu niso mogli zanašati na sebe - dobri stari problem kokoši in jajca).

Te bistvene storitve nizke ravni so bile uvedene z izvajanjem vsebnikov neposredno na nekaj ključnih vozliščih. Hkrati niso bile vključene standardne storitve platforme: povezovalnik, razporejevalnik in izvajalec. Če želite primerjati s sodobnimi kontejnerskimi platformami, je to, kot da bi izstrelili krmilno letalo z docker run neposredno na vozliščih, namesto da nalogo prenesete na Kubernetes. Konceptno je precej podoben statični moduli (stroki), ki uporablja kubeadm ali bootkube pri zagonu samostojne gruče.

Te storitve so bile razkrite na preprost in grob način: datoteka YAML je naštela njihova imena in naslove; in vsak odjemalec je moral vzeti kopijo te datoteke YAML za uvedbo.

Po eni strani je to izjemno zanesljivo, ker ne zahteva podpore zunanje shrambe ključev/vrednosti, kot je Zookeeper (ne pozabite, etcd ali Consul takrat še nista obstajala). Po drugi strani pa je otežila selitev storitev. Vsakič, ko je bila izvedena poteza, so morale vse stranke dobiti posodobljeno datoteko YAML (in morebitno ponovno naložiti). Ni ravno udobno!

Kasneje smo začeli izvajati novo shemo, kjer se je vsak odjemalec povezal z lokalnim proxy strežnikom. Namesto naslova in vrat mora poznati le številko vrat storitve in se povezati prek localhost. Lokalni proxy obravnava to povezavo in jo posreduje dejanskemu strežniku. Zdaj pri premikanju ozadja na drug stroj ali spreminjanju velikosti, namesto da bi posodobili vse odjemalce, je treba posodobiti samo vse te lokalne proxyje; in ponovni zagon ni več potreben.

(Načrtovano je bilo tudi enkapsuliranje prometa v povezave TLS in namestitev drugega proxy strežnika na sprejemni strani ter preverjanje potrdil TLS brez sodelovanja sprejemne storitve, ki je konfigurirana tako, da sprejema povezave samo na localhost. Več o tem pozneje).

To je zelo podobno smartstack od Airbnb, vendar je bistvena razlika v tem, da je SmartStack implementiran in razporejen v produkcijo, medtem ko je bil notranji sistem usmerjanja dotCloud zaprt, ko se je dotCloud spremenil v Docker.

Osebno menim, da je SmartStack eden od predhodnikov sistemov, kot so Istio, Linkerd in Consul Connect, ker vsi sledijo istemu vzorcu:

  • Zaženite proxy na vsakem vozlišču.
  • Odjemalci se povežejo s proxyjem.
  • Nadzorna ravnina posodobi konfiguracijo posrednika, ko se zaledja spremenijo.
  • … Dobiček!

Sodobna izvedba storitvenega omrežja

Če moramo danes uvesti podobno mrežo, lahko uporabimo podobna načela. Nastavite na primer interno območje DNS tako, da imena storitev preslikate na naslove v prostoru 127.0.0.0/8. Nato zaženite HAProxy na vsakem vozlišču gruče in sprejemajte povezave na vsakem naslovu storitve (na tem podomrežju 127.0.0.0/8) in preusmerjanje/uravnoteženje obremenitve na ustrezna ozadja. Konfiguracijo HAProxy je mogoče upravljati konf, ki vam omogoča shranjevanje informacij o zaledju v etcd ali Consul in samodejno pošiljanje posodobljene konfiguracije v HAProxy, ko je to potrebno.

Tako deluje Istio! Vendar z nekaj razlikami:

  • Uporabe Envoy Proxy namesto HAProxy.
  • Shrani konfiguracijo zaledja prek API-ja Kubernetes namesto etcd ali Consul.
  • Storitvam so dodeljeni naslovi v notranjem podomrežju (naslovi Kubernetes ClusterIP) namesto 127.0.0.0/8.
  • Ima dodatno komponento (Citadel) za dodajanje medsebojne avtentikacije TLS med odjemalcem in strežniki.
  • Podpira nove funkcije, kot so prekinitev tokokroga, porazdeljeno sledenje, uvajanje kanarčkov itd.

Oglejmo si na hitro nekaj razlik.

Envoy Proxy

Envoy Proxy je napisal Lyft [Uberjev tekmec na trgu taksijev – pribl. per.]. V mnogih pogledih je podoben drugim proxyjem (npr. HAProxy, Nginx, Traefik ...), vendar je Lyft napisal svojega, ker so potrebovali funkcije, ki jih drugi proxyji nimajo, in se je zdelo bolj smiselno narediti novega kot razširiti obstoječega.

Envoy se lahko uporablja sam. Če imam določeno storitev, ki se mora povezati z drugimi storitvami, jo lahko nastavim za povezavo z Envoy in nato dinamično konfiguriram in znova konfiguriram Envoy z lokacijo drugih storitev, hkrati pa dobim veliko odličnih dodatkov, kot je vidljivost. Namesto prilagojene odjemalske knjižnice ali vbrizgavanja v kodo za sledenje klicem pošljemo promet Envoyju, ki namesto nas zbira meritve.

Toda Envoy lahko deluje tudi kot podatkovna ravnina (podatkovna ravnina) za servisno mrežo. To pomeni, da je zdaj za to storitveno mrežo Envoy konfiguriran nadzorna ravnina (kontrolna ravnina).

Nadzorna ravnina

V nadzorni ravnini se Istio opira na Kubernetes API. To se ne razlikuje zelo od uporabe confd, ki se zanaša na etcd ali Consul za iskanje nabora ključev v shrambi podatkov. Istio pregleduje nabor virov Kubernetes prek API-ja Kubernetes.

Med tem in potem: Osebno se mi je to zdelo koristno Opis API-ja Kuberneteski se glasi:

Kubernetes API Server je "neumen strežnik", ki ponuja shranjevanje, urejanje različic, preverjanje, posodabljanje in semantiko virov API-ja.

Istio je zasnovan za delo s Kubernetesom; in če ga želite uporabljati zunaj Kubernetesa, potem morate zagnati primerek strežnika Kubernetes API (in pomožne storitve etcd).

Naslovi storitev

Istio se zanaša na naslove ClusterIP, ki jih dodeli Kubernetes, zato storitve Istio dobijo notranji naslov (ni v območju 127.0.0.0/8).

Promet do naslova ClusterIP za določeno storitev v gruči Kubernetes brez Istio prestreže kube-proxy in ga pošlje v zadnjo stran strežnika proxy. Če vas zanimajo tehnične podrobnosti, kube-proxy nastavi pravila iptables (ali izravnalnike obremenitve IPVS, odvisno od tega, kako je konfiguriran), da prepiše ciljne naslove IP povezav, ki gredo na naslov ClusterIP.

Ko je Istio nameščen v gručo Kubernetes, se nič ne spremeni, dokler ni izrecno omogočen za danega porabnika ali celo za celoten imenski prostor z uvedbo vsebnika sidecar na stroke po meri. Ta vsebnik bo zagnal primerek Envoy in nastavil nabor pravil iptables za prestrezanje prometa, ki gre v druge storitve, in ta promet preusmeril na Envoy.

Ko je integrirano s Kubernetes DNS, to pomeni, da se lahko naša koda poveže z imenom storitve in vse "preprosto deluje". Z drugimi besedami, naša koda izda poizvedbe, kot so http://api/v1/users/4242torej api rešiti zahtevo za 10.97.105.48, pravila iptables prestrežejo povezave iz 10.97.105.48 in jih preusmerijo na lokalni proxy Envoy, ki bo zahtevo posredoval dejanskemu zaledju API-ja. Fuj!

Dodatni dodatki

Istio zagotavlja tudi šifriranje od konca do konca in avtentikacijo prek mTLS (vzajemni TLS). Poklicana komponenta Citadela.

Obstaja tudi komponenta Mixer, ki jih lahko zahteva Envoy vsakega zahteva, da sprejme posebno odločitev o tej zahtevi glede na različne dejavnike, kot so glave, nalaganje zaledja, itd... (ne skrbite: obstaja veliko orodij, s katerimi Mixer deluje, in tudi če se zruši, bo Envoy še naprej deloval kot pooblaščenec).

In seveda smo omenili vidnost: Envoy zbere ogromno metrik, hkrati pa zagotavlja porazdeljeno sledenje. Če mora v arhitekturi mikrostoritev ena sama zahteva API-ja iti skozi mikrostoritve A, B, C in D, bo porazdeljeno sledenje ob prijavi dodalo enolični identifikator zahtevi in ​​ta identifikator shranilo prek podzahtev vsem tem mikrostoritvam, kar omogoča da zajamete vse povezane klice, njihove zakasnitve itd.

Razviti ali kupiti

Istio ima sloves kompleksnega sistema. Nasprotno pa je izdelava usmerjevalne mreže, ki sem jo opisal na začetku te objave, razmeroma enostavna z obstoječimi orodji. Torej, ali je namesto tega smiselno ustvariti lastno storitveno mrežo?

Če imamo skromne potrebe (ne potrebujemo vidnosti, odklopnika in drugih podrobnosti), potem pridejo misli o razvoju lastnega orodja. Če pa uporabljamo Kubernetes, morda niti ne bo potreben, ker Kubernetes že ponuja osnovna orodja za odkrivanje storitev in uravnoteženje obremenitve.

Če pa imamo napredne zahteve, potem se zdi "nakup" servisne mreže veliko boljša možnost. (To ni vedno "nakup", saj je Istio odprtokoden, vendar moramo še vedno vložiti inženirski čas, da ga razumemo, uvedemo in upravljamo.)

Kaj izbrati: Istio, Linkerd ali Consul Connect?

Doslej smo govorili samo o Istio, vendar to ni edina storitvena mreža. Priljubljena alternativa je Linkerd, vendar je še več Consul Connect.

Kaj izbrati?

Če sem iskren, ne vem. Trenutno se ne smatram za dovolj kompetentnega, da bi odgovoril na to vprašanje. Nekaj ​​jih je zanimivo članki s primerjavo teh orodij in celo merila uspešnosti.

Eden od obetavnih pristopov je uporaba orodja, kot je superglu. Implementira plast abstrakcije za poenostavitev in poenotenje API-jev, ki jih zagotavljajo storitvena omrežja. Namesto da bi se učili specifičnih (in po mojem mnenju razmeroma zapletenih) API-jev različnih storitvenih mrež, lahko uporabimo enostavnejše konstrukcije SuperGloo - in enostavno preklapljamo iz ene v drugo, kot da bi imeli vmesni konfiguracijski format, ki opisuje vmesnike in zaledja HTTP zmožen ustvariti dejansko konfiguracijo za Nginx, HAProxy, Traefik, Apache…

Malo sem se igral z Istio in SuperGloo, v naslednjem članku pa želim pokazati, kako dodati Istio ali Linkerd v obstoječo gručo s pomočjo SuperGloo in kako bo slednji opravljal svoje delo, to je, da vam omogoča preklop iz eno storitveno mrežo v drugo brez prepisovanja konfiguracij.

Vir: www.habr.com

Dodaj komentar