Tracing - Das Licht im Dunkel von Microservice-Systemen

Ein Ökosystem mit vielen Microservices zu durchschauen, ist für DevOps Teams im Betrieb eine echte Herausforderung. Tracing kann hier Licht ins Dunkel bringen.

 Autoren: Mirko Serbak & Simon Flühmann

Stell dir vor, du schläfst tief und fest und träumst von einer perfekten DevOps Toolchain. Mitten in der Nacht wirst du vom lauten Läuten des Pikett-Handys aus dem Schlaf gerissen - das End-to-End-Monitoring meldet eine kritische Anzahl an Fehlern auf der Produktion! Schlaftrunken und noch im Pyjama startest du deinen Rechner und machst dich sogleich auf die Suche nach der Lösung. Die Fehlermeldungen, die du finden kannst, sind sehr kryptisch und du kannst dir daraus keinen Reim machen. Zudem bist du dir nicht mal sicher, wo du deine Suche starten solltest…

Wie Tracing in einer solchen und weiteren Situationen helfen kann, was OpenTelemetry ist und worauf man beim Instrumentieren achten sollte, sowie wie man beim Implementieren vorgehen kann, darauf gehen wir in diesem Blog näher ein.  

 

Ausgangslage

Mit dem Aufkommen ständig komplexer werdender Software-Systeme sind solche Situationen leider nicht mehr nur der Ausnahmefall, sondern können jederzeit passieren. Wir, als DevOps Team, verlieren zunehmend die Fähigkeit zu erkennen, wie einzelne Komponenten funktionieren und voneinander abhängen. Es ist nicht mehr auf den ersten Blick erkennbar, wie ein Software-System als Ganzes funktioniert. 

Das Problem verschärft sich besonders beim Einsatz moderner Applikationen. Diese setzen auf hoch verteilte Architekturmuster mit Microservices, Skalierung und Asynchronität, nutzen hybride Cloud-Services bis hin zur kompletten Externalisierung einzelner Funktionsaufrufe oder Berechnungen (Functions as a Service (FaaS) und Serverless computing). Hinzu kommen schnelle und unabhängige Release-Zyklen mit Continuous Deployment, welche dafür sorgen, dass sich Systeme permanent verändern.

Wie sollen DevOps Teams solche komplexen Systeme überhaupt noch verstehen, geschweige denn betreiben können? Tracing to the rescue!

Tracing to the rescue!
Bild: Super Trace to the rescue!

Was ist Tracing and why should you care?

Ein Trace fasst eine oder mehrere kontextuell zusammengehörige und aufeinanderfolgende Arbeitseinheiten, sogenannte Spans, zu einem Paket zusammen. Ein Span repräsentiert eine zeitlich festgelegte Operation innerhalb einer Transaktion und teilt seinen Kontext mit anderen Spans innerhalb des Trace. Gantt-Diagramme oder gerichtete Graphen können diese Zusammengehörigkeit gut visualisieren:

Ein Trace als Gantt-Chart
Abbildung 1: Ein Trace als Gantt-Chart
Ein Trace als gerichteter Graph
Abbildung 2: Ein Trace als gerichteter Graph

Wie wird Tracing eingesetzt?

Für den effizienten Betrieb von Software ist ein gut kalibriertes Tracing-System für ein DevOps Team extrem hilfreich. Tracing beantwortet Fragen zu einem Request, die kein anderes System beantworten kann: 

Was macht unsere Applikation genau?

Tracing zeigt auf, welchen Weg ein Request durch welche Services genommen hat, wie sich die Services verhalten haben und wie unsere Applikation integriert ist.

Wo sind unsere Bottlenecks?

Falls ein Request langsam ist, hilft Tracing Latenzen zu identifizieren und effektiv anzugehen.

Was ist der Kontext eines Fehlers in unserer Applikation?

Falls ein Request scheitert, erleichtert Tracing, dank der Transaktionsicht die Lokalisation des Fehlers und visualisiert, welche Services daran beteiligt sind. Das ist sowohl hilfreich für die Root-Cause Analyse, als auch für den Einbau kurzfristiger Bypass-Rettungsaktionen.

Drei Säulen von Observability

Tracing ist neben Metrics und Logs eine der drei Säulen von Observability. Sie ergeben ein Gesamtbild über den Systemzustand.

Logs

Aufgezeichnete Nachrichten von Ereignissen aus einer Applikation kennen wir als Logs.

