Instant VM Management mit Vagrant

Veröffentlicht am 17. April 2013 von Julien Gantner

Jeder, der Software von der Entwicklung bis in den Betrieb begleitet hat weiß, dass dies oft ein schwieriges Unterfangen ist. Es muss mit der Administration die Rahmenbedingungen für den Betrieb ausgehandelt werden, Serverspezifikationen geschrieben, die Server installiert und konfiguriert werden. Themen wie Ausfallsicherheit und Verfügbarkeit müssen besprochen und festgelegt werden.

Die Installation und Konfiguration der Server wird heute vielerorts noch händisch durchgeführt und ist somit fehleranfällig. Doch wie kann man diesen Zustand verbessern? Wie auch in der Softwareentwicklung liegt die Lösung in der Transparenz und Überprüfbarkeit. Unit- und Acceptance-Tests sind heute gängig und gehören zum guten Stil in der Softwareentwicklung.Damit die Kosten im Rahmen bleiben, empfielt es sich diese weitgehend zu automatisieren. Für die Infrastruktur geht der Trend in dieselbe Richtung. Viele Unternehmen setzen aus Kostengründen schon Infrastrukturvirtualisierung ein. “Infrastructure as Code” und “DevOps” sind neue Schlagworte die Techniken beschreiben, mit denen die Serverspezifikationen ausführbar gemacht werden. Diese bringen folgende Vorteile:

  1. Geringere Fehleranfälligkeit: Wird die Spezifikation von einer Maschine ausgeführt, verschwinden Fehler die daraus resultieren, dass die Konfiguration aus der Spezifikation fehlerhaft übertragen wurde.
  2. Transparenz: Liegt die Spezifikation in ausführbarer Form vor, können diese Konfig-Scripte unter Versionskontrolle gestellt werden. Sie sind damit auditierbar und jede Änderung ist dokumentiert.
  3. Effizienz: Ist die komplette Server- und Infrastrukturkonfiguration automatisert, sind die Kosten, einen weiteren Server zu installieren, minimal.
  4. Testbarkeit: Analog zu Softwaretests ist es möglich auch die automatisierte Serverkonfiguration automatisiert zu testen.

Dieser Blogpost ist der erste in einer Reihe, die sich mit dem Thema Infrastrukturautomatisierung beschäftigt und einige Werkzeuge in dessen Umfeld beleuchtet.

Um sich weiter mit dem Thema automatisierte Installation und Konfiguration beschäftigen zu können benötigt man zunachst einen Server der installiert bzw. konfiguriert werden soll. Vagrant ist ein Werkzeug mit dem sich Virtuelle Maschinen beschreiben und erzeugen lassen. Vagrant benutzt standardmäßig Oracles VirtualBox als Virtualisierungsplattform. Seit der Version 1.1 ist es möglich Treiber (sog. Provider) als Plug-Ins hinzuzufügen und es gibt unter anderem einen Treiber für VMware Fusion und Amazon web services.

Ich möchte hier die Verwendung von Vagrant in Verbindung mit VirtualBox an einem Beispiel vorstellen und an den passenden Stellen Konzepte und Terminologien erklären.

In diesem Blogpost verwendete Technologien

Als Hostsystem dient ein Mackbook Pro mit Os X 10.8.2. VirtualBox kommt in der Version 4.2.12-r84980 und Vagrant in der Version 1.1.5 zum Einsatz. Als Gastsystem wird ein Ubuntu-Server 12.04 LTS verwendet.

Los gehts

Vagrant bietet auf seiner Website Installationpakete für gängige Systeme an. Die Installtion ist einfach und wird hier nicht näher erläutert. Die Installation von VirtualBox ist ähnlich einfach, die Installationsdateien finden sich auf der VirtualBox-Webseite.

Nachdem die Werkzeuge installiert sind benötigen wir ein Projektverzeichnis, in dem die Vagrant-Konfiguration abgelegt wird (hier ~/vagrant_demo). Zum Anlegen einer Konfiguration stellt Vagrant den Befehl vagrant init zur Verfügung:

          
            jgantner@macbook:~$ cd vagrant_demo

            jgantner@macbook:~/vagrant_demo$ vagrant init

            A `Vagrantfile` has been placed in this directory. You are now
            ready to `vagrant up` your first virtual environment! Please read
            the comments in the Vagrantfile as well as documentation on
            `vagrantup.com` for more information on using Vagrant.

            jgantner@macbook:~/vagrant_demo$ ls -la

            total 16
            drwxr-xr-x  3 jgantner  1361259469   102 15 Apr 14:39 .
            drwxr-xr-x  4 jgantner  1361259469   136 15 Apr 14:06 ..
            -rw-r--r--  1 jgantner  1361259469  4339 15 Apr 14:39 Vagrantfile

Das erzeugte Vagrantfileist die zentrale Konfigurationsdatei für dieses Projekt. In Ihm werden die Virtuellen Maschinen konfiguriert. In unserem Beispiel nur eine, mehrere sind aber auch möglich.

Vagrant nutzt eine DSLzum Beschreiben der Virtuellen Maschinen. Kernstück des Vagrantfiles ist der configure Block:


          Vagrant.configure("2") do |config|
            # hier werden die verschiedenen Einstellungen gemacht
          end

Der Parameter "2" des configure-Aufrufs aktiviert die neue Konfigurations-DSL, die für Vagrant ab der Version 1.1 zur Verfügung steht und mit der Version 2.0 die vorherige DSL ablöst.

Vagrant Box

Eine Vagrant Boxist, frei übersetzt aus der Dokumentation, ein Grundgerüst aus dem die Virtuellen Maschinen mit Vagrant erstellt werden. Man kann die Boxen als Basis Image verstehen. Sie beinhalten in der Regel eine Virtuelle Festplatte des Virtualisierungsproviders und einige Basiseinstellungen für diese VM. Auf der Seite Vagrantbox.es gibt es für viele Betriebssysteme Basisboxen. Diese sollten aber nur zu Entwicklungs- oder Testzwecken verwendet werden, da sie alle den Vagrant insecure Public Key beim vagrant-user eingetragen haben, dessen private Key mit Vagrant geliefert wird. Dies ermöglicht einen schnellen Start, ist für Server die von außen erreichbar sein sollen aber ein erhebliches Sicherheitsrisiko. Für den produktiven Einsatz empfiehlt es sich eine Basisbox für das jeweilige Unternehmen anzufertigen.

Der Demo-Server

Unser Demo-Server soll ein Basis Ubuntu 12.04 LTS sein mit 512 MB Hautpspeicher und einem privaten Netzwerk mit fester IP-Adresse. Der Hostname soll auf demo-server gesetzt werden. Die dazu notwenige Konfiguration könnte z.B. so aussehen:

          
            Vagrant.configure("2") do |config|
              # Every Vagrant virtual environment requires a box to build off of.
              config.vm.box = "precise64_squishy_2013-02-09"
            end
          
          
            # The url from where the 'config.vm.box' box will be fetched if it
            # doesn't already exist on the user's system.
            config.vm.box_url = "https://s3-us-west-2.amazonaws.com/squishy.vagrant-boxes/precise64_squishy_2013-02-09.box"
          
          
            # Configure the hostname
            config.vm.hostname = "demo-server"
          
          
            # Create a private network, which allows host-only access to the machine
            # using a specific IP.
            config.vm.network :private_network, ip: "192.168.33.10"
          
          
            # Provider-specific configuration so you can fine-tune various
            # backing providers for Vagrant. These expose provider-specific options.
            # Example for VirtualBox:
            #
            config.vm.provider :virtualbox do |vb|
              # Use VBoxManage to customize the VM. For example to change memory:
              vb.customize ["modifyvm", :id, "--memory", "512"]
            end
          end

Nachdem das Vagrantfile gespeichert wurde genügt ein vagrant up und Vagrant startet eine VM mit dem angegebenen Basis Image. Falls die angegebene Box nicht in den Vagrant bekannten Boxen gefunden wird, importiert Vagrant die Box von der angegebenen Url. Nachdem der Befehl vollständig ausgeführt wurde ist der Server bereit um benutzt zu werden. Mit Hilfe von vagrant ssh kann man sich auf der Maschine mittels ssh einloggen. Um die so gestarteten Server wieder herunter zu fahren kann der Befehl vagrant halt verwendet werden. Möchte man die Virtuelle Maschine wieder löschen genügt ein vagrant destroy. Dabei wird die Virtuelle Maschine, aber nicht das Vagrantfile gelöscht. Das bedeutet, dass man mit einem erneuten vagrant up wieder mit einer frisch installierten VM vom Basis Image anfängt.

In der Praxis eignen sich solche VM’s vor allem um Infrastruktur-Automatisierung zu testen oder neue Tools auszuprobieren. Vagrant macht die VM erstellung so einfach, dass eine Server-Installation inklusive Startvorgang in weniger als einer Minute zu erledigen ist.

          
            jgantner@macbook:~/vagrant_demo:$ time vagrant up

            Bringing machine 'default' up with 'virtualbox' provider...
            [default] Importing base box 'precise64_squishy_2013-02-09'...
            [default] Matching MAC address for NAT networking...
            [default] Setting the name of the VM...
            [default] Clearing any previously set forwarded ports...
            [default] Creating shared folders metadata...
            [default] Clearing any previously set network interfaces...
            [default] Preparing network interfaces based on configuration...
            [default] Forwarding ports...
            [default] -- 22 => 2222 (adapter 1)
            [default] Running any VM customizations...
            [default] Booting VM...
            [default] Waiting for VM to boot. This can take a few minutes.
            [default] VM booted and ready for use!
            [default] Setting hostname...
            [default] Configuring and enabling network interfaces...
            [default] Mounting shared folders...
            [default] -- /vagrant
          
          
            real  0m51.091s
            user  0m2.025s
            sys 0m0.696s