Aus Linux-Magazin 04/2006

Virtuelle Server erschließen zahlreiche Vorteile bei der Systemkonsolidierung

Als eine Spielart der Virtualisierung beherrscht Linux auch die Partitionierung des Betriebssystems, was zu besonders schnellen und einfach administrierbaren virtuellen Servern führt. Wie man mit Vserver am schnellsten zum Ziel gelangt und was die Unerschiede zu OpenVZ sind, erläutert dieser Beitrag.

Als Solaris 10 Ende 2004 auf der Bildfläche erschien, viel eine unter den mehr als 600 Neuerungen vielen Kunden besonders auf: Die integrierte Virtualisierung auf Grundlage der so genannten Zonen. Was vielleicht nicht jedermann bekannt ist: Linux beherrscht längst etwas ganz Ähnliches. Das Linux-Vserver-Projekt [1] partitioniert das Betriebssystem auf der Grundlage virtueller Server: Unterschiedliche Dienste und Applikationen lassen sich auf einem physischen Host konzentrieren.

Die Verantwortungsbereiche der Administratoren sind bei Bedarf leicht teilbar. Die Nachteile einer Parallelinstallation aller Dienste vermeiden die virtuellen Server dagegen. So gehören zum Beispiel Konflikte durch belegte Netzwerkports der Vergangenheit an, weil gleiche Services nun auf verschiedenen virtuellen Instanzen laufen.

In Schulungsumgebungen ist es vorteilhaft, dass die Teilnehmer ihren Server ohne weiteres mit Root-Rechten administrieren können, ohne andere zu gefährden. Verkonfiguriert ein angehender Admin einmal ein System oder übersieht eine Sicherheitslücke, sodass sein System kompromittiert wird, dann bleibt das Problem auf die enge virtuelle Welt dieser Serverinstanz beschränkt und stellt für andere keine Gefahr dar. Auch ist der Ausgangszustand auf Knopfdruck wiederherstellbar.

Die Applikationen merken von all dem nichts und bedürfen daher auch keiner Anpassung. Die Partitionierung bringt nicht einmal merkliche Leistungseinbußen mit sich und hat damit auch Vorteile gegenüber einer vollständigen Virtualisierung, beispielsweise durch VMware [9] oder Virtual PC beziehungsweise Virtual Server [10].

Im Extremfall lässt sich ohne Probleme für jeden Dienst oder jede Applikation ein eigener virtueller Server aufsetzen. Benutzt der Administrator dann auch noch die richtigen Werkzeuge für die Verwaltung, lässt ihn auch eine große Anzahl virtueller Server kalt. Dieser Beitrag zeigt, wie\’s funktioniert.

Virtuelle Diener

Leider sind alle diese Vorteile derzeit unter Linux noch nicht mit einem Vanilla-Kernel zu haben. Denn der enthält zwar bereits einige Zutaten für eine Partitionierung, doch den Rest bringen erst die Patches aus dem Projekt Linux Vserver mit. OpenVZ [2], die freie Variante der kommerziellen Virtualisierungslösung Virtuozzo [3] ist eine Alternative.

Für die meisten Distributionen gibt es spezielle Packages für den Kernel, die alle Patches enthalten, sodass der Admin den Kernel nicht mehr selbst patchen muss. Wer auch auf das Kompilieren des neuen Kernels verzichten möchte, findet sowohl für Linux Vserver [1] als auch für OpenVZ [2] bereits fertige Kerne auf den Projektseiten.

Gentoo als Wirt

Als Beispiel verwenden die Autoren dieses Beitrags als Wirtssystem Gentoo. Für diese Distribution enthält das Paket »vserver-sources« die gepatchten Kernelquellen und »util-vserver« die Sammlung der Userlevel-Werkzeuge. Aber Achtung: Es gibt ein weiteres Paket mit ähnlichem Namen: »vserver-utils« [5]. Dieses Paket befindet sich gegenwärtig aber noch sehr stark in der Entwicklung und funktioniert nur mit den Entwicklerversionen von Linux Vserver.

Diese Entwicklerversionen sind allerdings noch aus zwei anderen Gründen interessant: Nur sie enthalten die Bind-Mount-Extensions (BME) und das Copy-on-Write-Link-Breaking (COWLB, siehe unten). Die Installation der genannten Packages ist unter Gentoo einfach zu bewerkstelligen:

emerge vserver-sources util-vserver
rc-update add vservers default

Das letzte Kommando startet beim nächsten Booten auch die virtuellen Server. Anschließend baut Root den neuen Vserver-Kernel des Wirts, zum Beispiel mit Hilfe von »genkernel«, passt die Bootloader-Konfiguration an und bootet ihn. Zuvor ist ihm aber noch durch den Eintrag

echo 'kernel.vshelper=/usr/lib/util-vserver/vshelper' >> /etc/sysctl.conf

