Netramesh - ľahké riešenie servisnej siete

Keď prechádzame od monolitickej aplikácie k architektúre mikroslužieb, čelíme novým výzvam.

V monolitickej aplikácii je zvyčajne celkom jednoduché určiť, v ktorej časti systému sa chyba vyskytla. S najväčšou pravdepodobnosťou je problém v kóde samotného monolitu alebo v databáze. Keď však začneme hľadať problém v architektúre mikroslužieb, všetko už nie je také zrejmé. Musíme nájsť celú cestu, ktorou žiadosť prešla od začiatku do konca, a vybrať ju zo stoviek mikroslužieb. Navyše mnohé z nich majú aj svoje vlastné úložiská, čo môže tiež spôsobiť logické chyby, ako aj problémy s výkonom a odolnosťou voči chybám.

Netramesh - ľahké riešenie servisnej siete

Dlho som hľadal nástroj, ktorý by mi pomohol vyrovnať sa s takýmito problémami (písal som o tom na Habré: 1, 2), ale nakoniec som si vytvoril vlastné open source riešenie. V tomto článku hovorím o výhodách prístupu service mesh a zdieľam nový nástroj na jeho implementáciu.

Distribuované sledovanie je bežným riešením problému hľadania chýb v distribuovaných systémoch. Ale čo ak tento prístup k zhromažďovaniu informácií o sieťových interakciách ešte nie je v systéme implementovaný, alebo, čo je horšie, v časti systému už funguje správne, ale v časti nie, keďže nebol pridaný do starých služieb ? Na určenie presnej základnej príčiny problému je potrebné mať úplný obraz o tom, čo sa deje v systéme. Je obzvlášť dôležité pochopiť, ktoré mikroslužby sú zapojené do kľúčových kritických obchodných ciest.

Tu nám môže pomôcť prístup service mesh, ktorý sa bude zaoberať všetkými mašinériami na zber sieťových informácií na nižšej úrovni, ako fungujú samotné služby. Tento prístup nám umožňuje zachytiť všetku premávku a analyzovať ju za chodu. Navyše, aplikácie o tom ani nemusia nič vedieť.

Servisný sieťový prístup

Hlavnou myšlienkou prístupu service mesh je pridanie ďalšej vrstvy infraštruktúry cez sieť, ktorá nám umožní robiť čokoľvek s interakciou medzi službami. Väčšina implementácií funguje nasledovne: ku každej mikroslužbe je pridaný ďalší kontajner postranného vozíka s transparentným proxy, cez ktorý prechádza všetka prichádzajúca a odchádzajúca prevádzka služby. A to je práve miesto, kde môžeme robiť vyvažovanie klientov, uplatňovať bezpečnostné politiky, obmedzovať počet požiadaviek a zbierať dôležité informácie o interakcii služieb vo výrobe.

Netramesh - ľahké riešenie servisnej siete

riešenie

Existuje už niekoľko implementácií tohto prístupu: Istio и linkerd2. Poskytujú množstvo funkcií hneď po vybalení. Zároveň však prichádza veľká réžia na zdroje. Navyše, čím väčší je klaster, v ktorom takýto systém funguje, tým viac zdrojov bude potrebných na údržbu novej infraštruktúry. V spoločnosti Avito prevádzkujeme klastre kubernetes, ktoré obsahujú tisíce inštancií služieb (a ich počet neustále rýchlo rastie). Vo svojej súčasnej implementácii Istio spotrebuje ~ 300 Mb RAM na inštanciu služby. Vďaka veľkému množstvu možností ovplyvňuje transparentné vyvažovanie aj celkovú dobu odozvy služieb (do 10ms).

V dôsledku toho sme sa pozreli presne na to, aké schopnosti práve teraz potrebujeme, a rozhodli sme sa, že hlavným dôvodom, prečo sme začali implementovať takéto riešenia, bola schopnosť transparentne zbierať informácie o sledovaní z celého systému. Chceli sme mať tiež kontrolu nad interakciou služieb a robiť rôzne manipulácie s hlavičkami, ktoré sa medzi službami prenášajú.

V dôsledku toho sme dospeli k nášmu rozhodnutiu:  Netramesh.

Netramesh

Netramesh je ľahké sieťové riešenie služieb s možnosťou nekonečnej škálovateľnosti bez ohľadu na počet služieb v systéme.

Hlavným cieľom nového riešenia bola nízka réžia zdrojov a vysoký výkon. Medzi hlavné funkcie sme okamžite chceli mať možnosť transparentne posielať rozsahy sledovania do nášho systému Jaeger.

Dnes je väčšina cloudových riešení implementovaná v Golangu. A, samozrejme, existujú na to dôvody. Písanie sieťových aplikácií v Golang, ktoré pracujú asynchrónne s I/O a podľa potreby sa škálujú naprieč jadrami, je pohodlné a celkom jednoduché. A čo je tiež veľmi dôležité, výkon je dostatočný na vyriešenie tohto problému. Preto sme si vybrali aj Golang.

produktivita

