Bei einer steigenden Anzahl von Client- und Serversystemen ergibt es Sinn, Installation und Verwaltung weitgehend zu automatisieren. Die Infrastruktur lässt sich damit nicht nur beschleunigt administrieren, sondern als Nebeneffekt auch noch besser dokumentieren. Der Workshop beschreibt, wie Sie die Konfiguration von Servern mithilfe von Puppet und den dabei zum Einsatz kommenden Manifest-Dateien automatisieren und sich so viel Zeit sparen.
Der Markt für Produkte zur Automatisierung wächst stetig. Die Software Puppet existiert bereits seit 2005 und die Community ist sehr groß. Die hohe Anzahl an aktiven Nutzern führt dazu, dass sich Probleme und Fragen meist recht schnell klären lassen. Zudem gibt es eine sehr große Quelle an Modulen, die frei zur Verfügung stehen und sich in die eigene Umgebung einpflegen lassen. Der Autor dieses Beitrags betreibt seit einigen Jahren eine Serverfarm aus knapp drei Dutzend Linux-VMs, die über mehrere Rechenzentren in Deutschland verteilt laufen. Die Erkenntnisse aus dieser Arbeit und Betreuung fließen mit in diesen Workshop ein.
Puppetmaster in Betrieb nehmen
Wer mit Puppet arbeiten möchte, benötigt einen zentralen Server. Dieser Server wird auch als Puppetmaster bezeichnet und hält unter anderem die Konfigurationen der angebundenen Systeme vor. Die Installation unterscheidet sich je nach Distribution nur leicht. Hier sollten Sie sich an eine Installationsanleitung für das System Ihrer Wahl halten. Für diesen Workshop arbeiten wir mit Debian, die Screenshots basieren auf Version 10 (Buster) und Puppet 7.
Die Standard-Repositories von Debian für den APT-Paketmanager enthalten nach der Grundinstallation eine sehr alte Version von Puppet (5.5.22-2). Wenn Sie eine aktuellere Variante einsetzen möchten, achten Sie darauf, Ihre Paketquellen entsprechend anzupassen und zu aktualisieren. Debian- und Ubuntu-Systeme lassen sich sehr einfach mit einem DEB-Paket von "apt.puppet.com" ergänzen. Nach einem Update der Paketquellen finden Sie dann die aktuelle Version 7 der Software vor.
Der Markt für Produkte zur Automatisierung wächst stetig. Die Software Puppet existiert bereits seit 2005 und die Community ist sehr groß. Die hohe Anzahl an aktiven Nutzern führt dazu, dass sich Probleme und Fragen meist recht schnell klären lassen. Zudem gibt es eine sehr große Quelle an Modulen, die frei zur Verfügung stehen und sich in die eigene Umgebung einpflegen lassen. Der Autor dieses Beitrags betreibt seit einigen Jahren eine Serverfarm aus knapp drei Dutzend Linux-VMs, die über mehrere Rechenzentren in Deutschland verteilt laufen. Die Erkenntnisse aus dieser Arbeit und Betreuung fließen mit in diesen Workshop ein.
Puppetmaster in Betrieb nehmen
Wer mit Puppet arbeiten möchte, benötigt einen zentralen Server. Dieser Server wird auch als Puppetmaster bezeichnet und hält unter anderem die Konfigurationen der angebundenen Systeme vor. Die Installation unterscheidet sich je nach Distribution nur leicht. Hier sollten Sie sich an eine Installationsanleitung für das System Ihrer Wahl halten. Für diesen Workshop arbeiten wir mit Debian, die Screenshots basieren auf Version 10 (Buster) und Puppet 7.
Die Standard-Repositories von Debian für den APT-Paketmanager enthalten nach der Grundinstallation eine sehr alte Version von Puppet (5.5.22-2). Wenn Sie eine aktuellere Variante einsetzen möchten, achten Sie darauf, Ihre Paketquellen entsprechend anzupassen und zu aktualisieren. Debian- und Ubuntu-Systeme lassen sich sehr einfach mit einem DEB-Paket von "apt.puppet.com" ergänzen. Nach einem Update der Paketquellen finden Sie dann die aktuelle Version 7 der Software vor.
Die Installation führen Sie mittels apt install puppetserver durch. Nun müssen wir in der Datei "/etc/puppetlabs/puppet/puppet.conf" noch unseren Host-Namen eintragen. Ergänzen Sie die Konfiguration um die folgenden Einträge:
[server]
server = puppet.master-node
ca_server = puppet.master-node
dns_alt_names = puppet
Speichern Sie die Datei und starten Sie den Serverdienst mittels systemctl restart puppetserver neu. Stellen Sie außerdem durch die Ausführung von systemctl enable puppetserver sicher, dass der Dienst aktiviert ist und nach einem Reboot direkt wieder hochfährt. Ist dies abgeschlossen, wenden wir uns dem ersten Client zu.
Installation der Agenten
Die zu konfigurierenden Systeme statten Sie mit einem Agenten aus, installieren also auf jedem System einmalig ein Stück Software. Dies erfolgt auf ähnliche Weise wie beim Master, indem Sie die aktuellen Paketquellen für das genutzte OS ergänzen und aktualisieren. Danach spielen Sie den Agenten mittels
apt update && apt install puppet-agent
auf. Nach der Installation des Agenten ist dieser so zu konfigurieren, dass er eine Verbindung zum Master aufnehmen kann.
Dies geschieht über die Datei "puppet. conf”, die Sie unter "/etc/puppetlabs/puppet/ puppet.conf" finden. Mit ihrer Hilfe teilen Sie dem Agenten mit, mit welchem Master er sich verbinden soll. Ergänzen Sie dazu den folgenden Eintrag:
[main]
server = <FQDN des Puppetmaster>
Speichern Sie die Datei, setzen Sie den Agenten auf Autostart und booten Sie den Dienst mit
einmal neu. Kleiner Tipp: Haben Sie keinen Zugriff auf das DNS oder handelt es sich um ein einzelnes System, dann tragen Sie den Namen des Masters in "/etc/hosts" ein. Den Host-Namen eines Systems passen Sie ganz einfach per hostnamectl set-hostname puppet.master-node --static über die Kommandozeile an.
Nachdem nun die Grundvoraussetzungen geschaffen sind, verbinden wir den Puppet-Agenten mit unserem Server. Dazu müssen wir einmalig ein Zertifikat generieren, das für die Kommunikation zwischen Client und Master Verwendung findet. Führen Sie dazu den Befehl
/opt/puppetlabs/bin/puppet agent -t
auf dem Clientsystem aus. Der Client generiert einen neuen RSA-SSL-Schlüssel und versucht, eine Verbindung zum Master aufzubauen, um ein signiertes Zertifikat anzufragen. In den Standardeinstellungen passiert bei diesem Aufruf nichts, da die Ausstellung von uns noch nicht genehmigt wurde (Bild 1). Diese Genehmigung soll dafür sorgen, dass unerwünschte Systeme kein Zertifikat bekommen und somit auch nicht mit dem Master kommunizieren können.
Bild 1: Bevor ein Zertifikat serverseitig nicht signiert ist, mündet die Kontaktaufnahme des Agenten in einer Fehlermeldung.
Auf dem Puppetmaster lassen sich die bereits ausgestellten Zertifikate mit
/opt/puppetlabs/bin/puppetserver ca list
aufrufen. Hier ist zu sehen, dass der erste Client ein Zertifikat angefragt hat. Möchten Sie dies nun signieren, erledigen Sie dies mit
/opt/puppetlabs/bin/puppetserver ca sign --certname puppet.agent-node1
Erscheint nach der Signierung eine Erfolgsmeldung, wechseln Sie wieder auf den Client. Dort führen Sie den Befehl
/opt/puppetlabs/bin/puppet agent -t
erneut aus. Durch die Freischaltung auf dem Master kann das Zertifikat nun erstellt und heruntergeladen werden. Ab diesem Zeitpunkt sucht der Agent nach einer Konfiguration für den Host und wendet sie, sofern vorhanden, an. Mit diesen Schritten haben wir einen lauffähigen Puppetmaster-Server installiert und den ersten Client angebunden.
Wunschzustand in Manifest-Datei
Angebundene Clients steuern Sie über Manifest-Dateien. In einer solchen steht ein Zustand, den der Client haben beziehungsweise annehmen soll. Dieser gewünschte Zustand in Form einer Datei wird beim ersten Kontakt des Clients lokal heruntergeladen. Danach versucht der Client, das System den Vorgaben entsprechend anzupassen. Dies kann eine sehr umfassende Änderung sein oder auch nur eine einzelne Einstellung. Der Client fragt regelmäßig beim Master an – in den Standard-Settings alle 30 Minuten –, ob es eine aktualisierte Datei gibt. Wenn nicht, behält er die lokalen Einstellungen bis zum nächsten Durchlauf bei. Gibt es hingegen Änderungen, wird die lokale Datei durch die neue Datei ersetzt und der Client beginnt, den gewünschten Zustand umzusetzen.
Durch diese Zustandsbeschreibung lassen sich unglaublich viele Dinge erledigen und vereinheitlichen. Ein gutes Beispiel hierfür ist die Netzwerkkonfiguration der angebundenen Systeme. So können Sie die Nameserver aller angebundenen Clients mit nur einer einzigen Änderung auf dem Master anpassen, erweitern oder reduzieren. Dies spart nicht nur Zeit, sondern Sie stellen damit sicher, dass ein Client nicht ungewollt noch veraltete Einträge hat und DNS-Anfragen ins Leere laufen.
Bei einer großen Anzahl von Clients, die in weiten Teilen identisch sind, lässt sich die Zeit für die Einrichtung so extrem verringern. Stellen Sie sich eine Webserver-Farm vor, die aus mehreren hundert Servern inklusive den davor angebundenen Loadbalancern besteht. Wenn alle Webserver über eine identische Konfiguration verfügen (ausgenommen dem Namen und den Netzwerkeinstellungen), lässt sich diese Konfiguration einmal beschreiben und danach auf eine theoretisch unlimitierte Anzahl an Clients ausrollen. Die Verwaltung der Webserver wird so sehr stark vereinfacht und beschleunigt. Neue Server lassen sich innerhalb weniger Minuten provisionieren und dem bestehenden Webserver-Verbund hinzufügen.
Die Manifest-Dateien liegen auf dem Puppetmaster im Verzeichnis "/etc/puppetlabs/code/environments/production/ manifests/". Hier erstellen Sie eine Manifest-Datei pro Client, den Sie mit Puppet konfigurieren wollen. Der Name der Datei ist dabei egal. Sie muss nur die Endung ".pp" haben, sonst wird sie nicht aufgegriffen und genutzt. Sie können bei Bedarf auch Unterordner erzeugen und diese zum Beispiel nach den unterschiedlichen Standorten benennen.
Eine Manifest-Datei hat recht lockere Anforderungen, was die Formatierung angeht. Andere Werkzeuge, die etwa mit einer YAML-Formatierung arbeiten, sind deutlich anfälliger für fehlende Leerzeichen oder eine andere Art von fehlerhafter Formatierung. Beim Erstellen von Puppet-Dateien müssen Sie natürlich trotzdem gewisse Regeln einhalten, diese sind allerdings nicht so statisch wie in anderen Sprachen. Dadurch fällt die Arbeit leicht und Sie können das Manifest gut lesbar gestalten.
Der Inhalt der Datei beginnt immer mit dem Namen des Clients. Dieser muss übereinstimmen mit dem Namen im Zertifikat. Sind Sie nicht mehr sicher, welchen Namen Sie dem Client verpasst oder unter welchem Namen Sie ihn registriert haben, können Sie sich auf dem Master mit /opt/puppetlabs/bin/puppetserver ca list –all jederzeit alle Zertifikate beziehungsweise Namen anzeigen lassen.
Bild 2: Wer Änderungen an der Manifest-Datei sofort umsetzen will, kann dies mit dem entsprechenden Befehl erzwingen.
Wenige Zeilen Code genügen
Wollen Sie nun zum Beispiel mit einer Liste an Standardsoftware arbeiten und diese auf jedem System zur Verfügung stellen, setzen Sie die Installation der Software mit den folgenden Zeilen um:
node 'puppet.agent-node1' {
$packages = [
'htop', 'iftop', 'bwm-ng', 'tcpdump', 'mc'
]
package { $packages: ensure => installed; }
}
Damit definieren Sie für den Knoten "puppet.agent-node1", dass die Pakete installiert sein müssen, die in der Variablen "$packages" enthalten sind. In unserem Beispiel sind dies fünf Pakete, die in einer Basis-Installation nicht enthalten sind und die standardmäßig noch dazukommen sollen. Speichern Sie die Datei so ab, kommen die Änderungen beim nächsten Routinedurchlauf des Agenten zum Tragen. Alternativ erzwingen Sie die sofortige Anwendung auf dem Client mit dem Befehl /opt/puppetlabs/bin/puppet agent -t.
Kommt es nun zum Beispiel zu einer manuellen Deinstallation des Pakets "mc", fällt dieser "fehlerhafte" Zustand beim nächsten Durchlauf auf. Er wird korrigiert und das fehlende Paket wieder aufgespielt.
Neben der Installation von Software lassen sich so nahezu alle Einstellungen auf einem Server anpassen. Die Manifest-Datei der vom Autor betreuten Server umfasst beispielsweise über 1500 Zeilen Code, in denen die gewünschten Einstellungen enthalten sind. Der Durchlauf der initialen Konfiguration benötigt aktuell knapp 95 Sekunden, nach einem Neustart steht das System dann komplett eingerichtet zur Verfügung. Vorher hatte die manuelle Einrichtung des Servers ein bis zwei Tage gedauert.
Natürlich müssen Sie die Konfiguration einmalig in ein Manifest schreiben, was auch Zeit kostet. Mit einer steigenden Anzahl an Systemen sparen Sie dann aber nachträglich einiges an Aufwand. Weiterhin verfügen Sie durch das Manifest direkt über eine Dokumentation aller Settings, Adressen und Konfigurationen. Ziel sollte es also sein, den Server zunächst nur mit einer Basisinstallation auszustatten oder aus einer Vorlage heraus zu provisionieren. Dann erhält er den Puppet-Agenten, wird am Master registriert und danach vollständig durch Puppet konfiguriert und in den gewünschten Zustand gebracht. Zusätzliche manuelle Anpassungen sollten Sie tunlichst vermeiden, da die Änderung zum einen nicht im Manifest dokumentiert ist und sich manuelle Einstellungen mit dem Manifest beißen könnten.
Mit Modulen erweitern
Wie in anderen Skripten können Sie auch bei Puppet mit Variablen arbeiten, die dann im weiteren Verlauf zum Einsatz kommen. Dies vereinfacht die Nutzung von identischem Code über mehrere Server hinweg, die dann per Variable ihre spezielle Einstellung bekommen, zum Beispiel bei der IP-Adresse. Innerhalb der Konfiguration können Sie zudem mit Abhängigkeiten arbeiten, um eine Reihenfolge festzulegen. Die Konfiguration etwa von einem nginx-Webserver funktioniert natürlich nur dann, wenn das Paket inklusive aller Abhängigkeiten auch installiert ist.
Ein großer Teil des Codes, auf den Puppet zurückgreift, befindet sich in Modulen. Die Standardinstallation von Puppet bringt bereits einige Standardmodule mit, unter anderem das bereits genutzte für die Installation von Paketen über den APT-Paketmanager. Die Module enthalten Klassen, Aufgaben, Ressourcetypen und mehr. Die Funktionalität von Puppet lässt sich durch zusätzliche Module erweitern. Diese können Sie entweder selbst erstellen oder Sie greifen auf bereits fertige zurück. Eine gute Quelle hierfür ist Puppet Forge [1]. Dort finden Sie eine große Anzahl an offiziellen Modulen.
Ein beliebtes, das häufig in Abhängigkeit zu anderen Modulen existiert, ist für den APT-Paketmanager gedacht. Zur Installation nutzen Sie auf dem Puppetmaster den Befehl puppet module install puppetlabs-apt --version 8.3.0. Version 8.3.0 ist zum Zeitpunkt des Erstellens dieses Artikels aktuell. Schauen Sie vor der Installation am besten kurz nach, ob es bereits Updates gibt, und nutzen Sie die jeweils aktuelle Version.
Das Modul wird nun heruntergeladen und unter "/etc/puppetlabs/code/environments/production/modules" abgelegt. Danach steht es zur Benutzung bereit. Über das Modul können Sie in von Ihnen definierten Intervallen die Paketquellen aktualisieren (apt update), Updates installieren lassen (apt upgrade), neue Quellen hinzufügen, GPG-Schlüssel hinzufügen und vieles mehr. Die automatische Installation von Updates sorgt dafür, dass Systeme nicht mit veralteten Paketen laufen, in denen bekannte Sicherheitslücken vorhanden sind. Haben Sie auf der anderen Seite Pakete, die nur in einer gewissen Version betrieben werden dürfen, können Sie diese auf ein gewünschtes Release festpinnen. Die Pakete bekommen in diesem Fall keine Updates, selbst wenn neue Versionen erscheinen.
Möchten Sie nun etwa einen nginx-Webserver konfigurieren, könnten Sie dies mit einem herkömmlichen Verfahren nur auf manuellem Weg machen. Sie müssten per Hand die benötigten Dateien erstellen, mit Inhalt füllen, die entsprechenden Server in die Konfiguration einarbeiten und aktivieren. All diese Aufgaben nimmt Ihnen das nginx-Modul ab. Um es zu installieren, reicht der Aufruf puppet module install puppet-nginx --version 3.3.0 in der Kommandozeile. Über die Dokumentation des Moduls, ebenfalls über [1] erreichbar, sehen Sie Beispiele zur Konfiguration. Um den nginx-Webserver als Paket inklusive aller Abhängigkeiten zu installieren und eine Standardwebseite auf Port 80 zu eröffnen, reichen ein paar Zeilen in der Konfiguration:
include nginx
nginx::resource::server{'www.zueschen.eu':
www_root => '/var/www/html/MeinBlog',
}
Möchten Sie den Server neben einer HTTP-Konfiguration auch für HTTPS fit machen, ist dies mit wenigen weiteren Zeilen Code möglich. Sie müssen dazu im Manifest lediglich SSL aktivieren und auf die gewünschten SSL-Zertifikate verweisen. Haben Sie keine eigenen Zertifikate, könnten Sie auf Let’s Encrypt zurückgreifen. Um die Zertifikate anzufragen und ein Management möglichst einfach zu halten, arbeiten Sie wiederum mit dem Let's-Encrypt-Modul [2]. Mit dessen Hilfe lassen sich neue Zertifikate anfragen und bestehende verlängern. Für den nginx-Webserver selbst gibt es ebenfalls Module, die sich um die korrekte Einbindung der ausgestellten Zertifikate kümmern.
Wenn Sie Anpassungen an Manifest-Dateien oder Modulen vornehmen, kann es schon einmal vorkommen, dass die Änderungen nicht zum gewünschten Ziel führen und Sie die Einstellungen wieder zurückdrehen möchten. Natürlich ließe sich vor jeder Änderung eine Kopie der Datei erzeugen, bei vielen Änderungen und einer großen Anzahl an Dateien ist das allerdings ein viel zu großer Aufwand.
Aus diesem Grund lohnt es sich, ein Versionsmanagement für den Puppet-Datenbestand einzuführen. Durch solch eine Versionierung können Sie jede Änderung, die sie einbringen, einsehen und bei Bedarf wieder rückgängig machen. Weiterhin erkennen Sie bei der Arbeit im Team genau, welcher Benutzer welche Änderungen durchgeführt hat und wie diese aussehen. Sehr viele Entwickler weltweit nutzen eine Versionierung, um den von Ihnen geschriebenen Code abzulegen und, wie der Name schon sagt, zu versionieren.
Alle Dateien werden initial eingecheckt beziehungsweise erstellt, danach wird bei jeder Veränderung und Speicherung einer Datei eine neue Version erstellt. Die Versionen erhalten einen einmaligen Hashwert, über den Sie dann gezielt eine spezielle Version ansprechen können. Das Verfahren hierfür ist nicht neu, auf Github.com kommt ein solches System etwa zum Einsatz.
Sie müssen Ihre Daten dazu nicht aus der Hand geben, es gibt Projekte zum Realisieren eines eigenen Git-Systems auf eigener Hardware – GitLab ist hier ein sehr bekannter Anbieter. Der Autor dieser Zeilen hat sich in seiner Infrastruktur für die Puppet-Dateien einen selbstgehosteten Git-Dienst erstellt, um jederzeit Kontrolle über die Daten zu haben.
Fazit
Puppet ist ein mächtiges Werkzeug, um den Zustand von Servern zu beschreiben und diesen dann durch einen Agenten anzuwenden. Die Software kann sowohl kleine Anpassungen übernehmen als auch komplexe Installationen abbilden. Über ein Versionsmanagement greifen Sie jederzeit auf ältere Konfigurationen zurück und führen die Arbeit im Team zusammen.