das Vserver-Helper-Skript bekannt zu machen. Dieses Skript wird für »halt« und »reboot« im virtuellen Server benutzt. In diesem Fall soll ja nur die eigene Instanz gestoppt beziehungsweise neu gestartet werden. Das Wirtssystem muss hingegen weiterlaufen.

Gentoo als Gast

Das Einrichten eines virtuellen Servers auf dem so präparierten Wirt geht anschließend leicht von der Hand: Der Admin legt zunächst Name und Kontext-ID fest, die selbstverständlich beide eindeutig sein müssen. Zusätzlich bestimmt er ein Netzwerkinterface für den virtuellen Server sowie den Alias-Namen und die statische IP-Adresse.

Das folgende Kommando erzeugt die Konfiguration für eine Instanz VS01 in »/etc/vservers/vs01« und generiert gleichzeitig unter »/vservers/vs01« eine minimale Verzeichnisstruktur, die diese Installation aber später überschreibt:

vserver vs01 build -m skeleton --hostname vs01 --initstyle plain --context 1001 --interface vs01=eth1:192.168.39.11/24

Jetzt könnte man wie üblich die Installation des Gentoo-Ssystems einfach unterhalb von »/vservers/vs01« fortsetzen und ein Stage-3-Archiv sowie einen Portage-Snapshot dort entpacken. Wer wie hier einen Gentoo-Wirt hat, kann sich die Arbeit mit dem Portage-Snapshot aber sparen und das Portage-Dateisystem per Bind-Mount dem Gast für die Installationsphase zur Verfügung stellen:

mount /usr/portage /vservers/vs01/usr/portage -o bind,ro
mount /usr/portage/distfiles /vservers/vs01/usr/portage/distfiles -o bind,rw

BME-Extensions

Oft möchte der Admin allen oder auch nur einigen virtuellen Servern einen bestimmten Teil des Dateisystems gemeinsam zur Verfügung stellen. Genau zu diesem Zweck dienen in Linux die soeben benutzten Bind-Mounts, die einen Teilbaum des Dateisystems an anderer Stelle erneut montieren. Soll das jedoch nur lesend geschehen, macht sich sofort eine unschöne Linux-Eigenschaft bemerkbar: Das »ro«-Flag in Kombination mit der Option »bind« für das Mount-Kommando wird stillschweigend ignoriert. Eigentlich müsste hier eine Fehlermeldung erscheinen.

In der Chroot-Umgebung des virtuellen Servers setzen folgende Befehle das Profile auf »vserver« um:

(vs01 chroot) gs / # rm /etc/make.profile
(vs01 chroot) gs / # ln -s
/usr/portage/profiles/default-linux/x86/2005.1/vserver /etc/make.profile

Als vorläufiger Abschluss kommen noch die Pakete Syslog-NG und OpenSSH hinzu, die der Installateur dem Runlevel Default zuordnet. Natürlich braucht er für den virtuellen Server keinen Kernel zu kompilieren oder den Bootloader zu installieren. Stattdessen ersetzt er die normalen Bootskripte. Dazu muss er das Paket Baselayout durch Baselayout-Vserver austauschen. Der Inhalt von »/etc/init.d/« ändert sich dadurch allerdings dramatisch (Listing 1).

Listing 1:
Vserver-Baselayout

(vs01 chroot) gs / # emerge baselayout-vserver
(vs01 chroot) gs init.d # ls -l
total 84
-rwxr-xr-x  1 root root  2871 Jan 16 14:48 bootmisc
lrwxrwxrwx  1 root root 5 Jan 16 14:48 checkfs -> dummy
lrwxrwxrwx  1 root root 5 Jan 16 14:48 checkroot ->dummy
lrwxrwxrwx  1 root root 5 Jan 16 14:48 clock ->dummy
lrwxrwxrwx  1 root root 5 Jan 16 14:48 consolefont -> dummy
...
...
lrwxrwxrwx  1 root root 5 Jan 16 14:48 urandom -> dummy

Der Austausch der Bootskripte ist notwendig, da einem virtuellen Server ja der direkte Zugriff auf Geräte verwehrt ist und bestimmte Aktionen für ihn sowieso sinnlos wären, zum Beispiel Module zu laden. Dasselbe Verfahren sollte eigentlich genauso für OpenVZ gelten, jedoch sind dort noch zusätzliche Anpassungen erforderlich [4].

An dieser Stelle ist auch noch die Konfiguration von Syslog-NG zu ändern (siehe Listing 2), denn in einer Vserver-Umgebung ist der Zugriff auf »/proc/kmsg« nicht möglich. Die Vserver-Patches sperren außerdem auch andere Pseudodateien, beispielsweise »/proc/uptime«. Vor dem Verlassen der Chroot-Umgebung erhalten »/etc/conf.d/hostname« und »/etc/conf.d/domainname« noch die korrekten Inhalte.

