Vagrant

Gliederung

1. Definition
2. Installation und Konfiguration
3. Abgrenzung / Vergleich
4. Vor- und Nachteile
5. Demonstration

Definition

Vagrant ist ein Open-Source-Tool (MIT-Lizenz) zum Erstellen und Verwalten von virtuellen Maschinen. Es wurden von Mitchell Hashimoto und John Bender entwickelt. Die Steuerung von Vagrant erfolgt über eine Shell.

Es kommt ein einziger konsistenter Workflow zum Einsatz. Somit legt Vagrant den Fokus auf Automatisierung. Die Zeit für die Einrichtung virtueller Umgebungen wird deutlich verkürzt, da bestehende Vorlagen genutzt werden können. Somit kann die Produktivität und Flexibilität sowohl im betrieblichen als auch im privaten Umfeld gesteigert werden.

Eine virtuelle Maschine ist die Softwareimplementierung eines Computers mit einer virtuellen Festplatte und einer CPU. Ein vollständiges Betriebssystem kann durch eine Virtualisierungssoftware ausgeführt werden. Der Computer, auf welchem die Software ausgeführt wird, ist das Hostsystem. Das Gastsystem ist die virtuelle Maschine, die durch die Virtualisierungssoftware bereitgestellt wird. Aus Sicht des Hostsystems werden alle Ressourcen des Gastes von der Virtualisierungssoftware verwendet.

Durch Boxen werden Vorlagen für die virtuellen Maschinen bereitgestellt. Diese können lokal vorhanden sein oder aus dem Internet geladen werden.

Die von Vagrant erstellten virtuellen Maschinen werden mittles Virtualisierungssoftware wie VirtualBox, VMware oder AWS bereitgestellt. Im Rahmen des Projektes wird mit VirtualBox gearbeitet. VirtualBox ist Open-Source (GPLv2-Lizenz). Das Erweiterungspaket von VirtualBox verfügt über eine sparte Lizenz, wird jedoch für die Verwendung von Vagrant nicht benötigt. Wurde die verwendete Box jedoch mit dem Erweiterungspaket erstellt, so muss es auch installiert sein.

Vagrant ist in der Programmiersprache Ruby geschrieben. Diese kombiniert Teile der Sprachen Perl, Smalltalk, Eiffel, Ada und Lisp. Es handelt sich um eine dynamisch typisierte objektorientierte Skriptsprache.

Installation und Konfiguration

Installation

Die Installation von Vagrant ist unter Windows 10 und Linux Distributionen recht einfach und erfolgt in zwei Schritten.
Damit Vagrant die VM erzeugen und starten kann wird ein Hypervisor benötigt.
Standardmäßig wird dafür Oracle VirtualBox verwendet.
Auf Debian Linux Systemen kann dieser Schritt mit:
sudo apt update && sudo apt install VirtualBox
ausgeführt werden.

Sobald ein Hypervisor installiert ist, kann man entweder auf die leicht veraltete Version (2.0.2 bei Ubuntu bionic; 2.2.6 bei Ubuntu Focal) aus den normalen Package Management System zurückgreifen oder das Paket mit curl von der offiziellen Seite herunterladen:
curl -O https://releases.hashicorp.com/vagrant/2.2.14/vagrant_2.2.14_x86_64.deb
Für die aktuellste Version muss leider händisch auf der Webseite von Hashicorp nachgesehen werden.
Die *.deb Datei kann danach mit dem Befehl:
sudo apt install ./vagrant*.deb
installiert werden.

Für Windows und ebenso für andere Linux Distributionen werden auf der Offiziellen Webseite https://www.vagrantup.com/downloads die benötigten Installationsprogramme angeboten.

Bei der Installation unter Windows7 sind leider Probleme aufgetreten, da Vagrant eine PowerShell >= Version 3 benötigt und das nicht mehr mit Windows 7 kompatibel ist.

Sobald Vagrant installiert ist, kann man sich seine Version von der Kommandozeile ausgeben lassen mit:
Vagrant--version
Sofern eine Bash oder eine zsh verwendet wird, kann eine Autovervollständigung installiert werden.
vagrant autocomplete --bash --zsh

Eine komplette Anleitung für Linux kann man ebenfalls dieser Webseite entnehmen.
https://linuxize.com/post/how-to-install-vagrant-on-ubuntu-20-04/

Konfiguration

Die Konfiguration findet über die Datei „Vagrantfile“ statt.
Darin wird die zu erstellende VM mithilfe von Ruby beschrieben, sodass eine Mehrfachausführung immer zu dem gleichen Ergebnis führt.
Bei der Suche nach einem Vagrantfile steigt Vagrant im Dateibaum auf, bis es eins gefunden hat.
Außerdem hat der Nutzer an diesen Stellen die Möglichkeit eine zusätzliche Konfiguration vorzunehmen.
Ein später aufgeführter Punkt überschreibt lediglich abweichende Konfigurationen.

