Przejdź do treści
Lekcja 97 z 117

Kurs › Moduł 10 › Lekcja 97

Monitorowanie

⏱ ok. 11 min czytania· moduł 10: Usługi i serwery

Po tej lekcji: kursant zbiera i czyta historię obciążenia serwera w sar, rozumie, czym są progi i alarmy, wie, jak podłączyć serwer do Zabbiksa przez agenta, kiedy wystarczy Netdata, a kiedy Prometheus z node_exporter.

Wstęp

Najgorszy sposób, żeby dowiedzieć się o awarii? Od klienta. Drugi najgorszy: od szefa, który dowiedział się od klienta. Dysk zapełniał się przez trzy tygodnie, codziennie o kilka procent. Każdy, kto by na to spojrzał, wiedziałby, co się stanie. Tylko nikt nie patrzył.

Monitorowanie to deska rozdzielcza samochodu. Nie patrzysz na nią cały czas, ale jak zapali się kontrolka oleju, zjeżdżasz na pobocze, zanim silnik się zatrze. Dziś zbudujemy taką deskę: od jednej komendy, która pamięta, co działo się wczoraj o 14:00, przez kontrolki z progami, po systemy, które pilnują setek serwerów naraz.

Co w ogóle mierzymy

Czterech podejrzanych, których sprawdzasz zawsze: procesor, pamięć, dysk i sieć. Do tego pytanie najważniejsze dla użytkownika: czy usługa w ogóle odpowiada.

Dwa pojęcia, które musisz rozróżniać. Metryka to liczba w czasie: „zajętość dysku o 14:00 była 71%”. Log to opis zdarzenia: „o 14:03 usługa nginx nie wstała”. Monitoring patrzy głównie na metryki. Logi masz w journalctl i /var/log.

sar, czyli czarna skrzynka serwera

top pokazuje, co jest teraz. A co, jeśli serwer zwolnił wczoraj o 3 w nocy, a Ty przyszedłeś rano? top nie pamięta. Pamięta sar, z paczki sysstat. To czarna skrzynka samolotu: co kilka minut notuje odczyty wszystkich przyrządów, a po fakcie możesz je przeczytać.

sudo dnf install sysstat
sudo systemctl enable --now sysstat
sudo apt install sysstat
sudo systemctl enable --now sysstat
systemctl list-timers 'sysstat*'

Zbieranie robi timer sysstat-collect.timer. U mnie na Ubuntu wygląda tak:

systemctl cat sysstat-collect.timer
[Unit]
Description=Run system activity accounting tool every 10 minutes

[Timer]
OnCalendar=*:00/10

Co 10 minut zdjęcie stanu. Pliki z danymi leżą w /var/log/sa/ na RHEL-u i w /var/log/sysstat/ na Ubuntu, po jednym na dzień miesiąca: sa03 to trzeci dzień.

[Ubuntu] W pliku /etc/default/sysstat jest jeszcze przełącznik ENABLED="false". Pilnuje on starego zbierania przez crona. Jak włączasz zbieranie przez dpkg-reconfigure sysstat, ustawi go za Ciebie.

Podgląd na żywo: trzy pomiary co sekundę:

sar -u 1 3
16:37:07        CPU     %user     %nice   %system   %iowait    %steal     %idle
16:37:08        all     24.50      0.00     25.50      0.00      1.50     48.50
16:37:09        all     22.34      0.00     26.90      0.00      2.54     48.22
16:37:10        all     39.11      0.00     26.24      0.00      2.48     32.18
Average:        all     28.71      0.00     26.21      0.00      2.17     42.90

Czytamy kolumny:

  • %user — czas na programy użytkowników,
  • %system — czas na pracę jądra,
  • %iowait — procesor nic nie robi, bo czeka na dysk. Wysoki iowait to kucharz, który stoi z patelnią i czeka, aż ktoś przyniesie z piwnicy ziemniaki,
  • %steal — w maszynie wirtualnej: czas, który hiperwizor zabrał Ci na innych lokatorów. Wysoki steal znaczy, że problem nie jest w Twoim serwerze, tylko u sąsiadów,
  • %idle — czas wolny.