Metrics

Metrics beschreiben quantitative Messwerte wie Zähler oder Arbeitsspeicher/CPU Nutzung.

Traces

Logs als auch Metrics entstammen jeweils einer einzelnen Instanz -Tracing hingegen dokumentiert verteilte Transaktionen im Gesamtsystem

Woher kommt Tracing?

Am Beispiel von Uber Technologies erkennt man sofort, weshalb Tracing für ein DevOps Team absolut elementar ist: Um nicht im Chaos des Ökosystems von über 3’000 hochskalierten Microservices in unterschiedlichsten Programmiersprachen zu versinken, sah sich das Observability Team von Uber gezwungen ein eigenes Tool für Transaktions-Tracing zu entwickeln. So entstand das Open-Source Tracing Backend “Jaeger” (siehe Bild) und ein Grundstein für das Open-Source-Projekt “OpenTelemetry” war gelegt.

“Die verteilte Rückverfolgung ermöglicht einen beispiellosen Einblick in unsere verteilten Systeme”

Yuri Shkuro, SWE Uber Technologies, Autor "Mastering Distributed Tracing", Entwickler von Jaeger & Co-Gründer des OpenTelemetry CNCF Projekts

distributed Tracing.svg
Bild 2: “Eine visuelle Darstellung einer Teilmenge der Microservices-Architektur von Uber und einer hypothetischen Transaktion”, Abbildung aus dem Buch “Mastering Distributed Tracing” von Dr. Yuri Shkuro

OpenTelemetry - ein Open-Source Standard für Tracing

OpenTelemetry (OTel) ist ein Projekt der Cloud Native Computing Foundation (CNCF). Es vereint seit 2019 OpenTracing und OpenCensus, welche ursprünglich von Uber Technologies und Google Inc. entwickelt wurden und ist inzwischen ein etablierter Industriestandard. OpenTelemetry bietet ein Set an generischen, herstellerneutralen APIs, sprachspezifischen SDKs für gängige Programmiersprachen und Daten-Konventionen zur Instrumentierung von Code. Weiter bietet OpenTelemetry bewährte Werkzeuge wie den OpenTelemetry Collector für das Sammeln, Prozessieren und Weiterleiten von Daten sowie Mechanismen für die Kontext-Propagierung über Service-Grenzen hinweg.

 

Mit dem Einsatz von OpenTelemetry sind Unternehmen für die Zukunft mit verteilten Systemen gerüstet:

  • Der Standard deckt alle Telemetriedaten ab (Traces, Metrics, Logs) und ermöglicht so eine einheitliche Verarbeitung
  • Beliebig erweiterbare und lose gekoppelte Observability Architektur mit voller Kontrolle über die Daten (flexible Verarbeitung- und Export-Funktionalität)
  • Open-Source = herstellerneutrale APIs und Standards = kein Vendor Lock-in
  • Weiterentwicklung durch aktive Open-Source Community 

 

Instrumentierung mit OpenTelemetry

Damit ein System Tracing-Daten emittieren kann, muss es instrumentiert werden. Als Open-Source Standard bietet OpenTelemetry Entwicklern ein gutes Werkzeug, bestehend aus zwei Herangehensweisen:  Manuelle Instrumentierung oder automatische Instrumentierung. Je nach Use Case bietet sich automatische Instrumentierung, manuelle Instrumentierung oder eine Kombination der beiden Ansätze an. 

 

Automatisch instrumentieren

Die automatische Instrumentierung erfordert, anders als die manuelle Instrumentierung, keine Code-Anpassungen. Stattdessen wird der Code meist zur Laufzeit oder Kompilierzeit automatisch um die für das Tracing benötigten Bibliotheken und Frameworks von einem Agenten ergänzt. Momentan bietet OpenTelemetry solche Agents nur für ein Set von Sprachen an. Anbieter von proprietären Tracing- bzw. Observability-Tools bieten eine umfassendere Abdeckung von Programmiersprachen.

In Java kann der OpenTelemetry Agent beim Ausführen einer App beispielsweise folgendermassen mitgegeben werden:

Bildschirm_foto 2023-02-28 um 10.57.55.png
Abbildung 3: Code Beispiel automatische Instrumentierung

