Ein vollständiger Monitoring-Stack für Server und Kubernetes

R. B. Atai

Ein vollständiger Monitoring-Stack ist nicht Grafana mit einem hübschen Dashboard. Ein Dashboard hilft dabei, das System zu betrachten, beantwortet für sich genommen aber nicht die zentrale Betriebsfrage: Was ist kaputt, wo genau, wie schwerwiegend ist es und wen muss man wecken?

Ein kleines Produkt braucht in der Regel fünf Ebenen: Metriken, Logs, Traces, Alerts und eine durchdachte Speicherarchitektur. Prometheus, Grafana, Loki, Tempo, OpenTelemetry und Alertmanager decken diese Ebenen ab, ohne dich an einen einzigen Cloud-Anbieter zu binden. Diesen Stack kannst du auf einem einzelnen VPS, auf einigen wenigen Servern oder in Kubernetes betreiben. Aber du solltest ihn nicht als Haufen angesagter Container aufsetzen. Du musst ihn als System zusammensetzen, das dein Team auch wirklich betreiben kann und aus dem es Nutzen zieht.

Was ein vollständiger Stack abdecken muss

Monitoring beginnt nicht mit der Wahl eines Werkzeugs. Es beginnt mit der Liste der Fragen, die dein Team in der Produktion beantworten will.

Erste Frage: Lebt der Service? Dafür brauchst du Verfügbarkeitsmetriken, Health Checks, Latenz, Fehlerrate und grundlegende SLOs. Wenn die API 200 zurückgibt, die p95-Latenz aber auf fünf Sekunden gestiegen ist, ist das bereits ein Vorfall, auch wenn die Uptime formal intakt bleibt.

Zweite Frage: Reichen die Ressourcen? CPU, RAM, Disk-I/O, freier Speicher, Netzwerk, File Descriptors, Containerzustand, Last auf der Datenbank — das ist der langweilige Teil des Monitorings, aber gerade er bewahrt dich oft vor nächtlichen Ausfällen. Eine volle Festplatte oder ein außer Kontrolle geratenes Log-Volumen legt kleine Produkte häufiger lahm als komplexe verteilte Bugs.

Dritte Frage: Was ist innerhalb der Anwendung passiert? Hier reichen Metriken allein nicht. Du brauchst strukturierte Logs und Request-Tracing: Welcher Endpoint ist langsam, welcher externe Aufruf hängt, wo ist der Fehler aufgetreten und durch welche Services lief der Request.

Vierte Frage: Wer erfährt von dem Problem? Ein Alert ohne Routing ist nur ein Eintrag in einer UI. Du brauchst Regeln, Gruppierung, Unterdrückung abhängiger Alerts, Silences während Wartungsarbeiten und Zustellung an Telegram, Slack, E-Mail, PagerDuty oder ein anderes On-Call-System.

Fünfte Frage: Was kostet die Aufbewahrung? Die Retention für Metriken, Logs und Traces muss eine bewusste Entscheidung sein. Sämtliche Debug-Logs ein Jahr lang in einem selbst gehosteten Loki aufzubewahren, ist meist keine Strategie, sondern ein künftiger Plattencrash.

Die Rolle der einzelnen Komponenten

In diesem Stack hat jedes Werkzeug seinen eigenen Verantwortungsbereich.

Prometheus sammelt und speichert Metriken als Zeitreihen. Seine Stärken sind das Pull-Modell, Service Discovery, Labels und PromQL. Für Server zieht es Daten aus node_exporter, für Container aus cAdvisor oder Runtime-Metriken und für Kubernetes aus dem Kubelet, kube-state-metrics, dem Ingress-Controller, Datenbanken und Anwendungen. Prometheus beantwortet gut die Fragen „wie viel“, „wie schnell“, „wie oft“ und „wann hat es begonnen“. (Prometheus)

Grafana ist die Oberfläche für die Untersuchung. Grafana verbindet sich mit Prometheus, Loki, Tempo und anderen Datenquellen, baut Dashboards, hilft beim Erkunden der Daten über Explore und verknüpft verschiedene Signale miteinander. Grafana sollte nicht die einzige Quelle der Wahrheit sein: Wenn Prometheus oder Loki ausfällt, retten dich hübsche Panels nicht. Aber als zentrales Fenster für den Betrieb ist es zur Standardwahl geworden. (Grafana)

Loki speichert Logs. Sein wesentlicher Unterschied zum Elasticsearch-Ansatz ist, dass Loki nicht den gesamten Logtext indexiert, sondern Labels für Log-Streams. Das senkt die Speicherkosten, verlangt aber Disziplin: Labels sollten helfen, nach Service, Namespace, Pod, Host und Environment zu filtern, und nicht zu einer endlosen Menge eindeutiger Werte werden. (Loki)

