[Nagios] Monitorujemy Raspberry Pi i usługi

Nasz ekosystem złożony z Raspberry Pi i innych usług rozrasta się. Przydałby się jakiś mechanizm monitorowania. Skorzystajmy z profesjonalnego i bardzo popularnego Nagiosa. W tym artykule przedstawię jak uruchomić Nagiosa na Dockerze i monitorować zdalne środowiska.

Nagios na Dockerze

Jestem fanem Dockera i bez problemu użyję go także do hostowania mojego Nagiosa, środowisko konfiguruje przy pomocy docker-compose.yml:

version: '3'

services:
  nagios:
    image: manios/nagios:latest
    volumes:
    - /CLU/gv/nagios/etc:/opt/nagios/etc
    - /CLU/gv/nagios/var:/opt/nagios/var
    - /var/tmp:/opt/nagios/var/rw  #dla query.sh - konieczna zmiana w config nagios
    - /CLU/gv/nagios/customplugins:/opt/Custom-Nagios-Plugins
    - /CLU/gv/nagios/ssmtp:/etc/ssmtp
    ports:
      - 85:80  
    environment:          
      - TZ=Europe/Warsaw
    links:
      - smtp

 smtp:
    image: ixdotai/smtp
    container_name: smtp
    restart: always
    environment:
      - GMAIL_USER=xxx
      - GMAIL_PASSWORD=xxx     
      - RELAY_NETWORKS=:172.0.0.0/8:10.0.0.0/8
   # platform: linux/arm64/v7

Co tutaj się dzieje?

Korzystamy z obrazu Nagios udostępnionego przez usera community Manios. Ma on dobrą reputację i aktualizuje udostępniane obrazy co kilkanaście dni (!) od kilku lat, można więc mu zaufać.

Obraz zawiera Nagiosa Core uruchomionego na lekkim i bezpiecznym Alpine Linux, używa Appache’a do hostowania strony i sSMTP jako agenta e-mail do wysyłania powiadomień.
W moim przypadku (i jak czytałem w Internecie nie tylko w moim) agent ten sprawia nieco problemów dlatego stawiam dodatkowo Server Smtp działający jako Relay’ey w moim wewnętrznym środowisku docker’owym (nie wystawiam go na zewnątrz, a już tym bardziej do Internetu!).

Konfigurację Nagiosa (pliki konfiguracyjne) kieruję na dysk lokalny aby łatwiej manipulować na plikach.

Dość popularnym problemem w przypadku hostowania Nagiosa w kontenerze Dockera jest błąd:

Could not open nagios.cmd command file for update

wynikający z problemu z uprawnieniami, bez wnikania w szczegóły – pomaga skierowanie folderu /opt/nagios/var/rw np. do /var/tmp (co uczyniłem w moim pliku docker-compose.yml). Alternatywne rozwiązanie to ingerencja wewnątrz kontenera i zezwolenie userowi apache i nagios na dostęp do ww. folderu (komendy usermod i chown).

Kolejna linia kieruje natywny port 80 Apacha na port 85 hosta. Robię tak ze względu na fakt, że na porcie 80 działa już inna usługa w moim środowisku. Nagios dostępny będzie zatem na porcie 85.
Istotna kwestia to również ustawienie strefy czasowej, dzięki temu w GUI zobaczymy poprawne daty.

Usługa SMTP jest bardzo prosta i przyjemna w konfiguracji, odbywa się ona w całości poprzez ustawienie zmiennych konfiguracyjnych. Nasz Open Raley działa tylko wewnątrz środowiska Dockerowego, nie jest dostępny dla innych usług w systemie operacyjnym, ani udostępniony publicznie.

Konfiguracja Nagiosa

Nagios konfigurujemy poprzez edycję plików do czego z pewnością użytkownicy Linuxów przywykli.
Interesujące nas pliki konfiguracyjne znajdziemy w /opt/nagios/etc, który w moim przypadku skierowany jest do folderu /CLU/gv/nagios/etc hosta.

Nagios.cfg zawiera najważniejszą konfigurację samego systemu, nie musimy tutaj niczego zmieniać, jednak obszerne komentarze klarownie wyjaśniają przeznaczenie poszczególnych opcji.

Konfiguracja czujek

