Netramesh - lagano rješenje servisne mreže

Kako prelazimo sa monolitne aplikacije na arhitekturu mikroservisa, suočavamo se s novim izazovima.

U monolitnoj aplikaciji obično je prilično lako odrediti u kojem dijelu sistema je došlo do greške. Najvjerovatnije je problem u kodu samog monolita, ili u bazi podataka. Ali kada počnemo tražiti problem u mikroservisnoj arhitekturi, sve više nije tako očigledno. Moramo pronaći cijeli put kojim je zahtjev prošao od početka do kraja i odabrati ga među stotinama mikroservisa. Štoviše, mnogi od njih također imaju vlastita skladišta, što također može uzrokovati logičke greške, kao i probleme s performansama i tolerancijom grešaka.

Netramesh - lagano rješenje servisne mreže

Dugo sam tražio alat koji bi pomogao u rješavanju ovakvih problema (pisao sam o tome na Habréu: 1, 2), ali na kraju sam napravio svoje rješenje otvorenog koda. U ovom članku govorim o prednostima pristupa servisne mreže i dijelim novi alat za njegovu implementaciju.

Distribuirano praćenje je uobičajeno rješenje za problem pronalaženja grešaka u distribuiranim sistemima. Ali šta ako ovaj pristup prikupljanju informacija o mrežnim interakcijama još nije implementiran u sistem, ili, još gore, u dijelu sistema već radi kako treba, ali dijelom ne, jer nije dodat starim servisima ? Da bi se utvrdio tačan uzrok problema, potrebno je imati potpunu sliku o tome šta se dešava u sistemu. Posebno je važno razumjeti koje su mikroservise uključene u ključne poslovno kritične puteve.

Ovdje nam u pomoć može priskočiti pristup servisne mreže, koji će se baviti svom mašinerijom za prikupljanje mrežnih informacija na nivou nižem nego što rade same usluge. Ovaj pristup nam omogućava da presretnemo sav promet i analiziramo ga u hodu. Štaviše, aplikacije čak i ne moraju znati ništa o tome.

Pristup servisnoj mreži

Glavna ideja pristupa servisne mreže je dodavanje još jednog infrastrukturnog sloja preko mreže, koji će nam omogućiti da uradimo bilo šta uz međuservisnu interakciju. Većina implementacija radi na sljedeći način: svakom mikroservisu se dodaje dodatni sidecar kontejner sa transparentnim proxyjem, kroz koji se propušta sav dolazni i odlazni promet usluge. I to je upravo mjesto gdje možemo raditi balansiranje klijenata, primjenjivati ​​sigurnosne politike, nametati ograničenja broja zahtjeva i prikupljati važne informacije o interakciji usluga u produkciji.

Netramesh - lagano rješenje servisne mreže

Rešenja

Već postoji nekoliko implementacija ovog pristupa: Istio и linkerd2. Pružaju mnogo funkcija izvan kutije. Ali u isto vrijeme dolazi do velikih troškova vezanih za resurse. Štaviše, što je veći klaster u kojem takav sistem funkcioniše, to će više resursa biti potrebno za održavanje nove infrastrukture. U Avitu upravljamo kubernetes klasterima koji sadrže hiljade instanci usluge (i njihov broj nastavlja brzo rasti). U svojoj trenutnoj implementaciji, Istio troši ~300Mb RAM-a po instanci usluge. Zbog velikog broja mogućnosti, transparentno balansiranje utiče i na ukupno vreme odziva servisa (do 10ms).

Kao rezultat toga, pogledali smo tačno koje su nam mogućnosti trenutno potrebne i odlučili da je glavni razlog zašto smo započeli implementaciju ovakvih rješenja bila mogućnost transparentnog prikupljanja informacija o praćenju iz cijelog sistema. Također smo željeli imati kontrolu nad interakcijom servisa i vršiti razne manipulacije sa zaglavljima koji se prenose između servisa.

Kao rezultat toga, došli smo do naše odluke:  Netramesh.

Netramesh

Netramesh je lagano rješenje servisne mreže sa mogućnošću beskonačnog skaliranja, bez obzira na broj usluga u sistemu.

Glavni ciljevi novog rješenja bili su mali troškovi resursa i visoke performanse. Među glavnim karakteristikama, odmah smo željeli da budemo u mogućnosti da transparentno šaljemo raspone praćenja u naš Jaeger sistem.

Danas se većina rješenja u oblaku implementira u Golang. I, naravno, postoje razlozi za to. Pisanje mrežnih aplikacija u Golangu koje rade asinhrono sa I/O i skaliraju preko jezgara po potrebi je zgodno i prilično jednostavno. I, što je takođe veoma važno, performanse su dovoljne da se ovaj problem reši. Zato smo i odabrali Golang.

Produktivnost

