Icinga2 Cluster mit Puppet
Icinga2 und Puppet
In dieser Anleitung wird ein Vorschlag unterbreitet, wie ein Icinga2 Cluster in Kombination mit Icingaweb2 und Puppet installiert betrieben werden kann.
- Was fehlt:
- HA mit Keepalived
- Satellit für weitere Zone
Es empfiehlt sich erst einmal alles zu überfliegen, um sich einen Überblick zu verschaffen. Eventuell ist auch nicht das ganze Paket interessant, sondern nur Auszüge daraus.
Aufgrund der Länge werde ich die Anleitung etwas aufteilen, wenn alles soweit enthalten ist.
Zwei Konzepte
Der Autor (ich) hat so einige Zeit damit zugebracht zu schauen, was wie am Besten klappt. Es gibt zwei grundlegende Methoden, die ich kurz anreißen werden.
Puppet Ressource Export
Bei dieser Methode ist das zentrale Bindeglied die PuppetDB.
Bei jedem Aufruf des Puppet Agents, werden alle Fakten (facts) eingesammelt und in die PuppetDB geschrieben. Wenn diese Daten einmal vorhanden sind, kann man sie natürlich auch wieder abrufen.
Bei einer Icinga2 Installation kann es so aussehen, dass bei einer neuen Node (VM / physisch / Container) automatisch ein neuer Icinga2 Host erstellt und überwacht wird. Dank der Apply Regeln würde man recht schnell zu einem nahezu vollautomatischen Monitoring System kommen; immer unter der Voraussetzung, dass ein Puppet Agent darauf läuft.
Wird eine Node aus dem System entfernt (weil nicht mehr benötigt), kann sie auch aus der Überwachung verschwinden. Dafür benötigt es allerdings ein wenig Feintuning.
Was auf dem ersten Blick sehr verlockend erscheint, offenbart bei näherer Betrachtung allerdings einige Nachteile:
Es soll ein neuer Server mit in die Überwachung aufgenommen werden. Dazu muss natürlich erst einmal Puppet und Icinga eingerichtet worden sein, sodass beim initialen Aufruf des Puppet Agents der Icinga2 Agent auf dem neuen Server eingerichtet und gestartet wird. Danach sollte der Puppet Agent ein weiteres Mal gestartet werden, sodass die Fakten in der Datenbank auch wirklich alle vorhanden sind, auch die, die mit dem Icinga2 Puppet Modul mitkommen.
Damit auch der Icinga2 Master darüber Bescheid weiß, dass eine neue Node zum überwachen eingetroffen ist, muss auf dem Icinga2 Master ebenfalls der Puppet Agent aufgerufen werden. Dies hat zur Folge, dass das Puppet Icinga2 Modul diese neue Node in der Datenbank findet, eine passende Icinga2 Host Konfiguration erstellt und anschließend den Icinga2 Master neustartet, bzw. ein Reload durchführt.
Im Kern bedeutet dies, dass der Puppet Agent zwei Mal aufgerufen werden muss:
- Auf dem neuen zu überwachenden Host -> Daten in PuppetDB schreiben
- Auf dem Icinga2 Master -> Um neue Node aus der PuppetDB zu holen
Je nach Komplexität der Puppet Konfiguration, kann so ein Puppet Aufruf schon einmal länger dauern, erst Recht, wenn wir es nicht nur mit einer ein- oder zweistelligen Anzahl von Hosts zu tun haben.
Kompliziert wird es auch dann, wenn wir es nicht nur mit einem (logischen) Ort zu tun haben. Stichwort: DMZ / VPN / Rechenzentren.
Das gesamte Konstrukt baut darauf, dass es nur eine PuppetDB gibt und alle auf die gleiche Datenbank zugreifen. Wenn es aber mehrere Puppet Installationen gibt, bricht das Konzept. An dieser Stelle würde man zum Datenbank Spezialisten gehen und Konzepte entwickeln, um die fehlenden Informationen zu importieren.
Für kleinere und übersichtliche Installationen ist das Konzept großartig, für alles andere eher weniger.
Wer sich dafür interessiert, findet hier die nötigen Puppet Ideen.
Icingaweb2 + PuppetDB
Methode Zwei hat sich im Laufe der Zeit als wirklich sehr durchdachtes Konzept entpuppt. Die Aufgabe des Puppet Agent besteht nur noch aus zwei Aspekten:
- Icinga2 Agent installieren und einrichten (incl. Zertifikate)
- Fakten in die PuppetDB eintragen
Um nun eine weitere Icinga2 Hostkonfiguration zu erstellen, wird das PuppetDB Modul vom Icingaweb2 Director verwendet. Es greift auf die PuppetDB (Postgresql) zu, und geht wie folgt vor:
- Extrahieren der Nodes und Fakten aus der PostgreSQL und in die eigene Datenbank überführen
- Daten nach definierten Regeln verändern, löschen oder neue hinzufügen
- Neue Icinga2 Hostkonfiguration erstellen und über die API an den Icinga2 Master übergeben
Alle Schritte lassen sich automatisieren, sodass auch hier am Ende eine vollautomatische Überwachung stattfinden kann.
Der Große Unterschied zu dem vorhergehenden Konzept liegt darin, dass nur einmalige Aufrufe des Puppet Agents notwendig sind und danach nur noch bei Änderungen. Auf dem Icinga2 Master wird kein Aufruf benötigt, da die Konfiguration vom Icingaweb2 Director übernommen wird.
Des weiteren kann das PuppetDB Modul vom Icingaweb2 Director nicht nur eine PuppetDB abfragen, sondern beliebig viele. Die einzige Voraussetzung ist, dass der Datenbank Zugriff vom Icingaweb2 auf die jeweilige Postgresql Datenbank (TCP) gestattet ist.
Der Autor hat mit der ersten Methode angefangen und aufgrund der (Netzwerk / PuppetDB) Restriktionen nach und nach Methode Zwei implementiert, welche auch heute noch so genutzt und ausgebaut wird.
Zutaten
Wir werden Methode Zwei verwenden, da diese am flexibelsten ist. Für den Anfang begnügen wir uns mit dem “einfachsten” Setup, ohne DMZ und Satelliten. Dazu benötigen wir folgendes:
- Eine funktionierende Puppet Infrastruktur
- Siehe hier).
- Einen MariaDB Galera Cluster
- Siehe hier
- Drei Debian Buster VMs oder Container
- Icinga2 Master 1 / 2
- Icinga2 Agent
- (Alternativ können natürlich gleich die DB Hosts eingebunden werden)
- Puppet Kenntnisse
Beginnen wir mir dem Icinga2 Master. Um die Tipparbeit ein wenig in Grenzen zu halten, gelten folgende Konventionen:
- Puppet Dateien werden immer als eigener Benutzer editiert und per Git auf dem Puppetmaster hinterlegt
- Ein sehr großer Teil entstammt von einem fertigen Monitoring System, daher wird vieles per Copy/Paste übernommen, sofern sinnvoll.
- Unter Umständen müssen die Puppet Agents mehrfach aufgerufen werden, aber es wird versucht dies zu vermeiden
- Manifest/Konfigurations Dateien enthalten immer einen Kopf, damit klar wird, durch welches Modul eine Veränderung vorgenommen wurde
- Alles wird per Git gepflegt
- Der Ort ist, wenn nicht anders definiert:
puppet/environments/dev/
- Die Unterordner sind:
- hieradata/ -> Alles was mit Yaml zu tun hat
- modules/ -> Wo alle eigenen Module liegen
- Es ist nicht perfekt, aber nachvollziehbar und Anregungen nehme ich sehr sehr gern an
Icinga2 Master
Vorbereitung
Apache2
Für Icingaweb2 verwenden wir den Apache2 Webserver. Damit wir auch Hiera verwenden können, gibt es einige Hilfs- Manifests.
Zuerst müssen wir noch das Puppet Modul installieren:
$ puppet module install puppetlabs-apache --modulepath production/modules/
Nicht vergessen Git Bescheid zu geben.
modules/profile/manifests/webserver/apache2.pp:
# source modules/profile/manifests/webserver/apache2.pp # == Class: profile::webserver::apache2 class profile::webserver::apache2 { class { 'apache': default_vhost => false, } $myApache2Vhosts = hiera('apache::vhost', {}) create_resources('apache::vhost', $myApache2Vhosts) contain '::apache::mod::alias' contain '::apache::mod::env' contain '::apache::mod::rewrite' contain '::apache::mod::headers' contain '::apache::mod::setenvif' contain '::apache::mod::deflate' contain '::apache::mod::status' contain '::apache::mod::auth_basic' contain '::apache::mod::authn_core' contain '::apache::mod::authz_user' contain '::apache::mod::authn_file' }
profile/manifests/webserver/apache2_php.pp
# source modules/profile/manifests/webserver/apache2_php.pp # == Class: profile::webserver::apache2_php class profile::webserver::apache2_php { contain ::apache::mod::php }
modules/profile/manifests/webserver/apache2_remoteip.pp
# source modules/profile/manifests/webserver/apache2_remoteip.pp # == Class: profile::webserver::apache2_remopteip class profile::webserver::apache2_remoteip { contain ::apache::mod::remoteip }
SSL
Der Zugriff sollte ausschließlich per TLS erfolgen, daher entweder Zertifikate selbst erzeugen (z.B. per xca) oder LetsEncrypt verwenden.
Für dieses Szenario verwende ich letzteres und habe die Test VMs per IPv6 an das Welt-Weite-Netz angebunden. Als Client verwende ich gerne dehydrated.
Damit wir bei Puppet kein Henne-Ei Problem bekommen, ist im Hiera das Snakeoil Zertifikat angegeben.
# apt install dehydrated dehydrated-apache2
Wir installieren auch das Paket für Apache, welches einfach nur eine Konfiguration mitbringt. Diese wird dann im Hiera Abschnitt eingebunden.
/etc/dehydrated/config
CONFIG_D=/etc/dehydrated/conf.d BASEDIR=/var/lib/dehydrated WELLKNOWN="${BASEDIR}/acme-challenges" DOMAINS_TXT="/etc/dehydrated/domains.txt" IP_VERSION=6
/etc/dehydrated/domains.txt
Hier muss natürlich auch ein CNAME oder A existieren, für office-ffm-master.
office-ffm-master-01.4lin.net office-ffm-master.4lin.net
Sobald der Apache2 installiert und eingerichtet wurde, kann mittels dehydrated das korrekte Zertifikat bezogen werden.
# dehydrated --register --accept-terms ; dehydrated -c
Anschließend müssen um Hiera die Pfade für das SSL Zertifikat getauscht werden.
MariaDB
An dieser Stelle habe ich bereits aufgezeigt, wie ein MariaDB Galera Cluster erstellt werden kann.
Ich gehe davon aus, dass ein funktionierendes MariaDB vorhanden ist und folgende User und leere(!) Datenbanken erstellt worden sind:
- icingaweb2_director_db
- icinga2_ido_db
- icingaweb2_director_db
root@office-ffm-db-01:# mysql
MariaDB [(none)]> CREATE DATABASE icinga2_ido_db CHARACTER SET utf8mb4;
MariaDB [(none)]> CREATE DATABASE icingaweb2_db CHARACTER SET utf8mb4;
MariaDB [(none)]> CREATE DATABASE icingaweb2_director_db CHARACTER SET utf8mb4;
MariaDB [mysql]> GRANT SELECT INSERT UPDATE DELETE DROP CREATE VIEW CREATE INDEX EXECUTE ALTER REFERENCES ON icinga2_ido_db.* TO 'icinga2_ido_db'@'192.168.1.%' IDENTIFIED BY 'secret';
MariaDB [mysql]> GRANT SELECT INSERT UPDATE DELETE DROP CREATE VIEW CREATE INDEX EXECUTE ALTER REFERENCES ON icingaweb2_db.* TO 'icingaweb2_db'@'192.168.1.%' IDENTIFIED BY 'secret';
MariaDB [mysql]> GRANT SELECT INSERT UPDATE DELETE DROP CREATE VIEW CREATE INDEX EXECUTE ALTER REFERENCES ON icingaweb2_director_db.* TO 'icingaweb2_director_db'@'192.168.1.%' IDENTIFIED BY 'secret';
Man kann zwar auch von Puppet die Datenbank anlegen lassen, aber dafür müsste man noch das MySQL Puppet aufnehmen, was ich mir an dieser Stelle spare.
Icinga2 Puppet Modul
$ puppet module install icinga-icinga2 --modulepath environments/production/modules/
$ puppet module install icinga-icingaweb2 --modulepath environments/production/
$ puppet module install camptocamp-systemd --modulepath environments/production/modules/
$ git add environments/production/modules/
$ git commit -m "Add Icinga2 module and dependencies" environments/production/modules/
Struktur
$ mkdir -p environments/dev/modules/profile/{manifests,files,templates}/icinga2/
Manifests
Wir schmeißen im Grunde die Standardkonfiguration weg und erzeugen sie neu. Die Datenbank Daten entnehmen wir Hiera sowie diverse andere Parameter.
- Nagios gehört der ssl-cert Gruppe an, um SSL Zertifikate lesen zu können
- Repo wird von Puppet verwaltet
- Die Datenbank wird regelmäßig aufgeräumt
- API wird mit TLS Minimum 1.2 abgesichert (default ab Icinga 1.11)
- Standard Zone global-templates und director-global werden erstellt
- Nur der Config Master erhält Apply Rules, Commands und Co
- create_resource for Host und Service Objekte sowie API-User und Service Gruppen
- Bei 3rdparty Plugins wird zwischen Master und generischen Agent unterschieden
- Firewall wird geöffnet für Port 5665
Master
- environments/dev/modules/profile/manifests/icinga2/master.pp
- environments/dev/modules/profile/manifests/icinga2/applyrules.pp
Die Apply Regeln werden als Dateien gepflegt, da dies sehr viel einfacher und pflegeleichter ist, als sie zu exportieren.
Ein Auszug:
Die Dateien liegen in einem anderen Ordner und kann bei Bedarf natürlich geändert werden.
Alle “reinen” (also nicht Puppet Dateien) Icinga2 Dateien, Plugins, Scripte und Co. landen bei mir in modules/icinga2_checks/
$ mkdir -p environments/dev/modules/icinga2_files/files/{commands,plugins,plugins_agent,scripts,applyrules,templates}
Beispiel für service_check_apt.conf:
# Managed by Puppet
# modules/icinga2_checks/files/applyrules/service_check_apt.conf
apply Service "apt" {
import "generic-service"
check_command = "custom-apt"
if (host.name != NodeName) {
command_endpoint = host.name
}
assign where host.vars.distro == "Debian"
enable_notifications = false
ignore where host.vars.noagent
if (host.vars.distro_name == "stretch") {
vars.apt_list = true
}
}
Beispiel für service_check_linux_base.conf:
- profile/manifests/icinga2/checkcommands.pp
Hier hinterlegen wir die Kommandos. Historisch bedingt tatsächlich als Puppet Objekte. Auch hier wäre die ÜBerlegung wert, sie als reine Icinga2 Dateien zu hinterlegen. Diese Datei ist sehr umfangreich und sollte auf jeden Fall entschlackt werden. Allerdings hilft es dem einen oder anderen anhand der Syntax zu entnehmen, wie ich etwas umgesetzt habe.
- profile/manifests/icinga2/notifications.pp
Dieses Manifest trägt eigentlich einen falschen Namen. Es sorgt eigentlich nur für die Umgebung und hinterlegt Passwörter oder dass benötigte Pakete auf dem System sind, um bestimmte Tools für die Benachrichtigung verwenden zu können.
# Notifications scripts and passwords
class profile::icinga2::notifications (
$domain = hiera('monitoring::domain'),
){
$templates = '/etc/icinga2/zones.d/global-templates'
file { '/etc/icinga2/scripts':
ensure => directory,
mode => '0755',
owner => 'root',
group => 'nagios',
source => [
'puppet:///modules/icinga2_files/scripts',
],
recurse => true,
}
}
- profile/manifests/icinga2/templates.pp
Hier werden nur die Templates hinterlegt, aber als reguläre Dateien:
# Mostly all templates for import
class profile::icinga2::templates {
$global_templates = '/etc/icinga2/zones.d/global-templates'
$templates = "${global_templates}/templates.d"
file { "${global_templates}/templates.d":
ensure => directory,
owner => 'nagios',
group => 'nagios',
mode => '0750',
purge => true,
force => true,
}
-> file { "${templates}/host-templates.conf":
ensure => file,
owner => nagios,
group => nagios,
tag => 'icinga2::config::file',
source => [
'puppet:///modules/icinga2_files/templates/host-templates.conf',
],
}
-> file { "${templates}/service-templates.conf":
ensure => file,
owner => nagios,
group => nagios,
tag => 'icinga2::config::file',
source => [
'puppet:///modules/icinga2_files/templates/service-templates.conf',
],
}
}
Plugins
In den Foren wird oft gefragt, ob es nicht möglich wäre die Plugins per Icinga2 zu verteilen. Das geht natürlich nicht und würde den Code nur aufblasen, zumal es in sehr vielen Fällen ohnehin quatsch wäre. Bei vielen Plugins werden sehr oft weitere Pakete benötigt, die dann nach wie vor fehlen würden. Daher überlässt man das besser anderen.
Dieses Manifest unterscheidet im Grunde drei Typen:
- Icinga2 Agent oder Master
- Virtueller Host / Container
- Physischer Host
In meinem Fall bekommt der Master ein anderes Plugin Verzeichnis, als der Agent, weil zum Beispiel die IBM oder VMware Ordner auf den Clients nicht benötigt werden. Aber auch hier wäre noch sehr viel Luft zum optimieren. Da habe ich mir jetzt nicht soviel Mühe gegeben :-)
- profile/manifests/icinga2/plugins.pp
Sudo
Da wir an sehr vielen Stellen sudo benötigen, hinterlegen wir eine passende Konfiguration. Das Puppet saz-sudo Modul sorgt dafür, dass nur syntaktisch korrekte Sudo Dateien hinterlegt werden.
modules/profile/templates/icinga2/sudoers_nagios.erb
# This file is managed by Puppet; changes may be overwritten # Source modules/profile/templates/icinga2/sudoers_nagios.erb # Cmnd_Alias NAGIOS_MSECLI = /usr/local/sbin/msecli_64 Cmnd_Alias NAGIOS_IPMI = /usr/sbin/ipmi-sel, /usr/sbin/ipmi-sensors Cmnd_Alias NAGIOS_ZFS = /sbin/zpool, /sbin/zfs Cmnd_Alias NAGIOS_SMART = /usr/sbin/smartctl Cmnd_Alias NAGIOS_PWC = /usr/bin/chage <% if @fqdn =~ /-aicint/ -%> Cmnd_Alias NAGIOS_C = NAGIOS_MSECLI, NAGIOS_IPMI, NAGIOS_ZFS, NAGIOS_SMART, NAGIOS_PWC, NAGIOS_CRON <% else -%> Cmnd_Alias NAGIOS_C = NAGIOS_MSECLI, NAGIOS_IPMI, NAGIOS_ZFS, NAGIOS_SMART, NAGIOS_PWC <% end -%> Host_Alias NAGIOS_H = <%= @fqdn %> nagios NAGIOS_H = (ALL) NOPASSWD: NAGIOS_C
Agent
Beim Agent wurde am meisten gegrübelt, da die Anforderungen sich stetig änderten. Anfangs konnte der Master alle Agents direkt erreichen, dann kamen unterschiedliche Zonen sowie Satelliten hinzu. Am Ende bekam ein Satellit sogar einen weiteren Satelliten zugeordnet, der einen nochmaligen Umbau nach sich zog.
- mon = Monitoring Master
- monproxy = Monitoring Satellit
- jumper = Eigentlich ein Jumphost, aber dieser ist auch für die Zone MGMT zuständig. Im Manifest ist dies jumper-02
- profile/manifests/icinga2/agent.pp
Icingaweb2
Icingaweb2 wird ebenfalls auf dem Master installiert, daher haben wir auch dafür ein passendes Manifest.
- dev/modules/profile/manifests/icinga2/icingaweb2.pp
Hiera
Damit haben wir die wichtigsten Manifests zusammen. Gehen wir zum Hiera Teil über.
Ein erheblicher Anteil kann nun über Hiera definiert werden. Fangen wir beim Master an und gehen dann Monproxy und Agent.
Master
Es gibt drei Orte die zum Einsatz kommen:
- hieradata/common.eyaml
- Für allgemeine Parameter die für Master und Agents gleichermaßen gültig sind
- hieradata/role/master.yaml
- Parameter die nur die Master betreffen
- hieradata/node/office-ffm-master-01.4lin.net.eyaml
- Parameter die nur speziell diese Node betreffen.
Fangen wir wir mit der hieradata/common.eyaml
an. Alles mit secret muss natürlich durch eigene Kennwörter getauscht werden. Die monitoring Schlüssel sind sozusagen übergeordnet, da sie nicht nur bei Icinga2 zum Einsatz kommen, sondern auch noch für z.B. Grafana oder ähnliches. Ist aber reine Geschmackssache.
Die hieradata/role/master.yaml
beinhaltet alles für die Master Nodes:
* Icinga2 selbst
- Zonen
- Endpoints
- Plugins
* Apache2 für Icingaweb2
- PHP
* Icingaweb2
profile/dev/hieradata/node/office-ffm-master-01.4lin.net.eyaml
--- # We are config master icinga::config_master: true
Erster Puppetlauf
Hat man es bis zu diesem Punkt geschafft, kann man mittels puppet agent -t --noop
einen ersten Testlauf starten und nach Syntaxfehlern Ausschau halten. Erfahrungsgemäß gibt es jede Menge davon. Des weiteren kann (und wird) es nötig sein, den Lauf mehrfach zu starten, da das ganze Konstrukt zu komplex ist, als dass es auf Anhieb durchläuft.
Ein Erfolgt ist es, wenn der Login auf Icingaweb2 bereits klappt, auch wenn noch keine Hosts sichtbar sind, da die Standard Konfiguration von Puppet entfernt wird. Stattdessen nutzen wir das Director Modul und Puppet um neue Hosts hinzuzufügen.
Director PuppetDB
Nach dem Puppet durchgelaufen ist, können wir den PuppetDB Host hinzufügen und auf die dort enthaltenen Ressourcen zugreifen.
Wurde die erste Synchronisierung durchgeführt, dürften wie in diesem Fall zwei Nodes bereits in der Vorschau auftauchen. Das allein hilft noch nicht, den wir müssen dem Modul noch sagen, wie es damit verfahren soll.
Director Vorarbeit
Bevor die ersten Hosts im Icinga2 auftauchen und überwacht werden können, sind noch einige Schritte zuvor notwendig:
- Erstellen von eigenen Datenfeldern
- wir benötigen host.vars.os = Linux, damit die Apply Regeln greifen
- wir benötigen host.vars.client_endpoint
- werden über den Director später automatisch befüllt
- Host Templates erstellen
- Generic Host (oder generic-host) -> Für ICMP oder Hostalive Hostcheck
- Director Host -> Bindet Generic Host ein, zusätzlich wird aktive Agent Verbindung gesetzt (Endpoint / Zone )
- Datenfeld “os” hinzufügen
- generic-service Template erstellen
- es muss dieser Name sein, da in vielen Apply Regeln auf diesen Namen zurückgegriffen wird
- Dient zum Setzen von Standardwerten
Datenfelder
Fangen wir mit dem Datenfeld an. Wir erstellen eine Datenliste mit unterschiedlichen Betriebssystemen. Das ist besser als einfach nur ein String, wegen unterschiedlicher Schreibweisen:
Die Liste selbst habe ich “Operation Systems” genannt. Als Schlüssel und Bezeichnung habe ich das Gleiche genommen.
Es folgt als nächstes das Datenfeld “os”, welches sich auf diese Liste bezieht:
Folgt als letzten das Feld host.vars.client_endpoint. Das sorgt in den Apply Regeln dafür, dass der Check auf wirklich auf dem gewünschten Host ausgeführt wird:
Das waren für den Anfang die wichtigsten Felder.
Templates
Nun benötigen wir zwei Host Templates und ein Service Template. Das erste Host Template “Generic Host” (oder falls lieber “generic-host”) hat lediglich den Hostcheck gesetzt. In meinem Fall verwende ich lieber das Check Kommando “ICMP”, statt dem “Hostalive”.
Wurde das Template erstellt, muss auch das Feld “os” und “client_endpoint” hinzugefügt werden.
Das zweite Host Template “Director Host” sorgt dafür, dass beim Import durch den Director aus dem Puppet heraus, auch die notwendigen Zonen und Endpoints erstellt werden. Dafür muss lediglich unter den “Icinga Agenten- und Zoneneinstellungen Einstellungen” die Parameter dafür aktiviert werden:
Das Service Template “generic-service” wird wie das Host Template erstellt, aber es bedarf da aktuell keine weiteren Parameter, für dieses HowTo. Einen Screenshot erspare ich mir an dieser Stelle.
Sync Regeln
Nun kommt der fummligste Abschnitt: das Erstellen der Synchronisationsregeln.
Grob gesagt geht es darum, dem Director zu sagen, welches Puppet Fact (ip / hostname / role / blockdevice …) zu welchem Feld im Icinga2 Host Object gehören soll.
- Ein Beispiel:
Puppet Fact | Icinga Host Object |
---|---|
fact.ip | host.address |
certname | host.display_name |
fact.fqdn | host.vars.fqdn |
fact.role | host.vars.role |
Jedes gewünschte Feld im Icinga Host Object muss zuvor auch im Director unter Datenfelder erstellt werden (meistens als String), damit es dann in der Regel zugeordnet werden kann.
Der nächste wichtige Punkt ist der, dass die neuen Datenfelder im Host Template (z.B Generic Host oder Director Host) hinzugefügt wurden.
Hier werde ich sechs Regeln exemplarisch aufzeigen.
Zum erstellen des Regelsets im Director müsst ihr wie im Screenshot dargestellt auf Icinga-Director gehen, dann Automatisierung, Syncronisationsregel. Dort wird ein neuer Regelsatz erstellt:
Hier habe ich den Regelsatz “Master PuppetDB Sync” genannt und als Objekttyp “Host”, Aktualisierungsrichtlinie “Zusammenführen” und Bereinigen mit “Ja” angegeben.
Wurde der Satz erstellt, kommen die Regeln. Wählt den neu erstellten Regelsatz aus und dann direkt auf “Eigenschaften”. An dieser Stelle wird nun dem Director gesagt, was wir gerne wo hätten. Als Beispiel habe diese gewählt:
Puppet Fact | Icinga Host Object |
---|---|
icinga2_zone | zone |
certname | display_name |
facts.ipaddress | address |
certname | object_name |
facts.kernel | vars.os |
Director Host | import |
cername | vars.client_endpoint |
Die Möglichkeit einem Host Object Templates mit auf dem Weg zu geben, ist besonders hervorzuheben. In diesem Beispiel wird dem zu erstellendem Icinga Host Object das Template “Director Host” mitgegeben. In Kombination mit dem Filter kann ich sagen, dass der Host “office-ffm-srv-puppet” – welcher den Hostname “srv” hat – zum Beispiel ein Template “SRV Host” mitbekommt. Von dieser Funktion machen wir reichlich Gebrauch, um gleichartige Hosts zu erschlagen.
Ein fertiger Host vom Director sieht dann zum Beispiel so aus:
zones.d/master/hosts.conf
object Host "office-ffm-srv-puppet.4lin.net" {
display_name = "office-ffm-srv-puppet.4lin.net"
address = "192.168.1.33"
check_command = "icmp"
vars.client_endpoint = "office-ffm-srv-puppet.4lin.net"
vars.os = "Linux"
}
zones.d/master/agent_endpoints.conf
object Endpoint "office-ffm-srv-puppet.4lin.net" {
host = "192.168.1.33"
log_duration = 0s
}
zones.d/master/agent_zones.conf
object Zone "office-ffm-srv-puppet.4lin.net" {
parent = "master"
endpoints = [ "office-ffm-srv-puppet.4lin.net" ]
}
Fügen wir noch das Fact “role” hinzu:
Das Feld “role” habe ich natürlich vorher schon hinzugefügt. Damit können wir am Ende dann Apply Regeln erstellen, die nach host.vars.role == “foo” schauen :-)
Nehmen wir noch einen Import hinzu ! Dafür habe ich ein weiteres Template erstellt, das “DB Host” heißt und möchte, dass jedes Icinga Host Object dieses Template erhält, welches als certname=*db*
enthält:
Ist das auch geschafft, kann man im ersten Karteireiter den Sync anstoßen und sollte dann folgendes Ergebnis erhalten:
zones.d/master/hosts.conf
object Host "office-ffm-db-01.4lin.net" {
import "Director Host"
import "DB Host"
display_name = "office-ffm-db-01.4lin.net"
address = "192.168.1.30"
vars.client_endpoint = "office-ffm-db-01.4lin.net"
vars.os = "Linux"
vars.role = "db"
}
zones.d/master/agent_endpoints.conf
object Endpoint "office-ffm-db-01.4lin.net" {
host = "192.168.1.30"
log_duration = 0s
}
zones.d/master/agent_zones.conf
object Zone "office-ffm-db-01.4lin.net" {
parent = "master"
endpoints = [ "office-ffm-db-01.4lin.net" ]
}
Und das ist das geniale, denn mit dieser Funktion könnte ihr nahezu alles in ein Host Objekt packen lassen. Wir übergeben damit sogar Festplattentypen und Mountpoints, um dann mit entsprechenden Apply Regeln darauf zu reagieren.
Danksagung
An dieser Stelle gilt mein Dank vor allem der Netways Truppe Ich muss zugeben, dass ich ein Teil meines Gehaltes wegen ihrer Arbeit erhalte :-) Da sind besonders zu nennen:
- Lennart Betz - Der Mensch hinter den Puppet Modulen
- Thomas Gelf - Der Icingaweb2 Mensch
- Michael (dnsmichi) Friedrich - Der Typ der dafür sorgt, dass Icinga2 einen Saint Nessus Scan überlebt :-D
Dann wäre da noch Marianne M.Spiller, mit deren Hilfe ich überhaupt erst den Director kennen und nutzen gelernt habe.
Dann kämen natürlich noch die unzähligen Menschen von Puppet selbst und deren Module. Die wichtigsten für mich sind da:
- Steffen Zieger - hat etliche Puppet Module geschrieben
- Rob Nelson - ebenfalls ettliche Puppet Module und vor allem Rollen / Profile erklärt unter Puppet erklärt.
Links
- Rollen und Profile mit Hiera -https://rnelson0.com/2014/07/14/intro-to-roles-and-profiles-with-puppet-and-hiera/
- Icingaweb Director - https://www.unixe.de/icinga2-director-die-einrichtung/
- Puppet Beispiele für Icinga2 - https://github.com/Icinga/puppet-icinga2/tree/master/examples