Posted in

Monitorowanie AIX i VIOS w systemie Zabbix

Wstęp

Środowiska oparte na architekturze IBM Power, wykorzystujące systemy AIX oraz serwery wirtualizacji VIOS (Virtual I/O Server), stanowią fundament krytycznej infrastruktury w wielu organizacjach. Ich efektywne utrzymanie wymaga precyzyjnego nadzoru nie tylko nad podstawowymi parametrami systemu operacyjnego, ale przede wszystkim nad warstwą wirtualizacji wejścia/wyjścia oraz stanem interfejsów dyskowych i sieciowych.

Skuteczny monitoring infrastruktury to fundament pracy każdego administratora systemów. Ponieważ w sieci brakuje wyczerpujących informacji na temat integracji platform AIX i VIOS z Zabbixem, czyli niezwykle popularnym i dojrzałym narzędziem klasy enterprise, postanowiłem podjąć ten temat w formie artykułu.

Zabbix to system klasy enterprise o otwartym kodzie źródłowym, przeznaczony do monitorowania wydajności i dostępności infrastruktury IT. Działa w architekturze rozproszonej, zbierając dane za pośrednictwem dedykowanych agentów instalowanych na systemach docelowych, protokołów sieciowych takich jak SNMP lub zapytań bezagentowych. Pozwala na gromadzenie metryk w czasie rzeczywistym, analizę progów alarmowych oraz powiadamianie o anomaliach.

O ile standardowy agent Zabbix dla AIX bezproblemowo obsługuje podstawowe metryki systemowe, takie jak obciążenie procesora, zajętość pamięci RAM czy utylizacja systemów plików, o tyle specyfika środowiska VIOS i architektury wirtualnego I/O wymaga niestandardowego podejścia, dlatego chciałbym podzielić się gotowymi przykładami, które mogą uzupełniać domyślny szablon dla AIX oraz przedstawić sposób na tworzenie własnych metryk, pozwalających na rozszerzenie monitoringu o rzeczy specyficzne dla Twojego środowiska IT.

AIX i VIOS

W zakresie platformy Power dostępny jest skompilowany agent dla systemu AIX 7.2 oraz 7.3, a nawet gotowy do użycia template AIX:

https://www.zabbix.com/integrations/aix

Dla systemu VIOS nie ma dedykowanego agenta Zabbix, ale z powodzeniem możemy używać agenta dla AIX. Obecnie wydawane wersje agenta są udostępniane w formie pakietów RPM.

Jak wiadomo, serwer VIOS nie jest typowym systemem AIX, ponieważ działa na potrzeby wirtualizacji urządzeń IO (wejścia/wyjścia) i monitorowanie go wymaga nieco innego podejścia niż w przypadku zwykłego AIX-a.

Z tego, co wiem, nie ma żadnego gotowego Template dla serwera VIOS, ale możemy taki zbudować i użyć własnych skryptów oraz poleceń za pomocą User Parameters. Jeśli potrzebujemy uruchomić komendę typową dla VIOS na poziomie Restricted Shell (czyli tak jak na koncie padmin), możemy spróbować posłużyć się /usr/ios/cli/ioscli i podać komendę jako argument.

Dobrym rozwiązaniem może być utrzymywanie osobnych Template’ów – pierwszy dla systemu AIX, który będzie również monitorować system pod kątem np. utylizacji CPU,RAM zajętości filesystemów itp i kolejny Template dla serwera VIOS. Do serwera VIOS można przypisać w GUI Zabbix obydwa Template’y. Warto pilnować, by takie same Itemy nie były dublowane w różnych szablonach, ponieważ może to powodować problemy z przypisaniem szablonu do hosta.

W ramach monitorowania VIOS-a warto rozważyć rzeczy typowe dla AIX:

  • Zajętość CPU/RAM/SWAP, zajętość filesystemów, inode itp
  • Monitorowanie wirtualnych i fizycznych urządzeń: np. FibreChannel i Ethernet

Oraz dodatkowe rzeczy, specyficzne dla serwerów VIOS, np:

  • Monitorowanie Shared Ethernet Adapter
  • Ilość i poprawność mapowań NPIV/vSCSI
  • Shared Storage Pool

User Parameters

Zaletą Zabbixa, którą szczególnie sobie cenię, jest możliwość dodawania customowych rzeczy, które można monitorować. Każde środowisko IT ma swoją specyfikę i nie zawsze gotowe szablony mogą być dla nas wystarczające, dlatego możliwość tworzenia dodatkowych metryk pozwala nam na dużą elastyczność i dopasowanie zakresu monitoringu do naszych indywidualnych potrzeb. Dodatkowo dodanie dodatkowych metryk może służyć nie tylko monitorowaniu wydajności, ale również śledzeniu zmian konfiguracji.

