Blog JSystems - uwalniamy wiedzę!
Blog JSystems - uwalniamy wiedzę!
Jeśli Prometheus kojarzy Ci się z tajemniczym narzędziem, o którym mówią zespoły DevOps przy okazji awarii, to trafiłeś dobrze. W tym przewodniku wyjaśnimy od zera, co to jest Prometheus, do czego służy i jak działa, a wszystko pokażemy na przykładach. I nie na diagramach z internetu, tylko na prawdziwych zrzutach z działającej instalacji, którą specjalnie na potrzeby tego artykułu postawiliśmy na własnym serwerze: Prometheus, kilka eksporterów, mała aplikacja z własnymi metrykami oraz Alertmanager. Prometheus i Grafanę widuje się zwykle razem, dlatego ten tekst jest naturalnym uzupełnieniem naszego przewodnika o Grafanie.
Prometheus w pigułce: darmowe, otwartoźródłowe narzędzie do zbierania i przechowywania metryk (liczbowych pomiarów zapisywanych w czasie). Prometheus sam co kilkanaście sekund pobiera dane z monitorowanych systemów (model pull), zapisuje je we własnej bazie szeregów czasowych i pozwala je odpytywać językiem PromQL oraz uruchamiać na ich podstawie alerty. To fundament, na którym stoi większość nowoczesnego monitoringu.
Z tego artykułu dowiesz się:
Prometheus to otwartoźródłowy (open source, czyli o publicznie dostępnym kodzie) system monitoringu, który zbiera i przechowuje metryki, a następnie pozwala je odpytywać i uruchamiać na ich podstawie alerty. Mówiąc prościej: Prometheus co kilkanaście sekund odwiedza Twoje serwery i aplikacje, spisuje z nich liczby (ile zajętej pamięci, ile obsłużonych żądań, ile błędów) i zapisuje je ze znacznikiem czasu, żeby dało się później zobaczyć, jak te wartości zmieniały się w czasie.
Metryka (ang. metric) to po prostu liczbowy pomiar czegoś, zapisywany regularnie. Ciąg takich pomiarów tej samej rzeczy, ułożony w czasie, nazywamy szeregiem czasowym (ang. time series). Prometheus jest właśnie bazą szeregów czasowych (w skrócie TSDB, od time series database) wyspecjalizowaną w metrykach. To odróżnia go od Grafany, która danych nie przechowuje, tylko je pokazuje. Najprościej zapamiętać podział ról tak: Prometheus zbiera i trzyma dane, Grafana je rysuje. W praktyce prawie zawsze pracują razem.
Prometheus powstał w 2012 roku w firmie SoundCloud, a stworzyli go inżynierowie, którzy wcześniej pracowali w Google i wzorowali się na wewnętrznym systemie monitoringu Google o nazwie Borgmon. W 2015 roku projekt został udostępniony publicznie, a w 2016 dołączył do fundacji CNCF (Cloud Native Computing Foundation) jako jej drugi projekt, zaraz po Kubernetesie. W 2018 roku uzyskał status projektu dojrzałego (graduated). Dziś Prometheus jest de facto standardem monitoringu w świecie kontenerów i chmury, a jego format metryk stał się na tyle popularny, że obsługują go setki innych narzędzi.
Prometheus najlepiej czuje się tam, gdzie liczy się bieżący stan techniczny systemu i szybka reakcja na problemy. Oto obszary, w których sprawdza się najczęściej:
| Obszar | Przykłady użycia |
|---|---|
| Serwery i systemy | Zużycie procesora, pamięci, dysku i sieci na maszynach, przez eksporter node_exporter. |
| Kontenery i Kubernetes | Monitoring kontenerów Dockera i klastrów Kubernetes. To tutaj Prometheus jest standardem numer jeden. |
| Aplikacje (metryki własne) | Liczba żądań, błędy, czasy odpowiedzi, długość kolejek, wprost z Twojego kodu. |
| Niezawodność i SLO | Pilnowanie dostępności usług i celów jakości (SLO), z automatycznym alertem, gdy coś się psuje. |
| Bazy danych i kolejki | Gotowe eksportery dla PostgreSQL, MySQL, Redis, Kafki i wielu innych systemów. |
Wspólny mianownik tych zastosowań jest jeden: chcemy widzieć, co dzieje się teraz, i dostać sygnał, zanim użytkownicy zauważą awarię. Do analiz biznesowych i raportów historycznych sięga się raczej po inne narzędzia, o czym powiemy przy porównaniach.
Najważniejsza rzecz, którą warto zrozumieć na początku, to sposób, w jaki Prometheus zdobywa metryki. Większość ludzi zakłada, że to aplikacje same wysyłają dane do systemu monitoringu. Prometheus działa odwrotnie. To Prometheus sam łączy się z każdym monitorowanym celem i pobiera z niego metryki. Nazywamy to modelem pull (odpytywania), a samą czynność pobrania metryk słowem scrape.
Każdy monitorowany element udostępnia swoje metryki pod adresem zakończonym na /metrics, w formie zwykłego tekstu. Prometheus co ustalony czas (domyślnie co 15 sekund, parametr scrape_interval) odwiedza ten adres i zapisuje odczytane liczby. Ma to jedną świetną zaletę: przy okazji Prometheus od razu wie, czy cel w ogóle żyje. Jeśli pobranie się nie uda, zapisuje o tym specjalną metrykę up o wartości 0. Monitoring dostępności dostajemy więc za darmo, przy okazji.
Cała droga danych wygląda tak: eksportery udostępniają metryki, Prometheus je pobiera i zapisuje, a potem albo rysujemy z nich wykresy (najczęściej w Grafanie), albo Prometheus sam uruchamia alert i wysyła go dalej. Prześledźmy to na animacji:
A co z zadaniami, które są zbyt krótkie, żeby Prometheus zdążył je odpytać, na przykład nocny skrypt, który uruchamia się na dziesięć sekund? Do takich przypadków służy Pushgateway: zadanie wypycha swoje metryki do tego pośrednika, a Prometheus pobiera je już z niego, zwyczajnym scrape'em. To wyjątek, nie reguła. Domyślnie zostajemy przy modelu pull.
Prometheus bywa mylony z całym systemem monitoringu, a jest tylko jego sercem. Wokół niego pracuje kilka współpracujących elementów. Poznajmy je, bo każdy pełni inną rolę:
Ważna uwaga dla początkujących: serwer Prometheus to jeden proces i jeden plik konfiguracji. Nie potrzebujesz osobnej bazy danych ani klastra, żeby zacząć. To jedna z przyczyn jego popularności.
Żeby dobrze zrozumieć Prometheus, trzeba poznać sposób, w jaki opisuje dane. Każdy pomiar to nazwa metryki, zestaw etykiet, wartość liczbowa i znacznik czasu. Etykiety (ang. labels) to najważniejszy pomysł całego modelu: pozwalają ciąć tę samą metrykę na wymiary, bez zakładania osobnych metryk na każdy przypadek.
Weźmy metrykę z naszej demonstracyjnej aplikacji: demo_http_requests_total liczy obsłużone żądania. Dzięki etykietom method, endpoint i status jednym zapytaniem policzymy żądania w rozbiciu na metodę, ścieżkę i kod odpowiedzi. Warto od razu poznać cztery typy metryk, bo pytają o nie na każdej rozmowie o monitoringu:
Skoro metryki są zwykłym tekstem, możemy je po prostu podejrzeć. Tak wygląda surowy format ekspozycji spod adresu /metrics naszej aplikacji. Linie zaczynające się od znaku kratki to opisy (HELP) i typy (TYPE), reszta to konkretne szeregi z wartościami:
Prometheus działa w przeglądarce, domyślnie na porcie 9090. Nie ma logowania ani kolorowych dashboardów, bo do wizualizacji służy Grafana. Za to daje wszystko, czego potrzeba do sprawdzenia, co i jak jest zbierane. U góry mamy trzy miejsca: Query (zadawanie zapytań), Alerts (alerty) oraz rozwijane Status, w którym kryją się cele, wykrywanie celów, konfiguracja, reguły i stan bazy.
Zakładka Query to serce interfejsu. Wpisujesz zapytanie w języku PromQL i oglądasz wynik na dwa sposoby. Widok Graph (wykres) pokazuje przebieg w czasie, jak na zrzucie otwierającym ten artykuł. Widok Table (tabela) pokazuje bieżące wartości wraz ze wszystkimi etykietami. Tu widać model danych jak na dłoni: jedna metryka, a pod nią wiele szeregów różniących się etykietami.
Strona Status, Target health to pierwsze miejsce, które sprawdzasz, gdy coś nie działa. Pokazuje wszystkie cele (ang. targets), pogrupowane w zadania (ang. jobs), wraz ze stanem UP lub DOWN, czasem ostatniego pobrania i etykietami. Na naszym środowisku Prometheus odpytuje cztery zadania: samego siebie, node_exporter (serwer), cAdvisor (kontenery) oraz naszą aplikację demo. Wszystkie są zdrowe.
Strona Service discovery pokazuje ciekawą rzecz: po lewej surowe etykiety, jakie cel miał w chwili wykrycia (zaczynają się od dwóch podkreśleń, na przykład __address__), a po prawej etykiety końcowe, już po przetworzeniu. To przetwarzanie nazywa się relabeling i pozwala dodawać, zmieniać albo odrzucać etykiety, zanim dane trafią do bazy. W dużych środowiskach to potężne narzędzie porządkujące, u nas wystarczy wiedzieć, że coś takiego istnieje.
W Status, Configuration podejrzysz aktualny plik konfiguracji tak, jak widzi go Prometheus: interwał pobierania, adres Alertmanagera, pliki reguł i listę zadań do odpytania. To wygodne, bo nie musisz zaglądać na serwer.
Z kolei Status, TSDB status pokazuje kondycję bazy: ile trzyma szeregów czasowych, które etykiety i metryki mają ich najwięcej. To ważna strona, bo liczba szeregów (tak zwana liczność, ang. cardinality) wprost przekłada się na zużycie pamięci. Na naszej małej instalacji baza trzyma już ponad pięć tysięcy szeregów, głównie z metryk kontenerów.
Jest jeszcze Status, Runtime and build info, gdzie sprawdzisz wersję Prometheusa, czas działania i ustawienia przechowywania danych. Przydaje się przy diagnostyce i zgłoszeniach.
Skoro Prometheus przechowuje dane, potrzebujemy sposobu, żeby o nie pytać. Służy do tego PromQL (Prometheus Query Language), czyli język zapytań Prometheusa. Ten sam język wpisujesz potem w panelach Grafany, więc nauka procentuje podwójnie. Zacznijmy od klasyka, czyli obliczenia bieżącego obciążenia procesora:
100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
Wygląda groźnie, ale mówi prostą rzecz: policz, jaki procent czasu procesor był bezczynny, i odejmij to od stu. Rozłóżmy zapytanie na części, bo to najlepszy sposób, żeby zrozumieć składnię:
| Fragment | Co oznacza |
|---|---|
node_cpu_seconds_total | Metryka z node_exportera: łączny czas pracy procesora w sekundach (licznik). |
{mode="idle"} | Filtr etykiety. Bierzemy tylko czas, w którym procesor był bezczynny. |
[5m] | Okno czasu. Patrzymy na ostatnie 5 minut historii tej metryki. |
rate(...) | Tempo przyrostu na sekundę w tym oknie, czyli ile "bezczynności" przybywa co sekundę. |
avg(...) | Uśrednienie po wszystkich rdzeniach procesora do jednej liczby. |
100 - (... * 100) | Zamiana na procent i odjęcie bezczynności od stu, czyli procent obciążenia. |
Najczęstszy błąd początkujących to rysowanie licznika wprost. Licznik tylko rośnie, więc jego wykres to nudna, wiecznie rosnąca linia, z której nic nie wynika. Interesuje nas tempo, czyli ile przybywa na sekundę. Do tego służy funkcja rate(). Ma jeszcze jedną supermoc: mądrze radzi sobie z restartem aplikacji. Gdy licznik nagle spada do zera, rate() rozumie, że to restart, a nie gigantyczny spadek, i nie psuje wyniku. Zobaczmy to na animacji:
W praktyce nie musisz pamiętać wszystkich nazw metryk. Interfejs podpowiada je w trakcie pisania: wystarczy zacząć wpisywać nazwę, a Prometheus pokaże listę pasujących metryk wraz z ich typem i krótkim opisem.
Metryki typu histogram pozwalają odpowiedzieć na pytanie, które w monitoringu pada najczęściej: jak szybko odpowiada usługa. Nie interesuje nas średnia, bo ta ukrywa problemy. Interesuje nas percentyl, na przykład 95. Funkcja histogram_quantile() policzy go z kubełków histogramu. Poniższe zapytanie zwraca czas, w którym mieści się 95 procent najszybszych żądań, osobno dla każdej ścieżki:
histogram_quantile(0.95, sum by (le, endpoint) (rate(demo_request_duration_seconds_bucket[5m])))
Prometheus sam z siebie nie wie, ile pamięci zużywa serwer. Wie o tym system operacyjny. Rolą eksportera jest odczytać taki stan i wystawić go jako metryki pod adresem /metrics. To dzięki eksporterom Prometheus monitoruje praktycznie wszystko. Oto te, które spotkasz najczęściej:
| Eksporter | Co udostępnia |
|---|---|
| node_exporter | Metryki serwera z systemem Linux: procesor, pamięć, dysk, sieć. Podstawa monitoringu maszyn. |
| cAdvisor | Zużycie zasobów w rozbiciu na poszczególne kontenery Dockera. |
| blackbox_exporter | Sprawdza dostępność z zewnątrz: czy strona odpowiada, czy certyfikat nie wygasa. |
| Eksportery baz danych | Gotowe dla PostgreSQL, MySQL, Redisa, Kafki i wielu innych systemów. |
| Biblioteki klienckie | Gdy chcesz metryki własnej aplikacji, dokładasz bibliotekę do kodu (Python, Java, Go, .NET). |
W naszym środowisku demonstracyjnym korzystamy z node_exportera, cAdvisora oraz małej aplikacji w Pythonie, która przez bibliotekę kliencką udostępnia własne metryki. To ona produkuje liczniki i histogramy, które oglądaliśmy wyżej.
Prometheus potrafi liczyć nie tylko na żądanie, ale też w tle, według reguł zapisanych w pliku. Reguły dzielą się na dwa rodzaje:
Na stronie Status, Rule health widać oba rodzaje reguł wraz z ich stanem. U nas mamy dwie reguły zapisujące i cztery alertujące, wszystkie zdrowe (OK):
Same wykresy to nie wszystko. Nikt nie wpatruje się w ekran przez dobę. Dlatego sercem monitoringu są alerty. Reguła alertująca w Prometheusie ma trzy stany: inactive (warunek niespełniony, spokój), pending (warunek właśnie się spełnił, ale jeszcze nie na tyle długo, żeby alarmować) oraz firing (alert aktywny). Ten środkowy stan chroni przed budzeniem wszystkich z powodu jednosekundowego skoku.
Na naszym środowisku celowo uruchomiliśmy dwie reguły, które się palą. Pierwsza to Watchdog, alert, który zawsze jest aktywny. Brzmi dziwnie, ale to znana dobra praktyka: skoro alert, który powinien palić się zawsze, nagle milknie, to znaczy, że popsuła się sama droga powiadamiania. Druga to HighErrorRate, która pilnuje odsetka błędów serwera. Nasza aplikacja demo celowo zwraca około 30 procent błędów, więc alert słusznie się zapalił i pokazuje realną wartość.
Prometheus sam alertów nie wysyła. Od tego jest osobny program: Alertmanager. Prometheus przekazuje mu aktywne alerty, a Alertmanager decyduje, co z nimi zrobić. Jego zadania to:
Tak wyglądają nasze dwa alerty po dotarciu do Alertmanagera. Widać, że zostały pogrupowane i przypisane do odbiorcy o nazwie zespol-devops:
To jest właśnie sedno monitoringu. Interfejs pokazuje stan na życzenie, a Prometheus z Alertmanagerem same zawiadamiają, gdy dzieje się coś złego, nawet gdy nikt nie patrzy na ekran.
Prometheus rzadko pracuje sam. Najczęściej zestawia się go z innymi narzędziami, a część z nich bywa z nim mylona. Uporządkujmy to.
| Narzędzie | Jak się ma do Prometheusa |
|---|---|
| Grafana | Nie zbiera danych, tylko je rysuje. To najczęstszy partner Prometheusa: on jest źródłem, ona deską rozdzielczą. |
| InfluxDB | Też baza szeregów czasowych, ale domyślnie w modelu push i częsta w zastosowaniach IoT. Bezpośredni konkurent w warstwie przechowywania. |
| Zabbix | Kompletny system monitoringu z własnym interfejsem i alertami. Bardziej "wszystko w jednym", mniej elastyczny w metrykach aplikacji. |
| Datadog, New Relic | Płatne platformy w chmurze. Wygodne i bogate, ale kosztowne. Prometheus uruchomisz za darmo na własnym serwerze. |
| VictoriaMetrics, Thanos, Mimir | Rozwiązania do Prometheusa na dużą skalę: długie przechowywanie i łączenie wielu instancji w jedno. |
To para, którą najłatwiej pomylić, a różnica jest prosta. Prometheus zbiera i przechowuje dane, Grafana je pokazuje. Prometheus ma własny, skromny interfejs, który świetnie nadaje się do sprawdzania konfiguracji i szybkich zapytań, ale do codziennego oglądania metryk i budowania czytelnych dashboardów sięga się po Grafanę. Tak wygląda ten sam serwer, którego metryki zbiera nasz Prometheus, pokazany w gotowym dashboardzie Grafany:
Jeśli chcesz zrozumieć drugą połowę tego duetu, mamy osobny, równie praktyczny tekst: Co to jest Grafana, przewodnik dla początkujących. Pokazujemy w nim krok po kroku, jak podłączyć Prometheus jako źródło danych i zbudować pierwszy dashboard.
Oba to bazy szeregów czasowych, więc konkurują w warstwie przechowywania. Największa różnica to model zbierania: Prometheus domyślnie sam pobiera dane (pull), a InfluxDB częściej przyjmuje dane wysyłane do niego (push). Prometheus króluje w monitoringu infrastruktury i kontenerów, InfluxDB bywa wybierany w internecie rzeczy i tam, gdzie dane naturalnie płyną z urządzeń.
Zabbix to weteran monitoringu i rozwiązanie typu wszystko w jednym: sam zbiera dane, sam je pokazuje i sam alarmuje. Prometheus jest bardziej modułowy i mocniejszy w metrykach aplikacji oraz w świecie kontenerów. Co ciekawe, oba często łączy się z Grafaną, żeby mieć ładniejsze i bardziej elastyczne wykresy.
Prometheus jest darmowy i otwartoźródłowy (na licencji Apache 2.0), także do zastosowań komercyjnych. Najszybciej uruchomisz go przez Dockera. Jedno polecenie i po chwili Prometheus działa pod adresem http://localhost:9090:
docker run -d -p 9090:9090 --name prometheus prom/prometheus
W praktyce Prometheus rzadko działa sam. Zwykle idzie w parze z eksporterem metryk serwera. Poniższy plik docker-compose.yml stawia komplet: Prometheus oraz node_exporter, dokładnie taki, jakiego użyliśmy w tym artykule:
services:
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
ports: ["9090:9090"]
node-exporter:
image: prom/node-exporter:latest
ports: ["9100:9100"]
Do tego potrzebny jest krótki plik prometheus.yml, w którym mówimy, co odpytywać. Poniżej minimalny przykład: Prometheus monitoruje siebie oraz serwer przez node_exporter:
global:
scrape_interval: 15s
scrape_configs:
- job_name: prometheus
static_configs:
- targets: ["localhost:9090"]
- job_name: node
static_configs:
- targets: ["node-exporter:9100"]
A jak z kosztami? Sam Prometheus jest w pełni darmowy. Płatne bywają usługi zarządzane, które biorą Prometheus na siebie, żebyś nie musiał go utrzymywać, na przykład Grafana Cloud albo Amazon Managed Service for Prometheus. Na start i do średniej wielkości firm w zupełności wystarcza darmowa wersja na własnym serwerze.
_total to prawie zawsze licznik. Nie rysuj go wprost, użyj rate().| Pojęcie | Co oznacza |
|---|---|
| Metryka | Liczbowy pomiar zapisywany w czasie, na przykład zużycie CPU. |
| Szereg czasowy | Ciąg pomiarów tej samej rzeczy, ułożony w czasie. Prometheus przechowuje właśnie szeregi. |
| Scrape | Pojedyncze pobranie metryk z celu przez Prometheus. |
| Cel (target) | Adres, spod którego Prometheus pobiera metryki. Cele grupuje się w zadania (jobs). |
| Eksporter | Program, który tłumaczy stan systemu na metryki i udostępnia je pod /metrics. |
| Etykieta (label) | Para klucz i wartość, która opisuje wymiar metryki, na przykład metodę czy kod odpowiedzi. |
| PromQL | Język zapytań Prometheusa, ten sam, którego używasz potem w Grafanie. |
| Alertmanager | Osobny program, który odbiera alerty, grupuje je i wysyła powiadomienia. |
| Liczność (cardinality) | Liczba unikalnych szeregów. Im wyższa, tym więcej pamięci zużywa Prometheus. |
Prometheus to darmowy, otwartoźródłowy fundament nowoczesnego monitoringu. Sam co kilkanaście sekund pobiera metryki z serwerów i aplikacji (model pull), zapisuje je we własnej bazie szeregów czasowych i pozwala je odpytywać językiem PromQL oraz uruchamiać na ich podstawie alerty. Jego największe atuty to prostota startu (jeden proces, jeden plik), potężny model danych oparty na etykietach oraz ogromny ekosystem gotowych eksporterów. Prometheus zbiera i przechowuje dane, a do ich wygodnego oglądania dokłada się Grafanę. Te dwa narzędzia to dziś praktyczny standard.
Najlepszy sposób nauki to praktyka: postaw Prometheus i node_exporter przez Docker Compose, wejdź na stronę Targets, zadaj kilka zapytań z rate() i spróbuj napisać własny alert, dokładnie tak, jak pokazaliśmy w tym artykule. A jeśli chcesz przejść przez to z trenerem praktykiem i nauczyć się Prometheusa oraz całego monitoringu szybciej i w dobrze poukładanej kolejności, mamy dla Ciebie dwa szkolenia.
Chcesz opanować Prometheus od praktyka?
Poniżej dwa szkolenia JSystems. Pierwsze skupia się w całości na Prometheusie, drugie to szeroki monitoring i observability z Grafaną, Prometheusem, Lokim i Zabbixem. Oba mają termin gwarantowany, czyli odbywają się na pewno.
Szkolenie Monitoring serwerów i aplikacji: Prometheus ->
Szkolenie Monitoring i Observability: Grafana, Prometheus, Loki i Zabbix ->
Komentarze (0)
Brak komentarzy...