Der Agent kann zudem mit Parametern so konfiguriert werden, dass die Tracing-Daten an den richtigen Endpoint emittiert werden. Diese Herangehensweise ermöglicht es also, mit minimalem Entwicklungsaufwand Tracing-Daten zu erstellen und zu versenden. Da die Instrumentierung aber automatisiert erfolgt, können nur Standardfälle betrachtet werden und applikationsspezifische Logik kann nicht berücksichtigt werden.

Manuell Instrumentieren

Enthält ein System oder eine Applikation komplexe und Business-kritische Implementationen, kann es sich lohnen, diese manuell zu instrumentieren. Das Erstellen und Verwalten der Spans und des Context (OTel API) sowie die Pipeline Konfiguration (OTel SDK) müssen dabei explizit im Code angelegt werden. Im Folgenden wird wiederum ein Beispiel anhand einer Java Applikation gemacht.

Bildschirm_foto 2023-02-28 um 10.57.44.png
Abbildung 4: Code Beispiel automatische Instrumentierung

Tracing Backends

Das Angebot an auf dem Markt erhältlichen Observability Backends für die Interpretation von Tracing Daten ist sehr divers und auch deren Funktionsumfang unterscheidet sich stark. Anbieter wie Dynatrace oder Datadog bieten Observability-Suiten an - Komplettlösungen, welche alle Arten von Telemetriedaten erfassen und verarbeiten können. Beide Hersteller bieten ausgereifte Tools für den Betrieb und die Überwachung von Software.

Dem gegenüber stehen Open-Source Lösungen wie Jaeger oder Zipkin. Diese Tools sind primär für die Verarbeitung von Traces ausgelegt und können andere Telemetriesignale nur limitiert verarbeiten. Sie sind somit als ergänzendes Teilstück eines ganzheitlichen Observability Systems für Logs, Metrics und Traces zu betrachten.  

Otel Connector.svg
Abbildung 5: Darstellung einer Microservice-Architektur mit OpenTelemetry Agents - deployed als Sidecars auf einer Container-Plattform. Die Agents übermitteln Telemetriedaten aus den Services an eine zentrale OpenTelemetry Collector Instanz, welche die Daten aufbereitet für die Darstellung durch Tracing Backends wie Jaeger.

Tracing in der Cloud

So bietet AWS das Werkzeug AWS Observability, Microsoft den Azure Monitor und Google die Google Cloud's Operations Suite.

Alle diese Lösungen sind Observaility Werkzeuge, die Logs, Metrics, Tracing miteinbeziehen und somit eine Gesamtsicht des Systems geben

Wie starte ich mit Tracing?

Je komplexer und verteilter ein System, desto mehr lohnt sich der Einsatz von Tracing. Im Allgemeinen empfehlen wir folgende Schritte, um Tracing in einem System umzusetzen:

  1. Tracing kennenlernen: Beispielsweise mit dem Hotrod Example.
  2. Nutzung von Programmiersprachen, welche bereits OpenTelemetry unterstützen.
  3. Einsatz des OpenTelemetry Collectors als zentrale Drehscheibe für Telemetriedaten.
  4. Dort mit Tracing starten, wo im Betrieb die grössten Pain Points vorhanden sind.
  5. Wahl und Aufbau eines geeigneten Tracing Backends.
  6. Automatische Instrumentierung mit OpenTelemetry für eine allgemeine Übersicht.
  7. Manuelle Instrumentierung mit OpenTelemetry für eine feingranulare Sicht, die Abdeckung kritischer Pfade und Erhebung fachlicher Metadaten.

 

Um wieder auf unseren Pikettdienst-Vorfall zu kommen: So konntest du schnell mit Hilfe des Tracing Systems auf Spurensuche und den Authentication-Service als Verursacher identifizieren. Es hatte sich beim Abarbeiten von Login Events auf dem Kafka Topic ein riesiger Consumer-Lag aufgebaut. Mit diesem Wissen konnte das Problem durch das Zuschalten weiterer Authentication-Service Instanzen innerhalb kürzester Zeit behoben werden.  

 

Unser Fazit ist, dass ein gutes Tracing-System dir das Klingeln auf dem Pikett-Handy nicht ersparen wird, jedoch die benötigte Zeit, um das Problem zu identifizieren und zu beheben wesentlich verkürzen, sodass du bald wieder seelenruhig weiter träumen kannst ;-).

Deine ipt-Experten

Willst du mehr zum Thema Tracing erfahren? Dann melde Dich bei uns.