Netramesh - magaan na solusyon sa mesh ng serbisyo

Habang lumilipat kami mula sa isang monolitikong aplikasyon patungo sa isang arkitektura ng microservice, nahaharap kami sa mga bagong hamon.

Sa isang monolitikong aplikasyon, kadalasan ay medyo madaling matukoy kung saang bahagi ng system naganap ang error. Malamang, ang problema ay nasa code ng monolith mismo, o sa database. Ngunit kapag nagsimula kaming maghanap ng problema sa isang microservice architecture, ang lahat ay hindi na masyadong halata. Kailangan nating hanapin ang buong landas na tinahak ng kahilingan mula simula hanggang matapos at piliin ito mula sa daan-daang microservice. Bukod dito, marami sa kanila ay mayroon ding sariling mga pasilidad sa pag-iimbak, na maaari ring magdulot ng mga lohikal na error, pati na rin ang mga problema sa pagganap at fault tolerance.

Netramesh - magaan na solusyon sa mesh ng serbisyo

Matagal na akong naghahanap ng isang tool na makakatulong na makayanan ang gayong mga problema (isinulat ko ang tungkol dito sa HabrΓ©: 1, 2), ngunit sa huli ay gumawa ako ng sarili kong solusyon sa open source. Sa artikulong ito pinag-uusapan ko ang tungkol sa mga benepisyo ng diskarte sa serbisyo ng mesh at nagbabahagi ako ng bagong tool para sa pagpapatupad nito.

Ang distributed tracing ay isang karaniwang solusyon sa problema ng paghahanap ng mga error sa mga distributed system. Ngunit paano kung ang pamamaraang ito sa pagkolekta ng impormasyon tungkol sa mga pakikipag-ugnayan sa network ay hindi pa naipapatupad sa system, o, mas masahol pa, sa bahagi ng system ay gumagana na ito nang maayos, ngunit sa isang bahagi ay hindi, dahil hindi pa ito naidagdag sa mga lumang serbisyo ? Upang matukoy ang eksaktong ugat ng isang problema, kinakailangan na magkaroon ng kumpletong larawan ng kung ano ang nangyayari sa system. Lalo na mahalaga na maunawaan kung aling mga microservice ang kasangkot sa mga pangunahing landas na kritikal sa negosyo.

Dito ang service mesh approach ay maaaring tumulong sa amin, na haharap sa lahat ng makinarya para sa pagkolekta ng impormasyon sa network sa isang antas na mas mababa kaysa sa mga serbisyo mismo na nagpapatakbo. Ang diskarte na ito ay nagbibigay-daan sa amin upang maharang ang lahat ng trapiko at pag-aralan ito sa mabilisang. Bukod dito, hindi na kailangang malaman ng mga application ang anumang bagay tungkol dito.

Diskarte sa mesh ng serbisyo

Ang pangunahing ideya ng diskarte sa mesh ng serbisyo ay upang magdagdag ng isa pang layer ng imprastraktura sa network, na magpapahintulot sa amin na gumawa ng anumang bagay sa inter-service na pakikipag-ugnayan. Karamihan sa mga pagpapatupad ay gumagana tulad ng sumusunod: isang karagdagang sidecar container na may transparent na proxy ay idinagdag sa bawat microservice, kung saan ang lahat ng papasok at papalabas na trapiko ng serbisyo ay ipinapasa. At ito ang mismong lugar kung saan maaari tayong magsagawa ng pagbabalanse ng kliyente, maglapat ng mga patakaran sa seguridad, magpataw ng mga paghihigpit sa bilang ng mga kahilingan at mangolekta ng mahalagang impormasyon sa pakikipag-ugnayan ng mga serbisyo sa produksyon.

Netramesh - magaan na solusyon sa mesh ng serbisyo

Solusyon

Mayroon nang ilang mga pagpapatupad ng diskarteng ito: Istio ΠΈ linkerd2. Nagbibigay sila ng maraming mga tampok na wala sa kahon. Ngunit sa parehong oras, mayroong isang malaking overhead sa mga mapagkukunan. Bukod dito, mas malaki ang kumpol kung saan gumagana ang naturang sistema, mas maraming mapagkukunan ang kakailanganin para mapanatili ang bagong imprastraktura. Sa Avito, nagpapatakbo kami ng mga kubernetes cluster na naglalaman ng libu-libong mga pagkakataon ng serbisyo (at ang bilang ng mga ito ay patuloy na lumalaki nang mabilis). Sa kasalukuyang pagpapatupad nito, ang Istio ay kumokonsumo ng ~300Mb ng RAM bawat halimbawa ng serbisyo. Dahil sa malaking bilang ng mga posibilidad, ang transparent na pagbabalanse ay nakakaapekto rin sa pangkalahatang oras ng pagtugon ng mga serbisyo (hanggang 10ms).

