LXC Linux Containers zijn een lichtgewicht alternatief voor virtuele servers. De containers maken gebruik van de kernel van de host, daarom kunnen alleen Linux systemen in containers draaien. Vaak is complete systeem-virtualisatie overbodig en bereik je met behulp van efficiënte LXC containers hetzelfde resultaat. Je kunt gelijktijdig een groot aantal containers naast elkaar op je Linux machine laten lopen.

Container-virtualisatie is geen echte vorm van virtualisatie, het wordt ook wel para-virtualisatie of operating system-level virtualisatie genoemd. Het verschil met “echte” virtualisatie is dat je geen hypervisor-laag hebt die hardware simuleert waarop een nieuw besturingssysteem gestart wordt. Containers draaien op de kernel van de host en zijn meer een soort veredelde chroot omgeving.

Het gebruik van containers voor lichtgewicht virtualisatie is niet nieuw. Het besturingssysteem Solaris kent bijvoorbeeld zones en FreeBSD heeft al jaren jails. Linux liep op dit gebied wat achter tot dat enkele jaren terug cgroups en namespaces in de Linux kernel werden geïntroduceerd. Dat maakte de weg vrij voor de ontwikkeling van containertechnologie. In de afgelopen zes jaar is LXC Linux Containers uitgegroeid tot een volwassen product en vorig jaar besloten de ontwikkelaars daarom de nieuwe versie “1.0” te noemen. LXC Linux containers stelt geen speciale eisen aan je hardware.

Snelle start

Containers hebben hun eigen omgeving, een eigen virtuele netwerk-interface met een eigen mac-adres en een eigen IP-nummer. Containers kun je vergelijken met een chroot omgeving, maar dan met eigen netwerkinstellingen en betere afscherming van de rest van het systeem. De overhead die “echte” virtualisatie met zich mee brengt, is bij containers afwezig. Wanneer je een container start, wordt er niet opnieuw een compleet besturingssysteem inclusief kernel en dergelijke gestart. Bij het starten van de container wordt geen hardware geïnitialiseerd, worden geen filesystem checks gedaan en dergelijke. Het voordeel hiervan is dat de container in korte tijd opstart en veel minder resources van het systeem vraagt dan andere virtualisatie-technieken.

Omdat de containers op de kernel van de host draaien, kun je in de container alleen een Linux omgeving laten draaien. Je kunt bijvoorbeeld wel andere distributies als container opstarten, mits die voor de kernel van de host geschikt zijn. Je kunt bijvoorbeeld geen 64-bits container op een 32-bit host draaien.

Userspace tools

Naast de functionaliteiten in de kernel om LXC Linux Containers te gebruiken, zijn een aantal userspace tools nodig. De LXC ontwikkelaars gebruiken Ubuntu als ontwikkelplatform. In een standaard Ubuntu installatie vind je recente versies van alle benodigde tools. Alle grote distributies hebben packages met de LXC-tools aan boord, dus je kunt ze op je eigen favoriete distributie gebruiken, maar voor een eerste kennismaking met LXC Linux Containers is een Ubuntu-systeem een goede keuze.

Op je systeem ziet een container eruit als een directory. Hierin vind je een configuratiebestand en een subdirectory met het rootfs van de container. Je kunt een deel van dat rootfs via zogenoemde bind-mounts opzetten. Dit maakt niet alleen de benodigde schijfruimte kleiner, maar je kunt deze bind-mounts ook read-only aan de container aanbieden.

 

Doordat een container weinig extra systeembelasting met zich meebrengt en het fysiek uit een directory bestaat, zijn ze op veel manieren nuttig inzetten. Een container is gemakkelijk te verplaatsen of te kopiëren. Wil je zeker weten dat je applicatie na een systeem-upgrade nog vlekkeloos draait? Kloon de container, start de kloon, voer de upgrade uit, test of alles naar wens is en verwijder daarna de kloon. Op deze wijze kun je bijvoorbeeld eenvoudig een OTAP-omgeving (Ontwikkel, Test, Acceptatie en Productie) realiseren. Natuurlijk dien je bij het klonen van een container wel ervoor te zorgen dat deze een eigen mac-adres en een eigen IP-nummer krijgt, om zo netwerkproblemen te voorkomen.

 

