kuerbis.org weekly – Ansible, Graylog2

Willkommen zur neuen Rubrik „kuerbis.org weekly“. Um diesem Blog ein wenig mehr Leben einzuhauchen, will ich von Zeit zu Zeit ein paar Sätze über das schreiben, was mir in den letzten Tagen aufgefallen ist, woran ich gearbeitet habe usw.. Ob es wirklich jede Woche stattfindet, sei mal dahin gestellt, aber in loser Folge werde ich sicherlich dazu kommen.

Ansible

Für den Anfang habe ich mir zwei Themen ausgesucht, die mir letzte Woche einmal mehr über den Weg gelaufen sind. Ansible ist grob gesagt ein Tool zur Automatisierung von Administrationstätigkeiten. Vor einiger Zeit habe ich mich bereits damit beschäftigt, als es darum ging, das Deployment einer PHP-Anwendung zu vereinfachen bzw. neu zu erstellen. Neben Ansible existieren klassisch die beiden Tools Puppet und Chef. Ein Vorteil von Ansible ist, dass auf der Server-Seite außer einem SSH-Zugang keine weiteren Voraussetzungen bestehen. Ansible setzt auf Python auf, was zum Standardumfang der meisten Distributionen gehört.

Warum Ansible und wie wird es eingesetzt? An meiner Arbeitsstelle wurde die Server-Infrastruktur vor kurzem neu gestaltet. Mittlerweile gibt es ein paar Dutzend virtuelle Server, die auf einer Handvoll Hosts verteilt sind. Dabei lassen sich Kategorien von Servern zusammen fassen, etwa Web-Server, Datenbank-Nodes, Cache-Server usw.. Zwar betreibe ich privat auch ein paar virtuelle Server bei verschiedenen Providern, und die Anzahl der virtuellen Server im Keller nimmt gefühlt auch ständig zu, aber hier stellen sich andere Anforderungen, da diese Umgebung sehr heterogen ist. Hier gleicht kein Server dem anderen, muss es auch nicht, da ich viele der internen Server zu Testzwecken verwende, und auch die externen Server sind von den Aufgaben her eher vielfältig. Insofern unterscheidet sich auch die eingesetzte Software auf den einzelnen Servern. Ansible kann seine Vorteile jedoch erst richtig ausspielen, wenn mehrere Server, die zu Gruppen zusammen gefasst werden können, administriert werden müssen. Wenn Gruppen nicht ausreichen, lassen sich auch Hierarchien bilden, diesbezüglich verweise ich jedoch auf die offizielle Dokumentation.

Zur Vorbereitung  muss es einen User auf dem Server geben, der sich mit SSH einloggen darf. Ich habe auf allen Servern daher einen speziellen User eingerichtet, der sudo-Rechte besitzt. Aus praktischen Gründen sind die Rechte (mit visudo) so angepasst, dass bei diesem User für die sudo-Rolle keine weitere Passworteingabe mehr notwenig ist. Der SSH-Key hingegen ist mittels Passwort geschützt.

Ansible lässt sich grundsätzlich in zwei Modi betreiben. Zum einen gibt es die Ad-hoc-Commands, zum anderen die Ansible-Playbooks.

Ansible-Ad-hoc-Commands

Die Ad-hoc-Commands sind genau das, was ihr Name nahe legt: Dabei lassen sich einmalig Tätigkeiten ausführen, natürlich auf beliebigen einzelnen Hosts oder Gruppierungen.

Ein Beispiel:


Im betreffenden Fall ging es darum, die Konfiguration von Postfix auf einigen Servern zu korrigieren. Das Kommando nutzt das Ansible-Modul ‚replace‘ und ersetzt in der Datei /etc/postfix/main.cf mittels regulärem Ausdruck den leeren Eintrag ‚relayhost=‘ durch das hier genannte Beispiel. Dabei wird ein Backup der ursprünglichen Datei angelegt. Anstatt einen speziellen Server oder eine Gruppe zu verwenden, kann auch das Schlüsselwort ‚all‘ benutzt werden, damit wird Ansible dazu aufgefordert, das Kommando auf allen konfigurierten Hosts auszuführen. Die Hosts bzw. Gruppen werden per Default in /etc/ansible/hosts eingetragen.

Ein weiteres Beispiel:


Noch einfacher – der Postfix-Service wird neu gestartet. Anstatt sich also auf jedem Server einzuloggen und das Kommando zum Restart auszuführen, genügt hier ein einziger Befehl. In beiden Beispielen wurden Ansible-Module verwendet, von denen eine stattliche Anzahl bereit steht. Falls das einmal nicht ausreichen sollte, lassen sich auch beliebige Shell-Kommandos ausführen, eben mit dem shell-Modul.

Ansible-Playbooks

Kommen wir zur zweiten Möglichkeit, dem Einsatz von so genannten Ansible-Playbooks. Dabei handelt es sich um gescriptete Konfigurationsanweisungen im YAML-Format, man könnte es auch Konfigurations-Skript nennen. Ein Playbook kann dabei aus einer Vielzahl von Tasks und Handlers bestehen. Zur Wiederverwendung und einfachen Orchestrierung ganzer Server-Landschaften lassen sich zudem Roles einrichten, so dass z.B. eine ‚webserver‘-Role auf eine Anzahl von Servern angewendet werden kann, womit die Standard-Konfiguration von Web-Servern erledigt wird. Für Details verweise ich hier wieder auf die ausführliche, offiizielle Dokumentation.

