Provisionieren von Container Linux VMs mittels Vagrant – Klingt einfach, ist es auch (fast)

Nach Auswahl der passenden Laufzeitumgebung für die eigene Container-Spielwiese ist der nächste logische Schritt, eine solche Sandbox auf dem eigenen Rechner aufzusetzen.

Je nach verfügbaren CPU und Speicherressourcen kann der „eigene Rechner“ vom lokalen Notebook bis hin zu einer seitens Ops bereitgestellten „Entwickler-VM“ reichen.

Meine Anforderung ist, dass ich schnell und flexibel meine Container Sandbox auf unterschiedlichen Systemen zur Verfügung stellen möchte.

Auftritt Vagrant.

Vagrant ist ein Tool, mit dem virtuelle Maschinen  beziehungsweise Umgebungen von virtuellen Maschinen erzeugt, konfiguriert und managed werden können.

Vagrant verfolgt dabei einen Infrastructure-as-Code-Ansatz. Die Erzeugung und Konfiguration der VMs geschieht nicht manuell sondern wird in Form von Code in einem sogenannten Vagrantfile beschrieben. Um den Programmcode besser strukturieren zu können, kann das Vagrantfile weitere Code-Dateien inkludieren. Der Code kann dann mittels des Vagrant CLIs verarbeitet werden.

Auf diese Weise kann man die eigenen VMs quasi „auf Knopfdruck“ erzeugen, provisionieren und starten. Und wenn man die VMs nicht mehr benötigt, können diese ebenso schnell und einfach wieder zerstört werden.

Out of the box bietet Vagrant Provider für VirtualBox, Hyper-V und Docker. Provider für weitere Virtualisierungslösungen wie VMware (kommerziell) lassen sich über einen Plugin-Mechanismus einbinden.

Randbemerkung: Fokus von Vagrant die Provisionierung von Entwicklungsumgebungen. Für komplexe produktive Umgebungen existieren Infrastructure-as-Code-Tools wie Terraform.

Im Zusammenspiel mit sogenannten Vagrant Boxes entfaltet die Vagrant Lösung dann ihren ganzen Charme.
Boxen stellen das Paketformat für Vagrant-Umgebungen dar. Mittels einer Vagrant Box kann eine identische Arbeitsumgebung auf jeder Plattform, die Vagrant unterstützt, vollautomatisiert erzeugt werden.

Wie sieht das nun ganz konkret in Bezug auf die Infrastruktur für meine Container-Spielwiese aus?

https://stable.release.core-os.net/amd64-usr/current/ gibt einen guten Überblick für welche Virtualisierungs- und Cloud-Umgebungen Container Linux Images zur Verfügung stehen.

Auf meinem Notebook nutze ich Vagrant in Verbindung mit VirtualBox.

Prinzipiell sind es vier Schritte bis zur laufenden und einsatzbereiten Container Linux VM unter Virtual Box:

  1. Clonen des offiziellen CoreOS GitHub Repositories mit einem minimalen Vagrantfile für Container Linux VMs.
  2. Konfigurieren der VM Umgebung
    1. Bei Setup eines Container Linux Clusters Konfigurieren der der Cluster-Parameter in der Datei config.ign
    2. Konfigurieren der Virtual Machine-Parameter (vcpus, vmem, CoreOS update channel, etc.) in der Datei config.rb
  3. Ausführen des Befehls vagant up
  4. Ausführen des Befehls vagrant ssh und Loslegen

Wenn man anstelle von VirtualBox beispielsweise mit VMware arbeitet, erfolgt die Cluster-Konfiguration mittels cloud-init in der Datei user-data.

Abgesehen von der Cluster-Konfiguration kann man also mit einer einzigen, relativ simplen Vagrant-Konfiguration die eigene Entwicklungsumgebung sehr schnell, einheitlich und automatisiert auf den unterschiedlichsten Betriebssystemen und Virtualisierungslösungen installieren.

In der Praxis bin ich beim Provisionieren meiner Container Linux Sandbox auf eine Unschönheit und ein Problem gestoßen.

Stand 08.05.2018 ist im CoreOS Vagrant GitHub Repository  der CoreOS Update Channel hartcodiert auf den Alpha Channel konfiguriert. Eher eine Unschönheit, widerspricht aber der offiziellen CoreOS-Dokumentation in Bezug auf die Konfiguration des Update Channels und kann Verwirrung stiften.