Inne przyrządy:

sar -r 1 1
sar -q 1 1
sar -d 1 1
sar -n DEV 1 1
16:37:10    kbmemfree   kbavail kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit
16:37:11      2266960   6786264    925620     11.26    451256   3764432   2757468     33.54

16:37:11      runq-sz  plist-sz   ldavg-1   ldavg-5  ldavg-15   blocked
16:37:12            0       270      0.77      1.54      1.22         0

-r to pamięć (patrz na kbavail, czyli ile naprawdę jest do wzięcia), -q to kolejka i obciążenie, -d dyski, -n DEV karty sieciowe.

A teraz najważniejsze, historia. Co działo się trzeciego dnia miesiąca między 2:00 a 4:00 w nocy?

sar -u -s 02:00:00 -e 04:00:00 -f /var/log/sa/sa03

-f to plik z danego dnia, -s i -e to początek i koniec okna. Na Ubuntu ścieżka to /var/log/sysstat/sa03. Bez -f dostajesz dzisiejszy dzień. To pierwsza komenda, którą wpisujesz po słowach „wczoraj w nocy coś zwalniało”.

Progi i alarmy

Dane to dopiero połowa. Nikt nie będzie co rano czytał wykresów ze stu serwerów. Potrzebne są kontrolki, które zapalają się same. Kontrolka to próg: „zajętość dysku powyżej 90%”. Przekroczenie progu to alarm.

Najprostszy próg zrobisz w Bashu. Liczba procent zajętości dysku /, bez znaczka procentu:

df --output=pcent / | tail -1 | tr -dc '0-9'
42

Taką liczbę porównasz w if z progiem, a ostrzeżenie wyślesz do dziennika systemowego przez logger:

logger -t monitor "Dysk / zajęty w 92%"
journalctl -t monitor

Dobre progi mają dwa poziomy: ostrzeżenie (warning, na przykład 80%) i krytyczny (critical, na przykład 95%). Ostrzeżenie mówi „zaplanuj sprzątanie”, krytyczny mówi „wstawaj”.

I dwie pułapki. Pierwsza: alarm, który miga. Procesor skacze na 100% na dwie sekundy przy każdym backupie i telefon dzwoni co godzinę. Dlatego dobre systemy pytają nie „czy przekroczono”, tylko „czy przekroczono i trwa to od 10 minut”. Druga pułapka jest gorsza: za dużo alarmów. Jak kontrolka świeci się cały czas, przestajesz na nią patrzeć. Jak samochód, w którym od roku pali się „check engine” i nikt już nie wie, czy to ważne.

Zabbix z agentem

Kiedy serwerów jest więcej niż palców, potrzebujesz centrali. Zabbix to centrum monitoringu jak w ochronie osiedla: jeden pokój z monitorami (serwer Zabbix z bazą danych i stroną WWW) i czujniki w każdym budynku (agenci).

Agent to mała usługa na monitorowanym serwerze. Może pracować na dwa sposoby:

  • pasywnie — centrala dzwoni do agenta na port 10050 i pyta „ile masz wolnego miejsca?”,
  • aktywnie — agent sam dzwoni do centrali (domyślnie port 10051) i wysyła wyniki. Przydatne, gdy agent stoi za NAT-em i centrala nie może się do niego dodzwonić.

Agenta instalujesz z repozytorium Zabbiksa. Na stronie zabbix.com w dziale Download wybierasz wersję (najlepiej LTS), system i komponent, a strona podaje gotowe komendy dla Twojej dystrybucji. Paczka nowszego agenta nazywa się zabbix-agent2. Potem trzy linijki w /etc/zabbix/zabbix_agent2.conf:

