Vagrant: Von der Entwicklungsumgebung direkt in den Betrieb

In den letzten Jahren hat ein entscheidender Sinneswandel in der Softwareentwicklung stattgefunden. Je früher selbst entwickelte Softwarekomponenten aus dem Entwicklungsprozess in einer produktionsähnlichen Laufzeitumgebung in Betrieb genommen werden, desto eher erhält man Feedback zur Funktionsweise und desto reibungsloser verläuft der Transport über die anschließenden typischen Integrationssysteme (Dev, Stage, QS) auf die Live-Umgebung(en). Diese Herangehensweise trägt erheblich zu mehr Produktqualität und damit Kundenzufriedenheit bei.

Wir bei Consort verwenden für diesen ersten Schritt Vagrant von HashiCorp. Auf der Basis von VirtualBox von Oracle als Provider (viele andere sind ebenfalls möglich) sind wir mit Vagrant als Treiber in der Lage, reproduzierbare, leichtgewichtige sowie vollständige Entwicklungs- und Laufzeitumgebungen lokal auf dem eigenen Rechner zu erstellen.

Consort Virtuelles Rechenzentrum

Unsere derzeitige Vagrant-Umgebung besteht aus drei virtuellen Maschinen.

Übrigens: Für den sinnvollen Einsatz von Vagrant auf dem eigenen System, ist eine ausreichende Menge an Arbeitsspeicher empfehlenswert.

  • DEV-VM: Der Einfachheit halber enthält diese VM alle Infrastruktur-Services sowie die (entwickelten) Microservices. In einer Live-ähnlichen Umgebung ist es allerdings sinnvoll, diese Dinge zu trennen. Nichtsdestotrotz entspricht diese VM einer „echten“ Produktionsumgebung.
  • ELK-VM: Selbst für eine geringe Anzahl an Microservices ist es ratsam, sich gleich von Anfang an um das Logging zu kümmern. Wir benutzen den bekannten ELK-Stack bestehend aus Elasticsearch, Logstash und Kibana. Alle Logmeldungen aus der dev VM sind automatisch im Kibana einseh- und durchsuchbar.
  • MON-VM: Neben dem Logging spielt auch bereits zu diesem Zeitpunkt das Monitoring eine wichtige Rolle. Aufgrund ihrer geringen Größe ist es denkbar, dass bereits in der dev VM eine zweistellige Anzahl an Microservices gestartet sind. Um den Überblick zu behalten benutzen wir Icinga2.

Basis für jede Vagrant-Umgebung ist das „Vagrant-File“. Getreu dem Prinzip „Infrastructure as Code“ unterliegt diese Datei einer Versionskontrolle (Git). Ein Software-Engineer bei Consort checkt sich das Repository mit dem Vagrantfile aus und fährt die Umgebung wie folgt hoch (Reihenfolge: elk, dev, mon):

  • vagrant up elk dev mon

Damit auch tatsächlich Inhalte auf den 3 Systemen landen, sprich damit auch Docker, Ruby, Datenbankbenutzer, etc. pp auf den Systemen installiert und angelegt werden, provisionieren wir die VMs mit Ansible:

  • vagrant provision elk dev mon

Die Provisionierung kann dabei beliebig oft wiederholt werden. Soll beispielsweise eine neue Version des API-Gateways, welcher auf der dev VM läuft, deployed werden, bspw. weil ein anderer Engineer ein Update des API-Gateway Containers in die Docker Registry gepusht hat, dann reicht ein einfaches:

vagrant provision dev

Microservices von Kollegen erhalten

Wir gehen davon aus, dass in der dev VM alle für ein bestimmtes IT-Projekt notwendigen Services vorhanden sind. Diese Services sind jeweils als separater Docker-Container in der VM enthalten. Wenn wir Git-Repositories für einen Microservice erstellen, ist darin ebenfalls ein Build-Script enthalten, dass diesen Microservice baut und danach in eine zentrale Docker-Registry (in unserem Fall Artifactory) hochlädt.

Was muss ich als Entwickler nun konkret tun, um Kollegen meinen Microservice zur Verfügung zu stellen?

1. Git Repository anlegen und Code pushen

Dabei wird das Build-Script konfiguriert.

2. Build durchführen und Container bereitstellen

Dies passiert in der Grundversion von Hand (in der vollständigen Umgebung über einen Jenkins-Job).

3. Ansible-Definition für die Vagrant-Provisionierung anpassen und ins Git pushen

Der neue Microservice wird in die Provisionierungsroutine der dev VM hinzugefügt. Damit nun alle anderen Engineers diese Konfiguration erhalten, müssen diese Änderungen in das Git-Repository für die Vagrant-Umgebung gepusht werden.

4. Kollegen aktualisieren ihre lokale Vagrant-Umgebung

Über einen geeigneten Mitteilungsmechanismus (bspw. eine Mitteilung über Slack) holen sich die Kollegen (falls für ihre Teilaufgabe notwendig) den neuen Microservice mit:

git pull && vagrant provision dev

Sollte man als Software-Engineer irgendeinen merkwürdigen Stand haben, ist es vollkommen ungefährlich seine lokale Vagrant-Umgebung zurückzusetzen und alles neu bauen zu lassen:

vagrant destroy -f dev && vagrant up dev --provision

Sinn der Übung: DevOps

Software-Engineers bewegen sich vom reinen programmieren ein Stück weit in die Operations-Welt und lernen, sich mit grundsätzlichen Problematiken des Betriebs ihrer Software auseinanderzusetzen. So bleiben beliebte Kommandos wie:

docker ps -a

oder:

docker logs -f <Microservice-Name>

nicht länger ein gut gehütetes Geheimnis der System-Administratoren!

Als Gesamteffekt werden Probleme, die durch die Verwendung von Docker-Containern entstehen können, frühzeitig erkannt und beseitigt (durch das Rollout auf die lokalen Rechner der Kollegen).

Kommentar schreiben

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