Problematischer ist, dass zumindest unter Windows 7 und VirtualBox in einem Szenario mit mehreren virtuellen CPUs die VM im Bootvorgang mit der Log-Ausgabe „SSH auth method: private key“ hängen bleibt.
Startet man die VM nicht mittels Vagrant sondern über die VirtualBox Administrationsapp, friert der Bootvorgang bei der Log-Ausgabe „x86: Booting SMP configuration:“ ein.
Ursache hierfür ist eine fehlerhafte Konfiguration des Paravirtualization Providers auf den Wert „legacy“.

Für beide Punkte sind Bugfixes über Pull Requests (#316 und #317) im CoreOS Vagrant GitHub Repository bereitgestellt.

Möchte man nicht warten, bis die Pull Requests akzeptiert worden sind oder möchte man das Vagrantfile und die config.rb nicht selbst patchen, kann gerne mein Repository Fork genutzt werden. Dort sind beide Pull Requests integriert.

Nächster Schritt: Installieren und Konfigurieren von Jenkins als Service auf Basis eines Docker Containers via Ansible.

Welche Infrastruktur für die eigene Container-Spielwiese? Die Auswahl ist groß.

Für Newbies wie mich, die hands on in the schöne „neue“ Container-Welt einsteigen wollen, stellt sich die Frage: „Auf welcher Infrastruktur baue ich meine Sandbox auf?“.
Kurz zur Präzisierung: Mit Container-Welt meine ich Docker und Kubernetes. Das ist für’s erste mein Fokus.

Die Auswahl ist groß.
Man kann durchaus Gefahr laufen, sich spontan für irgendein Linux mit einem aktuellen Kernel zu entscheiden. Passt ja.
Im anderen Extrem kann man sich aber auch im Lesen von Doku verlieren und vom Hundertsten ins Tausendste kommen.

Es hilft, sich zu fragen: „Was sind eigentlich meine Anforderungen?“.

Mein Ziel ist es, eine klassische Continuous Integration Pipeline mit Git, Jenkins, SonarQube und Nexus Repository auf Cloud-Infrastruktur bereitzustellen.
Die Bereitstellung soll mit Infrastructure-as-Code-Mitteln realisiert werden und sowohl eine Minimalinstallation auf meinem Notebook als auch ein fully fledged Deployment in die AWS oder Azure Cloud unterstützen.

Meine weiteren Anforderungen sind:

  • Das Betriebssystem für Docker/Kubernetes soll einem der Hauptparadigmen von Containern folgen und ebenfalls immutable sein.
  • Um in der Entwicklungs-Stage der CI-Plattform flexibel zu bleiben, möchte ich aber doch eine gewisse Flexibilität in Bezug auf die eingesetzten Versionen von Kernkomponenten wie zum Beispiel Docker haben.
  • Ich möchte das Rad nicht neu erfinden und from scratch anfangen sondern etablierte Lösungen und best practices nutzen.
  • Das auszuwählende OS soll komfortabel in der Bedienung sein. Features, die mir das Leben leichter machen und meine Produktivität steigern sind herzlich willkommen.

Und darum…
… fiel meine Wahl auf Container Linux von CoreOS.

Inzwischen hat Red Hat CoreOS akquiriert und man wird sehen müssen, wie und wo sich Container Linux insbesondere in Bezug auf Atomic in das Produktportfolio von Red Hat einfügt.

Container Linux erfüllt alle meine Anforderungen. Um nur einen Teil der zusätzlichen Goodies, die CL mitrbringt zu nennen:

  • Komfortable Installations- und Provisionierungsoptionen von Vagrant Boxen über Tectonic Installer bis Terraform (bezüglich Tectonic Installer und Terraform wahlweise bereits miteinander integriert)
  • Ein flexibles Staging Modell mit Stable, Beta und Alpha Channels
  • Den Addon-Manager torcx, falls man in der eigenen Dev Stage doch einmal die Immutabilität aufweichen möchte, um z.B. eine aktuellere Docker Version zu testen
  • Out of the box ein Release und Update Management mit Rollback Features
  • Service/Demon Konfiguration mittels file drop-ins

Nächster Schritt: vagrant up Container Linux auf meiner Notebook VirtualBox