Usmjerili smo svoje napore na postizanje maksimalne produktivnosti. Za rješenje koje se postavlja pored svake instance usluge potrebna je mala potrošnja RAM-a i CPU vremena. I, naravno, kašnjenje odgovora takođe treba da bude malo.

Da vidimo kakve smo rezultate dobili.

RAM

Netramesh troši ~10Mb bez prometa i 50Mb maksimalno uz opterećenje do 10000 RPS po instanci.

Istio envoy proxy uvijek troši ~300Mb u našim klasterima sa hiljadama instanci. Ovo ne dozvoljava da se skalira na cijeli klaster.

Netramesh - lagano rješenje servisne mreže

Netramesh - lagano rješenje servisne mreže

Sa Netrameshom smo dobili ~10x smanjenje potrošnje memorije.

CPU

Upotreba CPU-a je relativno jednaka pod opterećenjem. Zavisi od broja zahtjeva po jedinici vremena do prikolice. Vrijednosti pri 3000 zahtjeva u sekundi na vrhuncu:

Netramesh - lagano rješenje servisne mreže

Netramesh - lagano rješenje servisne mreže

Postoji još jedna važna stvar: Netramesh - rješenje bez kontrolne ravni i bez opterećenja ne troši CPU vrijeme. Uz Istio, prikolice uvijek ažuriraju krajnje tačke usluge. Kao rezultat, ovu sliku možemo vidjeti bez opterećenja:

Netramesh - lagano rješenje servisne mreže

Koristimo HTTP/1 za komunikaciju između usluga. Povećanje vremena odgovora za Istio prilikom proxyja preko envoy-a bilo je do 5-10ms, što je dosta za servise koji su spremni odgovoriti u milisekundi. Sa Netramesh-om ovo vrijeme je smanjeno na 0.5-2ms.

Skalabilnost

Mala količina resursa koju troši svaki proxy omogućava njegovo postavljanje pored svake usluge. Netramesh je namjerno kreiran bez komponente kontrolne ravni kako bi jednostavno svaki bočni prikolica ostao lagan. Često u rješenjima servisne mreže, kontrolna ravnina distribuira informacije o otkrivanju usluge svakoj prikolici. Uz to dolaze i informacije o tajm-autima i postavkama balansiranja. Sve to vam omogućava da uradite mnogo korisnih stvari, ali, nažalost, povećava veličinu bočnih prikolica.

Otkriće usluge

Netramesh - lagano rješenje servisne mreže

Netramesh ne dodaje nikakve dodatne mehanizme za otkrivanje usluge. Sav promet se prenosi transparentno kroz netra sidecar.

Netramesh podržava HTTP/1 aplikacijski protokol. Da bi se to definiralo, koristi se konfigurabilna lista portova. Tipično, sistem ima nekoliko portova preko kojih se odvija HTTP komunikacija. Na primjer, za interakciju između usluga i vanjskih zahtjeva koristimo 80, 8890, 8080. U ovom slučaju, oni se mogu postaviti pomoću varijable okruženja NETRA_HTTP_PORTS.

Ako koristite Kubernetes kao orkestrator i njegov mehanizam servisnog entiteta za komunikaciju unutar klastera između usluga, onda mehanizam ostaje potpuno isti. Prvo, mikroservis dobija IP adresu usluge koristeći kube-dns i otvara novu vezu sa njom. Ova veza se prvo uspostavlja s lokalnom netra-sidecarom i svi TCP paketi u početku stižu u netra. Zatim, netra-sidecar uspostavlja vezu sa originalnim odredištem. NAT na pod IP na čvoru ostaje potpuno isti kao bez netra.

Distribuirano praćenje i prosljeđivanje konteksta

Netramesh pruža funkcionalnost potrebnu za slanje raspona praćenja o HTTP interakcijama. Netra-sidecar analizira HTTP protokol, mjeri kašnjenja zahtjeva i izdvaja potrebne informacije iz HTTP zaglavlja. Na kraju, sve tragove dobijamo u jednom Jaeger sistemu. Za detaljnu konfiguraciju možete koristiti i varijable okruženja koje pruža zvanična biblioteka jaeger go biblioteka.

Netramesh - lagano rješenje servisne mreže

Netramesh - lagano rješenje servisne mreže

Ali postoji problem. Sve dok usluge ne generiraju i pošalju posebno uber zaglavlje, nećemo vidjeti povezane raspone praćenja u sistemu. A to je ono što nam je potrebno da brzo pronađemo uzrok problema. I ovdje Netramesh ima rješenje. Proksiji čitaju HTTP zaglavlja i, ako ne sadrže uber trace ID, generiraju ga. Netramesh također pohranjuje informacije o dolaznim i odlaznim zahtjevima u pomoćnoj prikolici i uparuje ih obogaćujući ih potrebnim zaglavljima odlaznih zahtjeva. Sve što trebate učiniti u uslugama je da pošaljete samo jedno zaglavlje X-Request-Id, koji se može konfigurirati pomoću varijable okruženja NETRA_HTTP_REQUEST_ID_HEADER_NAME. Da biste kontrolirali veličinu konteksta u Netrameshu, možete postaviti sljedeće varijable okruženja: NETRA_TRACING_CONTEXT_EXPIRATION_MILLISECONDS (vrijeme za koje će kontekst biti pohranjen) i NETRA_TRACING_CONTEXT_CLEANUP_INTERVAL (učestalost čišćenja konteksta).