Server=192.168.1.10
ServerActive=192.168.1.10
Hostname=web01
  • Server — kto może zadawać pytania. Agent odpowie tylko tym adresom. To lista wpuszczonych gości, nie zostawiaj tu całego internetu,
  • ServerActive — dokąd wysyłać wyniki sprawdzeń aktywnych,
  • Hostname — jak się przedstawiać. Musi być dokładnie taki sam, z wielkością liter, jak nazwa hosta wpisana w centrali.
sudo systemctl enable --now zabbix-agent2
sudo firewall-cmd --permanent --add-port=10050/tcp
sudo firewall-cmd --reload
sudo ufw allow from 192.168.1.10 to any port 10050 proto tcp

Na Ubuntu od razu wpuszczamy tylko adres centrali. Ochroniarz z listą okienek i listą nazwisk.

Z centrali sprawdzasz, czy agent odpowiada, narzędziem zabbix_get:

zabbix_get -s 192.168.1.21 -k agent.ping
zabbix_get -s 192.168.1.21 -p 10050 -k "system.cpu.load[all,avg1]"

agent.ping zwraca 1, jeśli agent żyje. -k to klucz, czyli nazwa pomiaru. Resztę robisz w przeglądarce: dodajesz host, przypinasz mu gotowy szablon dla Linuksa i masz od razu kilkadziesiąt pomiarów, wykresy i wyzwalacze (triggers), czyli progi z alarmami.

Netdata: monitoring w minutę

Zabbix to centrala dla całego osiedla. A jeśli masz jeden serwer i chcesz zobaczyć wszystko teraz, z dokładnością do sekundy? Netdata. Instalujesz i po chwili w przeglądarce masz setki wykresów, które odświeżają się co sekundę. Jak lekarz, który podpina cię do aparatury i od razu widać puls, ciśnienie i saturację.

Oficjalny instalator z dokumentacji Netdaty:

wget -O /tmp/netdata-kickstart.sh https://get.netdata.cloud/kickstart.sh && sh /tmp/netdata-kickstart.sh

Zasada z kursu wraca: skrypt z internetu najpierw pobierasz i czytasz, dopiero potem uruchamiasz. Tutaj tak właśnie jest, najpierw plik, potem sh. [Ubuntu] Netdata jest też w repozytorium (apt install netdata), ale w starszej wersji.

Panel jest pod adresem http://SERWER:19999. Uwaga: nie wystawiaj tego portu na świat. Panel pokazuje bardzo dużo o Twoim serwerze. Ogranicz zaporą albo patrz przez tunel SSH: ssh -L 19999:localhost:19999 eryk@serwer i w przeglądarce localhost:19999. Konfiguracja leży w /etc/netdata/, a edytuje się ją skryptem edit-config z tego folderu.

Prometheus i node_exporter w skrócie

Trzecia szkoła, popularna w świecie kontenerów i chmury. Dwa elementy:

  • node_exporter — mały program na każdym serwerze, który wystawia jego pomiary jako zwykłą stronę tekstową na porcie 9100,
  • Prometheus — zbieracz, który co kilkanaście sekund chodzi po wszystkich serwerach i spisuje te strony. Jak inkasent, który obchodzi mieszkania i spisuje liczniki.

Zauważ różnicę: tu centrala sama przychodzi po dane. To model „pull”, zbieranie.

sudo apt install prometheus-node-exporter
curl -s localhost:9100/metrics | grep -E '^node_(load1|memory_MemAvailable_bytes) '
node_load1 0.83
node_memory_MemAvailable_bytes 6.72718848e+09

[RHEL] node_exporter to jeden plik wykonywalny. Pobierasz archiwum ze strony prometheus.io/download, rozpakowujesz i uruchamiasz node_exporter, najlepiej jako usługę systemd z lekcji o własnych usługach.

U mnie node_exporter wystawił ponad 500 pomiarów. Wszystko zwykłym tekstem, możesz to czytać curl-em i grep-em.

