Preorder drugiego tomu książki sekuraka: Wprowadzenie do bezpieczeństwa IT. -15% z kodem: sekurak-book

Ułatwianie pracy w Zabbix – używamy makr

04 września 2017, 11:30 | Teksty | komentarzy 7

Makra w zabbixie są bardzo użytecznym wbudowanym “narzędziem” do ułatwiania sobie konfiguracji oraz utrzymywania porządku. Temat ten jednak jest na tyle skomplikowany dla początkującego (i nie tylko) użytkownika, że często jest on pomijany.

W artykule omówimy teorię związaną z makrami oraz wyjaśnimy, jak ich używać najbardziej efektywnie. Dodatkowo nauczymy się obsługiwać konteksty. Wszystkie te punkty oczywiście będą posiadały odpowiednie przykłady. Zaczynamy!

Teoria

Makra to nic innego jak zmienne – posiadają one nazwę oraz przypisaną do nich wartość. Nazwa makra może składać się z dużych liter, cyfr, znaku podkreślenia (“_”) lub kropki (“.”). Zawsze znajduje się w nawiasach klamrowych np. {MAKRO_TEST1}. Na początku musimy wiedzieć, że istnieją trzy typy makr:

  • Makra wbudowane w zabbixa,
  • Makra wykrywania niskopoziomowego (LLD),
  • Makra użytkownika.

Makra wbudowane

Sam zabbix posiada dużą paletę wbudowanych makr np. {HOST.NAME} zostanie zamienione na nazwę hosta, {DATE} – na aktualną datę itd. Pełną listę makr wbudowanych można znaleźć w dokumentacji. Warto przyjrzeć się od razu, gdzie możemy użyć dane makro (kolumna “Supported in”) oraz, jeżeli nie mamy najnowszej wersji, od której wersji zabbixa dane makro jest wspierane (kolumna “Description”).

Najprostszym przykładem użycia makr wbudowanych jest domyślna akcja do wysyłki maili. Wystarczy wejść w zakładkę “Configuration” -> “Actions”, upewnić się, że po prawej stronie przy “Event source” wybraliśmy “Triggers” i wybrać “Report problems to Zabbix administrators”:

Rysunek 1. Domyślna akcja do wysyłki maili.

Kiedy przejdziemy do zakładki “Operations”, zobaczymy dużo makr wbudowanych, które podczas wysyłki maila zostaną zamienione na odpowiednie wartości np. {TRIGGER.NAME} zostanie zamienione na nazwę wyzwalacza itp.:

Rysunek 2. Przykład makra wbudowanego.

Uważny czytelnik zauważy, że niektóre makra wbudowane posiadają tzw. indeksy np. {HOST.NAME1}, {HOST.NAME2} itp. Najlepiej wyjaśnić to na przykładzie.

Wyobraźmy sobie, że posiadamy trigger, który wyzwala się przy problemach z apache na serwerach o nazwach “WWW1” i “WWW2” (warto zauważyć, że składa się z dwóch wyrażeń logicznych rozdzielonych operacją “and”):

Rysunek 3. Przykładowy wyzwalacz.

Teraz przy problemach na obydwu serwerach apache pokaże się trigger o następującej nazwie:

Nie działa serwer apache na WWW1 oraz WWW1

Wiadomość ta może być myląca, ponieważ zabbix pobrał nazwę hosta tylko z pierwszego wyrażenia logicznego (gdy nie podamy numeru indeksu, zabbix zawsze pobiera wartość z pierwszego wyrażenia). Dlatego musimy wskazać, z których wyrażeń logicznych pobieramy nazwę hosta (ważna jest tutaj ich kolejność). Dlatego gdy ustawimy trigger tak jak na Rysunku nr 4, otrzymamy następujący komunikat:

Nie działa serwer apache na WWW1 oraz WWW2

Rysunek 4. Przykładowy wyzwalacz z indeksami.

Makra wykrywania niskopoziomowego

Makra te są wykorzystywane podczas wykrywania niskopoziomowego np. przy wykrywaniu systemów plików albo kart sieciowych. Charakteryzują się znakiem “#” na początku nazwy np. {#IFNAME}.

