In het verleden We have examined the basic components of the Service Mesh Istio, got acquainted with the system, and addressed the main questions that usually arise at the beginning of working with Istio. In this part, we will look at how to organize the collection of tracing information across the network.

The first thing that comes to mind for many developers and system administrators when they hear the words Service Mesh is tracing. And indeed, we add a special proxy server at each node in the network through which all TCP traffic flows. It seems that now we can easily send information about all network interactions in the network. Unfortunately, in reality, there are many nuances that need to be considered. Let's take a look at them.
Myth number one: we can get data about network traversals for free.
In reality, relatively for free, we can only obtain the connected nodes of our system with arrows and the rate of data that flows between services (essentially only the amount of bytes per unit of time). However, in most cases, our services communicate using some application-level protocol, such as HTTP, gRPC, Redis, and so on. And of course, we want to see tracing information specifically for these protocols, we want to see the rate of requests, not the rate of data. We want to understand the latency of requests for our protocol. Finally, we want to see the complete path that a request takes from entering our system to receiving a response by the user. This task is not solved so easily.
Laten we beginnen met te bekijken hoe de verzending van tracing spans eruitziet vanuit architecturaal perspectief in Istio. Zoals we ons herinneren van deel ƩƩn, heeft Istio een aparte component voor het verzamelen van telemetrie, die Mixer wordt genoemd. Echter, in de huidige versie 1.0.* gebeurt de verzending rechtstreeks vanaf de proxyservers, met name van de envoy proxy. De envoy proxy ondersteunt de verzending van tracing spans via het zipkin-protocol direct 'out of the box'. Andere protocollen kunnen worden aangesloten, maar alleen via een plugin. Met Istio krijgen we een kant-en-klare en geconfigureerde envoy proxy, waarin alleen het zipkin-protocol wordt ondersteund. Als we bijvoorbeeld het Jaeger-protocol willen gebruiken en tracing spans via UDP willen verzenden, moeten we onze eigen istio-proxy-afbeelding bouwen. Ondersteuning voor aangepaste plugins voor istio-proxy is beschikbaar, maar is nog steeds in de alpha-versie. Daarom, als we zonder veel aangepaste instellingen willen werken, vermindert de kring van gebruikte technologieƫn voor het opslaan en ontvangen van tracing spans. Van de belangrijkste systemen kan momenteel in wezen alleen Zipkin zelf of Jaeger worden gebruikt, maar het moet allemaal worden verzonden via het zipkin-compatibele protocol (wat aanzienlijk minder efficiƫnt is). Het zipkin-protocol zelf gaat ervan uit dat alle tracing-informatie naar de collectors wordt verzonden via het HTTP-protocol, wat behoorlijk kostbaar is.
Zoals ik al zei, willen we de protocollen op toepassingsniveau traceren. Dit betekent dat de proxyservers die naast elke service staan, moeten begrijpen welke interactie er op dat moment plaatsvindt. Standaard configureert Istio voor alle poorten het type plain TCP, wat betekent dat er geen tracings zullen worden verzonden. Om tracing te kunnen verzenden, moet je allereerst deze optie inschakelen in de hoofd mesh-configuratie en, wat heel belangrijk is, alle poorten van de service-entiteiten in Kubernetes benoemen in overeenstemming met het protocol dat in de service wordt gebruikt. Dat wil zeggen, bijvoorbeeld zo:
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- port: 80
targetPort: 80
name: http
selector:
app: nginxJe kunt ook samengestelde namen gebruiken, zoals http-magic (Istio zal http zien en deze poort herkennen als een http-endpoint). Het formaat is als volgt: proto-extra.
Om een enorme hoeveelheid configuraties voor het definiƫren van het protocol niet te hoeven patchen, kun je gebruik maken van een vuile workaround: patch de Pilot-component op het moment dat deze net Uiteindelijk moet deze logica natuurlijk worden aangepast naar de standaard en moeten we overstappen op de naamgevingsconventie van alle poorten.
Om te begrijpen of het protocol inderdaad correct is gedefinieerd, moet je in een van de sidecar-containers met een envoy-proxy inloggen en een verzoek indienen op de poort van de admin-interface van envoy met de locatie /config_dump. In de resulterende configuratie moet je kijken naar het veld operation van de gewenste service. Dit wordt in Istio gebruikt als identifier voor waar het verzoek naartoe gaat. Om deze parameter in Istio te personaliseren (we zullen het later in ons tracing-systeem zien), moet je tijdens het opstarten van de sidecar-container de vlag serviceCluster opgeven. Bijvoorbeeld, je kunt het zo berekenen uit de variabelen die zijn verkregen uit de downward API van Kubernetes:
--serviceCluster ${POD_NAMESPACE}.$(echo ${POD_NAME} | sed -e 's/-[a-z0-9]*-[a-z0-9]*$//g')
Een goed voorbeeld om te begrijpen hoe tracing in envoy werkt, is .
De endpoint om tracing spans te verzenden moet ook worden opgegeven in de opstartvlaggen van de envoy-proxy, bijvoorbeeld: --zipkinAddress tracing-collector.tracing:9411
Misvatting nummer twee: we kunnen goedkoop volledige traces van verzoeken door het systeem uit de doos krijgen.
Helaas is dat niet het geval. De implementatiecomplexiteit hangt af van hoe je al eerder de interactie tussen services hebt gerealiseerd. Waarom is dat zo?
Het punt is dat, om ervoor te zorgen dat istio-proxy de overeenstemming tussen inkomende verzoeken naar de service en uitgaande verzoeken van diezelfde service kan begrijpen, het niet voldoende is om gewoon al het verkeer af te tappen. Je moet een soort identificator voor de verbinding hebben. In HTTP gebruikt de envoy-proxy speciale headers waarmee envoy begrijpt welke specifieke aanvraag aan de service bepaalde aanvragen naar andere services genereert. Een lijst van dergelijke headers:
- x-request-id,
- x-b3-traceid,
- x-b3-spanid,
- x-b3-parentspanid,
- x-b3-sampled,
- x-b3-flags,
- x-ot-span-context.
Als je een enkele plek hebt, bijvoorbeeld een basisclient, waar je dergelijke logica kunt toevoegen, is dat prima; je hoeft alleen maar te wachten op de update van deze bibliotheek bij alle klanten. Maar als je een zeer heterogeen systeem hebt en er geen uniformiteit is in de interacties tussen services over het netwerk, dan zal dit waarschijnlijk een groot probleem zijn. Zonder het toevoegen van dergelijke logica zal alle tracing-informatie slechts 'eenvormig' zijn. Dat wil zeggen, we zullen alle interacties tussen services krijgen, maar ze zullen niet samengevoegd zijn tot enkele ketens van netwerkdoorlopen.
Conclusie
Istio biedt een gebruiksvriendelijke tool voor het verzamelen van tracinginformatie in netwerken, maar het is belangrijk te begrijpen dat implementatie vraagt om aanpassing van je systeem en rekening houden met de specifieke kenmerken van de Istio-implementatie. Uiteindelijk moeten er twee belangrijke punten worden opgelost: de bepaling van het toepassingsprotocol (dat door de envoy proxy ondersteund moet worden) en de configuratie van het doorgeven van informatie over de samenhang van verzoeken naar de dienst vanuit de verzoeken van de dienst (met behulp van headers, in het geval van het HTTP-protocol). Zodra deze vragen zijn beantwoord, hebben we een krachtig hulpmiddel dat transparant informatie uit het netwerk kan verzamelen, zelfs in zeer heterogene systemen die zijn geschreven in verschillende programmeertalen en frameworks.
In het volgende artikel over Service Mesh zullen we een van de grootste problemen van Istio bespreken ā het hoge geheugengebruik van elke sidecar proxycontainer en hoe dit kan worden aangepakt.
Bron: habr.com