Bilang resulta, tiningnan namin nang eksakto kung anong mga kakayahan ang kailangan namin ngayon, at nagpasya na ang pangunahing dahilan kung bakit nagsimula kaming ipatupad ang mga naturang solusyon ay ang kakayahang mangolekta ng impormasyon sa pagsubaybay mula sa buong system nang malinaw. Nais din naming magkaroon ng kontrol sa pakikipag-ugnayan ng mga serbisyo at gumawa ng iba't ibang manipulasyon sa mga header na inililipat sa pagitan ng mga serbisyo.

Bilang resulta, dumating kami sa aming desisyon:β€Š Netramesh.

Netramesh

Netramesh ay isang magaan na solusyon sa mesh ng serbisyo na may kakayahang sumukat nang walang hanggan, anuman ang bilang ng mga serbisyo sa system.

Ang mga pangunahing layunin ng bagong solusyon ay mababang resource overhead at mataas na pagganap. Kabilang sa mga pangunahing tampok, agad naming nais na maipadala nang malinaw ang mga tracing span sa aming Jaeger system.

Ngayon, karamihan sa mga solusyon sa ulap ay ipinapatupad sa Golang. At, siyempre, may mga dahilan para dito. Ang pagsulat ng mga application ng network sa Golang na gumagana nang asynchronous sa I/O at sukat sa mga core kung kinakailangan ay maginhawa at medyo simple. At, kung ano ang napakahalaga, ang pagganap ay sapat upang malutas ang problemang ito. Kaya naman Golang din ang napili namin.

Pagiging Produktibo

Itinuon namin ang aming mga pagsisikap sa pagkamit ng maximum na produktibo. Para sa isang solusyon na naka-deploy sa tabi ng bawat pagkakataon ng serbisyo, kinakailangan ang isang maliit na pagkonsumo ng RAM at oras ng CPU. At, siyempre, ang pagkaantala sa pagtugon ay dapat ding maliit.

Tingnan natin kung anong mga resulta ang nakuha natin.

RAM

Kumokonsumo ang Netramesh ng ~10Mb nang walang traffic at maximum na 50Mb na may load na hanggang 10000 RPS bawat pagkakataon.

Palaging kumukonsumo ng ~300Mb ang Istio envoy proxy sa aming mga cluster na may libu-libong instance. Hindi nito pinapayagan na mai-scale ito sa buong cluster.

Netramesh - magaan na solusyon sa mesh ng serbisyo

Netramesh - magaan na solusyon sa mesh ng serbisyo

Sa Netramesh nakakuha kami ng ~10x na pagbawas sa pagkonsumo ng memorya.

CPU

Ang paggamit ng CPU ay medyo pantay sa ilalim ng pagkarga. Depende ito sa bilang ng mga kahilingan sa bawat yunit ng oras sa sidecar. Mga halaga sa 3000 na kahilingan sa bawat segundo sa peak:

Netramesh - magaan na solusyon sa mesh ng serbisyo

Netramesh - magaan na solusyon sa mesh ng serbisyo

May isa pang mahalagang punto: Netramesh - isang solusyon na walang control plane at walang load ay hindi kumonsumo ng oras ng CPU. Sa Istio, palaging ina-update ng mga sidecar ang mga endpoint ng serbisyo. Bilang resulta, makikita natin ang larawang ito nang walang pag-load:

Netramesh - magaan na solusyon sa mesh ng serbisyo

Gumagamit kami ng HTTP/1 para sa komunikasyon sa pagitan ng mga serbisyo. Ang pagtaas sa oras ng pagtugon para sa Istio kapag nag-proxy sa pamamagitan ng envoy ay hanggang 5-10ms, na napakarami para sa mga serbisyong handang tumugon sa isang millisecond. Sa Netramesh ang oras na ito ay bumaba sa 0.5-2ms.

Scalability

Ang maliit na halaga ng mga mapagkukunang natupok ng bawat proxy ay ginagawang posible na ilagay ito sa tabi ng bawat serbisyo. Ang Netramesh ay sadyang nilikha nang walang bahagi ng control plane upang mapanatiling magaan ang bawat sidecar. Kadalasan sa mga service mesh solution, ang control plane ay namamahagi ng impormasyon sa pagtuklas ng serbisyo sa bawat sidecar. Kasama nito ang impormasyon tungkol sa mga timeout at mga setting ng pagbabalanse. Ang lahat ng ito ay nagpapahintulot sa iyo na gumawa ng maraming mga kapaki-pakinabang na bagay, ngunit, sa kasamaang-palad, ito ay nagpapalaki ng mga sidecar sa laki.

