Kommen Ihnen die großen Virtualisierungen wie KVM, Xen, VMware oder Virtualbox etwas klobig vor, wenn es nur darum geht, einen einzelnen Dienst wie einen Druckerspooler oder ein Intrusion Detection System zu virtualisieren? Dann zeigt Ihnen dieser Workshop, wie Sie die leichtgewichtige Containervirtualisierung LXC unter Ubuntu 10.04 dafür vorbereiten.
Da LXC fester Bestandteil des Kernels ist, benötigen Sie nur die Userspace-Tools aus dem Paket »lxc«
, um damit erste Erfahrungen machen. Die Zeile
none /cgroup cgroup defaults 0 0
in »/etc/fstab«
hilft das zusätzlich notwendige, virtuelle Cgroup-Filesystem unter »/cgroup«
zu mounten.
Das reicht Root bereits, um ein einzelnes Kommando – etwa eine Shell – in einem Anwendungs-Container ablaufen zu lassen:
lxc-execute -n foo -f /usr/share/doc/lxc/examples/lxc-macvlan.conf /bin/bash
Das erzeugt gemäß der Konfigurationsdatei »lxc-macvlan.conf«
den Container und startet die Shell. Dass die in einer virtualisierten Umgebung läuft, zeigt bereits der Prompt an: Er trägt den geänderten Hostnamen. Die Liste der Prozesse – durch »ps auxw«
aufgerufen – ist außerordentlich übersichtlich, Kernelthreads fehlen dort sogar vollständig. Und wenn Sie in das Proc-Verzeichnis wechseln, sehen Sie auch hier im Vergleich zum Hostsystem die reduzierte Anzahl von Einträgen für Prozesse.
Ein- und Mehrwegbehälter
Das Anlegen eines Systemcontainers ist komplexer, weil Sie dafür ein komplettes System installieren und vorbereiten müssen. Außerdem will insbesondere auf dem Host das Netzwerk konfiguriert sein. Installieren Sie darum auf dem Hostsystem zusätzlich die Pakete: »debootstrap«
, »bridge-utils«
und »libcap2-bin«
. Als Teil der Netzkonfiguration benötigen Sie eine Brücke, um den Container unter einer eigenen IP-Adresse zu erreichen. Steht der Inhalt aus Listing 1 in »/etc/network/interfaces«
, aktiviert »/etc/init.d/networking restart«
die Einstellungen.
/etc/network/interfaces für Host anpassen
01 auto lo
02 iface lo inet loopback
03 # LXC-Config
04 # The primary network interface
05 #auto eth0
06 #iface eth0 inet dhcp
07 auto br0
08 iface br0 inet dhcp
09 bridge_ports eth0
10 bridge_stp off
11 bridge_maxwait 5
12 post-up /usr/sbin/brctl setfd br0 0
Legen Sie nun ein Verzeichnis an, beispielsweise »/lxc«
, in dem Sie die Systemdateien des Gastsystems ablegen. Ein Unterverzeichnis davon repräsentiert das Root-Filesystem des neuen Containers:
mkdir -p /lxc/rootfs.guest
Außerdem benötigen Sie eine Datei mit Namen »/lxc/fstab.guest«
, die Pfade zu Mountpoints ähnlich wie in »/etc/fstab«
festlegt (siehe Listing 2).
01 none /lxc/rootfs.guest/dev/pts devpts defaults 0 0
02 none /lxc/rootfs.guest/var/run tmpfs defaults 0 0
03 none /lxc/rootfs.guest/dev/shm tmpfs defaults 0 0
Bereiten Sie jetzt das Gastsystem vor. Dazu wechseln Sie in dessen eben angelegtes Verzeichnis und erzeugen dort mit dem Debian-Installer ein minimales Linux-System (hier für die 64-Bit-Variante, für die 32-Bit-Version tauschen Sie »amd64«
gegen »i386«
aus):
debootstrap --arch amd64 lucid/lxc/rootfs.guest/http://archive.ubuntu.com/ubuntu
Jetzt müssen Sie das neue System noch anpassen: Kommentieren Sie in der Datei »/lxc/rootfs.guest/lib/init/fstab«
die Zeilen aus, die »/proc«
, »/dev«
und »/dev/pts«
mounten. Sie vergeben einen Hostnamen, indem Sie die Datei »/lxc/rootfs.guest/hostname«
editieren. Im Beispiel heißt das System »guest«
. Schreiben Sie dazu in die neue Datei »/lxc/rootfs.guest/etc/hosts«
:
127.0.0.1 localhost guest
Die nächsten Änderungen führen Sie direkt im System aus, indem Sie mit Hilfe von »chroot«
vorläufig in die neue Umgebung wechseln:
chroot /lxc/rootfs.guest /bin/bash
Um sich später in den Container einzuloggen, bietet sich Open SSH an, das Sie mit dem Paket »openssh-server«
installieren. Nun fehlen noch ein Benutzeraccount und ein geregelter Weg, um per »sudo«
an Root-Rechte zu gelangen. Dazu legen Sie einen Benutzer an und machen ihn zum Mitglied der Gruppe »admin«
:
u=linuxmagazin; g=admin adduser $u; addgroup $g; adduser $u $g
Editieren Sie mit Hilfe des Kommandos »visudo«
die Datei »/etc/sudoers«
. Ersetzen Sie dabei in der Zeile
%sudo ALL=(ALL) ALL
den Eintrag »sudo«
durch »admin«
. Danach verlassen Sie die Chroot-Umgebung durch »exit«
wieder. Vor dem Test des vorbereiteten Containers konfigurieren Sie LXC noch in »/lxc/conf.guest«
mit dem Inhalt aus Listing 3 und passen in Zeile 8 die IP-Adresse an. Mit
Die Container-Konfiguration conf.guest
01 lxc.utsname = guest
02 lxc.tty = 4
03 lxc.network.type = veth
04 lxc.network.flags = up
05 lxc.network.link = br0
06 lxc.network.hwaddr = 08:00:12:34:56:78
07 #lxc.network.ipv4 = 0.0.0.0
08 lxc.network.ipv4 = 192.168.1.69
09 lxc.network.name = eth0
10 lxc.mount = /lxc/fstab.guest
11 lxc.rootfs = /lxc/rootfs.guest
12 lxc.pts = 1024
13 #
14 lxc.cgroup.devices.deny = a
15 # /dev/null and zero
16 lxc.cgroup.devices.allow = c 1:3 rwm
17 lxc.cgroup.devices.allow = c 1:5 rwm
18 # consoles
19 lxc.cgroup.devices.allow = c 5:1 rwm
20 lxc.cgroup.devices.allow = c 5:0 rwm
21 lxc.cgroup.devices.allow = c 4:0 rwm
22 lxc.cgroup.devices.allow = c 4:1 rwm
23 # /dev/{,u}random
24 lxc.cgroup.devices.allow = c 1:9 rwm
25 lxc.cgroup.devices.allow = c 1:8 rwm
26 lxc.cgroup.devices.allow = c 136:* rwm
27 lxc.cgroup.devices.allow = c 5:2 rwm
28 # rtc
29 lxc.cgroup.devices.allow = c 254:0 rwm
lxc-create -n guest -f /lxc/conf.guest
bereitet LXC nun die Konfiguration auf. Das ist Voraussetzung, um anschließend das System mit »lxc-start -n guest -d«
zu aktivieren. Die Option »-d«
führt das Kommando im Hintergrund als Daemon aus. Sie haben jetzt zwei Möglichkeiten, sich auf dem virtualisierten System einzuloggen: direkt per »lxc-console -n guest«
oder – falls das Netzwerk auf Anhieb funktioniert – per »ssh«
:
ssh linuxmagazin@192.168.1.69
Beim Zugang per »lxc-console«
müssen Sie allerdings etwas Geduld aufbringen. Bis der Systemcontainer sie aktiviert, kann es durchaus mehrere Minuten dauern! Dann meldet sich der Container, wie in Abbildung 1 zu sehen.
Abbildung 1: Die aktivierte Config startet den Container, was bisweilen einige Minuten dauert.
Recycling-Container
Um das System wieder anzuhalten, verwenden Sie vom Host aus das Kommando »lxc-stop -n guest«
. Nach jeder Änderung der Konfigurationsdatei »/lxc/conf.guest«
löschen Sie die alte Konfiguration mit »lxc-destroy -n Gastname«
und legen mit »lxc-create«
wieder eine neue an.
Im LXC-Howto finden Sie die wichtigsten Schritte zusammengefasst [1], optional auch Ubuntu-Eigenheiten [2]. Mehr von den LXC-Tools weiß ein IBM-Kernelentwickler zu sagen [3]. Sind alle Konfigurationen am rechten Ort, bietet LXC eine flotte Alternative für die Trennung kleiner Dienste, die sich untereinander nicht ins Gehege kommen sollen. (mg)
Eva-Katharina Kunst, Journalistin, und Jürgen Quade, Professor an der Hochschule Niederrhein, sind seit den Anfängen von Linux Fans von Open Source. Demnächst erscheint die dritte Auflage ihres Buches "Linux Treiber entwickeln".