Listing 2:
»syslog-ng.conf«

01 options {chain_hostnames(on);
02         sync(0);
03         stats(43200);};
04 source src { unix-stream("/dev/log"); internal();};
05 destination server { udp("192.168.39.10",port(514)); };
06 log { source(src); destination(server); };

Jetzt ist die Zeit gekommen, den neuen Server mit »vserver vs01 start« zu starten. Die Grenze zwischen dem Wirtssystem, das heißt dem Kontext 0, und den Vservern ist semi-permeabel. Daher kann der Benutzer ohne Authentifikation den virtuellen Server betreten. In umgekehrter Richtung geht dies selbstverständlich nicht (Abbildung 1). Anhand der Prozessliste ist schon zu erkennen, dass hier einiges etwas anders ist als in einer nativen Umgebung.

Abbildung 1: Das Betreten der virtuellen Welt vom Wirtssystem aus - der umgekehrte Weg ist natürlich nicht möglich.

Abbildung 1: Das Betreten der virtuellen Welt vom Wirtssystem aus – der umgekehrte Weg ist natürlich nicht möglich.

Serverstart im Detail

Zunächst richtet das Werkzeug »vnamespace« einen neuen Linux-Namensraum für Prozesse ein. Das bewerkstelligt der Systemcall »clone()« mit dem Flag »CLONE_NEWNS«. Ein Namensraum ist eine prozessspezifische Sicht auf die Dateisystemhierarchie. Ein »mount« im Namensraum des Prozesses A ist für Prozess B in einem anderen Namensraum nicht sichtbar. Daher stören die Mounts für die virtuellen Server den Namensraum des Wirtssystems nicht.

Zusätzlich ist in diesem neuen Namensraum auch die Wurzel des Vserver-Dateisystems mit einem rekursiven Bind-Mount über »/« montiert, was auch einen Ausbruch aus der Chroot-Umgebung effektiv verhindert. Sollte er dennoch gelingen, findet sich der Angreifer im Vserver-Dateisystem.

Anschließend konfiguriert der Bootprozess die Aliase für die Netzwerkinterfaces. Das Werkzeug »chbind« bindet die weiteren Prozesse an die IP-Adresse des Vservers. Seine Interfacekonfiguration passiert unter »/etc/vservers/vs01/interfaces/0/«. Soll der Server mehrere Interfaces bekommen, kann der Admin weitere Verzeichnisse »/etc/vservers/vs01/interfaces/[1-9]« erzeugen und die Dateien kopieren. Dabei sind mindestens »dev« und »ip« anzupassen.

Im nächsten Schritt montiert das System die notwendigen Verzeichnisse in den Namensraum. Das betrifft zunächst einmal das Wurzelverzeichnis, auf das der Link unter »/etc/vservers/vs01/vdir« zeigt. Anschließend führt es die Mounts aus der Datei »/etc/vservers/vs01/fstab« aus. Sie muss mindestens die Einträge für »/proc« und »/dev/pts« enthalten. Wer auch im laufenden Betrieb den Portage-Baum des Wirtssystems einbinden will, kann auf die »fstab« aus Listing 3 zurückgreifen.

Listing 3: »fstab«
des Vserver

01 none    /proc    proc    defaults                0 0
02 none    /tmp     tmpfs   size=16m,mode=1777      0 0
03 none    /dev/pts devpts  gid=5,mode=620          0 0
04 # shared portage tree
05 /usr/portage  /usr/portage    none bind,ro       0 0
06 /usr/portage/distfiles /usr/portage/distfiles none bind,rw 0 0

Ist der Vserver allerdings nicht vertrauenswürdig, sollte man hiermit vorsichtig umgehen. Zwar ist das Austauschen von Dateien durch die Prüfsummenbildung ausgeschlossen, doch darf das Gastsystem bei dieser Konfiguration zumindest Daten in den Wirt und andere Vserver ungeprüft einschleusen.

Zu guter Letzt erzeugt »vcontext« den Prozesskontext für den ersten Prozess des Vservers und »chbind« beschränkt das Binden ausschließlich auf die IP-Adressen dieses virtuellen Servers. Scheduling-Parameter und Ressourcen-Beschränkungen werden nur dann gesetzt, wenn sie vom Administrator explizit vorgesehen wurden. Bei einem Gentoo-Vserver startet als erster Prozess »/sbin/init«, bei einem Debian-VS dagegen »/etc/init.d/rc 3«.

Normalerweise hätte auf einem Gentoo-System das Starten von »init« zur Folge, dass zunächst die Skripte für den Softlevel »boot« und dann »default« ausgeführt würden. Die originalen Gentoo-Skripte sind hierfür natürlich nicht mehr verwendbar, da sie von einem nativen System ausgehen und einen privilegierten Systemzugriff voraussetzen, beispielsweise um auf »/dev/hda1« für einen Dateisystemcheck zuzugreifen oder die Uhr zu stellen.