Također je moguće kombinirati više putanja na vašem sistemu označavajući ih posebnim tokenom sesije. Netra vam omogućava da instalirate HTTP_HEADER_TAG_MAP da pretvorite HTTP zaglavlja u odgovarajuće oznake raspona praćenja. Ovo može biti posebno korisno za testiranje. Nakon prolaska funkcionalnog testa, možete vidjeti na koji dio sistema je utjecalo filtriranje po odgovarajućem ključu sesije.

Određivanje izvora zahtjeva

Da biste utvrdili odakle je zahtjev došao, možete koristiti funkciju automatskog dodavanja zaglavlja s izvorom. Korištenje varijable okruženja NETRA_HTTP_X_SOURCE_HEADER_NAME Možete odrediti ime zaglavlja koje će se automatski instalirati. Korišćenjem NETRA_HTTP_X_SOURCE_VALUE možete postaviti vrijednost na koju će zaglavlje X-Source biti postavljeno za sve odlazne zahtjeve.

Ovo omogućava da se distribucija ovog korisnog zaglavlja ravnomjerno distribuira kroz mrežu. Zatim ga možete koristiti u uslugama i dodati u dnevnike i metrike.

Usmjeravanje saobraćaja i Netramesh interni elementi

Netramesh se sastoji od dvije glavne komponente. Prvi, netra-init, postavlja mrežna pravila za presretanje saobraćaja. On koristi iptables pravila preusmjeravanja da presretne cijeli ili dio saobraćaja na bočnoj prikolici, koja je druga glavna komponenta Netramesha. Možete konfigurirati koji portovi trebaju biti presretnuti za dolazne i odlazne TCP sesije: INBOUND_INTERCEPT_PORTS, OUTBOUND_INTERCEPT_PORTS.

Alat također ima zanimljivu karakteristiku - vjerovatnost rutiranja. Ako koristite Netramesh isključivo za prikupljanje raspona praćenja, tada u proizvodnom okruženju možete uštedjeti resurse i omogućiti vjerojatnost rutiranja pomoću varijabli NETRA_INBOUND_PROBABILITY и NETRA_OUTBOUND_PROBABILITY (od 0 do 1). Zadana vrijednost je 1 (sav promet je presretan).

Nakon uspješnog presretanja, netra sidecar prihvata novu vezu i koristi SO_ORIGINAL_DST opcija socketa da dobijete originalno odredište. Netra zatim otvara novu vezu sa originalnom IP adresom i uspostavlja dvosmjernu TCP komunikaciju između strana, slušajući sav promet koji prolazi. Ako je port definiran kao HTTP, Netra ga pokušava raščlaniti i pratiti. Ako HTTP raščlanjivanje ne uspije, Netra se vraća na TCP i transparentno proksije bajtove.

Izrada grafa zavisnosti

Nakon što sam dobio veliku količinu informacija o praćenju u Jaegeru, želim da dobijem kompletan grafikon interakcija u sistemu. Ali ako je vaš sistem prilično opterećen i akumuliraju se milijarde raspona praćenja dnevno, njihovo agregiranje nije tako lak zadatak. Postoji službeni način da se to uradi: ovisnosti o iskri. Međutim, trebat će sati da se napravi potpuni grafikon i primorat će vas da preuzmete cijeli skup podataka sa Jaegera za posljednja XNUMX sata.

Ako koristite Elasticsearch za pohranjivanje raspona praćenja, možete koristiti jednostavan Golang uslužni program, koji će izgraditi isti grafikon za nekoliko minuta koristeći karakteristike i mogućnosti Elasticsearch-a.

Netramesh - lagano rješenje servisne mreže

Kako koristiti Netramesh

Netra se može lako dodati bilo kojoj usluzi koja pokreće bilo koji orkestrator. Možete vidjeti primjer ovdje.

U ovom trenutku, Netra nema mogućnost da automatski implementira pomoćne prikolice na usluge, ali postoje planovi za implementaciju.

Budućnost Netramesha

glavni cilj Netramesh je postizanje minimalnih troškova resursa i visokih performansi, pružajući osnovne mogućnosti za uočljivost i kontrolu komunikacije među službama.

U budućnosti, Netramesh će podržavati i druge protokole aplikacijskog sloja osim HTTP-a. L7 rutiranje će biti dostupno u bliskoj budućnosti.

Koristite Netramesh ako naiđete na slične probleme i pišite nam s pitanjima i prijedlozima.

izvor: www.habr.com

Dodajte komentar