Naše úsilie sme zamerali na dosiahnutie maximálnej produktivity. Pre riešenie, ktoré je nasadené vedľa každej inštancie služby, je potrebná malá spotreba RAM a CPU. A samozrejme oneskorenie odozvy by malo byť tiež malé.

Pozrime sa, aké výsledky sme dosiahli.

RAM

Netramesh spotrebuje ~ 10 Mb bez prenosu a maximálne 50 Mb so zaťažením až 10000 XNUMX RPS na inštanciu.

Istio envoy proxy vždy spotrebuje ~ 300 Mb v našich klastroch s tisíckami inštancií. To neumožňuje jeho škálovanie na celý klaster.

Netramesh - ľahké riešenie servisnej siete

Netramesh - ľahké riešenie servisnej siete

S Netramesh sme dosiahli ~10x zníženie spotreby pamäte.

CPU

Využitie CPU je pri záťaži relatívne rovnaké. Závisí to od počtu žiadostí za jednotku času do sajdkáry. Hodnoty pri 3000 požiadavkách za sekundu v špičke:

Netramesh - ľahké riešenie servisnej siete

Netramesh - ľahké riešenie servisnej siete

Je tu ešte jeden dôležitý bod: Netramesh – riešenie bez riadiacej roviny a bez záťaže nezaberá čas CPU. S Istio postranné vozíky vždy aktualizujú koncové body služby. V dôsledku toho vidíme tento obrázok bez zaťaženia:

Netramesh - ľahké riešenie servisnej siete

Na komunikáciu medzi službami používame HTTP/1. Nárast času odozvy pre Istio pri proxy cez envoy bol až 5-10 ms, čo je dosť veľa pre služby, ktoré sú pripravené reagovať v milisekunde. S Netramesh sa tento čas znížil na 0.5-2 ms.

Škálovateľnosť

Malé množstvo zdrojov spotrebovaných každým serverom proxy umožňuje umiestniť ho vedľa každej služby. Netramesh bol zámerne vytvorený bez komponentu riadiacej roviny, aby bol každý sajdkár jednoducho ľahký. V riešeniach servisnej siete často riadiaca rovina distribuuje informácie o objavení služby do každého postranného vozíka. Spolu s ním prichádzajú aj informácie o časových limitoch a nastaveniach vyváženia. To všetko vám umožňuje robiť veľa užitočných vecí, ale, žiaľ, nafukuje veľkosťou sajdkár.

Objavenie služby

Netramesh - ľahké riešenie servisnej siete

Netramesh nepridáva žiadne ďalšie mechanizmy na zisťovanie služieb. Všetka doprava je zabezpečená transparentne cez netra sajdkár.

Netramesh podporuje aplikačný protokol HTTP/1. Na jeho definovanie sa používa konfigurovateľný zoznam portov. Typicky má systém niekoľko portov, cez ktoré prebieha HTTP komunikácia. Napríklad na interakciu medzi službami a externými požiadavkami používame 80, 8890, 8080. V tomto prípade ich možno nastaviť pomocou premennej prostredia NETRA_HTTP_PORTS.

Ak používate Kubernetes ako orchestrátor a jeho mechanizmus entity Service na komunikáciu v rámci klastra medzi službami, mechanizmus zostane úplne rovnaký. Najprv mikroslužba získa IP adresu služby pomocou kube-dns a otvorí k nej nové pripojenie. Toto spojenie sa najskôr vytvorí s lokálnym netra-sidecar a všetky TCP pakety najprv dorazia do netra. Ďalej netra-sidecar nadviaže spojenie s pôvodným cieľom. NAT na pod IP na uzle zostáva úplne rovnaký ako bez netra.

Distribuované sledovanie a preposielanie kontextu

Netramesh poskytuje funkcie potrebné na odosielanie rozsahov sledovania o interakciách HTTP. Netra-sidecar analyzuje protokol HTTP, meria oneskorenia požiadaviek a extrahuje potrebné informácie z hlavičiek HTTP. Nakoniec získame všetky stopy v jedinom systéme Jaeger. Pre jemnú konfiguráciu môžete použiť aj premenné prostredia, ktoré poskytuje oficiálna knižnica knižnica jaeger go.

Netramesh - ľahké riešenie servisnej siete

Netramesh - ľahké riešenie servisnej siete

Ale je tu problém. Kým služby nevygenerujú a neodošlú špeciálnu hlavičku uber, v systéme neuvidíme prepojené rozsahy sledovania. A to je to, čo potrebujeme, aby sme rýchlo našli príčinu problémov. Tu má Netramesh opäť riešenie. Proxy čítajú hlavičky HTTP a ak neobsahujú identifikátor sledovania uber, vygenerujú ho. Netramesh tiež ukladá informácie o prichádzajúcich a odchádzajúcich požiadavkách do postranného vozíka a spáruje ich tak, že ich obohatí o potrebné hlavičky odchádzajúcich požiadaviek. Všetko, čo musíte urobiť v službách, je poslať iba jednu hlavičku X-Request-Id, ktorú je možné nakonfigurovať pomocou premennej prostredia NETRA_HTTP_REQUEST_ID_HEADER_NAME. Ak chcete ovládať veľkosť kontextu v Netramesh, môžete nastaviť nasledujúce premenné prostredia: NETRA_TRACING_CONTEXT_EXPIRATION_MILLISECONDS (čas, na ktorý bude kontext uložený) a NETRA_TRACING_CONTEXT_CLEANUP_INTERVAL (frekvencia čistenia kontextu).