Aus diesem Grund hat das Paket »baselayout-vserver« die »/etc/inittab« geändert und die Bootskripte ausgetauscht.

Jetzt werden nur noch die folgenden Skripte ausgeführt:

bootmisc
domainname
hostname
local
net.lo
rmnologin
ssh
syslog-ng

Hier bietet es sich an, den Vserver erst einmal mit Hilfe von »vserver vs01 stop« wieder zu stoppen und das gesamte Dateisystem als Grundlage für spätere virtuelle Server mit »cd /vservers; tar zcvf vserver-gentoo-template.tgz ./vs01« auf die Seite zu legen.

Stolperstein
Adressbindungen

Es ist darauf zu achten, dass Serverprozesse im Wirtskontext sich nicht an alle verfügbaren Interfaces und Aliase binden. Andernfalls können dies die entsprechenden Daemons in den virtuellen Servern nicht mehr. Eine häufige Fehlerquelle ist der »ssh«-Daemon. Er ist werkseitig so konfiguriert, dass er sich an alle Adressen bindet.

Um diesen Stolperstein sicher aus dem Weg zu räumen, sind in »/etc/ssh/sshd_config« die richtigen Adressen explizit einzutragen. Hier dürfen die Aliase der Vserver nicht auftauchen:

ListenAddress 192.168.1.0
ListenAddress 192.168.39.10
ListenAddress 192.168.48.10

Anomalien

Ein virtueller Server soll sich gegenüber Applikationen und Benutzern genau wie eine native Linux-Umgebung verhalten. Um dies zu erreichen, bedarf es einiger Abbildungen. Ein Beispiel ist die PID des Init-Prozesses. Obgleich es nicht zwingend erforderlich ist, gehen doch viele Programme implizit davon aus, dass »init« die PID 1 hat. Das kann in einem virtuellen Server allerdings nicht sein, weil schon der Init-Prozess des Wirts diese PID benutzt. Daher wird bei der Virtualisierung des »/proc«-Dateisystems der Eintrag für »init« explizit auf die PID 1 umgesetzt.

Ist der Gast ein Debian-Vserver, startet während des Bootens nur »/etc/init.d/rc 3«, sodass in diesem Falle überhaupt kein Init-Prozess existiert. Deshalb wird der Eintrag »/proc/1« vollständig simuliert. Ähnlich ist das Verfahren mit »/proc/uptime«.

Das Aufsetzen von weiteren Umgebungen ist nun sehr simpel: »vserver« erzeugt die neue Konfiguration und kopiert das Vserver-Dateisystem. Dann sind noch die Netzwerkeinstellungen des virtuellen Servers zu ändern. Noch bequemer gelingt dasselbe mit dem Werkzeug »vserver-new«. Ihm genügt bereits die folgende Eingabe:

vserver-new vs02 --context 1002 --hostnameU vs02 --interface vs02=eth1:192.168.39.14/24U clone vs01

Andere Gäste

Das Besondere an der Virtualisierung durch eine Partitionierung auf Kernelebene ist, dass der Kern für alle Partitionen beziehungsweise virtuellen Server derselbe ist. Das ist keine große Einschränkung, denn fremde Distributionen sind als Gast installierbar. Das folgende Beispiel setzt auf dem Gentoo-Wirt einen Debian-Gast auf.

»debootstrap« vereinfacht dies bemerkenswert. Statt wie oben nur ein Vserver-Skelett aufzusetzen, kann man »vserver« mit »debootstrap« zusammenarbeiten lassen. Nach »emerge debootstrap« wird gleich der Vserver durch

vserver vs03 build --context 1003 --hostname vs03 --interface vs03=eth1:192.168.39.23/24 -m debootstrap -- -d sarge

fertig installiert. Einfacher ist der ganze Vorgang kaum zu gestalten.

Wer sehr viele Vserver aufsetzt, verbraucht damit entsprechend viel Storage-Kapazität. Wenn alle Server aus demselben Template entstanden, sind jedoch andererseits die meisten Dateien in den einzelnen Servern identisch. Um hier etwas effektiver vorzugehen, bietet es sich an, bestimmte Teile der Dateisysteme der Vserver zusammenzufassen.

Kontexte

Zu den wichtigsten Modifikationen, die Vserver-Patches am Linux-Kern vornehmen, gehören die Kontexten. Ein Kontext definiert eine Menge von Prozessen, die wie üblich miteinander kooperieren und konkurrieren. Prozesse unterschiedlicher Kontexte können systemlokal nicht mehr kooperieren (siehe Abbildung 3). Dazu wird neben der PID die Kontext-ID eingeführt, sodass die Kombination aus PID und Kontext-ID eindeutig ist.

Abbildung 3: Mit Vserver entstehen gegeneinander abgeschottete Betriebssystem-Partitionen.