Najczęściej ingerować będziemy w definicje konfiguracji poszczególnych czujek Nagiosa, znajdują się one w folderze objects. Oprócz czujek znajdziemy tutaj także szablon domyślnego powiadomienia, listę odbiorców powiadomień (pliki contacts i templates). Nagios umożliwia bardzo wygodny podział odbiorców na grupy, dzięki czemu administratorzy mogą otrzymywać maile o każdej porze, a np. „szefowie” tylko w dni robocze i tylko o krytycznych błędach; a także zbiór podstawowych komend do weryfikacji działania usług.

Czujki lokalne

Dostarczone wraz z bazowym Nagiosem czujki lokalne pozwalają na monitorowanie bardzo wielu popularnych usług i parametrów serwera, są one przystępnie opisane tutaj: http://nagios-plugins.org/doc/man/index.html, prawdziwa moc jednak drzemie w społeczności i czujkach dostarczanych przez twórców, znajdziemy je tutaj: https://exchange.nagios.org/, jak widzicie są ich tysiące, praktycznie do wszystkiego, np.:

Przykładowa część listy czujek dostępna dla MS-SQL Server

To prawdziwa potęga Nagiosa.

Zacznijmy od skonfigurowania kilku podstawowych czujek lokalnych, monitorujących maszynę, na której zainstalowany jest Nagios (w naszym przypadku będzie to kontener Dockera, jednak w przypadku instalacji bezpośrednio w systemie operacyjnym będzie to ten właśnie system):

Dodajmy plik localhost.cfg w naszym folderze object. Następnie definiujemy jego zawartość:

  • Host – to serwer, który chcemy monitorować, w ramach danego serwera może występować wiele usług
  • HostGroup – to grupa hostów – np. serwery bazodanowe
  • Service – to najbardziej interesujący nas element – monitorowane usługi

Monitorowanie serwisu

Przykładowa definicja monitoringu serwisu wygląda tak:
define service {
    use                     local-service           
    host_name               localhost
    service_description     PING
    check_command           check_ping!100.0,20%!500.0,60%
}
  • Jak widać zaczynamy od nazwy serwisu – to etykieta wyświetlana przez Nagios.
  • Kolejna linia to nazwa monitorowanego hosta – ważne aby odpowiadała hostowi, którego definicje wprowadziliśmy powyżej.
  • Kolejna linia to nasz, własny opis usługi
  • I najważniejsze – sposób monitorowania usługi.
Używnaie check_command

Check command to nazwa komendy zdefiniowanej w pliku commands.cfg. Nagios dostarczany jest z obszernym plikiem commands.cfg zawierający wszystkie wbudowane w niego czujki, jeśli jednak chcemy dodać coś swojego lub skorzystać z czujki społecznościowej będziemy musieli rozszerzyć ten plik lub dodać własną definicję komendy w innym miejscu (generalnie: nazwa pliku nie ma znaczenia, liczy się nagłówek „define command„, definicje komendy możemy umieścić w dowolnym pliku).

Przykładowa zawartość pliku cfg:
define host {
    use                     linux-server            ; Name of host template to use
                                                    ; This host definition will inherit all variables that are defined
                                                    ; in (or inherited by) the linux-server host template definition.
    host_name               localhost
    alias                   localhost
    address                 127.0.0.1
}

define hostgroup {
    hostgroup_name          linux-servers           ; The name of the hostgroup
    alias                   Linux Servers           ; Long name of the group
    members                 localhost               ; Comma separated list of hosts that belong to this group
}

define service {
    use                     local-service           ; Name of service template to use
    host_name               localhost
    service_description     PING
    check_command           check_ping!100.0,20%!500.0,60%
}

define service {
    use                     local-service           ; Name of service template to use
    host_name               localhost
    service_description     Root Partition
    check_command           check_local_disk!20%!10%!/
}

Użyte komendy (ich definicje) znajdziemy w pliku commands.cfg:

define command {
    command_name    check_ping
    command_line    $USER1$/check_ping -H $HOSTADDRESS$ -w $ARG1$ -c $ARG2$ -p 5
}

define command {
    command_name    check_local_disk
    command_line    $USER1$/check_disk -w $ARG1$ -c $ARG2$ -p $ARG3$
}

