Netramesh: solució de malla de servei lleugera

A mesura que passem d'una aplicació monolítica a una arquitectura de microserveis, ens enfrontem a nous reptes.

En una aplicació monolítica, sol ser bastant fàcil determinar en quina part del sistema s'ha produït l'error. El més probable és que el problema estigui al codi del propi monòlit o a la base de dades. Però quan comencem a buscar un problema en una arquitectura de microservei, tot ja no és tan evident. Hem de trobar el camí complet que va prendre la sol·licitud des del principi fins al final i seleccionar-lo entre centenars de microserveis. A més, molts d'ells també tenen les seves pròpies instal·lacions d'emmagatzematge, que també poden provocar errors lògics, així com problemes de rendiment i de tolerància a errors.

Netramesh: solució de malla de servei lleugera

He estat buscant durant molt de temps una eina que ajudés a fer front a aquests problemes (vaig escriure sobre això a Habré: 1, 2), però al final vaig fer la meva pròpia solució de codi obert. En aquest article parlo dels avantatges de l'enfocament de la malla de servei i comparteixo una nova eina per a la seva implementació.

El traçat distribuït és una solució comuna al problema de trobar errors en sistemes distribuïts. Però, què passa si aquest enfocament per recopilar informació sobre les interaccions de xarxa encara no s'ha implementat al sistema, o, pitjor, en part del sistema ja funciona correctament, però en part no, ja que no s'ha afegit als serveis antics? ? Per determinar la causa arrel exacta d'un problema, cal tenir una imatge completa del que està passant al sistema. És especialment important entendre quins microserveis estan implicats en camins clau per a l'empresa.

Aquí ens pot ajudar l'enfocament de malla de serveis, que s'ocuparà de tota la maquinària de recollida d'informació de la xarxa a un nivell inferior al que operen els mateixos serveis. Aquest enfocament ens permet interceptar tot el trànsit i analitzar-lo sobre la marxa. A més, les aplicacions ni tan sols han de saber-ne res.

Enfocament de malla de servei

La idea principal de l'enfocament de la malla de servei és afegir una altra capa d'infraestructura a la xarxa, que ens permetrà fer qualsevol cosa amb la interacció entre serveis. La majoria de les implementacions funcionen de la següent manera: s'afegeix un contenidor sidecar addicional amb un servidor intermediari transparent a cada microservei, a través del qual es passa tot el trànsit entrant i sortint del servei. I aquest és el mateix lloc on podem fer l'equilibri de clients, aplicar polítiques de seguretat, imposar restriccions al nombre de peticions i recopilar informació important sobre la interacció dels serveis en producció.

Netramesh: solució de malla de servei lleugera

Solucions

Ja hi ha diverses implementacions d'aquest enfocament: Istio и linkerd2. Ofereixen moltes característiques fora de la caixa. Però al mateix temps, hi ha una gran sobrecàrrega de recursos. A més, com més gran sigui el clúster en el qual opera aquest sistema, més recursos es necessitaran per mantenir la nova infraestructura. A Avito, operem clústers de kubernetes que contenen milers d'instàncies de servei (i el seu nombre continua creixent ràpidament). En la seva implementació actual, Istio consumeix ~ 300 Mb de RAM per instància de servei. A causa del gran nombre de possibilitats, l'equilibri transparent també afecta el temps de resposta global dels serveis (fins a 10 ms).

Com a resultat, vam analitzar exactament quines capacitats necessitàvem ara mateix i vam decidir que la raó principal per la qual vam començar a implementar aquestes solucions era la capacitat de recopilar informació de rastreig de tot el sistema de manera transparent. També hem volgut tenir control sobre la interacció dels serveis i fer diverses manipulacions amb les capçaleres que es transfereixen entre serveis.

Com a resultat, vam arribar a la nostra decisió:  Netramesh.

Netramesh

Netramesh és una solució de malla de servei lleugera amb la capacitat d'escalar infinitament, independentment del nombre de serveis del sistema.

Els objectius principals de la nova solució eren una sobrecàrrega baixa en recursos i un alt rendiment. De les característiques principals, de seguida volíem poder enviar de manera transparent els intervals de traçat al nostre sistema Jaeger.

Avui, la majoria de solucions al núvol s'implementen a Golang. I, per descomptat, hi ha raons per això. Escriure aplicacions de xarxa a Golang que funcionin de manera asíncrona amb E/S i escalar entre nuclis segons sigui necessari és convenient i bastant senzill. I, el que també és molt important, el rendiment és suficient per resoldre aquest problema. Per això també hem escollit Golang.

Productivitat