Tempo speichert verteilte Traces. Traces sind dort wichtig, wo ein einzelner Nutzer-Request durch eine API, eine Queue, einen Worker, eine Datenbank und einen externen Service läuft. Eine Metrik zeigt den Anstieg der Latenz. Ein Log zeigt ein einzelnes Ereignis. Ein Trace zeigt den Weg des Requests und die Stelle, an der die Zeit verbraucht wurde. (Tempo)

OpenTelemetry ist die Ebene für die Instrumentierung und das Routing von Telemetrie. Sein Wert liegt nicht darin, „noch ein Agent“ zu sein, sondern darin, dass du die Anwendung einmal instrumentierst und Traces, Metriken und Logs über ein gemeinsames Protokoll und den Collector an verschiedene Backends schickst. Das verringert Vendor Lock-in und hilft dir, die Anwendung beim Wechsel des Speichers nicht neu schreiben zu müssen. (OpenTelemetry)

Alertmanager empfängt Alerts von Prometheus, gruppiert sie, dedupliziert sie, unterdrückt abhängige Ereignisse und schickt Benachrichtigungen an die Empfänger. Prometheus entscheidet, dass eine Bedingung wahr geworden ist. Alertmanager entscheidet, wie daraus kein Spam wird und wer genau das Signal bekommen soll. (Alertmanager)

Architektur für einen oder mehrere Server

Für einen einzelnen VPS oder eine kleine Gruppe von Servern musst du nicht mit einem Kubernetes-nativen Aufbau beginnen. Ein sauberer self-hosted Stack, den du mit Docker Compose oder systemd-Diensten hochfährst, genügt.

Ein minimaler Aufbau sieht so aus:

Ebene Komponenten Was sie erfasst
Servermetriken node_exporter + Prometheus CPU, RAM, Disk, Netzwerk, Load Average
Containermetriken cAdvisor oder ein Runtime-Exporter Containernutzung, Restarts, Limits
Anwendungsmetriken Prometheus-Endpoint oder OpenTelemetry Collector Request Rate, Latenz, Fehler, Business-Metriken
Logs Grafana Alloy oder ein anderer Loki-kompatibler Agent + Loki stdout/stderr der Container, System-Logs, App-Logs
Traces OpenTelemetry SDK/Agent + Collector + Tempo der Weg des Requests zwischen Services
UI und Alerts Grafana + Alertmanager Dashboards, Explore, Benachrichtigungen

Auf einem einzelnen Server kannst du Prometheus, Loki, Tempo, Grafana und Alertmanager neben der Anwendung betreiben, wenn die Last gering ist. Aber das ist ein Kompromiss: Wenn der Server komplett ausfällt, stirbt das Monitoring mit ihm. Ein reiferer Aufbau ist ein separater kleiner Monitoring-VPS, der die Produktionsserver von außen beobachtet und zumindest die Basismetriken getrennt von der Anwendung aufbewahrt.

Ein praktisches Minimum für einen VPS: node_exporter, Prometheus, Grafana, Loki, ein Log-Agent und Alertmanager. Tempo und OpenTelemetry lohnt es sich hinzuzufügen, sobald du mehrere Services, Queues, externe Abhängigkeiten oder regelmäßige Latenzuntersuchungen hast. Für einen Monolithen auf einem Server können Traces nützlich sein, sie sollten aber den Start des Basis-Monitorings nicht verzögern.

Architektur für Kubernetes

In Kubernetes wird Monitoring nicht nur zu einer Menge von Prozessen, sondern zu einem Teil der betrieblichen Control Plane. Hier zählen Service Discovery, Labels, Namespaces, Ownership und Scrape-Regeln.

Die Basisebene wird meist um kube-prometheus-stack herum gebaut. Er installiert den Prometheus Operator, Prometheus, Alertmanager, Grafana, Node Exporter, kube-state-metrics und ein Set fertiger Regeln. Der Hauptwert des Prometheus Operators liegt nicht darin, dass er „Prometheus installiert“, sondern in seinem Kubernetes-nativen Konfigurationsmodell: ServiceMonitor, PodMonitor, PrometheusRule und der deklarativen Verwaltung von Scrape-Targets. (Prometheus Operator)

Für Logs im Cluster wird ein Agent als DaemonSet auf jedem Node ausgerollt. Er liest die Container-Logs, fügt Labels wie namespace, pod, container, app, cluster hinzu und schiebt die Streams nach Loki. Es gilt dieselbe Label-Disziplin wie oben: request_id, user_id und rohe URLs gehören in die Logzeile oder den strukturierten Payload, nicht in den Index.

