Kapitel 1. Was ist Prometheus?
Diese Arbeit wurde mithilfe von KI übersetzt. Wir freuen uns über dein Feedback und deine Kommentare: translation-feedback@oreilly.com
Prometheus ist ein quelloffenes, metrikbasiertes Überwachungssystem. Natürlich ist Prometheus bei weitem nicht das einzige System auf dem Markt, aber was macht es so besonders?
Prometheus macht eine Sache, und zwar eine gute. Es verfügt über ein einfaches, aber leistungsstarkes Datenmodell und eine Abfragesprache, mit der du analysieren kannst, wie deine Anwendungen und deine Infrastruktur funktionieren. Prometheus versucht nicht, Probleme außerhalb des Bereichs der Kennzahlen zu lösen, sondern überlässt diese anderen, besser geeigneten Tools.
Seit den Anfängen mit nicht mehr als einer Handvoll Entwickler/innen, die 2012 bei SoundCloud arbeiteten, ist um Prometheus eine Gemeinschaft und ein Ökosystem gewachsen. Prometheus ist hauptsächlich in Go geschrieben und unter der Apache 2.0 Lizenz lizenziert. Hunderte von Menschen haben zu dem Projekt beigetragen, das nicht von einem Unternehmen kontrolliert wird. Es ist immer schwer zu sagen, wie viele Nutzer/innen ein Open-Source-Projekt hat, aber wir schätzen, dass ab 2022 Hunderttausende von Organisationen Prometheus in der Produktion einsetzen. Im Jahr 2016 wurde das Prometheus-Projekt das zweite Mitglied1 der Cloud Native Computing Foundation (CNCF).
Für die Instrumentierung deines eigenen Codes gibt es Client-Bibliotheken in allen gängigen Sprachen und Laufzeiten, darunter Go, Java/JVM, C#/.Net, Python, Ruby, Node.js, Haskell, Erlang und Rust. Viele beliebte Anwendungen sind bereits mit Prometheus-Client-Bibliotheken instrumentiert, z. B. Kubernetes, Docker, Envoy und Vault. Für Software von Drittanbietern, die Metriken in einem anderen Format als Prometheus bereitstellt, gibt es Hunderte von Integrationen. Diese werden Exporter genannt und umfassen HAProxy, MySQL, PostgreSQL, Redis, JMX, SNMP, Consul und Kafka. Ein Freund von Brian hat sogar Unterstützung für die Überwachung von Minecraft-Servern hinzugefügt, da ihm seine Bilder pro Sekunde sehr wichtig sind.
Ein einfaches Textformat2 macht es einfach, Metriken an Prometheus zu übermitteln. Andere Überwachungssysteme, sowohl Open-Source- als auch kommerzielle, haben dieses Format ebenfalls unterstützt. So können sich all diese Überwachungssysteme auf ihre Kernfunktionen konzentrieren und müssen nicht für jede einzelne Software, die ein Benutzer wie du überwachen möchte, doppelte Arbeit leisten.
Das Datenmodell identifiziert jede Zeitreihe nicht nur mit einem Namen, sondern auch mit einer ungeordneten Menge von Schlüssel-Wert-Paaren, den sogenannten Labels. Die Abfragesprache PromQL ermöglicht die Aggregation über jedes dieser Labels, so dass du nicht nur pro Prozess, sondern auch pro Rechenzentrum und pro Service oder nach anderen von dir definierten Labels analysieren kannst. Diese können in Dashboard-Systemen wie Grafana und Perses grafisch dargestellt werden.
Warnmeldungen können mit der gleichen PromQL-Abfragesprache definiert werden, die du auch für die grafische Darstellung verwendest. Wenn du ein Diagramm erstellen kannst, kannst du auch eine Warnmeldung dazu erstellen. Labels machen die Pflege von Warnmeldungen einfacher, da du eine einzige Warnmeldung für alle möglichen Labelwerte erstellen kannst. Bei anderen Überwachungssystemen müsstest du für jede Maschine/Anwendung eine eigene Warnmeldung erstellen. Außerdem kann die Service-Erkennung automatisch bestimmen, welche Anwendungen und Maschinen aus Quellen wie Kubernetes, Consul, Amazon Elastic Compute Cloud (EC2), Azure, Google Compute Engine (GCE) und OpenStack abgefragt werden sollen.
Trotz all dieser Funktionen und Vorteile ist Prometheus effizient und einfach zu betreiben. Ein einziger Prometheus-Server kann Millionen von Proben pro Sekunde aufnehmen. Es handelt sich um eine einzelne, statisch gelinkte Binärdatei mit einer Konfigurationsdatei. Alle Komponenten von Prometheus können in Containern ausgeführt werden und verzichten auf alles, was den Konfigurationsmanagement-Tools in die Quere kommen würde. Prometheus ist so konzipiert, dass es in die bereits vorhandene Infrastruktur integriert und darauf aufgebaut werden kann, und nicht als eigene Verwaltungsplattform.
Jetzt, wo du einen Überblick darüber hast, was Prometheus ist, lass uns einen Schritt zurücktreten und uns ansehen, was mit "Monitoring" gemeint ist, um einen gewissen Kontext zu schaffen. Danach werden wir uns ansehen, was die Hauptkomponenten von Prometheus sind und was Prometheus nicht ist.
Was ist Überwachung?
In der weiterführenden Schule sagte einer von Brians Lehrern zu ihm, dass man, wenn man 10 Ökonomen fragen würde, was Wirtschaft bedeutet, 11 Antworten bekäme. Bei der Überwachung herrscht ein ähnlicher Mangel an Konsens darüber, was genau sie bedeutet. Wenn er anderen erzählt, was er macht, denken die Leute, dass sein Job alles beinhaltet, von der Überwachung der Temperatur in Fabriken bis hin zur Überwachung von Mitarbeitern, bei der er herausfindet, wer während der Arbeitszeit auf Facebook zugreift, und sogar Eindringlinge in Netzwerken aufspürt.
Prometheus wurde nicht entwickelt, um diese Dinge zu tun.3 Es wurde entwickelt, um Softwareentwickler und -administratoren beim Betrieb von Produktionscomputersystemen zu unterstützen, z. B. bei den Anwendungen, Tools, Datenbanken und Netzwerken, die hinter beliebten Websites stehen.
Was ist also Überwachung in diesem Zusammenhang? Lasst uns diese Art der betrieblichen Überwachung von Computersystemen auf vier Dinge eingrenzen:
- Alerting
-
Zu wissen, wann etwas schief läuft, ist in der Regel das Wichtigste, was du mit der Überwachung erreichen willst. Du möchtest, dass das Überwachungssystem einen Menschen anruft, der sich die Sache ansieht.
- Fehlersuche
-
Jetzt, wo du einen Menschen hinzugezogen hast, muss er die Ursache ermitteln und das Problem beheben.
- Trending
-
Warnmeldungen und Fehlerbehebungen erfolgen in der Regel in Zeiträumen von Minuten bis Stunden. Auch wenn es weniger dringend ist, ist die Möglichkeit, zu sehen, wie deine Systeme genutzt werden und sich im Laufe der Zeit verändern, sehr nützlich. Trending kann in Designentscheidungen und Prozesse wie die Kapazitätsplanung einfließen.
- Klempnerarbeiten
-
Wenn du nur einen Hammer hast, sieht alles wie ein Nagel aus. Letzten Endes sind alle Überwachungssysteme Datenverarbeitungspipelines. Manchmal ist es günstiger, einen Teil deines Überwachungssystems für einen anderen Zweck zu verwenden, als eine maßgeschneiderte Lösung zu bauen. Dabei handelt es sich zwar nicht um ein reines Überwachungssystem, aber es kommt in der Praxis häufig vor, so dass wir es gerne einbeziehen.
Je nachdem, mit wem du sprichst und welchen Hintergrund er hat, kann es sein, dass er nur einige davon als Überwachung betrachtet. Das führt dazu, dass sich viele Diskussionen über Überwachung im Kreis drehen und alle frustriert zurückbleiben. Damit du verstehst, woher die anderen kommen, schauen wir uns einen kleinen Teil der Geschichte der Überwachung an.
Eine kurze und unvollständige Geschichte der Überwachung
Bei der Überwachung hat sich in den letzten Jahren eine Verschiebung hin zu Tools wie Prometheus vollzogen. Lange Zeit war die dominierende Lösung eine Kombination aus Nagios und Graphite oder deren Varianten.
Wenn wir von Nagios sprechen, meinen wir damit jede Software, die zur gleichen Familie gehört, wie z.B. Icinga, Zmon und Sensu. Sie funktionieren hauptsächlich durch die regelmäßige Ausführung von Skripten, die Checks genannt werden. Wenn ein Check fehlschlägt und einen Exit-Code ungleich Null zurückgibt, wird eine Warnung ausgegeben. Nagios wurde 1996 von Ethan Galstad als MS-DOS-Anwendung zur Durchführung von Pings ins Leben gerufen. Es wurde 1999 erstmals als NetSaint veröffentlicht und 2002 in Nagios umbenannt.
Um über die Geschichte von Graphite zu sprechen, müssen wir bis ins Jahr 1994 zurückgehen. Tobias Oetiker entwickelte ein Perl-Skript, aus dem 1995 der Multi Router Traffic Grapher, kurz MRTG 1.0, hervorging. Wie der Name schon sagt, wurde es hauptsächlich zur Netzwerküberwachung über das Simple Network Management Protocol (SNMP) eingesetzt. Es konnte auch Metriken durch die Ausführung von Skripten erhalten.4 Das Jahr 1997 brachte große Veränderungen mit sich: Ein Teil des C-Codes wurde nach C verlagert und die Round-Robin-Datenbank (RRD) zur Speicherung von Metrikdaten wurde entwickelt. Dies brachte erhebliche Leistungsverbesserungen mit sich und RRD war die Grundlage für andere Tools wie Smokeping und Graphite.
Graphite wurde 2006 ins Leben gerufen und verwendet Whisper für die Speicherung von Metriken, das ähnlich aufgebaut ist wie RRD. Graphite sammelt die Daten nicht selbst, sondern sie werden von Sammeltools wie collectd und StatsD, die 2005 bzw. 2010 entwickelt wurden, eingespeist.
Das Wichtigste dabei ist, dass die Erstellung von Diagrammen und die Meldung von Alarmen früher völlig getrennt waren und von unterschiedlichen Tools durchgeführt wurden. Du konntest ein Prüfskript schreiben, um eine Abfrage in Graphite auszuwerten und auf dieser Grundlage Warnungen zu generieren, aber die meisten Prüfungen betrafen unerwartete Zustände, wie z.B. einen nicht laufenden Prozess.
Ein weiteres Überbleibsel aus dieser Zeit ist der relativ manuelle Ansatz bei der Verwaltung von Computerdiensten. Die Dienste wurden auf einzelnen Rechnern installiert und von Systemadministratoren liebevoll gepflegt. Warnungen, die auf ein Problem hinweisen könnten, wurden von engagierten Technikern sofort beachtet. Mit dem Aufkommen von Cloud- und nativen Cloud-Technologien wie EC2, Docker und Kubernetes ist es nicht mehr möglich, einzelne Maschinen und Dienste wie Haustiere zu behandeln und ihnen individuelle Aufmerksamkeit zukommen zu lassen. Stattdessen werden sie eher als Vieh betrachtet und als Gruppe verwaltet und überwacht. So wie sich die Branche von der manuellen Verwaltung über Tools wie Chef und Ansible hin zur Nutzung von Technologien wie Kubernetes entwickelt hat, muss auch die Überwachung einen ähnlichen Wandel vollziehen. Das bedeutet, dass nicht mehr nur einzelne Prozesse auf einzelnen Rechnern überprüft werden, sondern der Zustand des Dienstes als Ganzes.
OpenTelemetry ist aus zwei anderen Open-Source-Projekten hervorgegangen: OpenCensus und OpenTracing. OTel5 ist eine Spezifikation und ein Satz vonKomponenten, die darauf abzielen, integrierte Telemetrie für Projekte anzubieten. Die Metrik-Komponente ist mit Prometheus kompatibel und wird durch den OpenTelemetry-Kollektor ergänzt,6 der für das Sammeln und Bereitstellen von Metriken für deinen Prometheus-Server verantwortlich ist.
Du hast vielleicht bemerkt, dass wir Logging, Tracing und Profiling nicht erwähnt haben. In der Vergangenheit wurden Protokolle als etwas verwendet, das du mit tail
, grep
und awk
von Hand auswertest. Vielleicht hattest du auch ein Analysetool wie AWStats, das stündlich oder täglich Berichte erstellt. In den letzten Jahren wurden die Logs auch als wichtiger Teil des Monitorings eingesetzt, z. B. mit dem Elasticsearch, Logstash und Kibana (ELK) und OpenSearch Stack. Tracing und Profiling werden in der Regel mit einem eigenen Software-Stack durchgeführt: Zipkin und Jaeger sind für das Tracing gedacht, während Parca und Pyroscope für das kontinuierliche Profiling zuständig sind.
Nachdem wir uns nun ein wenig mit der grafischen Darstellung und der Alarmierung befasst haben, wollen wir uns ansehen, wie Metriken und Protokolle in diese Landschaft passen. Gibt es noch mehr Kategorien der Überwachung als diese beiden?
Kategorien der Überwachung
Letztendlich geht es bei der Überwachung immer um das Gleiche: Ereignisse. Ereignisse können fast alles sein, zum Beispiel:
-
Empfangen einer HTTP-Anfrage
-
Senden einer HTTP 400 Antwort
-
Eingeben einer Funktion
-
Erreichen Sie die
else
einerif
Erklärung -
Verlassen einer Funktion
-
Ein Benutzer, der sich anmeldet
-
Daten auf die Festplatte schreiben
-
Daten aus dem Netzwerk lesen
-
Anfordern von mehr Speicher vom Kernel
Alle Ereignisse haben auch einen Kontext. Eine HTTP-Anfrage enthält die IP-Adresse, von der sie kommt und zu der sie geht, die angeforderte URL, die gesetzten Cookies und den Nutzer, der die Anfrage gestellt hat. Bei einer HTTP-Antwort wird angegeben, wie lange die Antwort gedauert hat, der HTTP-Statuscode und die Länge des Antwortkörpers. Ereignisse, an denen Funktionen beteiligt sind, enthalten den Aufrufstapel der darüber liegenden Funktionen und das, was diesen Teil des Stapels ausgelöst hat, z. B. eine HTTP-Anfrage.
Den gesamten Kontext für alle Ereignisse zu haben, wäre großartig für die Fehlersuche und das Verständnis der technischen und geschäftlichen Leistung deines Systems, aber diese Menge an Daten ist nicht praktikabel zu verarbeiten und zu speichern. Daher gibt es ungefähr vier Möglichkeiten, diese Datenmenge auf ein praktikables Maß zu reduzieren: Profiling, Tracing, Logging und Metriken.
Profiling
Beim Profiling wird davon ausgegangen, dass du nicht immer den gesamten Kontext für alle Ereignisse haben kannst, aber du kannst einen Teil des Kontexts für begrenzte Zeiträume haben.
Tcpdump ist ein Beispiel für ein Profiling-Tool. Mit ihm kannst du den Netzwerkverkehr auf der Grundlage eines bestimmten Filters aufzeichnen. Es ist ein unverzichtbares Werkzeug zur Fehlersuche, aber du kannst es nicht ständig einschalten, da dir sonst der Speicherplatz ausgeht.
Ein weiteres Beispiel sind Debug-Builds von Binärdateien, die Profiling-Daten aufzeichnen. Sie liefern eine Fülle nützlicher Informationen, aber aufgrund der Auswirkungen auf die Leistung, die das Sammeln all dieser Informationen, wie z. B. die Zeitangaben für jeden Funktionsaufruf, mit sich bringt, ist es in der Regel nicht praktikabel, sie ständig in der Produktion einzusetzen.
Im Linux-Kernel ermöglichen die erweiterten Berkeley Packet Filter (eBPF) eine detaillierte Analyse von Kernel-Ereignissen, von Dateisystemoperationen bis hin zu Netzwerkunregelmäßigkeiten.Diese ermöglichen einen Einblick, der bisher nicht allgemein verfügbar war. eBPF bietet weitere Vorteile wie Portabilität und Sicherheit. Wir empfehlen die Lektüreder Schriften von Brendan Gregg zu diesem Thema.
Das Profiling dient hauptsächlich der taktischen Fehlersuche. Wenn es längerfristig eingesetzt wird, muss das Datenvolumen reduziert werden, damit es in eine der anderen Kategorien der Überwachung passt, oder du musst zum kontinuierlichen Profiling übergehen, das die Erfassung über längere Zeiträume ermöglicht.
Das Neue an der kontinuierlichen Profilerstellung ist, dass die Frequenz der Profilerstellung reduziert wird, um das Datenvolumen zu verringern und den Overhead relativ gering zu halten. Eines der neuen Tools zur kontinuierlichen Profilerstellung, der eBPF-basierte Parca Agent, verwendet eine Frequenz von 19 Hz.7 Damit versucht er, statistisch aussagekräftige Daten über Minuten statt über Sekunden zu erhalten. Gleichzeitig liefert er die Daten, die nötig sind, um zu verstehen, wie die CPU-Zeit in einer Infrastruktur verbraucht wird, und hilft dabei, die Anwendungseffizienz zu verbessern, wo es nötig ist.
Nachverfolgung
Beim Tracing werden in der Regel nicht alle Ereignisse betrachtet, sondern nur ein Teil der Ereignisse, z. B. eines von hundert, die bestimmte Funktionen von Interesse durchlaufen. Tracing notiert die Funktionen im Stacktrace der interessanten Punkte und oft auch, wie lange jede dieser Funktionen für die Ausführung gebraucht hat. So kannst du dir ein Bild davon machen, wo dein Programm Zeit verbringt und welche Codepfade am meisten zur Latenz beitragen.
Anstatt Schnappschüsse von Stack Traces an interessanten Punkten zu machen, zeichnen einige Tracing-Systeme die Zeit jedes Funktionsaufrufs unterhalb der interessierenden Funktion auf. So könnte zum Beispiel eine von hundert HTTP-Anfragen eines Benutzers erfasst werden, und du könntest für diese Anfragen sehen, wie viel Zeit für die Kommunikation mit Backends wie Datenbanken und Caches aufgewendet wurde. So kannst du sehen, wie sich die Zeiten auf der Grundlage von Faktoren wie Cache-Hits und Cache-Misses unterscheiden.
Verteiltes Tracing geht noch einen Schritt weiter. Es ermöglicht prozessübergreifendes Tracing, indem es Anfragen, die in Remote Procedure Calls (RPCs) von einem Prozess an einen anderen weitergegeben werden, mit eindeutigen IDs versieht und darüber hinaus angibt, ob es sich um eine Anfrage handelt, die verfolgt werden soll. Die Spuren von verschiedenen Prozessen und Rechnern können anhand der Anfrage-ID wieder zusammengefügt werden. Dies ist ein wichtiges Werkzeug für die Fehlersuche in verteilten Microservices-Architekturen. Zu den Technologien in diesem Bereich gehören OpenZipkin und Jaeger.
Beim Tracing ist es das Sampling, das das Datenvolumen und die Auswirkungen auf die Instrumentenleistung in Grenzen hält.
Loggen
Bei der Protokollierung wird eine begrenzte Anzahl von Ereignissen untersucht und ein Teil des Kontexts für jedes dieser Ereignisse aufgezeichnet. Es kann zum Beispiel alle eingehenden HTTP-Anfragen oder alle ausgehenden Datenbankaufrufe aufzeichnen. Um nicht zu viele Ressourcen zu verbrauchen, ist die Anzahl der Felder pro Protokolleintrag in der Regel auf etwa hundert begrenzt. Darüber hinaus werden Bandbreite und Speicherplatz zum Problem.
Bei einem Server, der 1.000 Anfragen pro Sekunde bearbeitet, entspricht ein Protokolleintrag mit 100 Feldern, die jeweils 10 Byte benötigen, 1 Megabyte pro Sekunde. Das ist ein nicht unerheblicher Anteil einer 100-Mbit-Netzwerkkarte und 84 GB Speicherplatz pro Tag nur für die Protokollierung.
Ein großer Vorteil der Protokollierung ist, dass es (normalerweise) keine Stichproben von Ereignissen gibt. Obwohl die Anzahl der Felder begrenzt ist, ist es praktisch festzustellen, wie sich langsame Anfragen auf einen bestimmten Nutzer auswirken, der mit einem bestimmten API-Endpunkt spricht.
So wie Überwachung für jeden etwas anderes bedeutet, bedeutet auch Protokollierung etwas anderes, je nachdem, wen du fragst, was zu Verwirrung führen kann. Die verschiedenen Arten der Protokollierung haben unterschiedliche Verwendungszwecke, Haltbarkeits- und Aufbewahrungsanforderungen. Unserer Meinung nach gibt es vier allgemeine und sich teilweise überschneidende Kategorien:
- Transaktionsprotokolle
-
Dies sind die kritischen Geschäftsunterlagen, die du um jeden Preis und wahrscheinlich für immer sicher aufbewahren musst. Alles, was mit Geld zu tun hat oder für wichtige benutzerorientierte Funktionen verwendet wird, fällt in diese Kategorie.
- Protokolle anfordern
-
Wenn du jede HTTP-Anfrage oder jeden Datenbankaufruf verfolgst, ist das ein Anforderungsprotokoll.Sie können verarbeitet werden, um benutzerorientierte Funktionen zu implementieren oder einfach nur für interne Optimierungen. Du willst sie im Allgemeinen nicht verlieren, aber es ist auch kein Weltuntergang, wenn einige von ihnen verloren gehen.
- Anwendungsprotokolle
-
Nicht alle Protokolle beziehen sich auf Anfragen; einige betreffen den Prozess selbst. Typisch sind Startmeldungen, Wartungsaufgaben im Hintergrund und andere Protokollzeilen auf Prozessebene. Diese Protokolle werden oft direkt von einem Menschen gelesen, daher solltest du versuchen, im Normalbetrieb nicht mehr als ein paar pro Minute zu haben.
- Debug-Protokolle
-
Debug-Logs sind in der Regel sehr detailliert und daher teuer in der Erstellung und Speicherung. Sie werden oft nur in sehr engen Debugging-Situationen verwendet und tendieren aufgrund ihres Datenvolumens zum Profiling. Die Anforderungen an Zuverlässigkeit und Aufbewahrung sind eher gering, und Debug-Logs verlassen möglicherweise nicht einmal den Rechner, auf dem sie erstellt wurden.
Wenn du die verschiedenen Arten von Protokollen alle auf die gleiche Weise behandelst, kannst du in die schlimmste aller Welten geraten, in der du das Datenvolumen der Debug-Protokolle mit den extremen Zuverlässigkeitsanforderungen der Transaktionsprotokolle kombinierst. Wenn dein System wächst, solltest du daher planen, die Debug-Logs aufzuteilen, damit sie getrennt behandelt werden können.
Beispiele für Logging-Systeme sind der ELK-Stack, OpenSearch, Grafana Loki und Graylog.
Metriken
Metriken ignorieren weitgehend den Kontext und erfassen stattdessen die Häufung verschiedener Arten von Ereignissen im Laufe der Zeit. Um den Ressourcenverbrauch in Grenzen zu halten, muss die Anzahl der zu verfolgenden Zahlen begrenzt werden: 10.000 pro Prozess ist eine vernünftige Obergrenze, die du im Auge behalten solltest.
Beispiele für diese Art von Metriken wären die Anzahl der eingegangenen HTTP-Anfragen, die Zeit, die für die Bearbeitung der Anfragen aufgewendet wurde, und die Anzahl der laufenden Anfragen. Indem du alle Informationen über den Kontext ausschließt, bleiben die Datenmengen und die erforderliche Verarbeitung überschaubar.
Das heißt aber nicht, dass der Kontext immer ignoriert wird. Bei einer HTTP-Anfrage könntest du dich entscheiden, für jeden URL-Pfad eine Metrik zu haben. Dabei muss jedoch die 10.000er-Richtlinie beachtet werden, denn jeder einzelne Pfad zählt nun als Metrik. Es wäre unklug, einen Kontext wie die E-Mail-Adresse eines Nutzers zu verwenden, da diese eine unbegrenzte Kardinalität hat.8
Mithilfe von Metriken kannst du die Latenz und das Datenvolumen verfolgen, das von den einzelnen Subsystemen in deinen Anwendungen verarbeitet wird, und so die Ursache für eine Verlangsamung leichter ermitteln. Logs können zwar nicht so viele Felder aufzeichnen, aber sobald du weißt, welches Subsystem schuld ist, können dir die Logs helfen, herauszufinden, welche Benutzeranfragen genau betroffen sind.
Hier wird der Kompromiss zwischen Protokollen und Metriken am deutlichsten: Mit Metriken kannst du Informationen über Ereignisse aus allen Bereichen deines Prozesses sammeln, aber in der Regel nicht mehr als ein oder zwei Kontextfelder mit begrenzter Kardinalität. Mit Protokollen kannst du Informationen über alle Arten von Ereignissen sammeln, aber nur hundert Kontextfelder mit unbegrenzter Kardinalität erfassen. Die Kardinalität und die Grenzen, die sie den Metriken setzt, sind wichtig zu verstehen und werden in späteren Kapiteln behandelt.
Als metrikbasiertes Überwachungssystem ist Prometheus darauf ausgelegt, den Zustand, das Verhalten und die Leistung des gesamten Systems zu überwachen und nicht nur einzelne Ereignisse. Mit anderen Worten: Prometheus stellt fest, dass es in der letzten Minute 15 Anfragen gab, deren Bearbeitung 4 Sekunden dauerte, die zu 40 Datenbankaufrufen, 17 Cache-Treffern und 2 Käufen durch Kunden führten. Die Kosten und Codepfade der einzelnen Aufrufe wären das Anliegen von Profiling oder Logging.
Jetzt, wo du weißt, wo Prometheus in den gesamten Überwachungsbereich passt, wollen wir uns die verschiedenen Komponenten von Prometheus ansehen.
Prometheus Architektur
Abbildung 1-1 zeigt die Gesamtarchitektur von Prometheus. Prometheus findet Ziele, die über die Service Discovery abgerufen werden können. Dabei kann es sich um deine eigenen instrumentierten Anwendungen oder um Anwendungen von Drittanbietern handeln, die du über einen Exporter abfragen kannst. Die gescrapten Daten werden gespeichert und du kannst sie mit PromQL in Dashboards verwenden oder Alarme an den Alertmanager senden, der sie in Seiten, E-Mails und andere Benachrichtigungen umwandelt.
Kundenbibliotheken
Metriken entstehen in der Regel nicht auf magische Weise aus den Anwendungen heraus; jemand muss die Instrumente hinzufügen, die sie erzeugen. Hier kommen die Client-Bibliotheken ins Spiel. Mit meist nur zwei oder drei Codezeilen kannst du eine Kennzahl definieren und die gewünschte Instrumentierung inline in den von dir kontrollierten Code einfügen. Dies wird als direkte Instrumentierung bezeichnet.
Client-Bibliotheken sind für alle wichtigen Sprachen und Laufzeiten verfügbar. Das Prometheus-Projekt bietet offizielle Client-Bibliotheken in Go, Python, Java/JVM, Ruby und Rust. Außerdem gibt es eine Vielzahl von Client-Bibliotheken von Drittanbietern, z. B. für C#/.Net, Node.js, Haskell und Erlang.
Die Client-Bibliotheken kümmern sich um alle wichtigen Details wie Thread-Sicherheit, Buchführung und die Erstellung des Prometheus-Text- und/oder OpenMetrics-Ausgabeformats als Antwort auf HTTP-Anfragen. Da bei der metrikbasierten Überwachung keine einzelnen Ereignisse erfasst werden, steigt der Speicherverbrauch der Client-Bibliotheken nicht mit der Anzahl der Ereignisse. Vielmehr hängt der Speicherbedarf von der Anzahl der Metriken ab, die du hast.
Wenn eine der Bibliotheksabhängigkeiten deiner Anwendung über eine Prometheus-Instrumentierung verfügt, wird sie automatisch mit einbezogen. Wenn du also eine wichtige Bibliothek, wie z. B. deinen RPC-Client, instrumentierst, kannst du sie in allen deinen Anwendungen verwenden.
Einige Metriken, wie z.B. die CPU-Auslastung und die Speicherbereinigung, werden je nach Bibliothek und Laufzeitumgebung von den Client-Bibliotheken standardmäßig bereitgestellt.
Client-Bibliotheken sind nicht auf die Ausgabe von Metriken in den Prometheus- und OpenMetrics-Textformaten beschränkt. Prometheus ist ein offenes Ökosystem, und dieselben APIs, die für die Erzeugung des Textformats verwendet werden, können auch für die Erstellung von Metriken in anderen Formaten oder für die Einspeisung in andere Instrumentierungssysteme genutzt werden. Ebenso ist es möglich, Metriken aus anderen Instrumentierungssystemen in eine Prometheus-Client-Bibliothek zu übernehmen, wenn du noch nicht alles auf Prometheus-Instrumentierung umgestellt hast.
Exporteure
Nicht jeder Code, den du ausführst, ist ein Code, den du kontrollieren kannst oder auf den du Zugriff hast, und daher ist das Hinzufügen direkter Instrumente nicht wirklich eine Option. Es ist zum Beispiel unwahrscheinlich, dass Betriebssystem-Kernel in absehbarer Zeit Prometheus-formatierte Metriken über HTTP ausgeben werden.
Solche Software verfügt oft über eine Schnittstelle, über die du auf Metriken zugreifen kannst. Dabei kann es sich um ein Ad-hoc-Format handeln, das eine benutzerdefinierte Auswertung und Handhabung erfordert, wie es bei vielen Linux-Metriken der Fall ist, oder um einen etablierten Standard wie SNMP.
Ein Exporter ist eine Software, die du direkt neben der Anwendung einsetzt, von der du Metriken erhalten möchtest. Er nimmt Anfragen von Prometheus entgegen, sammelt die benötigten Daten von der Anwendung, wandelt sie in das richtige Format um und gibt sie schließlich als Antwort an Prometheus zurück. Du kannst dir einen Exporter als einen kleinen Eins-zu-Eins-Proxy vorstellen, der Daten zwischen der Metrik-Schnittstelle einer Anwendung und dem Prometheus-Ausgabeformat umwandelt.
Im Gegensatz zur direkten Instrumentierung, die du für den von dir kontrollierten Code verwenden würdest, verwenden Exporteure eine andere Art der Instrumentierung, die als Custom Collectors oderConstMetrics bekannt ist.9
Die gute Nachricht ist, dass angesichts der Größe der Prometheus-Gemeinschaft der Exporter, den du brauchst, wahrscheinlich schon existiert und mit wenig Aufwand von dir genutzt werden kann. Wenn dem Exporter eine Kennzahl fehlt, an der du interessiert bist, kannst du jederzeit einen Pull-Request senden, um ihn zu verbessern und ihn für die nächste Person, die ihn nutzt, besser zu machen.
Service Entdeckung
Sobald du alle deine Anwendungen instrumentiert hast und deine Exporter laufen, muss Prometheus wissen, wo sie sich befinden. So weiß Prometheus, was es überwachen soll, und kann feststellen, wenn etwas, das es überwachen soll, nicht reagiert. In dynamischen Umgebungen kannst du nicht einfach eine Liste von Anwendungen und Exportern bereitstellen, da sie sonst veraltet. Hier kommt die Service Discovery ins Spiel.
Wahrscheinlich hast du bereits eine Datenbank mit deinen Maschinen, Anwendungen und deren Funktionen. Das kann in der Chef-Datenbank sein, in einer Inventardatei für Ansible, auf der Grundlage von Tags auf deiner EC2-Instanz, in Labels und Anmerkungen in Kubernetes oder einfach in deinem Dokumentations-Wiki.
Prometheus verfügt über Integrationen mit vielen gängigen Service Discovery Mechanismen, wie z.B. Kubernetes, EC2 und Consul. Es gibt auch eine allgemeine Integration für diejenigen, deren Setup ein wenig abseits der ausgetretenen Pfade liegt (siehe "Datei" und "HTTP").
Ein Problem bleibt jedoch bestehen. Nur weil Prometheus eine Liste von Maschinen und Diensten hat, heißt das nicht, dass wir wissen, wie sie in deine Architektur passen. Du könntest zum Beispiel das EC2 Name
Tag verwenden10 um anzugeben, welche Anwendung auf einer Maschine läuft, während andere vielleicht ein Tag namens app
verwenden.
Da jede Organisation dies etwas anders handhabt, kannst du in Prometheus konfigurieren, wie Metadaten aus der Service Discovery mit Hilfe von Relabeling den Überwachungszielen und ihren Bezeichnungen zugeordnet werden.
Kratzen
Durch Service Discovery und Relabeling erhalten wir eine Liste von Zielen, die überwacht werden sollen. Jetzt muss Prometheus die Metriken abrufen. Dazu sendet Prometheus eine HTTP-Anfrage, einen sogenannten Scrape. Die Antwort auf den Scrape wird geparst und in die Speicherung aufgenommen. Außerdem werden einige nützliche Metriken hinzugefügt, z. B. ob der Scrape erfolgreich war und wie lange er gedauert hat. Scrapes werden regelmäßig durchgeführt. Normalerweise konfigurierst du sie so, dass sie alle 10 bis 60 Sekunden für jedes Ziel stattfinden.
Speicherung
Prometheus speichert Daten lokal in einer eigenen Datenbank. Verteilte Systeme sind schwer zuverlässig zu machen, deshalb versucht Prometheus nicht, irgendeine Form von Clustering durchzuführen. Das macht Prometheus nicht nur zuverlässiger, sondern auch einfacher zu betreiben.
Im Laufe der Jahre wurde die Speicherung mehrfach umgestaltet, wobei das Speichersystem in Prometheus 2.0 die dritte Iteration darstellt. Die Speicherung ist in der Lage, Millionen von Daten pro Sekunde zu verarbeiten, sodass ein einziger Prometheus-Server Tausende von Rechnern überwachen kann. Der verwendete Komprimierungsalgorithmus kann bei realen Daten 1,3 Byte pro Probe erreichen. Eine SSD wird empfohlen, ist aber nicht unbedingt erforderlich.
Dashboards
Prometheus verfügt über eine Reihe von HTTP-APIs, mit denen du sowohl Rohdaten abfragen als auch PromQL-Abfragen auswerten kannst. Diese können verwendet werden, um Grafiken und Dashboards zu erstellen. Prometheus bietet standardmäßig den Expression Browser. Er nutzt diese APIs und eignet sich für Ad-hoc-Abfragen und Datenexploration, ist aber kein allgemeines Dashboard-System.
Es wird empfohlen, Grafana für Dashboards zu verwenden. Es verfügt über eine Vielzahl von Funktionen, einschließlich der offiziellen Unterstützung für Prometheus als Datenquelle. Es kann eine Vielzahl von Dashboards erstellen, wie z. B. das in Abbildung 1-2. Grafana unterstützt die Kommunikation mit mehreren Prometheus-Servern, sogar innerhalb eines einzelnen Dashboard-Panels.
Aufzeichnungsregeln und Warnungen
PromQL und die Speicherung sind zwar leistungsfähig und effizient, aber die Zusammenfassung der Daten von Tausenden von Rechnern bei jedem Rendering eines Diagramms kann ein wenig verzögert werden. Mithilfe von Aufzeichnungsregeln können PromQL-Ausdrücke regelmäßig ausgewertet und die Ergebnisse in die Speicherung eingespeist werden.
Alerting-Regeln sind eine weitere Form der Aufzeichnungsregeln. Sie werten ebenfalls regelmäßig PromQL-Ausdrücke aus, und alle Ergebnisse dieser Ausdrücke werden zu Alarmen. Alarme werden an den Alertmanager gesendet.
Alert Management
Der Alertmanager empfängt Alarme von Prometheus-Servern und verwandelt sie in Benachrichtigungen. Zu den Benachrichtigungen können E-Mails, Chat-Anwendungen wie Slack und Dienste wie PagerDuty gehören.
Der Alertmanager kann mehr, als nur einzelne Alarme in Benachrichtigungen umzuwandeln. Zusammenhängende Alarme können in einer Benachrichtigung zusammengefasst und gedrosselt werden, um Pager-Stürme zu reduzieren,11 und für jedes deiner verschiedenen Teams können unterschiedliche Weiterleitungen und Benachrichtigungen konfiguriert werden. Alarme können auch stummgeschaltet werden, z. B. um ein Problem, das dir bereits bekannt ist, in den Schlummermodus zu versetzen, wenn du weißt, dass Wartungsarbeiten anstehen.
Die Rolle des Alertmanagers beschränkt sich auf das Versenden von Benachrichtigungen; um menschliche Reaktionen auf Vorfälle zu verwalten, solltest du Dienste wie PagerDuty und Ticketingsysteme nutzen.
Tipp
Alerts und ihre Schwellenwerte werden in Prometheus konfiguriert, nicht im Alertmanager.
Langfristige Speicherung
Da Prometheus Daten nur auf dem lokalen Rechner speichert, ist der Speicherplatz auf diesem Rechner begrenzt.12 Während du dich normalerweise nur um die Daten des letzten Tages kümmerst, ist für die langfristige Kapazitätsplanung eine längere Aufbewahrungsfrist wünschenswert.
Prometheus bietet keine geclusterte Speicherung an, um Daten auf mehreren Rechnern zu speichern, aber es gibt Remote-Lese- und Schreib-APIs, die es anderen Systemen ermöglichen, diese Rolle zu übernehmen. So können PromQL-Abfragen transparent auf lokale und entfernte Daten angewendet werden.
Was Prometheus nicht ist
Jetzt, wo du eine Vorstellung davon hast, wo Prometheus in die breitere Überwachungslandschaft passt und was seine Hauptkomponenten sind, wollen wir uns einige Anwendungsfälle ansehen, für die Prometheus keine besonders gute Wahl ist.
Als metrikbasiertes System ist Prometheus nicht geeignet, um Ereignisprotokolle oder einzelne Ereignisse zu speichern. Es ist auch nicht die beste Wahl für Daten mit hoher Kardinalität, wie z. B. E-Mail-Adressen oder Benutzernamen.
Prometheus wurde für die Betriebsüberwachung entwickelt, bei der kleine Ungenauigkeiten und Wettlaufbedingungen aufgrund von Faktoren wie Kernel-Scheduling und fehlgeschlagenen Scrapes zum Alltag gehören. Prometheus geht Kompromisse ein und zieht es vor, 99,9 % korrekte Daten zu liefern, während du auf perfekte Daten wartest. Bei Anwendungen, bei denen es um Geld oder Rechnungen geht, sollte Prometheus daher mit Vorsicht eingesetzt werden.
Im nächsten Kapitel zeigen wir dir, wie du Prometheus startest und einige grundlegendeÜberwachungen durchführst.
1 Kubernetes war das erste Mitglied.
2 Neben dem einfachen Textformat wurde eine standardisierte, leicht abweichende Version namens OpenMetrics aus dem Prometheus-Textformat entwickelt.
3 Die Temperaturüberwachung von Maschinen und Rechenzentren ist nicht ungewöhnlich. Es gibt sogar ein paar Nutzer, die Prometheus zum Spaß nutzen, um das Wetter zu überwachen.
4 Brian erinnert sich gerne an die Einrichtung von MRTG in den frühen 2000er Jahren, als ich Skripte schrieb, um die Temperatur und die Netzwerkauslastung auf meinen Heimcomputern zu melden.
5 OTel ist ein informeller Name für OpenTelemetry.
6 Zum Zeitpunkt der Erstellung dieses Artikels haben die Entwickler auf einem Prometheus-Entwickler-Gipfel beschlossen, dass der Prometheus-Server in Zukunft das OTel-Protokoll nativ unterstützen wird, aber es gibt noch keine feste Entscheidung darüber, wann und wie dies geschehen wird.
7 Verglichen mit der 100Hz-Frequenz der Go-Laufzeit oder sogar 10.000Hz in Chromium.
8 E-Mail-Adressen sind in der Regel auch persönlich identifizierbare Informationen (PII), die Bedenken hinsichtlich der Einhaltung von Vorschriften und des Datenschutzes mit sich bringen, die bei der Überwachung am besten vermieden werden sollten.
9 Der Begriff ConstMetric ist umgangssprachlich und stammt von der Funktion MustNewConstMetric
der Go-Client-Bibliothek, die verwendet wird, um Metriken von in Go geschriebenen Exportern zu erzeugen.
10 Das EC2 Name
Tag ist der Anzeigename einer EC2-Instanz in der EC2-Webkonsole.
11 Ein Pager ist eine Benachrichtigung an einen diensthabenden Techniker, von dem erwartet wird, dass er das Problem umgehend untersucht oder bearbeitet. Während du einen Pager über einen herkömmlichen Funkrufempfänger erhalten kannst, kommt er heutzutage eher in Form einer SMS, einer Benachrichtigung oder eines Anrufs auf dein Mobiltelefon. Von einem Pager-Sturm spricht man, wenn du eine Reihe von Pagern in schneller Folge erhältst.
12 Moderne Maschinen können jedoch viele Daten lokal speichern, so dass ein separates geclustertes Speichersystem für dich vielleicht nicht notwendig ist.
Get Prometheus: Up & Running, 2. Auflage now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.