Hem centrat els nostres esforços a aconseguir la màxima productivitat. Per a una solució que es desplega al costat de cada instància del servei, es requereix un petit consum de RAM i temps de CPU. I, per descomptat, el retard de resposta també hauria de ser petit.

A veure quins resultats hem obtingut.

RAM

Netramesh consumeix ~ 10 Mb sense trànsit i 50 Mb com a màxim amb una càrrega de fins a 10000 RPS per instància.

El servidor intermediari Istio Envoy sempre consumeix ~ 300 Mb als nostres clústers amb milers d'instàncies. Això no permet escalar-lo a tot el clúster.

Netramesh: solució de malla de servei lleugera

Netramesh: solució de malla de servei lleugera

Amb Netramesh hem aconseguit una reducció de ~10 vegades en el consum de memòria.

CPU

L'ús de la CPU és relativament igual sota càrrega. Depèn del nombre de peticions per unitat de temps al sidecar. Valors a 3000 sol·licituds per segon al màxim:

Netramesh: solució de malla de servei lleugera

Netramesh: solució de malla de servei lleugera

Hi ha un punt més important: Netramesh: una solució sense pla de control i sense càrrega no consumeix temps de CPU. Amb Istio, els sidecars sempre actualitzen els punts finals del servei. Com a resultat, podem veure aquesta imatge sense càrrega:

Netramesh: solució de malla de servei lleugera

Utilitzem HTTP/1 per a la comunicació entre serveis. L'augment del temps de resposta d'Istio quan s'envia a través d'envoy va ser de fins a 5-10 ms, la qual cosa és molt per als serveis que estan preparats per respondre en un mil·lisegon. Amb Netramesh, aquest temps s'ha reduït a 0.5-2 ms.

Escalabilitat

La petita quantitat de recursos que consumeix cada proxy permet situar-lo al costat de cada servei. Netramesh es va crear intencionadament sense un component de pla de control per mantenir lleugerament cada sidecar. Sovint, a les solucions de malla de servei, el pla de control distribueix informació de descobriment de serveis a cada sidecar. Juntament amb això, ve informació sobre els temps d'espera i la configuració d'equilibri. Tot això us permet fer moltes coses útils, però, malauradament, augmenta la mida dels sidecars.

Descobriment de serveis

Netramesh: solució de malla de servei lleugera

Netramesh no afegeix cap mecanisme addicional per al descobriment de serveis. Tot el trànsit es transmet de manera transparent a través de Netra sidecar.

Netramesh admet el protocol d'aplicació HTTP/1. Per definir-lo, s'utilitza una llista configurable de ports. Normalment, el sistema té diversos ports a través dels quals es produeix la comunicació HTTP. Per exemple, utilitzem 80, 8890, 8080 per a la interacció entre serveis i peticions externes. En aquest cas, es poden establir mitjançant una variable d'entorn NETRA_HTTP_PORTS.

Si utilitzeu Kubernetes com a orquestrador i el seu mecanisme d'entitat de servei per a la comunicació intra-clúster entre serveis, el mecanisme continua sent exactament el mateix. En primer lloc, el microservei obté una adreça IP de servei mitjançant kube-dns i hi obre una nova connexió. Aquesta connexió s'estableix primer amb el netra-sidecar local i tots els paquets TCP arriben inicialment a netra. A continuació, netra-sidecar estableix una connexió amb la destinació original. NAT a la IP del pod al node segueix sent exactament igual que sense netra.

Traçat distribuït i reenviament de context

Netramesh proporciona la funcionalitat necessària per enviar intervals de traça sobre les interaccions HTTP. Netra-sidecar analitza el protocol HTTP, mesura els retards de sol·licitud i extreu la informació necessària de les capçaleres HTTP. En definitiva, obtenim tots els rastres en un únic sistema Jaeger. Per a una configuració detallada, també podeu utilitzar les variables d'entorn proporcionades per la biblioteca oficial biblioteca jaeger go.

Netramesh: solució de malla de servei lleugera

Netramesh: solució de malla de servei lleugera