1. Vagrantfile packaged with the box that is to be used for a given machine.
2. Vagrantfile in your Vagrant home directory (defaults to ~/.vagrant.d). This lets you specify some defaults for your system user.
3. Vagrantfile from the project directory. This is the Vagrantfile that you will be modifying most of the time.
4. Multi-machine overrides if any.
5. Provider-specific overrides, if any.

Die Konfiguration der VM beginnt in einem Vagrantfile mit einem:

Vagrant.configure("1") do |config|
# v1 configs...
end

Vagrant.configure(„2“) do |config|
# v2 configs…
end

Der hier gezeigte Inhalt kann in einem Vagrantfile stehen, da Vagrant die verschiedenen Konfigurationsversionen in einer Datei zusammenfüht.

Abgrenzung / Vergleich

Mit welchen anderen Softwarelösungen und -konzepten kann Vagrant verglichen werden?

  • Nutzung von CLI-Tools zum Anlegen und Konfigurieren von VMs
  • Containervirtualisierung mit Docker zum Isolieren einzelner Anwendungen
  • Terraform zum Beschreiben von komplexen Infrastrukturen
  • Kubernetes zur Verwaltung, Konfiguration und Automatisierung von Containern

CLI-Tools

Hierbei geht es darum, mit Hilfe verschiedener Command Line Interface-Tools (von VirtualBox oder VMware) Virtuelle Maschinen anzulegen und zu konfigurieren. Dies geschieht in der Regel über Befehle und Skripte, die manuell ausgearbeitet und ausgeführt werden. Der hieraus resultierende Workflow ist für den Entwickler meist aufwändig, da es für die Konfiguration einer VM verschiedene CLI-Programme benötigt. Durch die manuelle Komponente ist die Arbeit mit CLI-Tools auch recht fehleranfällig.

Vagrant erweitert die Möglichkeiten der CLI-Tools um nützliche Features, wobei alle Konfigurationen zu einer Virtuellen Maschine in einer Datei (Vagrantfile) festgehalten werden. So können beispielsweise synchronisierte Ordner mit dem Hostsystem oder in der VM benötigte Programme, die schon installiert werden sollen, in dem Vagrantfile beschrieben werden, wodurch nach Ausführen von vagrant up die Virtuelle Maschine mit genau den beschriebenen Eigenschaften erstellt wird. Das Praktische an Vagrant ist dabei, dass man sich nicht mit den möglicherweise unterschiedlichen Versionen der Virtualisierungssoftware auseinandersetzen muss, wobei sich die Befehle der CLI ändern könnten. Vagrant erkennt die genutzten Versionen und setzt die korrekten Flags und Befehle. Dadurch können Vagrantfiles einfach auf verschiedenen Rechnern mit unterschiedlichen Versionen der Virtualisierungssoftware ausgeführt werden, ohne dass eine Änderung nötig ist.

Docker

Docker arbeitet mit sogenannten Containern, welche sich von Virtuellen Maschinen unterscheiden. Docker-Container sind im Vergleich zu VMs leichtgewichtig und werden vom Betriebssystem des Hosts abgeschottet. Sie enthalten meist nur eine einzige Anwendung, die beim Hochfahren des Containers gestartet wird, und die dazugehörigen Ressourcen (Datenbank, benötigte Bibliotheken für die Anwendung). Außerdem haben Docker-Container kein eigenes Betriebssystem und benötigen weniger Ressourcen als VMs, weshalb ein schnelleres Starten und Stoppen möglich ist.

Auf Grund dessen muss bei einer Differenzierung zwischen Vagrant und Docker hauptsächlich auf die Unterschiede von Virtualisierung und Containerisierung geachtet werden. Virtualisierung ermöglicht es mehreren virtuellen Maschinen, sich ein Hardware-System zu teilen. Jede dieser VMs bekommt ein eigenes Betriebssystem, eigenen Speicher usw. Im Kontext der VM und ihres Betriebssystems können dann Anwendungen gestartet werden. Die Containerisierung bietet im Gegensatz dazu eine granularere Aufteilung der Anwendungen und ist leichtgewichtiger. Dadurch können Container auch problemlos auf Entwicklungsrechnern verwendet werden (mit VMs ist dies auch möglich, jedoch recht ressourcenintensiv). Auch muss beachtet werden, dass bei der Containerisierung nur der Kernel genutzt werden kann, der beim Host-System verfügbar ist. Dadurch kann beispielsweise kein Windows-Container auf einem Linux-Host gestartet werden.