Prometheus dostaje listę adresów w pliku prometheus.yml:

global:
  scrape_interval: 15s

rule_files:
  - alerty.yml

scrape_configs:
  - job_name: "serwery"
    static_configs:
      - targets: ["192.168.1.21:9100", "192.168.1.22:9100"]

A progi to reguły w alerty.yml:

groups:
  - name: serwery
    rules:
      - alert: MaloMiejscaNaDysku
        expr: node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"} * 100 < 10
        for: 10m
        labels:
          severity: warning
      - alert: SerwerNieOdpowiada
        expr: up == 0
        for: 2m

expr to warunek, for: 10m to nasze „trwa od 10 minut”, które chroni przed migającym alarmem. up == 0 to najprostszy i najważniejszy alarm: Prometheus nie mógł spisać licznika, więc serwer albo exporter leży. Przed restartem zawsze sprawdzasz pliki:

promtool check config prometheus.yml
Checking prometheus.yml
  SUCCESS: 1 rule files found
 SUCCESS: prometheus.yml is valid prometheus config file syntax

Checking alerty.yml
  SUCCESS: 2 rules found

To apachectl configtest i nginx -t w wersji dla Prometheusa. Pytanie do Prometheusa można zadać nawet z terminala:

curl -s -G localhost:9090/api/v1/query --data-urlencode 'query=up'
{"status":"success","data":{"resultType":"vector","result":[{"metric":{"__name__":"up","instance":"127.0.0.1:9100","job":"serwery"},"value":[1793720291.329,"1"]}]}}

1 znaczy, że serwer odpowiada. Prometheus sam nie dzwoni do ludzi. Powiadomienia wysyła osobny program, Alertmanager, a ładne wykresy robi się zwykle w Grafanie. To temat na osobną serię, dziś wystarczy, że wiesz, jak te klocki do siebie pasują.

Jak to działa pod spodem

Wszystkie te narzędzia czytają to samo źródło, które poznaliśmy w lekcji o mapie Linuksa: /proc i /sys. Wszystko jest plikiem. sadc czyta /proc/stat, /proc/meminfo, /proc/diskstats i zapisuje odczyty do pliku. node_exporter czyta te same pliki i zamienia je na tekst na porcie 9100. Agent Zabbiksa robi to samo, tylko odpowiada w swoim protokole.

head -1 /proc/stat
grep MemAvailable /proc/meminfo

Jądro w /proc/stat trzyma liczniki: ile czasu procesor spędził w każdym trybie od startu systemu. Procent zajętości to zawsze różnica między dwoma odczytami podzielona przez czas między nimi. Dlatego sar -u zawsze pokazuje średnią z jakiegoś lekcji czasu, nigdy z jednej chwili. Jak prędkość auta: z jednego zdjęcia licznika kilometrów jej nie policzysz.

Ściąga flag

KomendaFlagaCo robi
sar-uprocesor
sar-rpamięć
sar-qkolejka i obciążenie
sar-ddyski
sar-n DEVkarty sieciowe
sar-P ALLkażdy rdzeń osobno
sar-f PLIKhistoria z pliku danego dnia
sar-s HH:MM:SS -e HH:MM:SSokno czasowe
sarINTERWAŁ ILEpomiary na żywo, np. 1 3
logger-t ZNACZNIKwpis do dziennika z własnym znacznikiem
zabbix_get-s HOST -p PORT -k KLUCZpytanie do agenta Zabbiksa
promtoolcheck config PLIKsprawdza konfigurację Prometheusa
curllocalhost:9100/metricspodgląd pomiarów node_exportera

⚠ Typowy błąd

Pierwszy dzień z sar. Instalujesz paczkę, wpisujesz sar i:

Cannot open /var/log/sysstat/sa03: No such file or directory
Please check if data collecting is enabled

