Tracing met Jaeger

Geplaatst door

Applicaties uitrollen op Kubernetes is mooi maar zonder de juiste hulpmiddelen kan het lastig zijn om te traceren waar een probleem zich voordoet. Als de monoliet is opgedeeld in een hoop microservices die ook nog eens over verschillende Kubernetes nodes verspreid actief zijn, wordt debuggen soms lastig. Waar gaat het mis? Waar zit de vertraging? Zit het probleem op specifieke pods of nodes? Zonder hulpmiddelen kan het lastig zijn. Jaeger kan hierbij goed van pas komen

Concepten van Jaeger

Jaeger maakt het mogelijk om distributed tracing te doen. Vanaf het moment dat een request op de applicatie op de ingress controller binnen komt, wordt er een tracing ID aan toegevoegd. De ingress controller stuurt informatie over het request, gekoppeld met het tracing ID naar Jaeger. Als het request naar een van de micro services wordt gerouteerd, wordt het tracing ID meegestuurd. De tracing integratie binnen je applicatie zal vervolgens de ins en outs van het request gekoppeld met het tracing ID doorsturen naar Jaeger. Elke individuele actie die je applicatie uitvoert wordt in Jaeger een “span” en maakt inzichtelijk wat er op dat moment gebeurt en hoe lang het duurt. In het geval meerdere micro services nodig zijn voor de afhandeling van het request, wordt dit tracing ID meegestuurd en zal ook de volgende applicatie zijn info naar Jaeger kunnen sturen. Het resultaat is dat Jaeger nu een geïsoleerd beeld heeft van alle “spans” die door het gezamelijke tracing ID gezamelijk een “trace” vormen die in de Jaeger web interface gevisualiseerd kan worden. Als achterliggende storage kan bijvoorbeeld Cassandra of ElasticSearch gebruikt worden.

Opentracing

Waar Jaeger de implementatie is, is Opentracing de specificatie. Als je het wil gebruiken, is het handig dat alle software componenten deze specificatie ondersteunen. Zo is er standaard wel support voor Jaeger in de Ingress Controller Traefik maar mogelijk is dat niet voor een andere implementatie het geval. Dit geldt ook voor de integratie met de gebruikte programmeertaal voor je applicatie. Voor een actueel overzicht van ondersteunde programmeertalen kan je kijken op https://opentracing.io In het geval de gebruikte programmeertaal er niet tussen staat, betekent dat niet direct dat Jaeger niet gebruikt kan worden. Zo ontbreekt .NET Core op het moment van schrijven in de lijst maar heb ik het recentelijk wel goed werkend gezien.

Installatie

Binnen Kubernetes zijn dingen simpel te installeren. dit geeft je echter geen garantie tot success. Zo zul je na moeten denken over schaling van componenten en de manier waarop het goed integreert met bestaande componenten van het Kubernetes cluster. het simpel installeren van de voorbeeld yaml files die je kan vinden op https://www.jaegertracing.io/ zullen mogelijk op een aantal plekken wat aangepast moeten worden. In dit voorbeeld heb ik gekozen voor ElasticSearch als datastore. De installatie en configuratie daarvan is out of scope in dit artikel.

Een Jaeger instalatie bevat verschillende componenten die allemaal op een eigen manier geconfigureerd kunnen worden.

Jaeger-Agent
De agent wordt gebruikt om vanuit de applicaties span informatie te versturen. De agent kan bijvoorbeeld als “daemon set” maar ook als sidecar geïnstalleerd worden. Het ligt aan je use case wat daar handig is maar in het testlab heb ik het als “daemon set” geïnstalleerd. de agent is dan standaard op elke kubernetes node actief en door je pod te voorzien van environment variabelen kun je achterhalen op welke kubernetes node de pod draait zodat je applicatie altijd de jaeger agent gebruikt die op dezelfde node actief is als de pod zelf. Zinloos UDP verkeer over het netwerk wordt hiermee voorkomen.

Jaeger-Collector
De collector ontvangt de informatie van alle agents. De collector is volledig stateless en kan als apart component geschaald worden. Dit levert een schalingsvoordeel op aangezien een enkele collector pod op een zeker moment het druk kan krijgen als het gebruik van Jaeger toeneemt en je Kubernetes cluster groeit. De collector stuurt de data vervolgens door naar in dit geval ElasticSearch.

Jaeger-Query
Dit is de Jaeger web interface waarop de traces en de bijbehorende spans te visualiseren zijn. Dit is een enkele pod met een kubernetes service er boven. je zou als je platform een ingress controller heeft, een ingress resource kunnen aanmaken zodat de web interface eenvoudig bereikt kan worden.

Jaeger-Ingester
De Ingester is instaat om span informatie te halen uit “Kafka topics”. Dit component is optioneel. Sinds in het testlab geen Kafka actief is, heb ik het niet gebruikt en is het out of scope in dit artikel.

demo

Jaeger integreert mooi met Kubernetes maar voor deze demo heb je alleen docker ( op linux) nodig. De demo bevat de hot-rod (rides on demand) applicatie demo bestaande uit een aantal microservices die hun span informatie doorsturen naar Jaeger. Door in de web interface van de applicatie te klikken wordt Jaeger gevuld met data. De demo setup is snel op te zetten met de volgende scripts:

docker run \   --rm \   --name jaeger \   -p6831:6831/udp \   -p16686:16686 \   jaegertracing/all-in-one:1.8
docker run \   --rm \   --link jaeger \   --env JAEGER_AGENT_HOST=IPVANSERVER \   --env JAEGER_AGENT_PORT=6831 \   -p8080-8083:8080-8083 \   jaegertracing/example-hotrod:latest \   all
  • De hot-rod applicatie is dan te benaderen op: http://ipvanserver:8080
  • De Jaeger web interface is dan te bereiken op http://ipvanserver:16686

Na wat rondklikken in de applicatie is het interessant om te kijken hoe de span informatie van de microservices zichtbaar wordt in de Jaeger web interface:

Al snel wordt er vanalles inzichtelijk. Op een manier die we ook kennen van developer tools in je browser wordt weergegeven welke units of work (spans) uitgevoerd worden binnen de micro services en ook wordt het inzichtelijk waar een probleem zich voordoet. Door op de spans te klikken kan er diep ingezoomd worden op wat er allemaal gebeurt binnen de micro services. Voor de demo wordt geen persistent storage gebruikt. Voor productieomgevingen is dat natuurlijk wel aan te raden zodat de data bewaard blijft. Wanneer Jaeger niet direct in Docker maar in Kubernetes geïnstalleerd wordt, wordt ook nog helder op welke Kubernetes node de pod draait die dat deel van het request uitvoert.

Tot slot

Jaeger is enorm handig. Begrijp wel dat het requests iets logger maakt. De overhead neemt iets toe. Voor het analyseren van een probleem is dat natuurlijk geen probleem maar voor de dagelijkse praktijk op een productieplatform kan het onwenselijk zijn. Maak je opstelling zo dat het makkelijk aan en uit te zetten is.

Eén reactie

Geef een reactie