Abbildung 3: Mit Vserver entstehen gegeneinander abgeschottete Betriebssystem-Partitionen.

Der Urkontext hat die Kontext-ID 0. Er wird beim Booten des Kerns automatisch erzeugt und ist bezogen auf die Trennung der Prozesse nichts Besonderes. Von ihm aus sind die Prozesse der anderen Kontexte nicht direkt zu beeinflussen. Um trotzdem eine Übersicht über alle Prozesse in allen Kontexten des Systems zu erhalten, wurde noch der Beobachtungskontext 1 eingeführt, hier sind alle Prozesse des Systems sichtbar. Er ist aber nur vom Urkontext zu betreten.

Andere Gäste

Das Werkzeug »vcontext« erzeugt einen neuen Kontext und erlaubt es, einen bestehenden zu betreten. Das Kommando »vcontext –migrate –xid 1 ps aux« betritt den Beobachtungskontext 1 und startet darin »ps aux«, um eine Prozessliste über alle Kontexte zu erhalten: Für die einfache Administration existieren auch noch die Werkzeuge »vps« und »vtop«, die außerdem die jeweilige Kontext-ID und Kontext-Namen auflisten.

Aus Sicherheitsgründen sollte der Admin bei einem Linux-Vserver-System den Urkontext 0 nur zur Verwaltung der anderen Kontexte nutzen. Die Dienste laufen dann in eigenen Kontexten. Der Zugang zum Urkontext muss natürlich entsprechend abgesichert sein.

Administration

Wollen die Gast-Administratoren keine wesentlichen Änderungen an den Servern vornehmen, besteht die Möglichkeit, das Wurzeldateisystem mit Ausnahme von »/etc«, »/var« und Daten-Dateisystemen nur read-only zu montieren. Dies bedeutet aber oftmals eine zu große Einschränkung.

Linux Vserver nutzt daher eine andere Technik: Unification und Copy-on-Write-Link-Breaking. Zunächst werden die Teilbäume der virtuellen Server durch Hardlinks vereinigt. Das Schreiben entfernt den Hardlink und setzt die geänderte Datei ein.

Vereinigung und Copy-on-Write-Link-Breaking

Liegen die Verzeichnisse der virtuellen Server in einem Dateisystem, kann der Admin mit Hilfe des Werkzeugs »vhashify« identische Dateien in einem zentralen Verzeichnis zusammenfassen und in den Vservern durch Hardlinks ersetzen. Somit sind die Dateiobjekte tatsächlich nur einmal vorhanden und es wird Speicherplatz gespart. Ein schreibender Zugriff darf sich natürlich nur im ausführenden Vserver auswirken.

Die Lösung heißt Copy-on-Write-Link-Breaking (COWLB). Der Hardlink auf das zentrale Verzeichnis wird dabei entfernt, die Datei durch die geänderte Kopie ersetzt. COWLB ist allerdings erst ab der Entwicklerversion 2.1.0 in den Vserver-Patches enthalten.

Die Technik lässt sich auch auf beliebige Verzeichnisse anwenden, wie das folgende Beispiel verdeutlicht. Die Datei »x« ist in den Verzeichnissen »/vservers/a0[12]« vorhanden:

gs vservers # ls -li a0[12]/x
685511 -rw-r--r--  1 root root 942 Jan 17 07:12 a01/x
685514 -rw-r--r--  1 root root 942 Jan 17 07:12 a02/x

Der folgende Aufruf ersetzt die Datei durch eine Kopie mit dem Inode 122620. Zu kleine Dateien überspringt er:

gs vservers # /usr/lib/util-vserver /vhashify --manually --destination /vservers/.hash /vservers/a01 exclude /vservers/vexclude

Für die Datei »a01/x« setzt »vhashify« das »immutable« sowie das »unlink«-Flag. Damit kann die Datei nicht mehr verändert, wohl aber können Hardlinks darauf entfernt werden. Dies wird verwendet, um das Copy-on-Write zu implementieren:

gs vservers # showattr a0[12]/x
----UI- a01/x
----ui- a02/x

Damit ist aber noch kein großer Effekt erzielt. Das Verzeichnis »/vservers/a02« wird nun ebenso behandelt:

gs vservers # /usr/lib/util-vserver/vhashify --manually --destination /etc/vservers/.defaults/apps/vunify/hash /vservers/a02 exclude /vservers/vexclude
gs vservers # ls -li a0[12]/x

122620 -rw-r--r--  3 root root 942 Jan 17 07:12 a01/x
122620 -rw-r--r--  3 root root 942 Jan 17 07:12 a02/x

Nun sind beide Einträge als Hardlink auf den Inode 122620 vorhanden. Verändert man nun die Datei, wird der Hardlink wieder entfernt und die Datei durch eine Kopie ersetzt:

gs vservers # echo "test" >> a02/x
gs vservers # ls -li a0[12]/x
122620 -rw-r--r--  2 root root 942 Jan 17 07:12 a01/x
685511 -rw-r--r--  1 root root 947 Jan 17 07:14 a02/x

Das Werkzeug »vhashify« vereinigt die beiden Verzeichnisse des Vservers »vs01« und des Clone »vs02«. Die Datei »/vservers/vexclude« beinhaltet eine Ausschlussliste mit Pfaden, deren Vereinigung nicht sinnvoll ist. Dies betrifft beispielsweise inhärent variable Daten wie unter »/var« oder auch Gerätedateien unter »/dev«.

»vhashify« ist der Nachfolger von »vunify« und kann auch dieselbe Standard-Ausschlussliste in »/usr/lib/util-vserver/defaults/vunify-exclude« benutzen. Mit dem Link »ln -s /vservers/.hash /etc/vservers/.defaults/apps/vunify/hash/0« ist die Vereinigung auch noch einfacher als »/usr/lib/util-vserver/vhashify vs02« ausführbar.

Zu erkennen ist, dass das ».hash«-Verzeichnis deutlich größer geworden ist, allerdings scheint sich bei »/vservers/vs0[12]« nichts getan zu haben:

gs vservers # du -sh /vservers/.hash /vservers/vs0[12]
391M    /vservers/.hash
331M    /vservers/vs01
331M    /vservers/vs02

Das Werkzeug »vdu« kann die Hardlinks korrekt auseinander halten. Die Platzersparnis bei einer großen Anzahl von Vservern ist enorm:

gs vservers # vdu /vservers/vs0[12]
/vservers/vs01  5K
/vservers/vs02  5K

Je nach Anwendungszweck driften allerdings im Laufe der Zeit zwangsläufig auch die vereinigten Vserver-Verzeichnisse auseinander.

Union-FS

Eine elegantere Variante bietet eine Vereinigung der Vserver-Teilbäume durch Union-FS [6]. Dies geht auch über Dateisystemgrenzen hinweg. Die Möglichkeiten von Union-FS sind in [7] gut beschrieben, es ist aber (noch) nicht Bestandteil des offiziellen Kerns und in Gentoo auch noch maskiert. Das Kernelmodul und die Userpace-Werkzeuge muss der Admin daher mit »ACCEPT_KEYWORDS=”~x86″ emerge unionfs« installieren.

Union-FS ist ein so genanntes Fan-out-Dateisystem, das Dateisystemoperationen auf einen Fächer von darunter liegenden Dateisystemen verteilt (siehe Abbildung 2). Je weiter links sich ein Zweig im Fächer befindet, desto höher ist seine Priorität. Wird eine Datei »a« gesucht, dann beginnt die Suche stets in dem Zweig ganz links und endet bei jenem Zweig, in dem sich die Datei schließlich findet.

Abbildung 2: Union-FS verteilt Dateisystemoperationen auf darunter liegende Systeme. Je weiter links ein Zweig liegt, desto höher ist seine Priorität.

Abbildung 2: Union-FS verteilt Dateisystemoperationen auf darunter liegende Systeme. Je weiter links ein Zweig liegt, desto höher ist seine Priorität.

Für den Fall, dass der Zweig mit der höchsten Priorität read-write in den Fächer eingebunden ist, lässt sich der Verbund auch schreibend verwenden. Um eine Datei »b« zu löschen, genügt es nicht, sie im Zweig mit der höchsten Priorität zu löschen. Eventuell würde damit eine Datei weiter rechts aufgedeckt. Dann schreibt Union-FS eine Whiteout-Datei ».wh.b«, die weiter rechts vorhandene Dateien verdeckt.

Das ist ebenfalls dann notwendig, wenn die Datei aus einem Read-only-Zweig stammt. Wird eine Datei »c« erzeugt, kann sie nur in den Read-write-Zweig gelangen. Soll die Datei »d« aus dem Read-only-Zweig verändert werden, ist sie zuvor in den nächsten Read-write-Zweig höherer Priorität zu kopieren (copy-up).

Zu diesem Zweck fertigt man zunächst eine weitere Chroot-Umgebung mit dem Read-only-Zweig des Masters in »/vservers/vsmaster« und einen Read-write-Zweig für jene Änderungen an, die durch das Entfernen des Portage-Systems entstehen:

mount -t unionfs none /vservers/vstmp -odirs=/vservers/vsnoportage=rw:/vservers/vsmaster=ro 0 0

Der Zweig »vservers/vsnoportage« lässt sich mit Hilfe von »unionctl« dynamisch vor »vservers/vsmaster« in ein Union-FS-Dateisystem einfügen. Nach dem Neustart des VS »vs04« ergibt sich ein System ohne das Paketmanagement »portage«. Dieses Prinzip lässt sich selbstverständlich auch auf andere Pakete anwenden, die aus irgendeinem Grund unabhängig vom Master hinzuzufügen oder zu entfernen sind. Aus Konsistenzgründen sollten allerdings Paketmanipulationen immer auf einen Zweig des Union-FS beschränkt bleiben.

