VMs mit Vagrant erstellen

Seite 3: Konfiguration und Clusterverwaltung

Inhaltsverzeichnis

Unter Umständen kann es hilfreich sein, weitere Ordner des Wirts in der virtuellen Maschine zur Verfügung zu stellen. Dieses Feature bezeichnet Vagrant als "Shared Folders". Ihre Konfiguration erfolgt in Vagrantfile, wobei pro Verzeichnis ein weiterer Eintrag erforderlich ist:

Vagrant.configure("2") do |config|
config.vm.box = "precise64"
config.vm.box_url = "http://files.vagrantup.com/precise64.box"

config.vm.synced_folder "./foo", "/foo"

config.vm.provider :virtualbox do |vb|
vb.customize [ "modifyvm", :id, "--hwvirtex", "off" ]
end
end

Die synced_folder-Konfigurationseinstellung nimmt dabei zwei Parameter entgegen: Den Pfad des zu teilenden Verzeichnisses auf dem Wirt und den Pfad, unter dem das Verzeichnis in der virtuellen Maschine einzubinden ist.

Ausgesprochen praktisch sind geteilte Verzeichnisse für Softwareentwickler: Sie können die darin enthaltenen Datei wie gewohnt auf dem Wirtssystem mit dem Editor oder der integrierten Entwicklungsumgebung ihrer Wahl bearbeiten. Nach dem Speichern stehen die Dateien sofort in der virtuellen Maschine bereit, wo sie sich beispielsweise von einem Webserver ausliefern lassen.

Damit man auf einen Webserver in der virtuellen Maschine zugreifen kann, muss man jedoch noch zwei Anpassungen vornehmen: Zum einen benötigt die virtuelle Maschine eine IP-Adresse, über die sie sich mit dem Netzwerk verbinden lässt, zum anderen muss der benötigte Port für den Zugriff von Außen freigegeben sein.

Für die Netzwerkkonfiguration unterstützt Vagrant drei Modi: Das Weiterleiten von Ports sowie "Host Only"- und "Bridged"-Netzwerke. Die einfachste Lösung besteht im Weiterleiten von Ports. Hierbei ordnet das Tool der virtuellen Maschine keine von Außen zugängliche IP-Adresse zu, stattdessen werden lediglich interne Ports auf Ports des Wirts abgebildet. Dieses Vorgehen verwendet Vagrant serienmäßig beispielsweise bei der Abbildung des SSH-Ports 22 auf den Port 2222 des Wirts.

Natürlich verfügt die virtuelle Maschine intern dennoch über eine eigene IP-Adresse. Sie lässt sich mit der Datei Vagrantfile konfigurieren. Es genügt, ihr die folgende Zeile hinzuzufügen und die gewünschte IP-Adresse zu hinterlegen:

config.vm.network :private_network, ip: "192.168.33.100"

Um darüber hinaus eine Portweiterleitung zu konfigurieren, muss man die folgende Zeile hinzufügen und die Ports nach Bedarf anpassen:

config.vm.network :forwarded_port, guest: 3000, host: 3000

Falls der Port 3000 auf dem Wirt bereits anderweitig Verwendung findet, meldet Vagrant beim Start der virtuellen Maschine einen Konflikt. Optional kann man es anweisen, letzteren automatisch aufzulösen, indem es eigenständig einen anderen Port auswählt. Dazu muss man zusätzlich die Option auto_correct übergeben und ihr den Wert true zuweisen:

config.vm.network :forwarded_port, guest: 3000,
host: 3000, auto_correct: true

Serienmäßig sucht Vagrant im Fall des Falles dann nach einem freien Port zwischen 2200 und 2250. Auch diesen Bereich kann man bei Bedarf innerhalb des Vagrantfile konfigurieren:

config.vm.usable_port_range = (2200..2250)

Außerdem gilt es zu beachten, dass das Programm lediglich das TCP-Protokoll weiterleitet, nicht jedoch UDP. Will man letzteres ebenfalls aktivieren, muss man der Portweiterleitung zusätzlich den Parameter protocol übergeben und ihm den Wert udp zuweisen:

config.vm.network :forwarded_port, guest: 3000, 
host: 3000, protocol: "udp"

Sofern man auf dem gleichen Port sowohl TCP als auch UDP verwendet, ist die Portweiterleitung zweifach zu konfigurieren: einmal ohne und einmal mit dem protocol-Parameter.

Nachteilig an der Portweiterleitung ist, dass man jeden erforderlichen Port einzeln auflisten muss und sie anschließend im ganzen Netzwerk unter der IP des Wirtsystems erreichbar sind.

Als Alternative bietet sich daher ein "Host Only"-Netzwerk an, das abgesehen von der virtuellen Maschine ausschließlich für den Wirt zugänglich ist. Damit ist die VM vor dem wahllosen Zugriff von Außen geschützt. Essenziell bei dem Verfahren ist, dass man zwingend eine IP-Adresse vorgeben muss – andernfalls ließe sich nicht auf die Maschine zugreifen:

config.vm.network :hostonly, ip: "192.168.33.100"

Innerhalb der virtuellen Maschine steht der Wirt stets unter der IP-Adresse zur Verfügung, die lediglich im letzten Block abweicht und dort eine 1 aufweist, im angegebenen Beispiel also 192.168.33.1.

Verwendet man Vagrant, um mehrere VMs gleichzeitig zu starten, können sie bei einem "Host Only"-Netzwerk über ihre jeweiligen IP-Adressen untereinander kommunizieren – beim reinen Weiterleiten von Ports ist das nicht möglich.

Das größte Problem bei diesem Vorgehen besteht darin, dass Vagrant Kenntnisse über das virtualisierte Betriebssystem besitzen muss, um das Netzwerk richtig aufsetzen zu können. Die Variante bietet sich folglich nicht in jedem Fall an.

Zu guter Letzt besteht als dritte Herangehensweise die Option, auf ein "Bridged"-Netzwerk zurückzugreifen. Dabei wird die virtuelle Maschine als eigenständiger Teilnehmer im Netzwerk des Wirts gemeldet. Die Konfiguration erfolgt, ähnlich wie zuvor, durch die Angabe der folgenden Zeile:

config.vm.network :bridged

Das Verfahren ist ausgesprochen praktisch, weist allerdings einen gravierenden Nachteil auf: Vagrant unterstützt in diesem Modus keine statischen IP-Adressen, sodass man nach dem Start der virtuellen Maschine zunächst eine SSH-Verbindung per vagrant ssh herstellen muss, um danach ihre IP-Adresse ermitteln zu können.

Alle vorgestellten Modi und Netzwerktypen unterstützt Vagrant gleichzeitig: Es ist folglich ohne Weiteres möglich, Ports weiterzuleiten und darüber hinaus ein eigenes Netzwerk mit dem Wirt zu betreiben. Die einzige Einschränkung ist, dass Ports stets über den ersten Netzwerkadapter des Wirts weitergeleitet werden.

Ausgesprochen hilfreich ist die Fähigkeit von Vagrant, mit einer einzigen Vagrantfile-Datei mehrere virtuelle Maschinen zu verwalten. Dazu muss man die Konfigurationsdatei lediglich in weitere Abschnitte unterteilen und den einzelnen Maschinen passende Namen zuordnen:

Vagrant.configure("2") do |config|
config.vm.define("web") do |web|
web.vm.box = "precise64"
web.vm.box_url = "http://files.vagrantup.com/precise64.box"
[...]
end

config.vm.define("database") do |database|
database.vm.box = "precise64"
database.vm.box_url = "http://files.vagrantup.com/precise64.box"
[...]
end
end

Führt man das Kommando vagrant up aus, startet das Programm alle konfigurierten virtuellen Maschinen gleichzeitig. Das Gleiche gilt für die übrigen Kommandos. Möchte man ein Kommando explizit nur auf eine einzige virtuelle Maschine beziehen, muss man zusätzlich deren Namen angeben:

$ vagrant up web

Besonders interessant in dem Szenario sind die zuvor besprochenen Netzwerkmodi "Host Only" und "Bridged", die das Zusammenspiel mehrerer virtueller Maschinen ermöglichen.