Czarna skrzynka jest zamontowana, ale nikt jej nie włączył. Paczka to dopiero przyrząd. Zbieranie robi timer, który trzeba uruchomić: systemctl enable --now sysstat, a na Ubuntu sprawdź też dpkg-reconfigure sysstat. Potem cierpliwość: pierwsze dane pojawią się po pierwszym przebiegu timera. Historii sprzed włączenia nie będzie nigdy. Dlatego sysstat włącza się na każdym serwerze pierwszego dnia, a nie w dniu awarii. Czarnej skrzynki nie montuje się w samolocie, który już spada.

Drugi klasyk, z Zabbiksa: host w centrali ma czerwoną ikonkę, a agent działa. Prawie zawsze winne jest jedno z trzech: zapora nie wpuszcza portu 10050, adres centrali w Server= jest inny niż ten, z którego centrala naprawdę dzwoni, albo Hostname= różni się od nazwy w centrali jedną literą. Log agenta powie Ci, które: journalctl -u zabbix-agent2.

✎ Zadanie

Napisz skrypt odpalany z crona co 5 minut, który sprawdza zajętość dysku /, dostępną pamięć i to, czy działa usługa SSH. Przy przekroczeniu progu zapisuje ostrzeżenie do dziennika przez logger.

Pokaż rozwiązanie

Skrypt, który co 5 minut zagląda pod maskę i zapala kontrolkę w dzienniku:

#!/bin/bash
# monitor.sh - odpalany z crona co 5 minut: dysk /, pamięć, SSH
PROG_DYSK=${PROG_DYSK:-90}     # alarm, gdy / zajęty w więcej niż tyle %
PROG_RAM=${PROG_RAM:-200}      # alarm, gdy dostępnej pamięci mniej niż tyle MiB

dysk=$(df --output=pcent / | tail -1 | tr -dc '0-9')
ram=$(free -m | awk '/^Mem:/ {print $7}')

if (( dysk > PROG_DYSK )); then
    logger -t monitor -p user.warning "Dysk / zajęty w ${dysk}% (próg ${PROG_DYSK}%)"
fi

if (( ram < PROG_RAM )); then
    logger -t monitor -p user.warning "Mało pamięci: ${ram} MiB dostępne (próg ${PROG_RAM} MiB)"
fi

# Ubuntu: usługa ssh, RHEL: sshd
if ! systemctl is-active --quiet ssh && ! systemctl is-active --quiet sshd; then
    logger -t monitor -p user.err "Usługa SSH nie działa!"
fi

Siódma kolumna free -m to available, czyli pamięć, którą naprawdę da się wziąć. Zapis ${PROG_DYSK:-90} znaczy „weź zmienną, a jak jej nie ma, to 90”. Dzięki temu skrypt da się przetestować bez edytowania: podajesz absurdalne progi i patrzysz, czy kontrolki się zapalą.

sudo install -m 755 monitor.sh /usr/local/bin/monitor.sh
PROG_DYSK=1 PROG_RAM=999999 /usr/local/bin/monitor.sh
journalctl -t monitor -n 3

Na mojej maszynie testowej, gdzie SSH akurat nie działało, do dziennika dotarły trzy wpisy:

Nov  4 02:38:38 monitor: Dysk / zajęty w 44% (próg 1%)
Nov  4 02:38:38 monitor: Mało pamięci: 7325 MiB dostępne (próg 999999 MiB)
Nov  4 02:38:38 monitor: Usługa SSH nie działa!

I wpis w sudo crontab -e, pełna ścieżka, bo cron ma krótki PATH:

*/5 * * * * /usr/local/bin/monitor.sh

ShellCheck bez uwag. Kontrolki działają. Teraz tylko trzeba kiedyś spojrzeć na deskę rozdzielczą.

Co dalej

Monitoring powie Ci, że dysk padł. Ale nie odda danych. W następnej lekcji kopie zapasowe na serio: zasada 3-2-1, kopie pełne, przyrostowe i różnicowe, borg i restic, i rzecz, o której wszyscy zapominają: test odtwarzania.