Wprawne oka zauważy tutaj jeszcze jedną zagadkę. Co to jest $USER1&$? Jest to wbudowane w Nagiosa makro zdefiniowane w pliku resources.cfg i wygląda tak:

# Sets $USER1$ to be the path to the plugins
$USER1$=/opt/nagios/libexec

Oznacza to w praktyce, że Nagios szuka we wskazanej lokalizacji definicji komendy (plik lub łącze symboliczne zawierające niskopoziomowy skrypt realizujący dane sprawdzenie):

Podsumowując: kolejne serwisy monitorujemy poprzez korzystanie z wbudowanych czujek Nagiosa lub tych dostarczonych przez społeczność. Instalacja czujek zewnętrznych jest relatywnie prosta, jednak konfiguracja każdej z nich może przebiegać nieco inaczej. Twórcy przedstawiają sposób instalacje w opisie każdej czujki.
Finalnie – po jej zainstalowaniu – dodajemy nową komendę i już. Korzystamy z niej!

Monitorowanie środowiska zdalnego

Kolejna potęga Nagiosa objawia się w monitorowaniu zdalnych środowisk, metody monitorowania możemy podzielić na dwie zasadnicze grupy:

  • Monitorowanie usług możliwe z poziomu serwera Nagios, np.: weryfikacja dostępności stron internetowych (http/https), weryfikacja możliwości połączenia lub zalogowania na określone porty i usługi (telnet, ssh), weryfikacja odpowiedzi na PING, itp. Po prostu Nagios wykona akcję na podstawie, której stwierdzi czy zdalna usługa jest dostępna. W ten sposób można np. sprawdzić czy inne Raspberry Pi w naszej infrastrukturze odpowiadają na PINGi, czy strona zarządcza PiHole jest dostępna, czy zasoby NFS udostępniane przez OpenMediaVault są dostępny lub czy router w naszej serwerowni odpowiada na PING.
  • Monitorowanie usług z poziomu wnętrza zdalnego serwera. Chodzi tutaj o takie informacje jak: status usługi Docker na zdalnych serwerach, ilość zajętego miejsca na dyskach zdalnych serwerów, weryfikacja czy są zamontowane określone dyski, uruchomione określone usługi, itp.
    Jeśli instalujemy Nagios w środowisku kontenerowym to host, na którym działa Docker jest również systemem zdalnym.

O ile punkt pierwszy załatwimy czujkami opisanymi w poprzednich paragrafach o tyle zdalne serwery monitorujemy nieco inaczej.

NRPE – monitorowanie zdalnych serwerów

Nagios udostępnia bardzo dobry mechanizm zdalnego wywoływania czujek (które w nomenklaturze Nagiosa nazywamy pluginami): NRPE: NRPE – Nagios Remote Plugin Executor:

NRPE działa zarówno z Windows’em jak i z innymi systemami operacyjnymi.

NRPE musimy zainstalować na zdalnym serwerach. Po instalacji uruchomiony zostanie proces w tle, który będzie oczekiwał komunikacji przychodzącej z serwera Nagiosa. Polecenie wydawane przez serwer ogranicza się do informacji jaki plugin/którą czujkę wywołać, wynik zwracany jest do serwera.

Dodatkowo, na naszym serwerze działa drugi proces check_nrpe, który odpowiada za komunikację ze zdalnymi nrpe.

Instalacja NRPE na zdalnym serwerze

sudo apt-get install nagios-nrpe-server nagios-plugins
Konfiguracja nrpe.cfg
sudo nano /etc/nagios/nrpe.cfg
Konfiguracja hosts.allow

Dodajemy adres IP serwera Nagios w sekcji allowed hosts:

sudo nano  /etc/hosts.allow

Tutaj również dodajemy adres IP serwera Nagios (tak właściwie to dodanie go w pliku nrpe.cfg najczęściej nie jest konieczne, w przypadku Raspberry Pi – wystarczy dodać go w pliku hosts.allow).
Jeśli chcemy dopuścić wszystkie komputery mające łączność sieciową z naszym Raspberry możemy wpisać ALL, nie jest to zalecane w sytuacji gdy udostępniamy naszą maszynę w Internecie, jeśli środowisko stoi za firewallem/NATem – w zastosowaniu nieprodukcyjnym możemy tak zrobić:

Z NRPE.cfg dowiemy się też kilku innych informacji, np., że server działa na porcie 5666, że skrypty będą wywoływane z uprawnieniami użytkownika nagios, a przede wszystkim możemy wskazać komendy, które chcemy wywoływać:

##MY####
command[check_load]=/usr/lib/nagios/plugins/check_load -r -w 0.55,0.40,0.35 -c 0.90,0.75,0.65
command[check_rpi_tmp]=/usr/lib/nagios/plugins/check_rpi_temp -w 55 -c 70
command[check_sd]=/usr/lib/nagios/plugins/check_disk -w 25% -c 15% -p /

#indywidualne
command[check_CLU]=/usr/lib/nagios/plugins/check_file_age -w 172800 -c 345600 -f /CLU/empty.txt
###

To kluczowy element zawiera definicje komend, które możemy wywołać zdalnie.

Streszczając: serwer Nagios poprzez NRPE wywołuje komendy z monitorowanego hosta, monitorowany host odpowiada tekstem, serwer Nagios przetwarza ten tekst i interpretuje.

Mała uwaga:
Nie musimy definiować wszystkich komend w pliku nrpe.config, równie dobrze, możemy wowołać je poprzez check_nrpe z serwera Nagios, mamy wtedy możliwość centralnego zarządzania. Sprawa komplikuje się jednak przy odpalaniu „customowych” pluginów takich jak check_rpi_temp, dlatego jestem zwolennikiem aby każdy host posiadał swoje komendy.
Nie w każdym scenariuszu jest to rozwiązanie optymalne, np. jeśli mamy środowisko złożone z kilkudziesięciu takich samych serwerów lepsze będzie zarządzanie z centralnego punktu. Traktujcie to jednak jako adnotacje na marginesie, nie chcę schodzić na tak wysoki poziom szczegółowości.

Wywołanie komend NRPE

W kolejnym kroku pozostaje nam już tylko wywołanie komend NRPE na serwerze nagios:

define host {
	use linux-server
	host_name docker1
	alias docker1
	address 192.168.1.151
}

define service{                     
            use                     local-service            
            host_name               docker1            
            service_description     Current Load            
            check_command           check_nrpe!check_load
}

define service{                     
            use                     local-service            
            host_name               docker1            
            service_description     Temperature          
            check_command           check_nrpe!check_rpi_tmp
}

define service{                     
            use                     local-service            
            host_name               docker1            
            service_description     SD - free space          
            check_command           check_nrpe!check_sd
}

define service{                     
            use                     local-service            
            host_name               docker1            
            service_description     CLU mounted
            check_command           check_nrpe!check_CLU
}

Jak widzicie:

  • Definiujemy host – czyli zdalna maszyne, którą chcemy monitorować przy użyciu zdefiniowanych na niej lokalnie komend (w tym scenariuszu)
  • Na rzecz tego hosta wywołujemy zdalne komendy poprzez check_nrpe
  • Powoduje to, że zdalny host wywołuje wskazaną komendę, a wynik zwraca do serwera Nagiosa
  • Najprościej jest dedykować oddzielny plik cfg, każdemu zdalnemu hostowi

Interfejs WEBowy

Po skonfigurowaniu wszystkiego restartujemy usługi NRPE na zdalnym serwerach:

sudo systemctl restart nagios-nrpe-server

Uruchamiamy kontener dockera z Nagiosem na haszym hoście poprzez najprostsze:

sudo docker-compose up

lub jeśli nasz Docker pracuje w klastrze Swarmowym (do czego zachęcam):

sudo docker stack deploy -c docker-compose.yml nagios

I obserwujemy czy na porcie 85 (w naszym przypadku) – zgodne z plikiem docker-compose.yml pojawiła się strona WWW:

Jeśli interfejs się pojawił i zawiera dane to wszystko zdefiniowaliśmy poprawnie, pozostaje jeszcze uzupełnić konfigurację serwera SMTP do wysyłania powiadomień (plik docker-compose.yml) i przetestować ten element.

Sam interfejs Nagiosa pomimo, że dość „rustykalny” ma kilka przydatnych opcji, myślę że użytkownik spokojnie sam jest w stanie je rozgryźć.

Powodzenia! 🙂

Leave a Reply