Noch ein Wort zur Strukturierung: Bei der Verwendung von Playbooks sollte eine gewisse Struktur der einzelnen Dateien vorliegen. Wenn Roles hinzu kommen, ist diese letztlich unerlässlich. Für viele Standard-Software finden sich vollständige Playbooks und Beispiele im Netz, u.a. auf Github. Die Struktur ist jedoch nicht immer einheitlich – Ansible erlaubt hier einige Freiheiten. Die Beispiele und fertigen Playbooks, die sich finden lassen, haben mir daher eher als Orientierung gedient. Darüber hinaus gibt es Ansible Best Practices als Empfehlung, die einen Blick wert sind.

Praxisbeispiel: Nginx, php5-fpm

Als konkrete Aufgabe habe ich auf einem Ubunu-Server Nginx mit php5-fpm einrichten wollen. Da ich mir sicher war, dass sich dieser Task wiederholen wird, wollte ich die Möglichkeit eines Playbooks nutzen. Die Wahl bestand nun darin, ein fertiges Nginx-Playbook zu verwenden, oder dies kurzerhand selbst zu schreiben.

Daher habe ich mir eines der vorhandenen Playbooks angesehen. Der Funktionsumfang war mächtig, vermutlich hätte sich alles damit erledigen lassen. Jedoch war es nicht speziell für die eingesetzte Ubuntu-Distribution geschrieben, sondern allgemein gehalten, so dass es auf vielen weiteren Distributionen lauffähig war. Das führte dann auch dazu, dass es sich nicht an den Bordmitteln von Ubuntu orientierte, sondern eine eigene Struktur von Nginx-Konfigurationsdateien mit sich brachte. Daran ist an sich nichts falsch, doch versuche ich im Allgemeinen, mich an der von der Distribution nahe gelegten Struktur zu orientieren. Beispielsweise liegen die Nginx-vhost-Konfigurationsdateien in /etc/nginx/sites-available/ und werden von /etc/nginx/sites-enabled/… per Symlink eingebunden. Eine komplett von diesem Standard abweichende Struktur empfinde ich daher eher als verwirrend denn als hilfreich. Daher habe ich mich dazu entschlossen, das entsprechende Playbook selbst zu schreiben.

Bevor ich zum Nginx-Beispiel komme, ein Beispiel eines sehr einfachen Playbooks. Damit soll git auf dem Server installiert werden.


Dieses Playbook besteht aus einem einzigen Task – genannt „Install git“. Damit wird das apt-Modul verwendet, um die Installation von git auszuführen bzw. genau genommen sicher zu stellen, dass git installiert ist. Falls git bereits existiert, wird keine Neuinstallation versucht, Ansible verhält sich insofern idempotent. Vorab wird mittels eines weiteren Tasks ggf. „apt-get update“ ausgeführt.

Die Hosts, auf die dieses Playbooks angewendet wird, sind hier in der Gruppe „webservergroup“ enthalten. Im einfachsten Fall wird eine so genannte Inventory-Datei, die vergleichbar ist mit der hosts-Datei unter /etc/ansible/ bei Ausführung des Kommandos als Parameter übergeben.

Nun kann Ansible-Playbook gestartet werden:


Natürlich wäre es für einen einzigen Server auf den ersten Blick einfacher, sich einzuloggen und dort ‚apt-get install git‘ auszuführen. Bei zwei oder mehr Servern wird es dann schon mühselig, vor allem weil dies das Übel der Wiederholung mit sich bringt. Und nach dem Motto DRY – Don’t repeat yourself – führt die Ansible-Variante einerseits zur Zeitersparnis, andererseits werden Fehler vermieden, insbesondere wenn es nicht bei der einfachen Installation ohne Konfiguration bleibt.

Dazu nun das Beispiel von Nginx mit php5-fpm und der Einrichtung des Default-vhosts mit einer Index-Datei, die den echten Namen des Webserver preis geben soll:


Dazu gehören noch zwei Template-Dateien, und zwar:


Sowie die Nginx-Konfigurationsdatei namens „default“, die hier in default.conf umbenannt und als Template gestaltet wurde.


Beide Templates liegen im Verzeichnis „templates“, so dass sich folgende Struktur ergibt:


Insgesamt ist diese Struktur sicherlich noch verbesserungswürdig. So könnten innerhalb des templates-Verzeichnisses die echten Verzeichnishierarchien angelegt werden. Falls später einmal Roles benutzt werden, wären ebenfalls Änderungen notwendig. Als erstes Experimentierfeld hat mir jedoch diese Struktur zunächst ausgereicht.

Die Ausführung erfolgt auch hier mittels:


Die wichtigsten Schritte:

  • Die Pakete php5-fpm, php5-mysqlnd, php5-cli und php5-curl werden installiert. Dabei kommt die Direktive „with_items“ zum Einsatz, mit der eine Schleife über eine Liste von Items erzeugt wird.
  • Nginx wird installiert, dazu wird sicher gestellt, dass die Services php5-fpm und nginx beim Booten automatisch gestartet werden.
  • Ein Verzeichnis /vol/www/{{ ansible_fqdn }} wird erzeugt, in dem sich später die HTML-Dateien für den Webserver befinden sollen. Darüber hinaus werden die Verzeichnisse logs und htdocs erzeugt. Bei mehreren Webservern halte ich es für geschickt, wenn der jeweilige Server, etwa web01.example.com unter diesem Namen erreichbar ist und seinen Namen ausgibt. Genau das passiert ahd. der Template-Datei index.html.j2, wobei daraus die index.html erzeugt wird. Der Platzhalter {{ ansible_fqdn }} wird durch den echten Hostnamen ersetzt, der durch die so genannten Facts ermittelt wird. Dabei ist eine Vielzahl von Variablen verfügbar, die mittels Kommando „ansible hostname -m setup“ angezeigt werden können. Die Templates sind mittels Jinja2 realisiert – wer Templates aus der Web-Programmierung kennt, wird sich vermutlich sofort heimisch fühlen.
  • Die Default-Konfiguration, bestehend aus der Datei /etc/nginx/sites-available/default und dem dazu gehörigen Symlink, werden entfernt. Daraufhin wird die Datei default.conf aus dem Template default.conf.j2 in das Verzeichnis sites-available kopiert. Dabei handelt es sich letztlich um eine Kopie der default-Konfigurationsdatei, erweitert durch die Aktivierung von PHP mittels FastCGI und das Setzen der hier eingerichteten Verzeichnisstruktur.
  • Die Handler am Ende der Datei dienen zum Restart des Webservers und werden durch die entsprechenden „notify“-Events aufgerufen.

Sollte nun beispielsweise ein weiteres PHP-Modul notwendig werden, genügt es, dies in der Liste der Items einzutragen und das Playbook erneut aufzurufen. Ansible führt daraufhin die notwendigen Schritte zur Installation des Moduls aus, lässt den Rest hingegen unangetastet.

Fazit

Meines Erachtens bestechen Playbooks durch ihre einfache Struktur und Übersichtlichkeit. Eine weiter gehende Dokumentation ist kaum notwendig, die Dateien sind nahezu selbsterklärend. Ansible-Module sind für nahezu jede Aufgabe verfügbar. Als nächstes könnte etwa die Einrichtung von vhosts mittels eines Playbooks erstellt werden. Genau genommen ist es mir schleierhaft, wie man dazu noch im letzten Jahr neue, aber dennoch unübersichtliche und fehlerträchtige Shell-Skripte schreiben konnte, aber das ist eine ganz andere Geschichte…

Neben der offiziellen Dokumentation ist mittlerweile auch ein E-Book Ansible for Devops verfügbar, was eine sehr gute Einführung bietet. Ansible selbst ist Open Source unter der GNU GPL zur Verfügung. Mit Ansible Tower wird eine (kostenpflichte) UI angeboten. Laut README beinhaltet Ansible Beiträge von über 900 Nutzern, weshalb mir diese kleine Anmerkung hoffentlich gestattet wird, denn letztes Jahr habe ich im Composer-Modul die bis dato fehlende update-Option hinzu gefügt, ein paar Zeilen Python genügten.

Graylog2

Eigentlich wollte ich an dieser Stelle noch einiges über Graylog2 schreiben, dessen Version 1.0 letzte Woche erschienen ist. Graylog2 ist eine Plattform für Log-Management und steht unter einer Open-Source-Lizenz bereit. Graylog2 nutzt die Datenbank MongoDB und die Search-Engine Elasticsearch und bietet eine vollumfassende Lösung zur Sammlung, Konsolidierung und Auswertung von Log-Informationen. Ich habe bereits einige Versionen vor der jetzt frei gegebenen Version 1.0 getestet und war begeistert von den vielfältigen Möglichkeiten – von der Integration von Syslogs bis hin zum Application-Monitoring. Aus dem kommerziellen Bereich ist vielleicht Splunk bekannt, was ich vor einiger Zeit im Einsatz gesehen habe, und davon ebenfalls recht beeindruckt war.

Die Installation von Graylog2 war jedoch selbst auf einem Server etwas komplexer, da zunächst die benötigten Abhängigkeiten, noch dazu in bestimmten Versionen, installiert werden mussten. Inzwischen werden neben Appliances für OpenStack, VMware oder Amazon EC2 auch Docker-Container bereit gestellt, so dass die Installation letztlich mit zwei, drei Kommandos erledigt sein sollte. Das wollte ich mir näher ansehen, insbesondere, da ich Docker bisher zwar faszinierend fand, aber aufgrund einiger Merkmale und fehlender Praxis noch nicht ganz warm geworden bin. Aus Gründen bin ich in der letzten Woche jedoch nicht dazu gekommen, somit wird dies ein Thema für einen der nächsten kuerbis.org-Weekly-Beiträge sein.

 

Tags:

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.