Für Traces werden Anwendungen über das OpenTelemetry SDK, Auto-Instrumentierung oder einen Sidecar-/Agent-Ansatz instrumentiert. Der OpenTelemetry Collector kann als DaemonSet für node-lokale Telemetrie-Aufnahme oder als Deployment-Gateway für zentrale Verarbeitung laufen. Auf einem kleinen Cluster reicht meist der Gateway-Modus. Auf einem großen senkt die Kombination aus Agent + Gateway Netzwerkverluste und zentralisiert Sampling, Anreicherung und Export.

In Kubernetes empfängt Tempo Traces meist über OTLP-, Jaeger- oder Zipkin-kompatible Endpoints und speichert sie in Object Storage oder einem lokalen Backend, sofern es eine kleine Umgebung ist. Für einen Produktionscluster ist eine lokale Festplatte als Langzeitspeicher für Traces eine Schwachstelle. Object Storage ist fast immer die ehrlichere Wahl.

Wie man Metriken, Logs und Traces verknüpft

Der größte Fehler bei self-hosted Observability ist, drei Speicher aufzusetzen und sie als drei getrennte Welten zu belassen. Dann sieht ein Engineer einen Ausschlag in Prometheus, sucht dann von Hand Logs in Loki und rät anschließend einen Trace in Tempo. Das ist besser als nichts, aber noch kein vollständiger Stack.

Die Verknüpfung beginnt mit einheitlichen Labels: service, environment, cluster, namespace, pod, instance. Wenn der Service in Prometheus api, in Loki backend-api und in den Traces main-http heißt, wird eine Untersuchung zur manuellen Übersetzung zwischen Systemen.

Die zweite Verknüpfung sind trace_id und span_id in den Logs. Wenn die Anwendung strukturierte Logs mit Trace-Kontext schreibt, kann Grafana einen Trace aus einer konkreten Logzeile öffnen. In die Gegenrichtung kann Tempo die zu einem Span gehörenden Logs anzeigen. Das ist besonders nützlich bei Fehlern, die nur bei einem einzigen Request sichtbar sind und keinen erkennbaren Ausschlag auf einem Dashboard erzeugen.

Die dritte Verknüpfung sind Exemplars. Eine Latenzmetrik zeigt einen Aggregatwert, aber ein Exemplar kann einen Punkt im Graphen an einen konkreten Trace binden. Der Weg der Untersuchung wird dann kürzer: Ausschlag im Graphen → Trace des langsamen Requests → Logs des konkreten Spans → Ursache.

Genau hier ist OpenTelemetry wichtiger, als es am Anfang scheint. Es liefert einen gemeinsamen Kontext für Telemetriesignale und bewahrt dich davor, Metriken, Logs und Traces als drei unabhängige Projekte zu sammeln.

Wo ein self-hosted Stack gerechtfertigt ist

Ein self-hosted Monitoring-Stack ergibt Sinn, wenn das Team einen Grund hat, sowohl die Daten als auch den Betrieb zu besitzen.

Der erste Grund ist Kontrolle. In geschlossenen Netzen, regulierten Umgebungen, B2B-Produkten mit sensiblen Logs oder Infrastruktur ohne stabilen ausgehenden Zugang kann es verboten oder unpraktisch sein, Telemetrie an ein externes SaaS zu schicken.

Der zweite Grund sind die Kosten bei Volumen. Bei managed Observability wachsen die Kosten oft mit der Zahl der Metrik-Serien, der Log-Ingestion, dem Trace-Volumen und der Retention. Bei kleinem Volumen kann SaaS günstiger sein, weil es keinen Engineer erfordert. Bei großem Volumen gewinnt ein self-hosted Stack manchmal, wenn das Team Cardinality, Retention und Object Storage beherrscht.

Der dritte Grund ist Unabhängigkeit. Prometheus, Loki, Tempo und OpenTelemetry erlauben eine portable Architektur: Die Anwendung muss nicht wissen, dass Traces heute nach Tempo gehen und morgen ein Teil der Telemetrie auf ein anderes Backend dupliziert wird.

Der vierte Grund ist betriebliches Lernen. Ein Team, das seine eigenen Alerts, Dashboards, Scrape-Configs und Retention eingerichtet hat, versteht seine Systeme meist besser. Aber dieser Vorteil entsteht nur, wenn es einen Owner gibt. Ein verwaistes self-hosted Monitoring ist schlechter als ein managed Service, weil es die Illusion von Kontrolle erzeugt.

Wo ein self-hosted Stack gefährlich ist

Das größte Risiko ist, zu unterschätzen, dass Monitoring ebenfalls ein Produktionssystem ist. Es muss aktualisiert, gesichert, abgesichert, skaliert und geprüft werden.

Der erste typische Fehler ist Cardinality. In Prometheus darfst du nicht gedankenlos Labels wie user_id, email, session_id, path mit rohen Parametern oder request_id hinzufügen. Jede eindeutige Kombination von Labels erzeugt eine neue Zeitreihe. Eine einzige schlechte Metrik kann mehr Ressourcen fressen als die gesamte Anwendung.

