Das LXD-Team spricht bei seinem Container-Management von einem "Lightervisor". Im Gegensatz zur traditionellen Virtualisierung sind Containern also leichtfüßig unterwegs. Tatsächlich benötigen Container weniger Ressourcen als vollvirtualisierte Maschinen mit Hypervisor, stellen aber trotzdem ein komplettes Linux zur Verfügung. Die Vorgehensweise, ein vollwertiges System statt nur einen Service im Container zu kapseln, ist der wesentliche Unterschied zu Docker, das die LXD-Entwickler vor allem als Mechanismus zur Auslieferung von Anwendungen sehen.
LXD ist die konsequente Weiterentwicklung des LXC-Toolsets. Die LXC-Kommandos sind erstmals 2008 aufgetaucht und dienen zur Verwaltung von Linux Containern. Im Hintergrund werkeln seit Beginn die Mainline-Kernel-Features Cgroups und Namespaces. Die für eine Virtualisierung wichtigen Funktionen der Ressourcen-Limitierung übernehmen Cgroups, über Namespaces werden Ressourcen voneinander isoliert. LXD ändert an der Container-Umsetzung nichts, ganz im Gegenteil. Braucht LXD neue Funktionen, implementieren sie die Entwickler zuerst im LXC-Toolset und reichen sie dann an den Lightervisor weiter.
Ubuntu propagiert LXD als wichtiges Feature von Ubuntu 16.04. Mindestens so viel Aufmerksamkeit kommt der Integration eines neuen Dateisystems zugute – dem von Solaris bekannten ZFS. Im Februar titelte der Ubuntu-Entwickler Dustin Kirkland: "ZFS is the FS for Containers in Ubuntu 16.04". Die Schlagzeile rund um Ubuntu und ZFS ließ viele Herzen höher schlagen, wünschen sich doch viele Linux-Fans seit langem eine native ZFS-Integration.
LXD-Enthusiasten finden somit bei Xenial Xerus alles zum Starten von Containern vor. In den ersten Schritten wird sichergestellt, dass der aktuelle Benutzer der Gruppe "lxd" angehört. Diese dürfen mit dem LXD-Daemon ohne root-Rechte kommunizieren:
$ id xenial | grep lxd
uid=1000(xenial) gid=1000(xenial) groups=1000(xenial),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),110(lxd),119(lpadmin),120(sambashare)
Um von Beginn an vom zuvor erwähnten ZFS zu profitieren, initialisieren Sie am besten ein separates Block-Device als Container-Speicher. Dazu kommt als Benutzer root das Kommando lxd init zum Einsatz, das vorzugsweise via sudo -i in einer root-Session ausgeführt wird (Listing 1). Bei direkter Verwendung von sudo lxd init werden fälschlicherweise Konfigurationsdateien im User-Verzeichnis dem Benutzer root zugewiesen – LXD-Befehle schlagen daraufhin fehl.
Im Zuge der ZFS-Initialisierung wird LXD auch für das Remote-Management per HTTPS-Protokoll konfiguriert. Eine sinnvolle Erweiterung zum traditionellen Management – zum einen werden Container per REST-API gesteuert, zum anderen lassen sich mehrere LXD-Hosts übers Netzwerk verwalten.
Nach dem Setup lauscht der LXD-Daemon der Konfiguration entsprechend am Port 8090 auf Netzwerkanfragen:
$ sudo service lxd status lxd.service - LXD - main daemon Loaded: loaded (/lib/systemd/system/lxd.service; indirect; vendor preset: enabled) Active: active (running) since Fri 2016-03-11 22:18:07 CET; 1min 11s ago
[…]
$ sudo netstat -tlnp | grep lxd
tcp 0 0 192.168.56.105:8090 0.0.0.0:* LISTEN 15295/lxd
Listing 1: LXD-Initialisierung
$ sudo -i # apt-get install zfsutils-linux # lxd init Name of the storage backend to use (dir or zfs): zfs Create a new ZFS pool (yes/no)? yes Name of the new ZFS pool: lxcs Would you like to use an existing block device (yes/no)? yes Path to the existing block device: /dev/sdb Would you like LXD to be available over the network (yes/no)? yes Address to bind LXD to: 192.168.56.101 Port to bind LXD to: 8090 Trust password for new clients: Again: LXD has been successfully configured.
LXD baut per Design eine abgesicherte Container-Umgebung auf. Dazu setzt das Projekt auf Kernel-Technologien wie User Namespaces, Apparmor und Seccomp. LXD ist außerdem so konzipiert, dass unprivilegierte Benutzer ohne Root-Rechte Container erzeugen und verwalten dürfen – sogenannte "Unprivileged Containers". Für einen ersten Container wird aus dem öffentlichen Ubuntu Image-Server eine gewünschte Distribution importiert, in Listing 2 ein Ubuntu Trusty 14.04.
Listing 2: Distribution importieren
$ lxc image copy ubuntu:14.04 local: --alias trusty Image copied successfully! $ lxc image list +--------+---------------------+-----------+-------------------------------------------------------------+--------+--------------+-----------------------------------------+ | ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE | +--------+---------------------+-----------+-------------------------------------------------------------+--------+--------------+-----------------------------------------+ | trusty | 510c27eb5e30 | no | ubuntu 14.04 LTS amd64 (release) (20160222) | x86_64 | 118.51MB | Mar 11, 2016 at 9:33pm (UTC) | +--------+---------------------+-----------+-------------------------------------------------------------+--------+--------------+-----------------------------------------+
Alle verfügbaren Images des Remote Servers listet der folgende Befehl auf:
$ lxc image list ubuntu:
Bei Bedarf startet ein Container auch ohne den Import direkt vom Remote-Image weg, wobei ein lokaler Image Cache angelegt wird. Bei häufigem Verwenden eines Images ist die lokale Kopie ein naheliegender Zwischenschritt, da der Image-Server in diesem Fall nicht kontaktiert werden muss.
Mit dem launch-Befehl startet im nächsten Schritt aus dem lokalen Image einen Container:
$ time lxc launch trusty container1
Creating container1
Starting container1
real 0m6.637s
$ lxc exec container1 -- /bin/bash
Da das Image bereits lokal zur Verfügung steht, dauert es nur rund 6s, bis "container1" erstellt und gestartet ist – "lxc exec" führt sogleich in eine Shell von "container0". Das Kommando "lxc init" legt den Container nur an, ohne zu starten:
$ lxc init trusty container1
Creating container1
Einen Überblick über laufende Container inklusive derer IP-Adressen bietet der list-Befehl (Listing 3).