Man kann hierbei jedoch auch differenzieren, ohne auf die Unterschiede von VMs und Containern zu achten. Docker ist an sich ein Kommandozeilentool, mit dem eigene Docker-Container verwaltet werden können. Vagrant bietet mit seinen CLI-Befehlen einen konsistenten Workflow zum Einrichten von Entwicklungsumgebungen. Dafür bietet Vagrant einen Wrapper fürs Erstellen von Virtuellen Maschinen mit Virtualisierungssoftware wie VMware oder VirtualBox. Docker hingegen arbeitet eigenständig und kann durch Tools wie Kubernetes erweitert werden

Zusammenfassend kann man sagen, dass sowohl Docker als auch Vagrant eigene Einsatzgebiete haben, für die sie besser geeignet sind.

Terraform

Vagrant und Terraform sind beides Projekte von HashiCorp, die unterschiedliche Einsatzgebiete haben. Terraform dient hauptsächlich dem Beschreiben und Managen von großen Infrastrukturen, die remote oder lokal vorliegen können. Dabei wird es als Infrastructure-as-code-Software bezeichnet, was für eine programmierbare Infrastruktur steht, die über eine Software erstellt und verwaltet werden kann.

Da bei Terraform unter anderem ein Feature zum Managen von Virtuellen Maschinen integriert ist, können Vagrant und Terraform recht schnell verwechselt werden. Vagrant wurde zum automatisierten Erstellen von Entwicklungsumgebungen entwickelt, weshalb es deutlich mehr Features in diese Richtung bietet (HTTP-Tunnel, Synchronisierte Ordner mit dem Hostsystem, …) als Terraform. Terraform hat ein potentiell größeres Einsatzgebiet mit ganzen Infrastrukturen, weshalb es sich nur rudimentär mit dem Einrichten Virtueller Maschinen befasst.

Kubernetes

Kubernetes dient dem Verwalten von Containern und containerisierten Anwendungen. Demzufolge gelten für den Vergleich (von Kubernetes und Vagrant) auch hier die Unterschiede zwischen Containerisierung und Virtualisierung. Wenn man jedoch die grundlegenden Funktionalitäten der Anwendungen betrachtet, sind sich Kubernetes und Vagrant in einigen Punkten ähnlich. Beide Tools sind Open Source und dienen der Verwaltung von Virtuellen Maschinen / Containern. Beide Tools sind für das Konfigurieren, Starten und Stoppen der jeweiligen Technologie zuständig und bedienen sich hierfür der Kommandozeile und eigenen Konfigurationsdateien. Kubernetes nutzt zur Beschreibung und Gruppierung von Containern das YAML-Format, wohingegen Vagrant eigene Vagrantfiles hat, um Boxes zu erstellen.

Vor- und Nachteile von Vagrant

Vorteile Nachteile
Open-Source-Software (MIT Lizenz) Benötigt externe Virtualisierungssoftware zur Erstellung von Virtuellen Maschinen (z.B. VirtualBox, VMware)
Vagrant ist dezentralisiert (jeder kann mit Vagrant Boxes erstellen, die bei jedem anderen Nutzer von Vagrant laufen sollten) Verschiedene Kombinationen von Vagrantversionen, Betriebssystemversionen und Versionen von Virtualisierungssoftware können zu Fehlern führen
Automatisierung verschiedener VM-Management-Tasks, wie zum Beispiel Installation und Konfiguration Kompatibilität mit Windows schwierig (auf Windows 7 hat es für uns nicht funktioniert, mit Windows 10?)
Umgebungen, die mit den selben Vagrantfiles erstellt wurden, sind i.d.R. exakt gleich, sodass die Entwicklungsumgebungen bei mehreren Entwicklern sich nicht unterscheiden (kein „Bei meinem System funktioniert es aber!“ mehr) Für kleine Projekte, an denen nur ein Entwickler beteiligt ist, müssen Kosten und Nutzen abgewogen werden
Erleichtert das Updaten oder Austauschen von Versionen

Demonstration

In unserem Arbeitsverzeichnis können wir mit folgendem Befehl ein vorgefertigtes Vagrantfile herunterladen.
In desem Fall ein offizielles von HashiCorp bereitgestelltes Vagrantfile für ein Ubuntu 18.04 LTS 64-bit Image.


    $ vagrant init hashicorp/bionic64
  

Ein Blick in die Datei zeigt die Minimalfassung eines Vagrantfiles. Diese werden wir später noch erweitern.


    Vagrant.configure("2") do |config|
      config.vm.box = "ubuntu/bionic64"
    end
  

Mit ‚vagrant up‘ starten wie die VM. Vagrant lädt das Ubuntuimage herunter und startet es as VirtualBox VM.