Wer auf einem Wirtssystem gleichzeitig sowohl BME und COWLB als auch Union-FS verwenden will, ist derzeit noch auf ein Patch von Union-FS angewiesen [8]. Grund dafür ist eine Änderung der Signaturen der VFS-Helper durch die Linux-Vserver-Patches. Dadurch geht allerdings die Kompatibilität zu Kernelmodulen verloren, denn die VFS-Helper verwenden sie noch in der ursprünglichen Art.

OpenVZ

OpenVZ [2] als freie Variante der kommerziellen Virtualisierungslösung Virtuozzo [3] von SWsoft bietet eine vergleichbare Funktionalität wie das Open-Source-Projekt Linux Vserver. Das zugehörige Kernelpatch ist von der OpenVZ-Webseite [2] zu beziehen. Dort sind auch bereits fertig kompilierte Kernel erhältlich. Für Gentoo gibt es wiederum ein Paket, das die Integration der OpenVZ-Patches und anderer wichtiger Patches durchführt und sie unter der Bezeichnung »openvz-sources« zur Verfügung stellt. Die notwendigen Userlevel-Werkzeuge befinden sich in den Paketen »vzctl« und »vzquota«.

Derzeit sind die OpenVZ-Patches auf die Kernelversion 2.6.8 abgestimmt. Für neuere Kernel sind leider noch keine stabilen Patches erhältlich. Lediglich eine Betaversion ist für die Kernelversion 2.6.15 zu bekommen.

Auch lässt sich der Kernel nicht mit »genkernel« erzeugen. Der einfachste Ausweg besteht darin, eine verlässliche Konfiguration von der OpenVZ-Webseite zu verwenden. Diese wird dann als ».config« in »/usr/src/linux« gelegt. Der Kernel wird anschließend wie üblich kompiliert. Um die OpenVZ-Server auch automatisch zu starten, bedarf es eines »rc-update add vz default«.

Vor dem ersten Starten ist noch die Gerätedatei »/dev/vzctl« zu erzeugen, und zwar mit: »/bin/mknod /dev/vzctl c 126 0«. Sofern in »/etc/conf.d/rc« die Option »RC_DEVICE_TARBALL=”yes”« gesetzt ist, sichert OpenVZ diese Gerätedatei beim Herunterfahren des Wirts in »/lib/udev-state/devices.tar.bz2« und erzeugt sie beim nächsten Booten auch automatisch wieder. Wichtig ist außerdem, die notwendigen Einstellungen in »/etc/sysctl.conf« vorzunehmen:

net.ipv4.ip_forward = 1
net.ipv4.conf.default.proxy_arp = 0
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.send_redirects = 1
net.ipv4.conf.all.send_redirects = 0
kernel.sysrq = 1

Wenn der Kernel erzeugt und der Bootloader entsprechend angepasst ist und außerdem die Userlevel-Werkzeuge installiert sind, kann der Admin das System wieder hochfahren.

Gäste in OpenVZ

Nahe liegend ist es, zunächst ein Gentoo-Gastsystem aufzusetzen. Das sollte in nicht allzu ferner Zukunft auch mit dem oben verwendeten »baselayout-vserver« möglich sein [4]. Dazu packt der Admin seinen Vserver-Master und legt ihn unter »/vz/template/cache/vsmaster.tar.gz« ab. Anschließend erzeugt er einen OpenVZ-Gast mit:

vzctl create 2001 --ostemplate vsmaster --ipadd 192.168.39.21 --hostname ovz01

Der Befehl vergibt genau wie die Vserver-Lösung eine Kontext-ID. Der Parameterwert für »ostemplate« wird um ».tar.gz« ergänzt, er benennt damit das Archiv mit dem Gastsystem in »/vz/template/cache«. Derzeit scheitert dies jedoch für Gentoo noch an einigen Kleinigkeiten, die sich zwar vielleicht beheben lassen, aber einen produktiven Einsatz eigentlich verhindern.

Recht problemlos lässt sich dagegen Debian als Gast verwenden. Dazu bereitet man mit »debootstrap« ein System vor und packt es für die Installation unter OpenVZ:

cd /vz/template/cache
mkdir debian_sarge
debootstrap sarge ./debian_sarge
cd debian_sarge 
tar zcvf ../debian_sarge.tar.gz .

Die Installation mit dem Werkzeug »vzctl« entpackt alles wieder unter »/vz/private/ID« und nimmt durch das Skript »/etc/vz/dists/scripts/postcreate.sh« einige Anpassungen vor:

vzctl create 2005 --ostemplate debian-sarge --ipadd 192.168.39.25 --hostname ovz05

Anschließend ist der virtuelle Server lauffähig. OpenVZ startet allerdings jedes Gastsystem über »/sbin/init«. Die von dort gestarteten »getty«-Prozesse sind wegen des fehlenden Hardwarezugriffs nutzlos, genauso wie »klogd«, denn OpenVZ entfernt »/proc/kmsg«. Dieses Problem sollte der Admin gleich beheben und die Dienste deaktivieren. Da die Bootskripte selbst keine Mounts ausführen, sollte er auch »/etc/mtab« durch einen symbolischen Link auf »/proc/mounts« ersetzen.

»vzctl enter 2005« wechselt in den Kontext des Virtual Private Server (VPS). Achtung: Die Umgebungsvariablen der Bash sind kontrolliert beziehungsweise explizit zu setzen. Nach einem »apt-get update«-Durchlauf lässt sich jetzt noch die benötigte Software installieren. Sinnvoll ist es, das auf diese Weise modifizierte Gastsystem als Debian-Template zu sichern, um später weitere Systeme daraus erzeugen zu können.

Sind beim Starten und Stoppen der VPS spezielle Aktionen für einen der virtuellen Server auszuführen, kann dies über entsprechende Skripte geschehen. Anders als es das OpenVZ-Handbuch beschreibt, sucht das Gentoo-Wirtssystem unter sie »/etc/vz/VSID.[mount/umount/start/stop]«. Die Mount-Umount-Skripte werden noch im Wirtskontext ausgeführt, die Start-Stop-Skripte dagegen bereits im Kontext des neuen virtuellen Servers.

Auf [2] können sich interessierte Anwender für eine Reihe von Distributionen angepasste Templates herunterladen. Neben Debian stehen derzeit schon Centos- sowie Fedora-Templates bereit. So können auch diese Systeme bequem aufgesetzt werden.

Einschränkungen

Leider sind die geschilderten Methoden, um eine Vielzahl von virtuellen Servern effektiv zu verwalten, auf OpenVZ (noch) nicht anwendbar. Doch dafür hat SWsoft schließlich auch das kommerzielle Produkt Virtuozzo. Union-FS ist nicht kompatibel zu dem etwas angestaubten Kernel 2.6.8 und auch die BME-Patches lassen sich nicht anwenden. Das wird sich aber mit der Unterstützung neuerer Kernel ändern.

Als Ausweg bietet sich in diesem Fall nur die Auslagerung der VS-Dateisysteme auf einen performanten NFS-Server an, mit dem die oben genannten Möglichkeiten wieder offen stehen. Dann ist auch eine bequeme Migration der virtuellen Server von einem physischen Host auf einen anderen möglich.

Weitere Möglichkeiten

Damit sind die Möglichkeiten der beiden Projekte aber längst nicht ausgeschöpft. Neben der effektiven Verwaltung der Vserver ist es wichtig, deren Ressourcenverbrauch gut zu steuern. Das betrifft einerseits den Festplattenplatz und andererseits die CPU-Auslastung. Auch hierfür bieten beide Projekte geeignete Mechanismen wie zum Beispiel Quoten für den Plattenplatz oder Fair-Share-Scheduling für die Verteilung der Ressource CPU. (jcb)

Infos

[1] Linux Vserver: [http://linux-vserver.org]

[2] OpenVZ: [http://openvz.org]

[3] SWsoft Virtuozzo: [http://www.virtuozzo.com]

[4] Gentoo VPS: [http://dev.croup.de/proj/gentoo-vps]

[5] Gentoo-Vserver-Utils-Projekt: [http://dev.croup.de/proj/vserver-utils]

[6] Union-FS-Homepage: [http://www.fsl.cs.sunysb.edu/project-unionfs.html]

[7] Oliver Frommel, “Glücklich vereint”: Linux-Magazin 10/05, S. 42

[8] Vserver-Developement, Union-FS-Patch: [http://mozart.informatik.fh-kl.de/download/Software/VServer/vserver.html]

[9] VMware: [http://www.vmware.com]

[10] Microsoft Virtual Server und Virtual PC: [http://www.microsoft.com/windows/virtualpc/default.mspx] und [http://www.microsoft.com/windowsserversystem/virtualserver/default.mspx]

Die Autoren

Dipl.-Inf. Torsten Kockler arbeitet als Assistent des Ko-Autors dieses Artikels im Fachbereich Informatik/Mikrosystemtechnik an der FH Kaiserslautern in Zweibrücken, und zwar in den Lehrgebieten Betriebssysteme sowie Programmiersprachen.

Prof. Dr.-Ing. Wilhelm Meier ist an der FH Kaiserslautern in Zweibrücken als Dozent im Fachbereich Informatik/Mikrosystemtechnik für das Lehrgebiet Betriebssysteme tätig.

LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben