Najczęściej o awarii dowiadujecie się od klienta: „strona nie działa”. Potem okazuje się, że dysk na serwerze bazy zapełnił się już wczoraj, replika była godzinę w tyle, a log z błędem leżał na trzeciej maszynie, do której nikt nie zaglądał. Dane o tym wszystkim istniały. Tylko nikt ich nie zbierał w jednym miejscu.

Bywa też odwrotnie: monitoring jest, ale to pięć różnych paneli z pięcioma hasłami, a czat z powiadomieniami od dawna jest wyciszony, bo leci tam sto wiadomości dziennie. Taki monitoring daje tylko złudzenie kontroli.

Stawiamy kompaktowy stos, który odpowiada na trzy pytania: co dzieje się wewnątrz serwerów, co usługi piszą w logach i czy użytkownicy widzą was z zewnątrz. Jedno wejście, jedno logowanie, alerty tylko o tym, co naprawdę wymaga reakcji.

Co robimy

  • Prometheus zbiera metryki ze wszystkiego, co u was działa. Na każdym serwerze, VM i LXC instalujemy node_exporter: dyski, pamięć, obciążenie, sieć, stan usług systemd.
  • pve-exporter patrzy na Proxmoxa od strony hypervisora: status i zużycie wszystkich VM i kontenerów, także wyłączonych. Korzysta z API z tokenem tylko do odczytu.
  • Bazy danych: eksportery dla PostgreSQL i MariaDB oraz wbudowane metryki Patroni, etcd, HAProxy i ProxySQL. Widać, kto jest teraz primary, jakie jest opóźnienie replik i ile węzłów Galery jest zsynchronizowanych.
  • Alertmanager grupuje alerty i wysyła je na Telegram, e-mail albo firmowy czat.
  • Loki z agentem Promtail lub Alloy zbiera logi ze wszystkich maszyn. Przeszukujecie je w tej samej Grafanie, obok wykresów.
  • Uptime Kuma sprawdza strony, API i porty z zewnątrz, pilnuje ważności certyfikatów TLS i daje publiczną status page dla waszych klientów.
  • Grafana pokazuje to wszystko na dashboardach przygotowanych pod waszą infrastrukturę.
  • Traefik stoi z przodu jako reverse proxy i sam pobiera certyfikaty Let’s Encrypt.
  • Authentik daje jedno logowanie do Grafany, Uptime Kumy i wewnętrznych paneli, z 2FA. Usługi bez własnego logowania zamykamy przez forwardAuth w Traefiku.

Wdrażamy na docker compose albo w osobnych kontenerach LXC. Konfiguracja, reguły alertów i dashboardy leżą w git, więc stos da się odtworzyć od zera.

Jak sprawić, żeby ktoś czytał alerty

Największe ryzyko nie jest techniczne. Jeśli alert przychodzi, a reagować nie trzeba, po tygodniu nikt go już nie otwiera. Dlatego każdą regułę sprawdzamy jednym pytaniem: co trzeba zrobić, gdy się odpali? Jeśli nie ma odpowiedzi, to nie jest alert, tylko wykres na dashboardzie.

W praktyce: każdy alert ma warunek for:, żeby krótki skok nie budził nikogo w nocy. Zapełnianie dysku liczymy z trendu, a nie z progu „90%”. Martwe i wygasłe usługi usuwamy z testów, bo inaczej świecą na czerwono bez końca i uczą, że czerwony nic nie znaczy. Przykładowa reguła:

groups:
  - name: infra
    rules:
      - alert: DiskWillFillIn24h
        expr: predict_linear(node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"}[6h], 24*3600) < 0
        for: 30m
        labels: {severity: warning}
        annotations:
          summary: "{{ $labels.host }}: {{ $labels.mountpoint }} zapełni się w ciągu doby"
      - alert: GaleraNodeLost
        expr: mysql_global_status_wsrep_cluster_size < 3
        for: 2m
        labels: {severity: critical}

Dashboardy budujemy pod konkretne pytania, a nie „wszystko o wszystkim”. Na co dzień wystarcza jeden ekran: hypervisor, magazyny danych, kto zjada najwięcej zasobów, komu kończy się miejsce, kto nie ma backupu. Dla klastrów baz inna logika: rolę węzła i stan Galery pokazujemy jako pasek na osi czasu, więc failover widać od razu, bo pasek po prostu przeskakuje na inny węzeł. Duże dashboardy generujemy skryptem i po każdej zmianie sprawdzamy, czy żaden panel nie jest pusty.

Kilka rzeczy warto wiedzieć z góry. node_exporter w LXC częściowo widzi metryki hosta, bo jądro jest wspólne, więc realne zużycie kontenera bierzemy z pve-exporter. Maszyny w Prometheusie oznaczamy nazwami, a nie adresami IP, żeby w Grafanie nie trzeba było pamiętać adresów.

Kompromisy i kiedy to się nie sprawdzi

Loki to nie Elasticsearch. Indeksuje tylko etykiety (host, usługa, poziom), a treść przegląda w momencie zapytania. Dzięki temu jest lekki i tani w przechowywaniu, ale pełnotekstowe wyszukiwanie po miesiącach logów będzie wolne. Jeśli potrzebujecie analityki logów albo długiej retencji pod audyt, lepszy będzie ELK lub OpenSearch, a to już inna skala sprzętu.

Monitoring musi żyć osobno od tego, co monitoruje. Jeśli Prometheus stoi na tym samym serwerze co produkcja, przy awarii serwera nie dostaniecie nawet alertu o niej. Minimum to osobna VM albo LXC. Uptime Kumę najlepiej wynieść do innej lokalizacji lub do innego dostawcy, bo to wasze spojrzenie oczami użytkownika. Dodatkowo ustawiamy alert-„strażnika”, który ma przychodzić zawsze: jeśli ucichł, zepsuł się sam łańcuch powiadomień.

Authentik staje się bramą. Jeśli padnie, do paneli się nie zalogujecie. Dlatego przed każdą aktualizacją robimy backup jego bazy, a po aktualizacji sprawdzamy nie tylko, czy strona się otwiera, ale też dokąd prowadzi przekierowanie logowania. Awaryjny dostęp do serwerów zostaje osobny i nie zależy od SSO.

Dla jednego małego VPS-a cały stos to przesada: wystarczy Uptime Kuma i kilka alertów. Ma sens od kilku serwerów albo tam, gdzie są bazy z replikacją.

Co dostajecie

  • Działający stos Prometheus, Alertmanager, Grafana, Loki i Uptime Kuma za Traefikiem, z HTTPS.
  • Jedno logowanie z 2FA do wszystkich paneli i konta dla waszego zespołu.
  • Metryki wszystkich serwerów, VM/LXC i baz danych, łącznie z replikacją, Patroni czy Galerą.
  • Dashboardy pod waszą infrastrukturę, a nie zaimportowane „na wszystko”.
  • Alerty na Telegram, e-mail lub czat, z opisem, co znaczy każdy z nich i co robić.
  • Status page dla waszych klientów, jeśli jej potrzebujecie.
  • Cały stos w git: konfiguracja, reguły, dashboardy, plus dokumentacja, jak dodać nowy serwer czy nowy test.

Jeśli macie już kilka serwerów, a o problemach dowiadujecie się od klientów, napiszcie do nas. Opiszcie, co i gdzie u was działa, a zaproponujemy, jak to obserwować z jednego miejsca.