$ vagrant up

Um sicherzustellen, dass alles funktioniert, können wir eine SSH-Verbindung zur VM herstellen.

$ vagrant ssh

Mit dem Befehl ‚logout‘ verlässt man die SSH-Session. Alternativ müsste die VM auch in der GUI von VirtualBox angezeigt werden.

Vagrant synchronisiert den Inhalt des Projektordners (der das Vagrantfile enthält) mit dem Ordner ‚/vagrant‘ in der VM. Das ermöglicht es die VM als virtuelle Entwicklungsumgebung zu verwenden, aber dennoch den bevorzugten Editor auf dem Hostsystem zu verwenden, um Dateien zu bearbeiten.

Die Synchronisation funktioniert in beide Richtungen.

Aufsetzen eines Webservers

Als nächstes werden wir einen Apache-Webserver in der VM bereitstellen.

Dazu erstellen wir uns erst einmal einen Ordner im Projektverzeichnis.

$ mkdir html

Darin erstellen wir die Datei ‚index.html‘ mit einfachem HTML-Gerüst.


    <!DOCTYPE html>
    <html>
      <body>
        <h1>Getting started with Vagrant!</h1>
      </body>
    </html>
  

Um Apache in der VM zu installieren könnte wir dies manuell per SSH machen, müssten diese Schritte jedoch wiederholen, sobald wir das Image bspw. löschen und später neu anlegen.

Einfacher geht dies mit einem Shellscript. Dazu legen wir im Projektordner die Datei ‚bootstrap.sh‘ mit folgendem Inhalt an:

#!/usr/bin/env bash

apt update
apt install -y apache2
if ! [ -L /var/www ]; then
  rm -rf /var/www
  ln -fs /vagrant /var/www
fi

Das Script installiert das apache2-Package und erstellt einen Symlink zwischen unserem synchroniserten Ordner und dem Verzeichnis ‚/var/www‘, wo Apache unsere ‚index.html‘ finden kann.

Jetzt müssen wir Vagrant noch mitteilen, dass dieses Shellscript beim Erstellen des Images ausgeführt werden soll. Dazu ändern wir das Vagrantfile, wie folgt ab:


Vagrant.configure("2") do |config|
  config.vm.box = "hashicorp/bionic64"
  config.vm.provision :shell, path: "bootstrap.sh"
end

Da unsere Ubuntu-VM bereits läuft, reicht ein reload mit dem ‚provision‘ Flag, um die Änderungen anzuwenden.

$ vagrant reload --provision

Jetzt sollten wir im Log sehen, dass Apache2 installiert wird.

Port Forwarding

Damit die von Apache bereitgestellte Website auch außerhalb der VM aufgerufen werden kann müssen wir ein Port-forwarding für Port 80 einrichten. Dazu fügen wir folgende Zeile in das Vagrantfile ein…

config.vm.network :forwarded_port, guest: 80, host: 4567

und laden die VM neu:

$ vagrant reload

Jetzt können wir auf der Host-Maschine die Website unter http://127.0.0.1:4567 aufrufen.

Beenden einer VM

Stoppt die VM und speichert deren aktuellen Stand.

$ vagrant suspend

Startet die VM und setzt deren gespeicherten Stand fort.

$ vagrant suspend

Startet den Shutdownprozess des Betriebssystems in der VM und stoppt die VM.

$ vagrant halt

Jetzt startet der Befehl die VM frisch neu.

$ vagrant up

Stoppt die VM und löscht sie von der Host-Maschine.

$ vagrant destroy

Literaturverzeichnis

„Über Ruby,“ [Online]. Available: https://www.ruby-lang.org/de/about/. [Zugriff am 05. Januar 2021].

„Vagrant Documentation,“ [Online]. Available: https://www.vagrantup.com/docs. [Zugriff am 05. Januar 2021].

S. Kumar, „How To Use Vagrant With Libvirt KVM Provider,“ 27. August 2020. [Online]. Available: https://ostechnix.com/how-to-use-vagrant-with-libvirt-kvm-provider/. [Zugriff am 09. Januar 2021].

„How to Install Vagrant on Ubuntu 20.04,“ 02. Juni 2020. [Online]. Available: https://linuxize.com/post/how-to-install-vagrant-on-ubuntu-20-04/. [Zugriff am 09. Januar 2021].

„Vagrant vs. Other Software,“ [Online]. Available: https://www.vagrantup.com/intro/vs. [Zugriff am 08. Januar 2021].

J. Palat, „Introducing Vagrant,“ 14. November 2021. [Online]. Available: https://www.linuxjournal.com/content/introducing-vagrant. [Zugriff am 05. Januar 2021].

Anhänge

Vortrag Vagrant