Istio en Kubernetes in productie. Deel 2. Tracering

In het verleden статье We hebben de basiscomponenten van Service Mesh Istio bekeken, kennis gemaakt met het systeem en antwoord gegeven op de belangrijkste vragen die doorgaans ontstaan ​​als je met Istio aan de slag gaat. In dit deel zullen we bekijken hoe we het verzamelen van traceringsinformatie via een netwerk kunnen organiseren.

Istio en Kubernetes in productie. Deel 2. Tracering

Het eerste waar veel ontwikkelaars en systeembeheerders aan denken als ze de woorden Service Mesh horen, is traceren. We voegen inderdaad een speciale proxyserver toe aan elk netwerkknooppunt waar al het TCP-verkeer doorheen gaat. Het lijkt erop dat het nu mogelijk is om eenvoudig informatie over alle netwerkinteracties op het netwerk te verzenden. Helaas zijn er in werkelijkheid veel nuances waarmee rekening moet worden gehouden. Laten we ze eens bekijken.

Misvatting nummer één: we kunnen gratis online wandelgegevens krijgen.

In feite kunnen we relatief gratis alleen de knooppunten van ons systeem met elkaar verbinden door middel van pijlen en de datasnelheid die tussen services verstrijkt (in feite alleen het aantal bytes per tijdseenheid). In de meeste gevallen communiceren onze services echter via een soort applicatielaagprotocol, zoals HTTP, gRPC, Redis, enzovoort. En uiteraard willen we traceringsinformatie zien die specifiek voor deze protocollen geldt; we willen de verzoeksnelheid zien, niet de datasnelheid. We willen de latentie van verzoeken begrijpen die ons protocol gebruiken. Ten slotte willen we het volledige pad zien dat een verzoek aflegt vanaf het inloggen op ons systeem tot het ontvangen van een antwoord van de gebruiker. Dit probleem is niet meer zo eenvoudig op te lossen.

Laten we eerst eens kijken hoe het verzenden van traceringsbereiken eruit ziet vanuit architectonisch oogpunt in Istio. Zoals we ons uit het eerste deel herinneren, heeft Istio een aparte component genaamd Mixer voor het verzamelen van telemetrie. In de huidige versie 1.0.* wordt het verzenden echter rechtstreeks vanaf proxyservers gedaan, namelijk vanaf de envoy proxy. Envoy-proxy ondersteunt het verzenden van traceringsbereiken met behulp van het zipkin-protocol. Het is mogelijk om andere protocollen aan te sluiten, maar alleen via een plug-in. Met Istio krijgen we onmiddellijk een samengestelde en geconfigureerde envoy-proxy, die alleen het zipkin-protocol ondersteunt. Als we bijvoorbeeld het Jaeger-protocol willen gebruiken en traceringsbereiken via UDP willen verzenden, zullen we ons eigen istio-proxy-image moeten bouwen. Er is ondersteuning voor aangepaste plug-ins voor istio-proxy, maar deze bevindt zich nog in de alfaversie. Als we het dus zonder een groot aantal aangepaste instellingen willen doen, wordt het scala aan technologieën dat wordt gebruikt voor het opslaan en ontvangen van traceerreeksen verkleind. Van de belangrijkste systemen kun je nu Zipkin zelf of Jaeger gebruiken, maar alles daar naartoe sturen met behulp van het zipkin-compatibele protocol (wat veel minder efficiënt is). Het zipkin-protocol zelf houdt in dat alle traceringsinformatie via het HTTP-protocol naar verzamelaars wordt verzonden, wat vrij duur is.

Zoals ik al zei, willen we protocollen op applicatieniveau traceren. Dit betekent dat de proxyservers die naast elke dienst staan, moeten begrijpen wat voor soort interactie er nu plaatsvindt. Standaard configureert Istio alle poorten als gewoon TCP, wat betekent dat er geen sporen worden verzonden. Om traceringen te kunnen verzenden, moet u eerst deze optie inschakelen in de hoofdmesh-configuratie en, wat erg belangrijk is, alle poorten van Kubernetes-service-entiteiten een naam geven in overeenstemming met het protocol dat in de service wordt gebruikt. Dat is bijvoorbeeld zo:

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
  - port: 80
    targetPort: 80
    name: http
  selector:
    app: nginx

Je kunt ook samengestelde namen gebruiken, zoals http-magic (Istio zal http zien en die poort herkennen als een http-eindpunt). Het formaat is: proto-extra.