Na Rysunku nr 5 można zauważyć makra wykrywania niskopoziomowego dla systemów plików – pod makro {#FSNAME} będzie wstawiana nazwa każdego FS (a skąd ta nazwa się bierze to już temat na inny artykuł).

Rysunek 5. Przedstawienie makra wykrywania niskopoziomowego.

Makra użytkownika

Dopiero makra użytkownika ukazują prawdziwy potencjał tego rozwiązania. Są to zmienne tworzone przez użytkownika i mogą być wykorzystywane w wielu miejscach. Nazwy tych makr zawsze zaczynają się od znaku “$” np. {$MAKRO}.

Makra użytkownika można podzielić na 3 rodzaje:

Globalne – makro, które działa w całym obszarze konfiguracji zabbixa; ustawia się je poprzez wejście w zakładkę “Administration” -> “General” i wybrania z prawej strony z listy pozycji “Macros”; na Rysunku nr 6 można zauważyć domyślne makro globalne ustawiające community dla SNMP na wartość “public”,

Rysunek 6. Konfiguracja makr globalnych.

Szablonu – Makra, które są ustawiane w template i działają w obrębie tego szablonu i wszystkich hostów, które są do niej podłączone; przykładowe makra przedstawia Rysunek nr 7,

Rysunek 7.Konfiguracja makr szablonu.

Hosta – makra, które są ustawione na samym hoście i działają tylko w jego obrębie; Przykładowe makra dla hosta zabbix-server przedstawia Rysunek nr 8.

Rysunek 8. Konfiguracja makr hosta.

Najczęstszymi wątpliwościami podczas pracy z makrami użytkownika jest pytanie: “Które makro jest przetwarzane jako pierwsze?”. Patrząc na Rysunki nr 7 i 8 można zauważyć, że zarówno w szablonie “Template OS Linux”, jak i na samym hoście “Zabbix server” jest makro {$CPU_LIMIT}. W dużym uproszczeniu kolejność jest następująca:

  • na początku brana jest wartość makra hosta,
  • jeżeli go nie ma, uwzględniana jest wartość makra szablonu,
  • gdy szablon nie posiada makra, na końcu jest sprawdzane makro globalne.

Kolejność może budzić wiele wątpliwości, dlatego deweloperzy zabbixa wprowadzili w wersji 3.0.0 wzwyż listę “makr dziedziczonych”. W naszym przykładzie wystarczy podczas wyświetlania makr na hoście kliknąć na przycisk “Inherited and host macros”, aby zobaczyć:

  • Makro hosta (1°),
  • Makro szablonu, które zostało zastąpione przez makro hosta (2°),
  • Niezmienione makro szablonu (3°),
  • Makro globalne (4°).

Rysunek 9. Widok makr dziedziczonych.

Konteksty

By wyjaśnić pojęcie kontekstów wyobraźmy sobie następującą sytuację – posiadamy monitoring routera, który automatycznie (poprzez wykrywanie niskopoziomowe) dodaje nam wszystkie porty do zabbixa (uzyskuje nazwy interfejsów poprzez makro {#IF_NAME}) i monitoruje ruch przychodzący/wychodzący (w % zajętości; 0% – brak ruchu w danym kierunku, 100% – wysycenie łącza). Chcemy być poinformowani, gdy ruchu przychodzącego będzie za dużo. Przyjmujemy również, że ustawiliśmy makro użytkownika w wyzwalaczu, by móc zmieniać próg dla różnych hostów o nazwie {$NET_IN} i wartości 80 (należy pamiętać, że to jest wartość procentowa). Przykład takiego triggera pokazuje Rysunek nr 10.

Rysunek 10. Konfiguracja wyzwalacza dla ruchu przychodzącego.

Załóżmy, że nasz router posiada 4 porty – eth0, eth1, eth2 oraz eth3. Ostatni port służy do backupu serwerów przez co wysycenie łącza jest stałe i wynosi 90%. W powyższej sytuacji trigger dla eth3 będzie cały czas włączony (jest powyżej ustawionej przez nas wartości 80%). Pierwszą myślą jest zmienienie makra {$NET_IN} na powiedzmy 95% – ale wtedy podniesiemy próg również i dla innych portów, co w naszym przypadku jest niedopuszczalne. W takiej sytuacji pomocne będą konteksty.

Używanie makr z kontekstami jest bardzo przydatne przy wykrywaniu niskopoziomowym. Dzięki nim wartość makra użytkownika może być zależna od wykrytych elementów. Składnia makra z kontekstem wygląda następująco:

{$MAKRO:kontekst}

Warto dodać, że sam kontekst może być w cudzysłowiu, lecz nie jest to wymagane. Oczywiście nic nie stoi na przeszkodzie, by w kontekście było makro wykrywania niskopoziomowego.

Wróćmy do naszego przykładu – w tym przypadku różnymi kontekstami (lub elementami) są porty routera, a dokładniej ich nazwy (“{#IF_NAME}”). Zmieńmy wyrażenie regularne wyzwalacza, by używał makra z kontekstem:

Rysunek 11. Konfiguracja wyzwalacza – makro z kontekstem.

W wyrażeniu wyzwalacza pojawiło się makro z kontekstem: {$NET_IN:”{#IF_NAME}”}, które podczas wykrywania elementów zostanie zamienione na {$NET_IN:”eth0”}, {$NET_IN:”eth1”}, {$NET_IN:”eth2”} oraz {$NET_IN:”eth3”}. Innymi słowy – możemy teraz ustawić inną wartość progu dla interfejsu sieciowego eth3:

Rysunek 12. Przykład makra z kontekstem w konfiguracji hosta.

Na szczęście nie musimy dodawać wszystkich makr z kontekstem, ponieważ gdy zabbix ich nie wykryje (np. {$NET_IN:”eth0”}), to będzie szukał makra bez kontekstu ({$NET_IN}). W naszym przykładzie dla eth0, eth1 i eth2 wartość makra będzie wynosiła 80, a dla eth3 95.

Praktyka

Czas na praktyczne wykorzystanie tej wiedzy. Załóżmy, że na serwerze zabbix posiadamy dwa systemy plików:

  • “/” – wielkość 50 GB,
  • “/mnt” – wielkość 10 GB.

Podpięliśmy domyślny szablon dla Linuxa (“Template OS Linux”), który dla każdego systemu plików tworzy następujący wyzwalacz:

Rysunek 13. Domyślny wyzwalacz dla zajętości systemu plików.

Po pewnym czasie zauważamy następujące wyzwalacze:

Rysunek 14. Podstawowe alarmy zajętości systemów plików.

Jako zaawansowani użytkownicy triggerów zauważamy kilka problemów:

  • próg alarmu dla wszystkich hostów z tą templatką jest równy 20%,
  • Nie możemy tworzyć różnych progów dla różnych systemów plików,
  • Patrząc na problem nie wiemy, jaka jest aktualna wartość; czy ledwo przekroczyliśmy próg (np. 19%), czy też miejsce zaraz się skończy (np. 0.1%),
  • Procent procentowi nierówny – kiedy mamy poniżej 20% na filesystemie, który posiada 10TB, raczej jesteśmy spokojni o miejsce; jednak poniżej 20% na systemie plików o pojemności 10MB sygnalizuje dość poważny problem.

Chcemy naprawić w/w problemy, dlatego wykorzystamy nowe makro użytkownika wraz z kontekstem (w tym przypadku kontekstem będzie nazwa systemu plików) – {$DISK_SPACE:”{#FSNAME}”}. Dodatkowo chcemy w nazwie wyświetlić aktualnie wolne miejsce w bajtach, dlatego dodamy jeszcze jedno wyrażenie logiczne w wyzwalaczu:

{Template OS Linux:vfs.fs.size[{#FSNAME},pfree].last(0)}<={$DISK_SPACE:"{#FSNAME}"} and {Template OS Linux:vfs.fs.size[{#FSNAME},free].last(0)}>=0

Powyższy wyzwalacz można traktować następująco: wywołaj alarm jeżeli procentowa wartość wolnego miejsca na systemie plików jest mniejsza lub równa niż wartość w makrze {$DISK_SPACE:”{#FSNAME}”} (zależna od kontekstu) i kiedy wartość wolnego miejsca (w bajtach) jest większa lub równa 0 (to wyrażenie logiczne zawsze jest prawdą, bo wolne miejsce nie może być ujemne).

Drugie wyrażenie logiczne w tym triggerze wydaje się bez sensu, jednak dzięki takiej operacji możemy wyświetlić aktualną zajętość dysku w bajtach. Dlatego zmieńmy trochę samą nazwę wyzwalacza:

Free disk space is less than {$DISK_SPACE:"{#FSNAME}"}% on volume {#FSNAME} - {ITEM.LASTVALUE1} ({ITEM.LASTVALUE2})

Dzięki użyciu makra z kontekstem będziemy mogli wyświetlić odpowiedni próg (po słowach “less than”), a dodatkowo, po myślniku, aktualną procentową wartość dzięki pierwszemu wyrażeniu logicznemu w wyzwalaczu. Dodatkowo w nawiasie wyświetlimy aktualną wartość w bajtach dzięki drugiemu wyrażeniu. Po zapisaniu takiego wyzwalacza powinien on wyglądać mniej więcej tak jak na Rysunku nr 15.

Rysunek 15. Końcowa konfiguracja nowego wyzwalacza.

Następnym krokiem jest ustawienie makra {$DISK_SPACE} na samej templatce (bez kontekstu) – będziemy traktować ją jako domyślną wartość progu dla zajętości systemów plików, którą możemy zmienić na każdym hoście:

Rysunek 16. Dodanie “domyślnego” makra do template.

Na końcu chcemy zmienić wartość progu alarmu z 20 na 10 (procent) dla serwera zabbixa na głównym systemie plików (“/”). Wchodzimy na naszego hosta, klikamy na zakładkę “Macros” a następnie “Add” i dodajemy następujące makro:

Rysunek 17. Dodawanie makra z kontekstem na hoście.

Uwaga – po kliknięciu na “Inherited and host macros” pokaże nam wszystkie makra dziedziczone z szablonu i globalne, jednak nie znajdziemy tam makr z kontekstem – musimy dodać je ręcznie.

Po kliknięciu na “Update” i odczekaniu aż wykrywanie niskopoziomowe dysków się odświeży, naszym oczom powinno ukazać się następujące problemy:

Rysunek 18. Ulepszone alarmy.

Podsumowanie

Jeżeli chcesz utrzymać porządek w konfiguracji zabbixa, powinieneś zacząć używać makr. Początkowo wydają się one trudne, jednak później zauważysz, że nie możesz bez nich żyć.

Na koniec, jako bonus, kilka zasad “best practice”:

  • Używaj jednoznacznych nazw – makro {$CPU} nic nie mówi, nie mówiąc już o {$MAKRO_TESTOWE} czy {$123}.
  • Gdy twoja lista makr użytkownika jest już duża, opisz je w osobnym dokumencie; to samo przy makrach wykrywania niskopoziomowego,
  • Gdy używasz jakiegoś makra na szablonie, zawsze dodawaj je do templatki (analogicznie do Rysunku nr. 16); unikniesz sytuacji, że jakieś makro nie posiada wartości, a zawsze będziesz mógł je nadpisać na hoście,
  • Ogranicz używanie makr globalnych do minimum; najlepiej używaj ich tylko wtedy, gdy potrzebujesz makro w wielu lokalizacjach (np. w kilku szablonach),
  • Przy konfiguracji wykrywania niskopoziomowego od razu załóż, że będziesz używać makr z kontekstami,
  • Wszystko z umiarem – makra nie muszą znaleźć się w każdym miejscu twojej konfiguracji.

— Albert Przybylski, fanatyk Zabbixa, pełnoprawny admin 24/7

Spodobał Ci się wpis? Podziel się nim ze znajomymi:



Komentarze

  1. Bartek

    Witam
    Świetne artykuły, ale mam pytanie odnośnie powiadomień zabbixa, bo coś nie mogę tego odpalić w 3.2 na ubuntu 16.04. Czy byłby ktoś w stanie mi pomóc ? :)

    Pozdrawiam
    Bartek

    Odpowiedz
    • filu

      A z czym dokładnie jest problem ?

      Odpowiedz
  2. wolvvi

    Pytanie , jak w nazwie triggera uzyska wstawienie ip zdefiniowanego dla monitoringu po SNMP ( nie chodzi o ip agenta zabbixa zwracane przez {HOST.IP(1-9)} )

    Odpowiedz
  3. Zabbix to kombajn, który jak się go opanuje, daje tyle możliwości, że przestajesz sobie wyobrażać pracę bez niego przy nawet najmniejszej sieci. ;) ten artykuł przyda się w 100%
    —————–
    I love Zabbix

    Odpowiedz
  4. Patrykk

    Panie Albercie ŚWIETNY artykuł!

    Czekam z niecierpliwością na kolejne dotyczące zabbixa! :)

    Jeżeli mogę Panu podsunąć jakieś pomysły to chętnie bym poczytał o:
    – optymalizacji zabbixa (wydajność, na jakie parametry zwrócić uwagę, konfigurację aby nie zapchać bazy, jak ją czyścić jeżeli osiągnie zbyt duży rozmiar) i jak zabezpieczyć zabbixa na wypadek awarii aby nie stracić danych (replikacja?)?
    – Jak używać zabbix proxy
    – Jakieś ciekawe przykłady praktycznego monitorowania i modyfikacji standardowych wyzwalaczy/ grafów i ekranów

    Odpowiedz
    • kolejny art prawie gotowy :-)

      Odpowiedz
      • Patrykk

        Czekam z niecierpliwością! :)

        Odpowiedz

Odpowiedz