Je tiež možné kombinovať viacero ciest vo vašom systéme tak, že ich označíte špeciálnym tokenom relácie. Netra umožňuje inštaláciu HTTP_HEADER_TAG_MAP premeniť hlavičky HTTP na zodpovedajúce značky rozsahu sledovania. To môže byť užitočné najmä pri testovaní. Po absolvovaní funkčného testu môžete vidieť, ktorá časť systému bola ovplyvnená filtrovaním zodpovedajúcim kľúčom relácie.

Určenie zdroja požiadavky

Ak chcete zistiť, odkiaľ požiadavka prišla, môžete použiť funkciu automatického pridávania hlavičky so zdrojom. Použitie premennej prostredia NETRA_HTTP_X_SOURCE_HEADER_NAME Môžete zadať názov hlavičky, ktorý sa automaticky nainštaluje. Používaním NETRA_HTTP_X_SOURCE_VALUE môžete nastaviť hodnotu, na ktorú bude hlavička X-Source nastavená pre všetky odchádzajúce požiadavky.

To umožňuje, aby bola distribúcia tejto užitočnej hlavičky distribuovaná rovnomerne v celej sieti. Potom ho môžete použiť v službách a pridať do denníkov a metrík.

Traffic routing a Netramesh internals

Netramesh sa skladá z dvoch hlavných komponentov. Prvý, netra-init, nastavuje pravidlá siete na zachytenie prevádzky. Používa pravidlá presmerovania iptables na zachytenie celej premávky alebo jej časti na postrannom vozíku, ktorý je druhou hlavnou zložkou Netramesh. Môžete nakonfigurovať, ktoré porty je potrebné zachytiť pre prichádzajúce a odchádzajúce relácie TCP: INBOUND_INTERCEPT_PORTS, OUTBOUND_INTERCEPT_PORTS.

Nástroj má aj zaujímavú funkciu – pravdepodobnostné smerovanie. Ak používate Netramesh výhradne na zhromažďovanie rozsahov sledovania, potom v produkčnom prostredí môžete ušetriť zdroje a povoliť pravdepodobnostné smerovanie pomocou premenných NETRA_INBOUND_PROBABILITY и NETRA_OUTBOUND_PROBABILITY (od 0 do 1). Predvolená hodnota je 1 (všetka premávka je zachytená).

Po úspešnom zachytení netra sajdkár akceptuje nové spojenie a používa SO_ORIGINAL_DST možnosť zásuvky na získanie pôvodného cieľa. Netra potom otvorí nové spojenie s pôvodnou IP adresou a nadviaže obojsmernú TCP komunikáciu medzi stranami, pričom bude počúvať všetku komunikáciu, ktorá cez ňu prechádza. Ak je port definovaný ako HTTP, Netra sa ho pokúsi analyzovať a sledovať. Ak analyzovanie HTTP zlyhá, Netra sa vráti k TCP a transparentne zastúpi bajty.

Vytvorenie grafu závislosti

Po prijatí veľkého množstva informácií o sledovaní v Jaegeri chcem získať úplný graf interakcií v systéme. Ak je však váš systém dosť zaťažený a denne sa hromadia miliardy úsekov sledovania, ich agregácia nie je taká jednoduchá úloha. Existuje oficiálny spôsob, ako to urobiť: iskrové závislosti. Vytvorenie kompletného grafu však bude trvať hodiny a prinúti vás stiahnuť si celý súbor údajov od spoločnosti Jaeger za posledných XNUMX hodín.

Ak používate Elasticsearch na ukladanie rozsahov sledovania, môžete použiť jednoduchý nástroj Golang, ktorý vytvorí rovnaký graf v priebehu niekoľkých minút pomocou funkcií a možností Elasticsearch.

Netramesh - ľahké riešenie servisnej siete

Ako používať Netramesh

Netra sa dá ľahko pridať do akejkoľvek služby, na ktorej beží akýkoľvek orchestrátor. Môžete vidieť príklad tu.

Netra momentálne nedisponuje možnosťou automatickej implementácie sajdkár do služieb, ale plány na implementáciu sú.

Budúcnosť Netramesh

hlavný cieľ Netramesh je dosiahnuť minimálne náklady na zdroje a vysoký výkon, poskytujúc základné schopnosti pre pozorovateľnosť a kontrolu medziservisnej komunikácie.

V budúcnosti bude Netramesh podporovať ďalšie protokoly aplikačnej vrstvy okrem HTTP. Smerovanie L7 bude dostupné v blízkej budúcnosti.

Ak narazíte na podobné problémy, použite Netramesh a napíšte nám s otázkami a návrhmi.

Zdroj: hab.com

Pridať komentár