Icinga2 – check_mssql_health
Das check_mssql_health Modul kann in Icinga2, als auch in Nagios dazu verwendet werden, seine MSSQL Datenbank zu überwachen. Dabei können Checks von Verbindungszeiten, Deadlocks, angemeldete User, existierende Tabellen und viele weitere ausgewählt werden. So macht es das Modul zu einem starken Tool für die Datenbanken. Leider wird check_mssql_health nicht bei der icinga2 respektive nagios mit installiert und muss manuell nachgeholt werden. Ich rede hier von der Installation über den Packet Manager. Die Installation dabei ist aber relativ einfach. Ich gehe davon aus, dass Icinga aus dem Repository heruntergeladen und nach Standard Parametern installiert worden ist.
Vorbereitung
Um mssql_health vollständig und erfolgreich installieren zu können, müssen einige Vorbereitungen getroffen werden, die ich hier kurz erläutere. Zunächst müssen ein paar Pakete nachinstalliert werden.
apt install libdbd-sybase-perl freetds-common freetds-dev freetds-bin
Dann laden wir die aktuelle mssql_health Version mit wget runter, was in meinem Fall(10.11.2018) die Version 2.6.4.14 ist.
wget https://labs.consol.de/assets/downloads/nagios/check_mssql_health-2.6.4.14.tar.gz
Natürlich müssen wir die tar.gz jetzt noch entpacken und gehen direkt in das neu erstellte Verzeichnis hinein.
tar xvzf check_mssql_health_2.6.4.14 cd check_mssql_health_2.6.4.14
Sobald wir im Verzeichnis sind, fangen wir an mssql_health zu kompilieren. Ich benutze jeweils die default Parameter. Änderungen können sonst mit dem ./configure Command geändert werden.
./configure make make install
Wenn die Kompilierung abgeschlossen und das Modul installiert ist, sollten wir überprüfen, ob es nicht doch noch eigene Syntax Errors im Perl Code gibt. Wenn alles soweit in OK ist, kopieren wir das Script in das jeweilige Icinga Verzeichnis
cd plugin-scripts/ perl -c check_mssql_health cp check_mssql_health /usr/lib/Nagios/plugins
Zuguterletzt müssen wir eine Datenbank-Instanz in der freetds.conf einfügen. Dort ist schon ein Beispiel vorhanden, welches wir einfach für unsere Einstellungen übernehmen können. Falls dieser Eintrag übersprungen wird, kann keine Verbindung mit der Datenbank hergestellt werden.
nano /etc/freetds/freetds.conf
Aus Sicherheitsgründen sollten wir das TDS Protokoll noch auf Version 8.0 ändern. Die anderen Versionen verschicken Username/Passwort im Klartext. Somit hätten wir die Installation + Einrichtung des Modules vollzogen. Machen wir weiter mit der Konfiguration der Datenbank.
Datenbank einrichten
Das schöne an der Datenbank Einrichtung ist, dass wir hier nicht viel machen müssen. Auf der Projekt Seite steht ein vorgefertigtes Script zur Verfügung. Es ist zu empfehlen sich einen SQL-Benutzer anzulegen und diesen in der dafür vorgesehenen Stelle im Script anzugeben.
declare @dbname varchar(255) declare @check_mssql_health_USER varchar(255) declare @check_mssql_health_PASS varchar(255) declare @check_mssql_health_ROLE varchar(255) declare @source varchar(255) declare @options varchar(255) declare @backslash int /*******************************************************************/ SET @check_mssql_health_USER = '"icinga"' SET @check_mssql_health_PASS = 'password' SET @check_mssql_health_ROLE = 'icinga' /****************************************************************** PLEASE CHANGE THE ABOVE VALUES ACCORDING TO YOUR REQUIREMENTS - Example for Windows authentication: SET @check_mssql_health_USER = '"[Servername|Domainname]\Username"' SET @check_mssql_health_ROLE = 'Rolename' - Example for SQL Server authentication: SET @check_mssql_health_USER = 'Username' SET @check_mssql_health_PASS = 'Password' SET @check_mssql_health_ROLE = 'Rolename' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! It is strongly recommended to use Windows authentication. Otherwise you will get no reliable results for database usage. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! *********** NO NEED TO CHANGE ANYTHING BELOW THIS LINE *************/ SET @options = 'DEFAULT_DATABASE=MASTER, DEFAULT_LANGUAGE=English' SET @backslash = (SELECT CHARINDEX('\', @check_mssql_health_USER)) IF @backslash > 0 BEGIN SET @source = ' FROM WINDOWS' SET @options = ' WITH ' + @options END ELSE BEGIN SET @source = '' SET @options = ' WITH PASSWORD=''' + @check_mssql_health_PASS + ''',' + @options END PRINT 'create Nagios plugin user ' + @check_mssql_health_USER EXEC ('CREATE LOGIN ' + @check_mssql_health_USER + @source + @options) EXEC ('USE MASTER GRANT VIEW SERVER STATE TO ' + @check_mssql_health_USER) EXEC ('USE MASTER GRANT ALTER trace TO ' + @check_mssql_health_USER) EXEC ('USE MSDB GRANT SELECT ON sysjobhistory TO ' + @check_mssql_health_USER) EXEC ('USE MSDB GRANT SELECT ON sysjobschedules TO ' + @check_mssql_health_USER) EXEC ('USE MSDB GRANT SELECT ON sysjobs TO ' + @check_mssql_health_USER) PRINT 'User ' + @check_mssql_health_USER + ' created.' PRINT '' declare dblist cursor for select name from sysdatabases WHERE name NOT IN ('master', 'tempdb', 'msdb') open dblist fetch next from dblist into @dbname while @@fetch_status = 0 begin EXEC ('USE [' + @dbname + '] print ''GRANT permissions IN the db '' + ''"'' + DB_NAME() + ''"''') EXEC ('USE [' + @dbname + '] CREATE ROLE ' + @check_mssql_health_ROLE) EXEC ('USE [' + @dbname + '] GRANT EXECUTE TO ' + @check_mssql_health_ROLE) EXEC ('USE [' + @dbname + '] GRANT VIEW DATABASE STATE TO ' + @check_mssql_health_ROLE) EXEC ('USE [' + @dbname + '] GRANT VIEW DEFINITION TO ' + @check_mssql_health_ROLE) EXEC ('USE [' + @dbname + '] CREATE USER ' + @check_mssql_health_USER + ' FOR LOGIN ' + @check_mssql_health_USER) EXEC ('USE [' + @dbname + '] EXEC sp_addrolemember ' + @check_mssql_health_ROLE + ' , ' + @check_mssql_health_USER) EXEC ('USE [' + @dbname + '] print ''Permissions IN the db '' + ''"'' + DB_NAME() + ''" GRANTED.''') fetch next from dblist into @dbname end close dblist deallocate dblist
Haben wir das Script ausgeführt, können wir außerhalb von Icinga testen, ob unsere Einstellungen soweit korrekt sind. Hierzu führen wir eine erste Überprüfung durch.
./check_mssql_health –server=wpsql3 –port=1433 –username=icinga –password=<password> --mode=locks-deadlocks –commit
Wenn dieser Check erfolgreich war, haben wir die Datenbank und das mssql_health modul korrekt installiert und eingerichtet. Jedoch fehlen noch die Änderungen in Icinga, damit dieser die Checks überhaupt ausführen kann. Ich hab es soweit eingerichtet, dass ich jedem Host mehrere Serviceobjekte von mssql_health zuweisen kann. Diese Objekte führen unterschiedliche Checks aus. Dazu habe ich einen Command angelegt, der bestimmte Parameter erwartet, aber auch solche die schon fest zugewiesen sind, wie Benutzername und Passwort.
object CheckCommand "checkmssql_health" { import "plugin-check-command" command = [PluginDir + "/check_mssql_health"] arguments = { "--server" = "$mssqlhealth_server$" "--username" = "$mssqlhealth_username$" "--password" = "$mssqlhealth_password$" "--mode" = "$mssqlhealth_mode$" "--critical" = "$mssqlhealth_critical$" "--warning" = "$mssqlhealth_warning$" "--commit" = "" } vars.mssqlhealth_username = "icinga" vars.mssqlhealth_password = "passwort" }
Der erstellte Service geht dabei durch jedes, im Host Objekt angegebene, mssql_health Objekt.
apply Service "mssql_check_health" for (mode => config in host.vars.mssqlhealth_modes){ import "generic-service" check_command = "checkmssql_health" vars.mssqlhealth_mode = mode vars+=config vars.mssqlhealth_critical = config.mssqlhealth_critical vars.mssqlhealth_warning = config.mssqlhealth_warning assign where ((host.address || host.address6) && host.vars.mssql == "true") }
Mein Host Objekt sieht dementsprechend so aus und ist gefüllt mit mehreren Modis des Modules.
vars.mssqlhealth_modes["connected-users"] = { mssqlhealth_modes = "connected-users" mssqlhealth_warning = "1100" mssqlhealth_critical = "1500" } vars.mssqlhealth_modes["locks-waits"] = { mssqlhealth_modes = "locks-waits" mssqlhealth_warning = "1" mssqlhealth_critical = "2" } vars.mssqlhealth_modes["locks-deadlocks"] = { mssqlhealth_modes = "locks-deadlocks" mssqlhealth_warning = "1" mssqlhealth_critical = "2" } vars.mssqlhealth_modes["database-backup-age"] = { mssqlhealth_modes = "database-backup-age" mssqlhealth_warning = "24" mssqlhealth_critical = "48" }
In „modes“ werden die verfügbaren Modis von mssql_health eingetragen, während die anderen beiden den jeweils kritischen und warnenden Zustand angeben.
Haben wir alles soweit eingerichtet muss selbstverständlich der Icinga Service neugestartet werden, damit die vollzogenen Änderungen überhaupt aktiv werden
service icinga2 restart
Fazit
Wenn alles geschafft ist, haben wir unser Monitoring Tool für MSSQL Datenbanken erweitert und können dementsprechend Checks ausführen. Die Installation von mssql_health an sich ist einfach nur die jeweilige Integration in Icinga bedarf etwas Überlegung. Natürlich kann das Modul auch auf andere Wege in Icinga implementiert werden. Dort stehen alle Möglichkeiten offen. Ich habe mich für diese Integration entschieden, da ich für mich hier die meisten Vorteile sehe. Mit dieser Art der Erstellung müssen nur noch im Host Objekt die einzelnen Modis mit ihren Werten eingeben werden. So kann auf einfachste Weise ein neuer Check eingefügt werden, ohne den Service bzw. den Command anpacken zu müssen.