Flexibiliteit

Door je applicatie in een container te draaien, ontkoppel je deze van het systeem waar het op draait. Dit biedt veel flexibiliteit. Je kunt de container gemakkelijk migreren naar een andere host, bijvoorbeeld met behulp van rsync. Hierdoor houd je de downtime beperkt. Daarnaast biedt het gebruik van containers de mogelijkheid om verschillende versies van een applicatie naast elkaar op hetzelfde systeem te laten draaien of bijvoorbeeld naast elkaar Apache en Lighttpd als webserver. Verder kun je in een container een andere versie van je besturingssysteem draaien, bijvoorbeeld Debian stable op de host en Debian Sid als container, of Debian 8 als host en Debian 7 als container. Of twee verschillende distributies, bijvoorbeeld Debian als host en Gentoo als container, als ze maar met dezelfde kernel overweg kunnen. Wil je eens een andere desktop-omgeving uitproberen? Geen probleem, maak een container aan en gebruik deze als X-server of als systeem met RDP. Kortom, de mogelijkheden met containers zijn enorm.

 

Nu wordt het tijd om te gaan kennismaken met LXC Linux containers. We beginnen met een verse installatie van 64-bits Ubuntu 15.04. Wanneer de installatie is voltooid, log je in en open je een terminal scherm. Voor de zekerheid doen we eerst een systeem-upgrade, met ‘sudo apt-get update’ gevolgd door ‘sudo apt-get upgrade’. Hierna installeer je LXC met behulp van het commando ‘sudo apt-get install lxc’.

 

Nieuwe container

We gaan nu onze eerste container aanmaken met behulp van het commando: ‘lxc-create -t download -n eerste’. De switch ‘-t download’ geeft aan dat we gebruik willen maken van een nog te downloaden template. De switch ‘-n eerste’ geeft de te maken container de naam ‘eerste’.

 

De switch ‘-n containernaam’ komen we tegen in de syntax van alle lxc commando’s die betrekking hebben op een specifieke container. Na invoer van bovenstaand lxc-create commando krijg je een lijst met templates te zien waar je er één uit kunt kiezen. De lijst bevat achtereenvolgens de kolommen distributie (bijvoorbeeld: Ubuntu), release (bijvoorbeeld: vivid), architectuur (bijvoorbeeld: amd64), variant (meestal default) en de bouw-datum van het template. Je wordt gevraagd om een keuze te maken, kies bijvoorbeeld voor ubuntu, vivid, i386. Het systeem gaat nu de betreffende template downloaden en gebruiken om de nieuwe container aan te maken. Je krijgt de melding dat wegens veiligheidsredenen de container geen gebruikers en geen root-wachtwoord bevat. We gaan daarom via chroot eerst een gebruiker aanmaken. Het gedownloade bestand wordt gecached, zodat de volgende keer dat je deze template gebruikt dit proces een stuk sneller gaat.

 

Alle containers komen in /var/lib/lxc te staan. Onze container met de naam ‘eerste’ staat daar nu, dit kun je zien met behulp van ‘sudo ls /var/lib/lxc’. Je ziet dat voor de container een directory /var/lib/lxc/eerste gemaakt is. Kijken we in die directory (met ‘sudo ls /var/lib/lxc/eerste’) dan zien we hierin het bestand config en een directory rootfs. Om de gebruiker aan te maken, moeten we een chroot naar dit rootfs doen: ‘sudo chroot /var/lib/lxc/eerste/rootfs’. Je bent nu root in het rootfs van de container. Dit kun je controleren door bijvoorbeeld naar de inhoud van het bestand hostname te kijken: ‘cat /etc/hostname’.

 

Nu we zeker weten dat we goed zitten, kun je een gebruiker voor jezelf aanmaken. In dit voorbeeld maken we de gebruiker annemarie aan: ‘adduser annemarie’. Het systeem vraagt om het invoeren van een wachtwoord voor annemarie en daarna ter controle nog een keer. Hierna kun je dingen als de volledige naam, kamernummer en dergelijke invoeren, wij hebben de gewoonte hier doorheen te enteren. Nadat de gebruiker annemarie is aangemaakt, moeten we ervoor zorgen dat deze gebruiker ook rechten krijgt om sudo commando’s uit te voeren, door annemarie lid te maken van de groepen ‘sudo’ en ‘adm’. Hiervoor gebruiken we het usermod commando: ‘usermod -aG sudo,adm annemarie’.

 

