Reproduzierbare Virtual Machines für die Cloud – und den Desktop YAML-basierte VM-Konfiguration mit cloud-init

Von Mirco Lang Lesedauer: 5 min

Anbieter zum Thema

Schon einmal eine virtuelle Maschine konfiguriert? Dank cloud-init ist das nur noch ein einziges Mal erforderlich – danach heißt es: Klick, fertig.

Mithilfe von cloud-init lässt sich eine VM per YAML beschreiben und immer gleich konfiguriert bereitstellen.
Mithilfe von cloud-init lässt sich eine VM per YAML beschreiben und immer gleich konfiguriert bereitstellen.
(Bild: Canonical)

Cloud-init ist ein Projekt von Canonical und beschreibt sich selbst wie folgt: „Cloud-init ist die branchenübliche Multi-Distributionsmethode für die plattformübergreifende Initialisierung von Cloud-Instanzen.“ Hier war zwar vermutlich die Übersetzung von DeepL am Werk, im Original klingt es aber deshalb nicht weniger blumig.

Einfacher ausgedrückt: Cloud-init ermöglicht die komplette Konfiguration von virtuellen Maschinen (VMs) per simpler Textdatei. Mit Cloud-Instanzen ist freilich nichts anderes gemeint als VMs, die bei Cloud-Anbietern wie AWS, Azure oder GCC laufen. Im Grunde nur mit einer Besonderheit, nämlich dass die VMs oft flüchtig (ephemeral) sind, sprich nur kurz laufen und dann wieder gelöscht werden.

Die Initialisierung wiederum meint einfach die Konfiguration, sprich alles abseits der Hardware-Ausstattung: Netzwerkverbindungen, Einstellungen, installierte Software, Userprofile und so weiter. Und „Multi-Distribution“ heißt hier wohl nichts anderes, als dass man mehrere identisch konfigurierte VMs gleichzeitig erstellen lassen kann.

Plattformübergreifend bedeutet, dass so ziemlich alle großen Cloud-Anbieter unterstützt werden; neben den bereits erwähnten unter anderem noch Oracle, UpCloud, VMware, OpenNebula, insgesamt rund 25 an der Zahl. Und auch bezüglich der unterstützten Betriebssysteme für die VMs gibt es kaum Einschränkungen, 26 Distributionen werden aufgeführt, neben Selbstverständlichkeiten wie Debian, Ubuntu, RHEL, Arch Linux und Fedora auch openEuler, Rocky, Virtuozzo sowie die gängigen BSD-Systeme.

Cloud-init mal sehr rudimentär erklärt: „Liebe IT-Abteilung, wir brauchen mehrere VMs mit SSH-Zugriff durch Server X, Apache-Webserver, gemounteten Netzlaufwerken, Software-Paketen gemäß anhängender Liste, dem Nutzer foobar und einer RHEL-Registrierung.“ Cloud-init ist nichts weiter als eine solche Anfrage – nur eben formalisiert und an ein unterstütztes System.

Cloud-init in der Praxis

Die einfachste Möglichkeit, mit cloud-init zu spielen, bietet vermutlich Multipass, ebenfalls ein Canonical-Projekt und hier vor einiger Zeit schon vorgestellt. Mit Multipass lassen sich lokal „Cloud-Instanzen“ erzeugen, sprich VMs, die optional mittels cloud-init eingerichtet werden können. Das funktioniert unter Windows ebenso wie unter Linux.

Standardmäßig erzeugt Multipass VMs mit Ubuntu 22.04, Hardware-Ausstattung und Netzwerkverbindung werden einfach über Optionen angegeben:

multipass launch --mem=2G --cpus=2 --name testvm1 --network name=LAN-Verbindung

Hier wird also eine Ubuntu-VM mit 2 GB RAM, 2 CPUs und der (Windows-)Standard-Netzwerkverbindung „LAN-Verbindung“ erzeugt.

Soll nun eine Konfiguration über cloud-config vorgenommen werden, wird die Config-Datei ebenfalls „multipass launch“ übergeben:

multipass launch --mem=2G --cpus=2 --name testvm1 --network name=LAN-Verbindung -- cloud-init testconf.ini

Die gesamte cloud-init-Arbeit spielt sich in dieser „testconf.ini“ ab – einer YAML-Datei. Falls YAML (YAML Ain’t Markup Language, früher: Yet Another Markup Language …) kein Begriff ist: YAML ist eine an XML angelehnte Sprache zur maschinenlesbaren Darstellung von Datenstrukturen.

Diese Darstellung kann bisweilen etwas frickelig sein: Achten Sie unbedingt auf korrekte Einrückungen. Zwar ist es in der Regel egal, ob Items zwei, vier oder auch drei Leerzeichen eingerückt werden, aber es muss über das gesamte Dokument konsistent sein – Einrückung ist Teil der YAML-Syntax! Ein Leerzeichen zu viel oder zu wenig führt umgehend zu Fehlern.

Cloud-config bietet rund 60 Module, die allgemeine Dinge wie Nutzer, aber auch eher spezielle Aspekte wie den textbasierten Fenstermanager Byobu verwalten. Eine einfache Version könnte zum Beispiel schlicht ein Kommando in der neu erstellten Multipass-VM ausführen:

#cloud-config
runcmd:
   - echo „Hello World!“
   - echo „Ende“