Pagtuklas ng serbisyo

Netramesh - magaan na solusyon sa mesh ng serbisyo

Hindi nagdaragdag ang Netramesh ng anumang karagdagang mekanismo para sa pagtuklas ng serbisyo. Ang lahat ng trapiko ay na-proxy nang malinaw sa pamamagitan ng netra sidecar.

Sinusuportahan ng Netramesh ang HTTP/1 application protocol. Upang tukuyin ito, ginagamit ang isang na-configure na listahan ng mga port. Karaniwan, ang system ay may ilang mga port kung saan nangyayari ang komunikasyon sa HTTP. Halimbawa, ginagamit namin ang 80, 8890, 8080 para sa pakikipag-ugnayan sa pagitan ng mga serbisyo at mga panlabas na kahilingan. Sa kasong ito, maaaring itakda ang mga ito gamit ang isang variable ng kapaligiran NETRA_HTTP_PORTS.

Kung gagamitin mo ang Kubernetes bilang isang orkestra at ang mekanismo ng entity ng Serbisyo nito para sa intra-cluster na komunikasyon sa pagitan ng mga serbisyo, ang mekanismo ay nananatiling eksaktong pareho. Una, ang microservice ay nakakakuha ng IP address ng serbisyo gamit ang kube-dns at nagbubukas ng bagong koneksyon dito. Ang koneksyon na ito ay unang itinatag sa lokal na netra-sidecar at lahat ng TCP packet ay unang dumating sa netra. Susunod, ang netra-sidecar ay nagtatatag ng koneksyon sa orihinal na destinasyon. NAT sa pod IP sa node ay nananatiling eksaktong kapareho ng walang netra.

Ibinahagi ang pagsubaybay at pagpapasa ng konteksto

Nagbibigay ang Netramesh ng functionality na kailangan para magpadala ng mga tracing span tungkol sa mga pakikipag-ugnayan sa HTTP. Pina-parse ng Netra-sidecar ang HTTP protocol, sinusukat ang mga pagkaantala sa kahilingan, at kinukuha ang kinakailangang impormasyon mula sa mga header ng HTTP. Sa huli, nakukuha namin ang lahat ng bakas sa isang sistema ng Jaeger. Para sa fine-grained configuration, maaari mo ring gamitin ang environment variables na ibinigay ng opisyal na library jaeger pumunta sa library.

Netramesh - magaan na solusyon sa mesh ng serbisyo

Netramesh - magaan na solusyon sa mesh ng serbisyo

Pero may problema. Hanggang sa bumuo at magpadala ang mga serbisyo ng isang espesyal na uber header, hindi namin makikita ang mga konektadong tracing span sa system. At ito ang kailangan natin upang mabilis na mahanap ang sanhi ng mga problema. Narito muli ang Netramesh ay may solusyon. Binabasa ng mga proxy ang mga header ng HTTP at, kung hindi naglalaman ang mga ito ng uber trace id, bumuo ng isa. Nag-iimbak din ang Netramesh ng impormasyon tungkol sa mga papasok at papalabas na kahilingan sa isang sidecar at itinutugma ang mga ito sa pamamagitan ng pagpapayaman sa kanila ng mga kinakailangang header ng papalabas na kahilingan. Ang kailangan mo lang gawin sa mga serbisyo ay magpadala lamang ng isang header X-Request-Id, na maaaring i-configure gamit ang isang environment variable NETRA_HTTP_REQUEST_ID_HEADER_NAME. Upang kontrolin ang laki ng konteksto sa Netramesh, maaari mong itakda ang mga sumusunod na variable ng kapaligiran: NETRA_TRACING_CONTEXT_EXPIRATION_MILLISECONDS (ang oras kung kailan iimbak ang konteksto) at NETRA_TRACING_CONTEXT_CLEANUP_INTERVAL (dalas ng paglilinis ng konteksto).

Posible rin na pagsamahin ang maramihang mga path sa iyong system sa pamamagitan ng pagmamarka sa mga ito ng isang espesyal na token ng session. Pinapayagan ka ng Netra na mag-install HTTP_HEADER_TAG_MAP upang gawing mga katumbas na tag ng span ng pagsubaybay ang mga header ng HTTP. Maaari itong maging kapaki-pakinabang lalo na para sa pagsubok. Pagkatapos makapasa sa functional test, makikita mo kung aling bahagi ng system ang naapektuhan ng pag-filter gamit ang kaukulang session key.

Pagtukoy sa Pinagmulan ng Kahilingan