Der zweite Fehler sind Logs ohne Budget. Wenn jede Anwendung in der Produktion auf Debug-Level schreibt, wird Loki schnell zu einer Maschine, die Plattenplatz verbrennt. Logs müssen normiert werden: Levels, Sampling, Retention, Ausschluss lauter Zeilen und eine eigene Policy für Audit-Logs.

Der dritte Fehler sind laute Alerts. Ein Alert, der zehnmal am Tag feuert und keine Handlung erfordert, bringt dem Team bei, das Monitoring zu ignorieren. Ein guter Alert sollte bedeuten: Ein Mensch muss eingreifen, sonst leidet ein Nutzer oder das Geschäft.

Der vierte Fehler ist Monitoring innerhalb derselben Fehlerdomäne. Wenn die gesamte Observability in demselben Cluster lebt, den sie diagnostizieren soll, kann ein Netzwerk- oder Storage-Ausfall sowohl die Anwendung als auch deine Untersuchungswerkzeuge mitreißen. Für kleine Projekte ist das ein akzeptabler Kompromiss, aber man muss ihn verstehen.

Eine minimale Startkonfiguration

Für einen VPS ist das dasselbe Basisset aus Metriken, Logs, Grafana und Alertmanager aus dem Serverabschnitt. Nur eines lohnt sich separat hinzuzufügen: einen externen Uptime-Check. Ein internes Prometheus zeigt nicht immer, dass der Service für Nutzer aus dem Internet nicht erreichbar ist, weil es selbst auf derselben Seite des Ausfalls landen kann.

Für Kubernetes sieht die Startkonfiguration anders aus: kube-prometheus-stack, Loki mit einem DaemonSet-Agenten, Grafana-Datenquellen für Prometheus und Loki, Alertmanager-Routes und separate PrometheusRules für Anwendungen. Danach fügst du den OpenTelemetry Collector und Tempo für die Services hinzu, bei denen Latenz und service-übergreifende Aufrufe wirklich Traces erfordern.

Beginne nicht mit Thanos, Mimir, Multi-Cluster-Federation, einem komplexen HA-Aufbau und einem Jahr Retention, wenn du einen Cluster und ein Team aus wenigen Personen hast. Das sind Werkzeuge für die nächste Stufe. Die erste Stufe ist, Symptome vor dem Nutzer zu sehen, funktionierende Alerts zu haben und schnell von einem Graphen zu den Logs zu wechseln.

Eine praktische Baseline:

Szenario Minimum Wann erweitern
Einzelner VPS Prometheus, node_exporter, Grafana, Loki, Alertmanager Wenn mehrere Services, Queues oder häufige Latenzuntersuchungen auftauchen
Mehrere Server Ein separater Monitoring-VPS, Exporter auf den Hosts, zentralisiertes Loki Wenn du HA-Prometheus oder lange Retention brauchst
Ein Kubernetes-Cluster kube-prometheus-stack, Loki, Grafana, Alertmanager Wenn du Traces, Cross-Signal-Korrelation und Object Storage für lange Aufbewahrung brauchst
Mehrere Cluster Eine separate Observability-Ebene, Remote Write oder Federation, einheitliche Labels Wenn Teams und Umgebungen einander in die Quere kommen

Kurzes Fazit

Ein vollständiger Monitoring-Stack für Server und Kubernetes ist keine Liste angesagter Open-Source-Projekte. Er ist eine Architektur, in der Prometheus die Metriken übernimmt, Loki die Logs, Tempo die Traces, OpenTelemetry die Erfassung und Portabilität der Telemetrie, Grafana die Untersuchung und Alertmanager die Zustellung der Benachrichtigungen an Menschen.

Die self-hosted Variante ist gut, wenn du Kontrolle, vorhersehbare Kosten und Unabhängigkeit von einer managed Plattform brauchst. Aber sie verlangt Disziplin: Labels, Retention, Alerts, Updates, Speicher und Owner müssen vom ersten Tag an durchdacht sein.

Wenn du einen kurzen praktischen Rat willst: Beginne mit Metriken, Logs und vernünftigen Alerts. Füge dann Traces und OpenTelemetry dort hinzu, wo sie Untersuchungen wirklich verkürzen. Monitoring sollte die Zeit bis zum Verständnis eines Problems verkürzen und nicht zu einem weiteren System werden, das niemand zu überwachen schafft.

Und wenn dein Team oder Produkt diese Art von Monitoring braucht, aber die Kapazität fehlt, es selbst aufzubauen und zu betreiben, ist es eine völlig vernünftige Engineering-Entscheidung, Einrichtung und Betrieb zu delegieren. Was sich auslagern lässt, zeigt unser Leistungskatalog: von einer einmaligen Monitoring- und Logging-Einrichtung bis zu laufender SRE-Betreuung.