Die Shebang-Zeile ist erforderlich. Anschließend wird das Modul „runcmd“ (run command) aufgerufen, welches schlicht die darauffolgenden Kommandos ausführt.

Hier mal ein praktisches Beispiel, das folgende Aufgaben erledigen soll:

  • „Hello, World!“ ausgeben
  • Die Pakete git und apache2 installieren
  • Standard-Nutzer („ubuntu“) und Nutzer „peter“ einrichten
  • Passwortlosen Zugriff vom Server „myserver“ für Nutzer „peter“ ermöglichen
  • Ein Netzlaufwerk (Samba-Share) „myserver/myshare“ mounten
  • Eine Nachricht in den Installationslog schreiben

Formuliert per YAML:

#cloud-config
runcmd:
   - echo 'Hello, World!'
packages:
   - git
   - apache2
users:
   - default
   - peter
ssh_authorized_keys:
   - ssh-rsa AAAAB3... peter@myserver
mounts:
   - [ //192.168.178.1/myshare, /media/myshare, cifs, "defaults,uid=1000,username=peter,password=peter" ]
final_message: |
   cloud-init done
   Version: $version
   Timestamp: $timestamp
   Datasource: $datasource
   Uptime: $uptime

Das Modul „packages“ wird hier lediglich zum Installieren von Paketen genutzt, kann über die Aufrufe „package_update“ und „package_upgrade“ aber auch aktualisieren.

An dieser Stelle ist auch die Plattformunabhängigkeit schön zu sehen. In früheren Versionen hieß es etwa noch „apt_update“, nun wird auf den jeweils passenden Paketmanager abgezielt. Für die Konfiguration der Paketmanager, bspw. apt, yum/dnf oder zypper, stehen dann jeweils eigene Module zur Verfügung.

Jetzt Newsletter abonnieren

Täglich die wichtigsten Infos zu Softwareentwicklung und DevOps

Mit Klick auf „Newsletter abonnieren“ erkläre ich mich mit der Verarbeitung und Nutzung meiner Daten gemäß Einwilligungserklärung (bitte aufklappen für Details) einverstanden und akzeptiere die Nutzungsbedingungen. Weitere Informationen finde ich in unserer Datenschutzerklärung.

Aufklappen für Details zu Ihrer Einwilligung

Das Modul „users“ hat natürlich auch noch deutlich mehr zu bieten. Hier lässt sich die komplette Bandbreite der Konteneinstellungen nutzen, etwa Gruppenzugehörigkeiten, Nutzerinformationen, Passwörter, Home-Verzeichnisse, spezifische Nutzer-Shell, sudo-Zugehörigkeit etc.

Wirklich interessant ist aber das Modul „ssh_authorized_keys:“. Hier ist es möglich, die Inhalte von öffentlichen SSH-Schlüsseln zu hinterlegen (oben freilich in gekürzter Form), um umgehend passwortlosen Zugang für bestimmte Nutzer zu gewähren. Praktisch wäre das zum Beispiel für automatische Konfiguration via Ansible, welches sich standardmäßig über SSH mit den zu verwaltenden Hosts verbindet.

Das „mounts“-Modul macht ebenfalls genau das, was zu erwarten ist: Es schreibt Einträge in die fstab – lediglich die Trennung via Komma unterscheidet sich hier von händischen Einträgen.

Man sieht an diesen Beispielen eindrücklich, was cloud-init im Wesentlichen tut: Standard-Befehle ausführen. Nur, dass es beispielsweise abstrakt „packages: apache2“ heißt, statt systemspezifisch „apt install apache2“. Man könnte sagen, cloud-init ist letztlich „nur“ eine Abstraktionsschicht für das, was Admins ansonsten händisch in der ersten halben Stunde nach Aufsetzen einer VM erledigen… oder auch am ersten Tag.

Weitere Funktionen

Die einzelnen Module schauen Interessierte am besten selbst durch, die Cloud-init-Modulreferenz ist sehr übersichtlich und erfreulicherweise meist mit praktische Beispielen angereichert. Um den Facettenreichtum zu verdeutlichen, hier aber noch ein paar Highlights.

Über das Ansible-Modul können Playbooks via ansible-pull ausgeführt werden – dann auch ohne SSH-Zugang. Es gibt ein Modul „Byobu“, über das der bereits erwähnte Fenstermanager konfiguriert werden kann – schon sehr speziell. Mächtig ist das Modul „Phone Home“, über das Daten an eine URL geschickt werden können.

Ähnlich mächtig ist „Scripts per Boot“, das erwartungsgemäß beliebige Skript beim Start einer Instanz ausführt – wohlgemerkt bei jedem Start! Die meisten Module laufen „Once per Instance“, also einmalig bei der Einrichtung. Optional können sie aber auch („Always“) bei jedem Start aktiv sein. So ließen sich zum Beispiel via „Phone Home“ nach jedem Start Daten an eine API senden.

Zu guter Letzt: Cloud-init hat auch eine Kommandozeilen-Schnittstelle, um beispielsweise einzelne Module auszuführen, cloud-config-Dateien zu prüfen, Logs zu analysieren und so weiter.

Cloud-init ist ein wunderbares Werkzeug, um „Infrastructure as Code“ zu verstehen und umzusetzen. Und das übrigens nicht bloß in großem Maßstab, selbst für lokale Testumgebungen auf dem Desktop ist die Kombination cloud-init plus Multipass unschlagbar.

(ID:49641362)