SSH-server

In de container is nog geen ssh geïnstalleerd, terwijl we straks graag via ssh toegang willen krijgen. Daarom installeren we nog snel even de ssh-server. Dit doe je door ‘apt-get update’ gevolgd door ‘apt-get install openssh-server’ (omdat je root bent, hoeft voorafgaand aan deze commando’s geen sudo te worden ingegeven).

 

Nu kun je de chroot-omgeving verlaten en de container opstarten. Met exit verlaat je de container. Met behulp van ‘cat /etc/hostname’ kun je dit weer controleren. Start de container op met behulp van het commando ‘sudo lxc-start -n eerste’. Met behulp van ‘sudo lxc-info -n eerste’ check je of de container draait. Je krijgt in dat geval een overzichtje met wat gegevens over de container, met onder andere State: RUNNING. Met ‘sudo lxc-ls -f’ vraag je het IP-nummer van de lopende containers op.

 

We zien dat de container een IP-nummer in het 10.0.3.xxx netwerk gekregen. Ubuntu heeft bij de installatie van LXC voor ons een lokale netwerkbridge en een lokale DHCP-server geïnstalleerd en de containers krijgen via NAT (netwerk-adres translation) een verbinding naar buiten de host. Nu je het IP-adres weet, kun je met ssh inloggen als de gebruiker die je hebt aangemaakt op de container. Je kunt nu wat rondkijken in de container. Wanneer je een ‘ps aux’ doet, zie je alleen de processen van de container, niet die van de host. Met ‘cat /proc/cpuinfo’ zie je de gegevens van de cpu van de host. Met behulp van ‘uname -a’ zie je dat je een i386 machine als container hebt. Vergelijk de uitkomst eens met de uitkomst van ‘uname -a’ op de host. Je kunt eenvoudig controleren of je een verbinding naar buiten hebt, bijvoorbeeld via ‘ping www.linuxmag.nl’. Zoals je ziet, lijkt het alsof je op een eigen systeem werkt. Je kunt nu bijvoorbeeld met sudo apt-get update en sudo apt-get install software op de container installeren.

 

Webserver

Wil je dat je container vanuit andere systemen op je netwerk bereikbaar is, bijvoorbeeld om een webserver te draaien, dan moeten we eigen bridge op de host configureren. Dit doen je door aan het bestand /etc/network/interfaces te wijzigen. Zie hiervoor listing 1. Je kunt hierbij de bridge bijvoorbeeld hetzelfde IP-adres geven als de host nu heeft, controleer ook het IP-adres van de nameserver en gateway. Hierna doe je een reboot, waarna eth0 geen IP-adres meer heeft en de bridge br0 het ingevoerde IP-adres. Nu moeten we nog in de config-file van de container de juiste bridge zetten, via ‘sudo vi /var/lib/lxc/eerste/config’ (of, in plaats van vi, je favoriete editor). Wijzig de regel ‘lxcbr0’ in ‘br0’. Wanneer je nu de container start, dan gaat deze via dhcp de netwerkinstellingen voor je netwerk opvragen. De container krijgt hiermee een IP-nummer in je netwerk waarmee deze rechtstreeks vanuit het netwerk te benaderen is. Dit betekent dat je nu bijvoorbeeld een webserver of een gitserver in de container kunt draaien.

 

De uitgebreide LXC-toolset bevat een aantal handige commando’s, zoals bijvoorbeeld lxc-freeze en lxc-unfreeze om containers te bevriezen en te ontdooien, en lxc-clone en lxc-snapshot om een kopie van een container te maken. Wanneer je met LXC aan de gang gaat, is het interessant om deze ook te bekijken. Kijk verder eens naar zogenoemde unprivileged containers. Dit zijn containers die je als user kunt opstarten en daardoor veiliger zijn.

 

Conclusie

LXC Linux containers is gemakkelijk te installeren en eenvoudig in gebruik. Wanneer je containers gaat gebruiken, ontdek je al snel hoe handig ze zijn. Voor je het weet kun je niet meer zonder.