Upang matukoy kung saan nanggaling ang kahilingan, maaari mong gamitin ang pagpapagana ng awtomatikong pagdaragdag ng header na may pinagmulan. Paggamit ng environment variable NETRA_HTTP_X_SOURCE_HEADER_NAME Maaari kang tumukoy ng pangalan ng header na awtomatikong mai-install. Sa pamamagitan ng paggamit NETRA_HTTP_X_SOURCE_VALUE maaari mong itakda ang halaga kung saan itatakda ang header ng X-Source para sa lahat ng papalabas na kahilingan.

Nagbibigay-daan ito sa pamamahagi ng kapaki-pakinabang na header na ito na maipamahagi nang pantay-pantay sa buong network. Pagkatapos ay magagamit mo ito sa mga serbisyo at idagdag ito sa mga log at sukatan.

Pagruruta ng trapiko at mga panloob na Netramesh

Ang Netramesh ay binubuo ng dalawang pangunahing sangkap. Ang una, ang netra-init, ay nagtatakda ng mga panuntunan sa network upang harangin ang trapiko. Ginagamit niya Mga panuntunan sa pag-redirect ng iptables upang maharang ang lahat o bahagi ng trapiko sa sidecar, na siyang pangalawang pangunahing bahagi ng Netramesh. Maaari mong i-configure kung aling mga port ang kailangang ma-intercept para sa mga papasok at papalabas na TCP session: INBOUND_INTERCEPT_PORTS, OUTBOUND_INTERCEPT_PORTS.

Ang tool ay mayroon ding isang kawili-wiling tampok - probabilistic routing. Kung eksklusibo kang gumagamit ng Netramesh para sa pagkolekta ng mga tracing span, sa isang kapaligiran ng produksyon maaari kang mag-save ng mga mapagkukunan at paganahin ang probabilistic routing gamit ang mga variable. NETRA_INBOUND_PROBABILITY ΠΈ NETRA_OUTBOUND_PROBABILITY (mula 0 hanggang 1). Ang default na halaga ay 1 (lahat ng trapiko ay naharang).

Pagkatapos ng matagumpay na pagharang, tinatanggap ng netra sidecar ang bagong koneksyon at mga gamit SO_ORIGINAL_DST opsyon sa socket para makuha ang orihinal na destinasyon. Ang Netra ay nagbukas ng bagong koneksyon sa orihinal na IP address at nagtatatag ng two-way na TCP na komunikasyon sa pagitan ng mga partido, nakikinig sa lahat ng trapikong dumadaan. Kung ang port ay tinukoy bilang HTTP, sinusubukan ng Netra na i-parse at i-trace ito. Kung nabigo ang pag-parse ng HTTP, babalik ang Netra sa TCP at malinaw na i-proxy ang mga byte.

Pagbuo ng isang dependency graph

Pagkatapos makatanggap ng malaking halaga ng impormasyon sa pagsubaybay sa Jaeger, gusto kong makakuha ng kumpletong graph ng mga pakikipag-ugnayan sa system. Ngunit kung ang iyong system ay medyo na-load at bilyun-bilyong mga tracing span ang naipon bawat araw, ang pagsasama-sama ng mga ito ay hindi magiging isang madaling gawain. Mayroong isang opisyal na paraan upang gawin ito: spark-dependencies. Gayunpaman, aabutin ng ilang oras upang makabuo ng kumpletong graph at pipilitin kang i-download ang buong dataset mula sa Jaeger sa nakalipas na XNUMX na oras.

Kung gumagamit ka ng Elasticsearch upang mag-imbak ng mga tracing span, maaari mong gamitin isang simpleng Golang utility, na bubuo ng parehong graph sa ilang minuto gamit ang mga feature at kakayahan ng Elasticsearch.

Netramesh - magaan na solusyon sa mesh ng serbisyo

Paano gamitin ang Netramesh

Ang Netra ay madaling maidagdag sa anumang serbisyo na nagpapatakbo ng anumang orkestra. Makakakita ka ng isang halimbawa dito.

Sa ngayon, walang kakayahan ang Netra na awtomatikong ipatupad ang mga sidecar sa mga serbisyo, ngunit may mga plano para sa pagpapatupad.

Ang kinabukasan ng Netramesh

pangunahing layunin Netramesh ay upang makamit ang kaunting mga gastos sa mapagkukunan at mataas na pagganap, na nagbibigay ng mga pangunahing kakayahan para sa pagmamasid at kontrol ng inter-service na komunikasyon.

Sa hinaharap, susuportahan ng Netramesh ang iba pang protocol ng layer ng application bukod sa HTTP. Ang pagruruta ng L7 ay magiging available sa malapit na hinaharap.

Gamitin ang Netramesh kung nakatagpo ka ng mga katulad na problema at sumulat sa amin ng mga tanong at mungkahi.

Pinagmulan: www.habr.com

Magdagdag ng komento