Però hi ha un problema. Fins que els serveis no generin i enviïn una capçalera especial d'uber, no veurem espais de traçat connectats al sistema. I això és el que necessitem per trobar ràpidament la causa dels problemes. Aquí de nou Netramesh té una solució. Els servidors intermediaris llegeixen les capçaleres HTTP i, si no contenen l'identificador de traça uber, en generen un. Netramesh també emmagatzema informació sobre les sol·licituds entrants i sortints en un sidecar i les relaciona enriquint-les amb les capçaleres de sol·licituds sortints necessàries. Tot el que heu de fer als serveis és enviar només una capçalera X-Request-Id, que es pot configurar mitjançant una variable d'entorn NETRA_HTTP_REQUEST_ID_HEADER_NAME. Per controlar la mida del context a Netramesh, podeu establir les variables d'entorn següents: NETRA_TRACING_CONTEXT_EXPIRATION_MILLISECONDS (el temps durant el qual s'emmagatzemarà el context) i NETRA_TRACING_CONTEXT_CLEANUP_INTERVAL (freqüència de neteja del context).

També és possible combinar diversos camins al vostre sistema marcant-los amb un testimoni de sessió especial. Netra us permet instal·lar HTTP_HEADER_TAG_MAP per convertir les capçaleres HTTP en etiquetes d'abast de traça corresponents. Això pot ser especialment útil per fer proves. Després de superar la prova funcional, podeu veure quina part del sistema es va veure afectada filtrant per la clau de sessió corresponent.

Determinació de la font de la sol·licitud

Per determinar d'on prové la sol·licitud, podeu utilitzar la funcionalitat d'afegir automàticament una capçalera amb la font. Ús d'una variable d'entorn NETRA_HTTP_X_SOURCE_HEADER_NAME Podeu especificar un nom de capçalera que s'instal·larà automàticament. Mitjançant l'ús de NETRA_HTTP_X_SOURCE_VALUE podeu establir el valor al qual s'establirà la capçalera X-Source per a totes les sol·licituds sortints.

Això permet que la distribució d'aquesta capçalera útil es distribueixi uniformement per tota la xarxa. A continuació, podeu utilitzar-lo als serveis i afegir-lo als registres i mètriques.

Encaminament del trànsit i sistemes interns de Netramesh

Netramesh consta de dos components principals. El primer, netra-init, estableix regles de xarxa per interceptar el trànsit. Ell utilitza regles de redirecció d'iptables per interceptar tot o part del trànsit en sidecar, que és el segon component principal de Netramesh. Podeu configurar quins ports s'han d'interceptar per a les sessions TCP entrants i sortints: INBOUND_INTERCEPT_PORTS, OUTBOUND_INTERCEPT_PORTS.

L'eina també té una característica interessant: l'encaminament probabilístic. Si utilitzeu Netramesh exclusivament per recopilar intervals de traçat, en un entorn de producció podeu estalviar recursos i habilitar l'encaminament probabilístic mitjançant variables. NETRA_INBOUND_PROBABILITY и NETRA_OUTBOUND_PROBABILITY (de 0 a 1). El valor per defecte és 1 (s'intercepta tot el trànsit).

Després d'una intercepció correcta, netra sidecar accepta la nova connexió i utilitza SO_ORIGINAL_DST opció de sòcol per obtenir la destinació original. Aleshores, Netra obre una nova connexió a l'adreça IP original i estableix una comunicació TCP bidireccional entre les parts, escoltant tot el trànsit que hi passa. Si el port es defineix com a HTTP, Netra intenta analitzar-lo i rastrejar-lo. Si l'anàlisi HTTP falla, Netra torna a TCP i envia els bytes de manera transparent.

Construcció d'un gràfic de dependència

Després de rebre una gran quantitat d'informació de traça a Jaeger, vull obtenir un gràfic complet de les interaccions del sistema. Però si el vostre sistema està bastant carregat i milers de milions de traçats s'acumulen al dia, agregar-los no es converteix en una tasca tan fàcil. Hi ha una manera oficial de fer-ho: dependències d'espurna. Tanmateix, es necessitarà hores per crear un gràfic complet i us obligarà a descarregar tot el conjunt de dades de Jaeger durant les últimes 24 hores.

Si utilitzeu Elasticsearch per emmagatzemar espais de traça, podeu utilitzar-lo una senzilla utilitat Golang, que crearà el mateix gràfic en qüestió de minuts utilitzant les funcions i capacitats d'Elasticsearch.

Netramesh: solució de malla de servei lleugera

Com utilitzar Netramesh

Netra es pot afegir fàcilment a qualsevol servei que executi qualsevol orquestrador. Podeu veure un exemple aquí.

De moment, Netra no té la capacitat d'implementar automàticament sidecars als serveis, però hi ha plans d'implementació.

El futur de Netramesh

L'objectiu principal Netramesh és aconseguir uns costos mínims de recursos i un alt rendiment, proporcionant capacitats bàsiques per a l'observabilitat i el control de la comunicació entre serveis.

En el futur, Netramesh admetrà altres protocols de capa d'aplicació a més d'HTTP. L'encaminament L7 estarà disponible en un futur proper.

Utilitzeu Netramesh si trobeu problemes similars i escriu-nos amb preguntes i suggeriments.

Font: www.habr.com

Afegeix comentari