Konfigurationsmanagement mit Puppet

puppet-title

Im Laufe meiner zweiten Praxisphase des Studiums bei der ORDIX AG habe ich mich mit Puppet beschäftigt. Meine Aufgabe war es, mich in das Systemkonfigurationswerkzeug Puppet einzuarbeiten und Inhalte für ein neues Seminar herauszuarbeiten. Hierauf basierend soll der folgende Artikel eine kleine Einführung geben, was Puppet genau ist und wie es funktioniert.

Was ist Puppet?

Puppet ist ein Werkzeug für die automatisierte Konfiguration von Servern, sowie allen darauf installierten Diensten. Programmiert ist Puppet in Ruby, die Konfiguration wird jedoch in einer einfachen Beschreibungssprache (DSL domain-specific language) vorgenommen. Puppet ist ein Client-Server-System, was bedeutet, dass der Server (Puppet Master) die Konfiguration aller Clients (Puppet Agenten) verwaltet und die Agenten sich mit dem Master verbinden, um die benötigte Konfiguration zu laden. Der Abgleich zwischen Agenten und Master erfolgt standardmäßig alle 30 Minuten. Dabei wird immer die Einstellung des Masters übernommen. Falls in Ausnahmefällen Änderungen auf den Agenten vorgenommen werden, bleiben diese maximal 30 Minuten bestehen, wenn nicht anders konfiguriert. Für eine dauerhafte Änderung muss die Konfiguration auf dem Master verändert werden.

Sicherheit bei Puppet

Die Kommunikation zwischen dem Master und den Agenten erfolgt über HTTPS, und der regelmäßige Abgleich wird durch eine SSL-Verschlüsselung gesichert. Dabei ist der Master selbst die Zertifizierungsstelle. Nach dem ersten Start des Puppet Master erzeugt dieser ein SSL-Zertifikat. Der Agent fordert beim ersten Start ein Zertifikat bei dem Master an, welches manuell auf dem Master bestätigt werden muss.

Ab dem Augenblick werden bei jeder Kommunikation zwischen Master und Agent gegenseitig die Zertifikate geprüft. Wenn die Überprüfung fehlschlägt kommt keine Kommunikation zustande.

Konfiguration

Die Konfiguration für den Master und Agent findet in der Datei /etc/puppet/puppet.conf statt. Die Datei wird in vier Abschnitte unterteilt:

  1. [main] -> globaler Abschnitt. Wird von allen Befehlen und Diensten verwendet. Kann von den folgenden Abschnitten überschrieben werden.
  2. [master] -> beinhaltet die Konfiguration, die nur für den Puppet Master relevant ist.
  3. [agent] -> beinhaltet die Konfiguration, die nur für die Puppet Agents relevant ist.
  4. [user] -> wird von dem puppet apply und einigen spezielleren Befehlen verwendet.

Wenn in den drei anwendungsspezifischen Abschnitten (master, agent, user) keine Einstellungen stehen, wird die Konfiguration aus dem Abschnitt main verwendet. Ist der main Abschnitt auch ohne Einstellungen, dann wird auf den Standardwert zurückgegriffen.

Ressourcen

Ressourcen sind die grundlegende Einheit bei der Modellierung des Systems. Jede einzelne Ressource beschreibt den vorgesehenen Status für einen Aspekt im System, zum Beispiel ein Dienst oder ein Paket. Dabei gibt es viele verschiedene Ressourcen mit unterschiedlichen Aufgaben, zum Beispiel:

  1. Package -> verwaltet alle Softwarepakete (installieren, deinstallieren)
  2. Service -> verwaltet alle Dienste (starten, stoppen, neustarten)
  3. File -> Verwalten einer Datei (Inhalt, Eigentümer, Rechte)
  4. Exec -> Ausführen von Befehlen auf dem Puppet Agenten
  5. Mount -> hängt Dateisysteme ein und aus

Die Ressourcen lassen sich mit zusätzlichen Ausführungsbedingungen kombinieren. Darunter zählen zum Beispiel notify und require, mit denen Abhängigkeiten zwischen mehreren Ressourcen abgebildet werden können. Dadurch kann bei mehreren Ressourcen eine Ausführungsreihenfolge festgelegt werden.

Beispiele

In dem ersten Beispiel soll eine Konfigurationsdatei für den MySQL Service angelegt werden. Im Anschluss soll der Service gestartet werden. Dies erfolgt über das Attribut notify innerhalb der file-Ressource. Darüber lässt sich definieren, welche Ressource als nächstes ausgeführt werden soll.

file {'/etc/mysql/mysql.cnf': 
  source => '/examples/files/mysql.cnf', 
  notify => Service['mysql'] 
} 

service {'mysql': 
  ensure => running, 
  enable => true 
}  

Hierbei soll jedoch vorher auf benötigte Voraussetzungen, durch das Attribut require in der Service Ressource, geprüft werden. Dies soll erneut am Beispiel von MySQL betrachtet werden. Der MySQL-Service benötigt das Paket und die Konfigurationsdatei. Bevor der Service nun gestartet wird, prüft Puppet, ob das benötigte Paket bereits installiert ist. Ist dies nicht der Fall, wird es installiert. Zusätzlich wird nach der Konfigurationsdatei geschaut. Ist diese auch vorhanden, wird der Service von Puppet gestartet.

package {'mysql-server': 
  ensure => installed 
} 
service {'mysql': 
  ensure => running, 
  enable => true, 
  require=> [Package['mysql-server'], File['/etc/mysql/mysql.cnf']] 
}  

Fazit

Auch wenn der Einarbeitungsaufwand in Puppet etwas größer ist und etwas Zeit in Anspruch nimmt, wird der Administrator der Systeme im Nachhinein deutlich weniger Arbeit haben, die Systeme zu verwalten. Gerade wenn mehrere Server und Dienste ähnliche Einstellungen haben, können diese mit Hilfe von Puppet schnell und einfach umkonfiguriert und verwaltet werden. Somit rentiert sich der vorherige Zeitaufwand. Auch weitere Server können dank der Konfiguration schnell und einfach hinzugefügt werden.

By accepting you will be accessing a service provided by a third-party external to https://blog.ordix.de/