Przykładowo, możemy przyjąć że jakiś administrator systemu AIX, oprócz wartości procentowej utylizacji CPU, chciałby zbierać dane zużycia CPU, ale wyrażone poprzez liczbę użycia rdzeni procesora.

Jest wiele poleceń systemowych, które zwrócą nam taką wartość, ale wspomniany administrator najczęściej korzysta z polecenia mpstat -h. Jak więc sprawić by wartość zwracana przez to polecenie trafiała do Zabbixa?

Z pomocą przychodzi nam właśnie UserParameters, które pozwala nam utworzyć dodatkowy klucz (Key) w Zabbix:

UserParameter=<key>,<command> 

Listę UserParameters warto umieścić w osobnym pliku konfiguracyjnym, do którego ścieżka będzie uwzględniona w głównym pliku konfiguracyjnym agenta Zabbix, czyli zabbix_agentd.conf, poprzez parametr Include, np. Include=/katalog_z_roznymi_configami/*.conf.

Takie ustawienie z użyciem * jako wildcarda lub wskazanie katalogu daje elastyczność jeśli chodzi o utrzymywanie wielu list UserParameters do różnych zastosowań.

Wracając do przykładu, możemy utworzyć nowy Item, o nazwie „mpstat.coreutil” (nazwa dowolna), który w Zabbix będzie zwracać wynik komendy mpstat -h 1 1 (czyli jednorazowe uruchomienie narzędzia mpstat prezentujące dane z ostatniej sekundy).

Pokazowe uruchomienie narzędzia mpstat -h 1 1 może wyglądać następująco:

# mpstat -h 1 1

System configuration: lcpu=8 ent=0.4 mode=Uncapped

cpu    pc   ilcs   vlcs
  0  0.03     16    243
  1  0.02      5     60
  2  0.01      0     14
  3  0.01      0     12
  4  0.01      0     14
  5  0.01      0     14
  6  0.01      0     13
  7  0.01      0     20
ALL  0.12     21    390 

Wspomnianego administratora interesuje wartość sumaryczna, a nie pojedynczych rdzeni procesora, dlatego by ograniczyć wynik do tej konkretnej wartości możemy użyć typowego jednolinijkowca np. z użyciem grep/AWK i tym samym zawęzić output do wiersza zawierającego tekst ALL i drugiej kolumny:

UserParameter=mpstat.coreutil,mpstat -h 1 1 | grep ALL | awk '{print $2}' 

Lub jeszcze lepiej, za pomocą samego AWKa:

UserParameter=mpstat.coreutil,mpstat -h 1 1 | awk '/ALL/ {print $2}' 

Różnice w czasie wykonania obydwu poleceń będą raczej niezauważalne, jednak wersja z użyciem samego awk wydaje się być bardziej elegancka i używa o jeden proces mniej 🙂

Aby wartość była widoczna w GUI Zabbix, należy utworzyć nowy Item dla danego hosta lub szablonu (https://www.zabbix.com/documentation/current/en/manual/config/items/item).

Oczywiście znacznie elastyczniejszym rozwiązaniem jest tworzenie takich itemów w ramach szablonu, który możemy przypisywać później do wielu hostów, niż tworzyć je na poziomie samego hosta. Ważne jest, by Key był utworzony z odpowiednią jednostką (https://www.zabbix.com/documentation/current/en/manual/appendix/suffixes#item-value-suffixes) oraz Typem. Jeśli wartość jest liczbą całkowitą należy użyć typu „Numeric (unsigned)”, jeśli zmiennoprzecinkowa „Numeric (float)„, a jeśli tekstem to odpowiednio Character/Long/Text.

Brak ustawienia odpowiedniego typu będzie skutkować błędem.

Przykładowy wykres prezentujący zebrane dane za pomocą takiego Itemu, może wyglądać w następujący sposób:

Treść artykułu

Zabbixa możemy również wykorzystać do śledzenia konfiguracji. Dla przykładu, możemy chcieć śledzić ustawienie SMT, tworząc Key o nazwie „conf.smt”

UserParameter=conf.smt,lparstat -i | awk '/^Type/ {print $3}'

W tym przypadku wartość jest tekstem (np. SMT-2, SMT-4, SMT-8), dlatego Item powinien mieć typ Character.

Możemy sobie również wyobrazić sytuację, że dla części LPAR-ów jakie mamy w środowisku, zainstalowana aplikacja najwydajniej działa w trybie SMT-4, czyli w trybie czterowątkowym. Przyjmijmy, że zostały przeprowadzone testy wydajnościowe, które wykazały, że dla danej aplikacji takie ustawienie jest optymalne, lub taka jest rekomendacja dostawcy danego oprogramowania, dlatego w tym konkretnym przypadku chcielibyśmy, żeby zmiana na ustawienie inne niż SMT-4 wygenerowała alert w systemie monitoringu, np. na wypadek gdyby jeden z administratorów uznał, że SMT-2 będzie lepszym wyborem i zastosował takie ustawienie, ale nikomu się nie przyznał do zmiany, którą wykonał 😉

W takim celu powinniśmy utworzyć Trigger, który będzie reagował na zmianę wartości:

https://www.zabbix.com/documentation/current/en/manual/config/triggers/trigger

Trigger dla takiego przykładu może wyglądać następująco:

Name: SMT mode on {HOST.NAME} is {ITEM.LASTVALUE}, expected value is 4

Expression: last(/DEMO_AIX_Template/conf.smt)<>”SMT-4″

W tym przypadku, alert w Zabbix zniknie, dopiero gdy SMT zostanie przywrócone do SMT-4.

Jeżeli dla różnych LPAR-ów chcielibyśmy stosować różne ustawienia SMT, warto też rozważyć użycie macro hosta: {$EXPECTED_SMT}=SMT-4. Dzięki temu łatwiej będzie nadawać indywidualne ustawienie dla różnych serwerów:

Name: SMT mode on {HOST.HOST} is {ITEM.LASTVALUE}, expected value is „{$EXPECTED_SMT}”

Expression: last(/DEMO_AIX_Template/conf.smt)<>”{$EXPECTED_SMT}”

Dobrą praktyką, jest umieszczenie w polu Description linku do bazy wiedzy, lub informacji typu:

„Dla tego serwera i bazy danych XZY rekomendowana wartość to SMT-4, ale wartość ta została zmieniona. Należy przywrócić prawidłową wartość poleceniem smtctl”

Low-Level Discovery (LLD) na przykładzie monitorowania adapterów

W systemach operacyjnych możemy mieć widocznych wiele urządzeń, o różnych nazwach, dlatego wpisywanie nazw bezpośrednio byłoby bardzo trudne do utrzymania. Zamiast tego znacznie lepiej jest używać zmiennych i mechanizmu w Zabbix, który nazywa się Low-Level Discovery. Dzięki niemu nie musimy bezpośrednio hardkodować nazw urządzeń typu hdisk1, ent0, fcs4 itp. Lepiej dla nas, żeby wszystko się samo wykrywało i automatycznie tworzyło odpowiednie Itemy i Triggery w zabbix.

Wykorzystanie UserParameters i Low-Level Discovery może się wydawać na początku nieco zawiłe, jednak uważam że zdecydowanie warto z tego korzystać.

Uznałem że dobrym przykładem na zaprezentowanie tego, jak można budować monitoring w oparciu Low-Level Discovery, będzie przykład adapterów vFC/FC i vSCSI, który możesz wykorzystać w swoim środowisku. Analogicznie będziesz mógł utworzyć np. monitorowanie dysków i innych urządzeń które mogą mieć zmienną prezentację nazw w systemie.

Discovery rule

By umożliwić przekazanie listy urządzeń do serwera Zabbix, do wspomnianej wcześniej listy User Parameters, możemy dodać skrypt, który zwróci listę adapterów w formacie JSON (dlatego, że akurat w tej formie jest czytelny dla Zabbixa).

Skrypt który zwróci nam listę adapterów vSCSI, może wyglądać następująco

Adaptery vSCSI:

#!/usr/bin/ksh
adapters=$(/usr/bin/iostat -a | awk '/vscsi/ {print $1}')

echo "{"
echo "  \"data\":["

first=true
for adapter in $adapters; do
    if [ "$first" = true ]; then
        first=false
    else
        echo ","
    fi
    print -n "    {\"{#VSCSIADAPTER}\":\"$adapter\"}"
done

echo ""
echo "]"
echo "}" 

Wynik tego skryptu, powinien wyglądać tak, jak poniżej. Nazwy #VSCSIADAPTER, użyjemy w dalszej części na poziomie GUI Zabbix.

{
"data":[
    {"{#VSCSIADAPTER}":"vscsi0"},
    {"{#VSCSIADAPTER}":"vscsi1"}
]
} 

Analogiczny skrypt, do wylistowania adapterów FC/vFC (tym razem używamy nazwy #FCADAPTER)

#!/usr/bin/ksh
adapters=$(/usr/bin/iostat -a | awk '/fcs/ {print $1}')

echo "{"
echo "  \"data\":["

first=true
for adapter in $adapters; do
    if [ "$first" = true ]; then
        first=false
    else
        echo ","
    fi
    print -n "    {\"{#FCADAPTER}\":\"$adapter\"}"
done

echo ""
echo "]"
echo "}" 

Przykładowy wynik:

{
"data":[
    {"{#FCADAPTER}":"fcs4"},
    {"{#FCADAPTER}":"fcs5"},
    {"{#FCADAPTER}":"fcs6"},
    {"{#FCADAPTER}":"fcs7"}
]
} 

Skrypty umieszczamy jako UserParameters:

# Discover adapters
UserParameter=discover.adapters.vscsi,/ZABBIX/SCRIPTS/discover_vscsi_adapters.sh
UserParameter=discover.adapters.fc,/ZABBIX/SCRIPTS/discover_fc_adapters.sh 

Tych kluczy użyjemy przy tworzeniu Discovery rules do szablonu w GUI Zabbix, na tym przykładzie w nowym szablonie o nazwie “DEMO Template AIX – Storage Adapters”. Po wejściu w Data collection –> Templates i wybraniu pozycji “Discovery rules” w szablonie, tworzymy nową regułę (przycisk “Create discovery rule” w prawym górnym rogu)

Treść artykułu

Należy zwrócić uwagę na to by użyć dokładnie tej samej nazwy klucza, jak w pliku konfiguracyjnym agenta.

Treść artykułu
Treść artykułu

Item prototypes

Teraz, gdy mamy mechanizm, który nam wykryje nazwy urządzeń, możemy użyć kluczy z poleceniami, dla których nazwy zostaną pobrane z Zabbix, za pomocą parametru $1. Trudność polega na tym, że w przypadku użycia AWK-a, takiego parametru używamy dla podania numeru kolumny, ale na szczęście da się to pogodzić, używając podwójnego znaku dolara (np. $$1)

Zarówno dla adapterów vSCSI, jaki FC/vFC, możemy użyć polecenia iostat, które zwróci nam poniższe wartości:

  • Kbps (data trasferred, read of written per second)
  • tps (number of transfers per second)
  • bkread (Number of blocks per second received)
  • bkwrite (Number of blocks per second sent)

Output polecenia iostat -a (z pominięciem dysków i części danych) wyglądałby mniej więcej następująco:

Vadapter:                  Kbps      tps     bkread    bkwrtn
vscsi0                      0.0      1.4        0.7       0.7            

Vadapter:                  Kbps      tps     bkread    bkwrtn
vscsi2                      0.0     11.7        0.1      11.6 

Z takiego outputu możemy wyciągnąć dane, tworząc klucze tak jak poniżej, używając AWK do wybrania danych z wiersza z nazwą adaptera ($1 pobrane z Zabbixa) oraz odpowiedniej kolumny.

Podejście proste (nieoptymalne)

UserParameter=iostat.vscsi.Kbps[*],iostat -a 1 1| awk '/^$1/ {print $$2}'
UserParameter=iostat.vscsi.tps[*],iostat -a  1 1| awk '/^$1/ {print $$3}'
UserParameter=iostat.vscsi.bkread[*],iostat -a 1 1| awk '/^$1/ {print $$4}'
UserParameter=iostat.vscsi.bkwrite[*],iostat -a 1 1| awk '/^$1/ {print $$5}' 

Dodatkowo, dla adapterów FC, możemy pobrać statystyki dotyczące np. poniższych błędów

  • Error Frames
  • Link Failure
  • Loss of Sync
  • Invalid Tx Word
  • Invalid CRC
UserParameter=fcstat.frames[*],fcstat $1 | awk '/Error Frames/ {print $$3}'
UserParameter=fcstat.link[*],fcstat $1 | awk '/Link Failure Count/ {print $$4}'
UserParameter=fcstat.syncloss[*],fcstat $1 | awk '/Loss of Sync Count/ {print $$5}'
UserParameter=fcstat.invalidtx[*],fcstat $1 | awk '/Invalid Tx Word Count/ {print $$5}'
UserParameter=fcstat.invalidcrc[*],fcstat $1 | awk '/Invalid CRC Count/ {print $$4}' 

Jest to w miarę proste podejście i łatwe do wytłumaczenia, jednak ma swoje istotne wady:

  • polecenie iostat/fcstat uruchamiamy wiele razy podczas jednego przebiegu zebrania danych przez agenta Zabbix.
  • dane zostają zebrane z różnych punktów w czasie
  • jedno uruchomienie polecenia “iostat 1 1” to sekunda * ilość Itemów

W przypadku kilku adapterów może nie być to szczególnie istotne, jednak gdybyśmy chcieli monitorować w ten sposób wiele urządzeń (np. dyski), i zestawiać ze sobą te wszystkie dane, to musimy się liczyć z długim przebiegiem (UserParameters są wywoływane po kolei) i z rozjazdem czasowym wyników poleceń.

Na szczęście możemy to zrobić nieco lepiej.

Podejście sprytniejsze

Zamiast wykonywać wiele razy polecenie iostat -a 1 1 poprzez różne klucze, możemy je wykonać raz, a output przekierować do pliku. Kolejne klucze, które pobierają dane, nie muszą wykonywać niepotrzebnie tego samego co zostało już wykonane, tylko po prostu odczytają wartości z zapisanego już pliku. W tym celu, na początku listy UserParameters, możemy umieścić skrypt np. o nazwie iostat_adapter_to_file.sh

#!/usr/bin/ksh
iostat -a 1 1 > /tmp/iostat_adapter_out
istat /tmp/zabbix_iostat_adapter_out | grep modified 

Drugi wiersz został użyty po to, by zachować informację z jakiego konkretnie czasu jest wynik komendy iostat.

Przykładowa lista UserParameters może teraz wyglądać następująco:

# Discover adapters
UserParameter=discovery.adapters.vscsi,/SCRIPTS/discover_vscsi_adapters.sh
UserParameter=discovery.adapters.fc,/SCRIPTS/discover_fc_adapters.sh
# Saving iostat to a file 
UserParameter=iostat.adapter_to_file,/scripts/iostat_adapter_to_file.sh
# vSCSI adapters statitics - read from file
UserParameter=iostat.vscsi.KBps[*],/usr/bin/awk '/^$1/ {print $$2}' /tmp/iostat_adapter_out
UserParameter=iostat.vscsi.tps[*],/usr/bin/awk '/^$1/ {print $$3}' /tmp/iostat_adapter_out
UserParameter=iostat.vscsi.bkread[*],/usr/bin/awk '/^$1/ {print $$4}' /tmp/iostat_adapter_out
UserParameter=iostat.vscsi.bkwrite[*],/usr/bin/awk '/^$1/ {print $$5}' /tmp/iostat_adapter_out 

Po co w ogóle pokazałem najpierw podejście ocenione jako gorsze?

Uznałem, że przedstawienie tematu w ten sposób ułatwi jego wyjaśnienie. Intencją tego artykułu było nie tylko zaprezentowanie gotowych rozwiązań, ale przede wszystkim nauka jak można tworzyć własny monitoring samodzielnie.

Kolejnym krokiem jest utworzenie w GUI Zabbixa Item prototype, zwracając uwagę na odpowiednie użycie nazw {#VSCSIADAPTER} i {#FCADAPTER}, oraz stosując odpowiedni typ i jednostki. Całą resztę można utworzyć analogicznie, tak jak jest to przedstawione poniżej:

Treść artykułu

Item prototypes dla adapterów vSCSI:

Treść artykułu

Item prototypes dla adapterów FC

Treść artykułu

Utworzenie szablonu z takimi Discovery rules oraz Item prototypes może być nieco żmudne, na szczęście jednak wykonujemy to tylko raz. Taki gotowy szablon, będziemy mogli łatwo przypisywać do kolejnych systemów AIX/VIOS, bez ręcznego tworzenia osobnych Itemów dla każdego hosta i co równie istotne, bez opisywania każdego urządzenia z osobna.

Zakończenie

Choć wymienione i wymyślone przeze mnie przykłady możesz z powodzeniem zastosować do monitorowania swojej infrastruktury, zachęcam Cię do eksperymentowania i tworzenia własnych UserParameters. Zabbix daje ogromne możliwości w zakresie własnych Itemów, co jest ogromnym plusem tego rozwiązania. Jeśli wymyśliłeś własne przykłady, które dotyczą monitoringu AIX lub VIOS i nie zostały ujęte w tej publikacji, ani w gotowym Template dla AIX dostarczanym przez Zabbix, zachęcam do podzielenia się w komentarzu, lub na polskim forum grupy użytkowników Power:

Poland Power User Group:
https://community.ibm.com/community/user/usergroup?CommunityKey=864bdb4f-30d1-4382-99e0-018fc17a0aff