Om niet een groot aantal configuraties te patchen om het protocol te bepalen, kun je een vuile oplossing gebruiken: patch de Pilot-component op het moment dat deze net is voert protocoldefinitielogica uit. Uiteindelijk zal het natuurlijk nodig zijn om deze logica te veranderen naar standaard en over te schakelen naar een naamgevingsconventie voor alle poorten.

Om te begrijpen of het protocol echt correct is gedefinieerd, moet u naar een van de zijspancontainers met envoy proxy gaan en een verzoek indienen bij de beheerderspoort van de envoy-interface met locatie /config_dump. In de resulterende configuratie moet u naar het bedieningsveld van de gewenste service kijken. Het wordt in Istio gebruikt als identificatie voor de plaats waar het verzoek wordt gedaan. Om de waarde van deze parameter in Istio aan te passen (we zullen deze dan zien in ons traceringssysteem), is het noodzakelijk om de serviceCluster-vlag te specificeren tijdens het starten van de zijspancontainer. Het kan bijvoorbeeld als volgt worden berekend op basis van variabelen die zijn verkregen uit de neerwaartse Kubernetes-API:

--serviceCluster ${POD_NAMESPACE}.$(echo ${POD_NAME} | sed -e 's/-[a-z0-9]*-[a-z0-9]*$//g')

Een goed voorbeeld om te begrijpen hoe tracering werkt in envoy is hier.

Het eindpunt zelf voor het verzenden van traceringsbereiken moet ook worden opgegeven in de lanceringsvlaggen van de proxy-proxy, bijvoorbeeld: --zipkinAddress tracing-collector.tracing:9411

Misvatting nummer twee: we kunnen kant-en-klaar via het systeem goedkoop volledige sporen van verzoeken verkrijgen

Helaas is dat niet zo. De complexiteit van de implementatie hangt af van hoe u de interactie van services al hebt geïmplementeerd. Waarom is dat?

Feit is dat om istio-proxy de correspondentie van inkomende verzoeken aan een dienst met degenen die dezelfde dienst verlaten te kunnen begrijpen, het niet voldoende is om simpelweg al het verkeer te onderscheppen. Je hebt een soort communicatie-ID nodig. HTTP-envoy-proxy gebruikt speciale headers, waardoor de envoy begrijpt welk specifiek verzoek aan de service specifieke verzoeken aan andere services genereert. Lijst met dergelijke headers:

  • x-verzoek-id,
  • x-b3-traceid,
  • x-b3-spanid,
  • x-b3-ouderspanid,
  • x-b3-bemonsterd,
  • x-b3-vlaggen,
  • x-ot-span-context.

Als je één enkel punt hebt, bijvoorbeeld een basisclient, waarin je dergelijke logica kunt toevoegen, dan is alles in orde, je hoeft alleen maar te wachten tot deze bibliotheek voor alle clients is bijgewerkt. Maar als je een zeer heterogeen systeem hebt en er geen unificatie is bij het overstappen van service naar service via het netwerk, dan zal dit hoogstwaarschijnlijk een groot probleem zijn. Zonder een dergelijke logica toe te voegen, zal alle traceringsinformatie slechts “single-level” zijn. Dat wil zeggen: we zullen alle interacties tussen diensten ontvangen, maar ze zullen niet in afzonderlijke doorgangsketens door het netwerk worden gelijmd.

Conclusie

Istio biedt een handig hulpmiddel voor het verzamelen van traceringsinformatie via een netwerk, maar u moet begrijpen dat u voor de implementatie uw systeem moet aanpassen en rekening moet houden met de kenmerken van de Istio-implementatie. Als gevolg hiervan moeten twee hoofdpunten worden opgelost: het definiëren van het protocol op applicatieniveau (dat moet worden ondersteund door de gezant-proxy) en het instellen van het doorsturen van informatie over de verbinding van verzoeken naar de dienst vanuit verzoeken van de dienst (met behulp van headers , in het geval van het HTTP-protocol). Wanneer deze problemen zijn opgelost, hebben we een krachtig hulpmiddel waarmee we op transparante wijze informatie uit het netwerk kunnen verzamelen, zelfs in zeer heterogene systemen die in veel verschillende talen en raamwerken zijn geschreven.

In het volgende artikel over Service Mesh kijken we naar een van de grootste problemen met Istio – het grote RAM-verbruik door elke sidecar-proxycontainer en bespreken we hoe je hiermee kunt omgaan.

Bron: www.habr.com

Voeg een reactie