Mise à jour le 21/07/09: la version de dev (!) permet désormais de daemoniser le lancement d'un container.

Mise à jour le 31/08/09: remarques concernant la nouvelle version

Mise à jour le 05/09/09 : Voir commentaires




Ce nouveau projet de virtualisation/isolation semble bien prometteur d'autant que IBM est sur l'affaire.

Pour mettre en place cette solution je me suis aidé de:

http://www.ibm.com/developerworks/linux/library/l-lxc-containers/

http://lxc.sourceforge.net/lxc.html

http://download.boulder.ibm.com/ibmdl/pub/software/dw/linux/l-lxc-containers/l-lxc-containers-pdf.pdf

L'install a été réalisée dans une vmware sur une debian lenny x86_64. L'avantage de cette solution par rapport à openvz ou linux-vserver est qu'elle ne nécessite AUCUN patch pour le noyau. Il faudra cependant utiliser un noyau >= 2.6.29 ce qui implique de mettre les mains dans le camboui et se recompiler un petit noyau en attendant des versions plus récentes dans les distribs (ubuntu 9.10 ou debian dans quelques années malheureusement).

Un extrait de la doc:


Containers provide lightweight virtualization that lets you isolate processes and resources without the need to provide instruction interpretation mechanisms and
other complexities of full virtualization. In this step-by-step tour of the container tools called Linux® Containers (LXC), the author introduces you to the tools and shows
how to get up and running on them.
Containers effectively partition the resources managed by a single operating system into isolated groups to better balance the conflicting demands on resource usage
between the isolated groups. In contrast to virtualization, neither instruction-level emulation nor just-in-time compilation is required. Containers can run instructions
native to the core CPU without any special interpretation mechanisms. None of the complexities of paravirtualization or system call thunking are required either.

By providing a way to create and enter containers, an operating system gives applications the illusion of running on a separate machine while at the same time
sharing many of the underlying resources. For example, the page cache of common files—glibc for example—may effectively be shared because all containers use the
same kernel and, depending on the container configuration, frequent the same libc library.
This sharing can often extend to other files in directories that do not need to be written to.
The savings realized by sharing these resources, while also providing isolation, mean that containers have significantly lower overhead than true virtualization.

Dans le même temps une petite discussion sur l'irc de linux-vserver (irc://irc.oftc.net#vserver) me laissait entendre que :

[11:02] <xxxx> are there any fundamental differences between linux containers and vservers?
[11:05] <yyyy> Linux-VServer _are_ a form of linux containers (lightweight isolation)
[11:06] <yyyy> if you mean the LXC project, it is very new and (at least a month ago) looked quite incomplete
[11:07] <xxxx> yeah i played a round a bit with it and i feels a bit incomplete
[11:08] <xxxx> LXC also focuses on virtualization instead of isolation, so certain things have twice the overhead of a normal system (or a Linux-VServer guest)

Donc virtualisation ou isolation ? Et du coup surcharge ou non ?

Le plus simple est donc de tester .

La machine de test (après install et 1 container en fonction):

srvglus237:/# uname -a
Linux srvglus237 2.6.30.1 #3 Thu Jul 9 17:23:44 CEST 2009 x86_64 GNU/Linux

srvglus237:/# cat /etc/issue.net
Debian GNU/Linux 5.0

srvglus237:/# free
             total       used       free     shared    buffers     cached
Mem:        160524     141840      18684          0       8516     104228
-/+ buffers/cache:      29096     131428
Swap:       152576          0     152576

srvglus237:/# df -hT
Sys. de fich. Type     Tail. Occ. Disp. %Occ. Monté sur
/dev/sda1     ext3    1,9G  1,2G  585M  68% /
tmpfs        tmpfs     79M     0   79M   0% /lib/init/rw
udev         tmpfs     10M   88K   10M   1% /dev
tmpfs        tmpfs     79M     0   79M   0% /dev/shm
/dev/sdb1     ext3    564M  296M  240M  56% /usr/share
/dev/sdb2     ext3    433M  218M  194M  53% /var
/dev/sdc1     ext3   1004M  640M  314M  68% /usr/src
/dev/sdd1     ext3    496M  417M   54M  89% /lxc

srvglus237:/tmp# lspci
00:00.0 Host bridge: Intel Corporation 440BX/ZX/DX - 82443BX/ZX/DX Host bridge (rev 01)
00:01.0 PCI bridge: Intel Corporation 440BX/ZX/DX - 82443BX/ZX/DX AGP bridge (rev 01)
00:07.0 ISA bridge: Intel Corporation 82371AB/EB/MB PIIX4 ISA (rev 08)
00:07.1 IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)
00:07.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 08)
00:0f.0 VGA compatible controller: VMware Inc Abstract SVGA II Adapter
00:10.0 SCSI storage controller: LSI Logic / Symbios Logic 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (rev 01)
00:11.0 Ethernet controller: Intel Corporation 82545EM Gigabit Ethernet Controller (Copper) (rev 01)


srvglus237:/# ifconfig
br0       Link encap:Ethernet  HWaddr 00:0c:29:ad:4c:72 
          inet adr:192.168.1.237  Bcast:192.168.1.255  Masque:255.255.255.0
          adr inet6: fe80::20c:29ff:fead:4c72/64 Scope:Lien
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3421 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2684 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:0
          RX bytes:292017 (285.1 KiB)  TX bytes:610251 (595.9 KiB)

eth0      Link encap:Ethernet  HWaddr 00:0c:29:ad:4c:72 
          adr inet6: fe80::20c:29ff:fead:4c72/64 Scope:Lien
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:11279 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3325 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:1000
          RX bytes:2900768 (2.7 MiB)  TX bytes:654235 (638.9 KiB)

lo        Link encap:Boucle locale 
          inet adr:127.0.0.1  Masque:255.0.0.0
          adr inet6: ::1/128 Scope:H
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

veth0_1951 Link encap:Ethernet  HWaddr 62:90:ec:b1:9c:2a 
          adr inet6: fe80::6090:ecff:feb1:9c2a/64 Scope:Lien
          UP BROADCAST RUNNING PROMISC MULTICAST  MTU:1500  Metric:1
          RX packets:658 errors:0 dropped:0 overruns:0 frame:0
          TX packets:955 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:1000
          RX bytes:35798 (34.9 KiB)  TX bytes:1049035 (1.0 MiB)

srvglus237:/# uptime
 18:43:21 up  1:08,  2 users,  load average: 0.00, 0.00, 0.00

srvglus237:/tmp# lsmod
Module                  Size  Used by
veth                    5888  0
ipv6                  271856  28
bridge                 47784  0
stp                     2764  1 bridge
llc                     6928  2 bridge,stp
serio_raw               5756  0
pcspkr                  2584  0
e1000                 114104  0
i2c_piix4              10888  0
i2c_core               25288  1 i2c_piix4
container               4152  0
shpchp                 32804  0
pci_hotplug            29000  1 shpchp
intel_agp              28704  1
ac                      5120  0
thermal                16024  0
button                  6520  0
processor              27344  0
thermal_sys            15192  2 thermal,processor



On passe à la compil d'un noyau 2.6.30.1 (autant prendre le dernier). Je présume que les outils de dev sont installés sur la machine (build-essential, etc...)


srvglus237:/# cd /usr/src

srvglus237:/usr/src# wget ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.30.1.tar.bz2

srvglus237:/usr/src# tar jxvf linux-2.6.30.1.tar.bz2 && rm linux-2.6.30.1.tar.bz2

srvglus237:/usr/src# cd linux-2.6.30.1/

srvglus237:/usr/src/linux-2.6.30.1# make menuconfig

Il y aura plusieurs options à valider impérativement dont le détail est donné sur les copies d'écrans suivantes:

lxc config kernel lxc config kernel lxc config kernel lxc config kernel
lxc

Je laisse à dispo le .config utilisé pour la compil sur cette machine sachant que:

1) c'est une vmware (pas de support ata,sata juste scsi avec driver LSI)
2) pas de support carte son

srvglus237:/usr/src/linux-2.6.30.1#make
srvglus237:/usr/src/linux-2.6.30.1#make modules_install
srvglus237:/usr/src/linux-2.6.30.1# make install
srvglus237:/usr/src/linux-2.6.30.1# update-grub

.....REBOOT.....

Je me reconnecte et monte tout de suite cgroup qui est un pré-requis

Extrait de l'aide du noyau:
This option adds support for grouping sets of processes together, for 
use with process control subsystems such as Cpusets, CFS, memory
controls or device isolation. 


srvglus237:/# mkdir /cgroup
srvglus237:/# mount -t cgroup cgroup /cgroup

srvglus237:/tmp# df -hTa
Sys. de fich. Type     Tail. Occ. Disp. %Occ. Monté sur
/dev/sda1     ext3    1,9G  1,2G  585M  68% /
tmpfs        tmpfs     79M     0   79M   0% /lib/init/rw
proc          proc       0     0     0   -  /proc
sysfs        sysfs       0     0     0   -  /sys
udev         tmpfs     10M   88K   10M   1% /dev
tmpfs        tmpfs     79M     0   79M   0% /dev/shm
devpts      devpts       0     0     0   -  /dev/pts
/dev/sdb1     ext3    564M  296M  240M  56% /usr/share
/dev/sdb2     ext3    433M  218M  194M  53% /var
/dev/sdc1     ext3   1004M  640M  314M  68% /usr/src
/dev/sdd1     ext3    496M  417M   54M  89% /lxc
cgroup      cgroup       0     0     0   -  /cgroup
df: `/proc/2338/net': Aucun fichier ou répertoire de ce type

La dernière ligne n'est pas une erreur mais le démarrage d'une vm entraine la modification de certains params du noyau et sur celle-ci justement un container est en fonctionnement.

Il faut ensuite installer les outils pour gérer les containers. Comme indiqué en début d'article ce projet est jeune et pour l'instant il n'y a pas de paquets dispos sur nos distribs favorites (au moins en stable). On va donc récupérer les sources et compiler ce joli monde après avoir installé certains paquets nécessaires:


srvglus237:~# apt-get install deboostrap bison flex

srvglus237:~# apt-get install libdb4.2-dev

srvglus237:~# apt-get install libcap2 libcap2-bin libcap2-dev


Le paquet iproute2 n'est pas dispo chez debian:

srvglus237:/# cd /usr/local

srvglus237:/usr/local# wget http://devresources.linux-foundation.org/dev/iproute2/download/iproute2-2.6.26.tar.bz2

srvglus237:/usr/local# tar jxvf iproute2-2.6.26.tar.bz2 && mv iproute2-2.6.26.tar.bz2 src

srvglus237:/usr/local# cd iproute2-2.6.26

srvglus237:/usr/local/iproute2-2.6.26# ./configure && make
....
make[1]: quittant le répertoire « /usr/local/iproute2-2.6.26/genl »

srvglus237:/usr/local/iproute2-2.6.26# make install


Maintenant les outils lxc:

srvglus237:/# cd /usr/local

srvglus237:/usr/local# wget http://downloads.sourceforge.net/sourceforge/lxc/lxc-0.6.2.tar.gz?use_mirror=freefr

srvglus237:/usr/local# tar zxvf lxc-0.6.2.tar.gz && mv lxc-0.6.2.tar.gz src

srvglus237:/usr/local# cd lxc-0.6.2


srvglus237:/usr/local/lxc-0.6.2# ./configure
.....
config.status: executing depfiles commands
config.status: executing default commands
configure:

Warning:
--------
The docbook tool is not installed, the man pages won't be generated.
If you want the man pages, install docbook and rerun 'configure'.



srvglus237:/usr/local/lxc-0.6.2#

srvglus237:/usr/local/lxc-0.6.2# make
OK
srvglus237:/usr/local/lxc-0.6.2# make install

Voyons donc les binaires mis à disposition dans /usr/local/bin:

srvglus237:/usr/local/bin# lxc-<TAB>
lxc-cgroup       lxc-console      lxc-destroy      lxc-freeze       lxc-monitor      lxc-restart      lxc-start        lxc-unshare
lxc-checkconfig  lxc-create       lxc-execute      lxc-info         lxc-netstat      lxc-setcap       lxc-stop         lxc-version
lxc-checkpoint   lxc-debian       lxc-fedora       lxc-ls           lxc-ps           lxc-sshd         lxc-unfreeze     lxc-wait

srvglus237:~# lxc-info
lxc-info: error while loading shared libraries: liblxc-0.6.2.so: cannot open shared object file: No such file or directory

Petite frayeur vite solutionnée:

srvglus237:~# cd /usr/local
srvglus237:/usr/local# find . -name liblxc-0.6.2.so
./lxc-0.6.2/src/lxc/.libs/liblxc-0.6.2.so
./lib/liblxc-0.6.2.so

srvglus237:/usr/local# ldconfig -v

srvglus237:/usr/local# lxc-info
lxc-info <command>
     -n <name>   : name of the container


On commence à se faire une petite idée: lxc-start fait tout de suite penser à vzctl start (openvz) ou vserver name start (linux-vserver).

Il faut ensuite configurer un bridge sur lequel s'appuiera l'interface virtuelle : j'installe donc les bridge-utils et configure :


srvglus237:~# apt-get install bridge-utils

srvglus237:~# brctl addbr br0

srvglus237:~# cd /etc/network

Une sauvegarde du fichier d'origine
srvglus237:/etc/network# cp interfaces interfaces.origine

Puis modif de interfaces et résultat:

srvglus237:/etc/network# cat interfaces | egrep -v '^#|^$'
auto lo eth0
iface lo inet loopback
auto br0
iface br0 inet static
    address 192.168.1.237
    netmask 255.255.255.0
    network 192.168.1.0
    gateway 192.168.1.1
    bridge_ports eth0
    bridge_stp off
    bridge_maxwait 5
    # dns-* options are implemented by the resolvconf package, if installed
    dns-nameservers 192.168.1.1
    dns-search net.pat

Evidemment ce genre de modif implique un redémarrage de la couche réseau. Pensez-y si vous travailler à distance !


srvglus237:/etc/network# logout

Sur la console en tty1:
srvglus237:~# /etc/init.d/networking restart

Je me reconnecte et vérifie:

root@pme-linux:~# ssh root@192.168.1.237
root@192.168.1.237's password:
channel 0: open failed: administratively prohibited: open failed
Linux srvglus237 2.6.30.1 #1 Wed Jul 8 19:17:41 CEST 2009 x86_64
Last login: Wed Jul  8 20:08:14 2009

srvglus237:~# ifconfig
br0       Link encap:Ethernet  HWaddr 00:0c:29:ad:4c:72 
          inet adr:192.168.1.237  Bcast:192.168.1.255  Masque:255.255.255.0
          adr inet6: fe80::20c:29ff:fead:4c72/64 Scope:Lien
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:45 errors:0 dropped:0 overruns:0 frame:0
          TX packets:38 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:0
          RX bytes:5164 (5.0 KiB)  TX bytes:5680 (5.5 KiB)

eth0      Link encap:Ethernet  HWaddr 00:0c:29:ad:4c:72 
          adr inet6: fe80::20c:29ff:fead:4c72/64 Scope:Lien
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:4006 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3044 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:1000
          RX bytes:421625 (411.7 KiB)  TX bytes:452340 (441.7 KiB)

lo        Link encap:Boucle locale 
          inet adr:127.0.0.1  Masque:255.0.0.0
          adr inet6: ::1/128 Scope:Hôte
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

C'est bon. On continue:


Je vais installer ma première machine virtuelle en utilisant le script: lxc-debian mais auparavant je modifie celui-ci en ligne 252 sachant que je préfére utiliser mon apt-proxy local pour procéder à un debootstrap.

Ligne 252 du script /usr/local/bin/lxc-debian

     lenny $CACHE/partial-$ARCH http://192.168.1.80:9999/debian

On peut également renseigner à l'avance certaines variables endébut de script: ip allouée, passerelle.

Attention: la création de la machine virtuelle s'effectuera par défaut par rapport au répertoire où vous avez lancée la commande: si vous êtes sur /home
il va créer: /home/rootfs.[nom que vous donnez]. Donc pensez à dédier une partition pour la création des vm et positionnez-vous dans celle-ci ou indiquez le chemin complet lorsqu'il vous pose la question: Specify the location of the rootfs

srvglus237:/# lxc-debian create
What is the name for the container ? [debian] debian
What hostname do you wish for this container ? [debian]
What IP address do you wish for this container ? [192.168.1.232]
What is the gateway IP address ? [192.168.1.1]
What is the MTU size ? [1500]
Specify the location of the rootfs [./rootfs.debian]
Choose your architecture
1) amd64
2) i386
#? 1
Architecture amd64 selected
Checking cache download ...not cached
Downloading debian minimal ...
I: Retrieving Release
I: Retrieving Packages
I: Validating Packages
I: Resolving dependencies of required packages...
....
I: Configuring apache2-mpm-worker...
I: Configuring apache2...
I: Base system installed successfully.
Download complete.
Copying rootfs ...


La seule question qui vous est posée concerne les locales à générer: j'ai opte pour fr_FR.ISO-8859-1 et fr_FR.UTF-8.

Generating locales (this might take a while)...
  fr_FR.ISO-8859-1... done
  fr_FR.UTF-8... done
Generation complete.
 Removing any system startup links for /etc/init.d/umountfs ...
   /etc/rc0.d/S40umountfs
   /etc/rc6.d/S40umountfs
 Removing any system startup links for /etc/init.d/hwclock.sh ...
   /etc/rc0.d/K25hwclock.sh
   /etc/rc6.d/K25hwclock.sh
   /etc/rcS.d/S11hwclock.sh
 Removing any system startup links for /etc/init.d/hwclockfirst.sh ...
   /etc/rcS.d/S08hwclockfirst.sh
Done.

You can run your container with the 'lxc-start -n debian'

Eh bien allons-y !!!

srvglus237:~# lxc-start -n debian

INIT: version 2.86 booting
Activating swap...done.
Cleaning up ifupdown....
Checking file systems...fsck 1.41.3 (12-Oct-2008)
done.
Setting kernel variables (/etc/sysctl.conf)...done.
Mounting local filesystems...done.
Activating swapfile swap...done.
/etc/rcS.d/S37mountoverflowtmp: line 31: test: 1024-blocks: integer expression expected
Setting up networking....
Configuring network interfaces...if-up.d/mountnfs[eth0]: waiting for interface lo before doing NFS mounts (warning).
done.
INIT: Entering runlevel: 3
Starting OpenBSD Secure Shell server: sshd.
Starting web server: apache2apache2: apr_sockaddr_info_get() failed for debian
apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
.

Debian GNU/Linux 5.0 debian console

debian login:

BINGO !!!  

Je me loggue en root sans mot de passe et fais le tour du propriètaire:

debian:~# hostname
debian
debian:~# ifconfig
eth0      Link encap:Ethernet  HWaddr 6e:e3:05:37:6f:30 
          inet adr:192.168.1.232  Bcast:0.0.0.0  Masque:255.255.255.0
          adr inet6: fe80::6ce3:5ff:fe37:6f30/64 Scope:Lien
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:54 errors:0 dropped:0 overruns:0 frame:0
          TX packets:22 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:1000
          RX bytes:15267 (14.9 KiB)  TX bytes:928 (928.0 B)

lo        Link encap:Boucle locale 
          inet adr:127.0.0.1  Masque:255.0.0.0
          adr inet6: ::1/128 Scope:H
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:3 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:0
          RX bytes:240 (240.0 B)  TX bytes:240 (240.0 B)


debian:~# ps ax
  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:00 init [3] 
  264 ?        Ss     0:00 /usr/sbin/sshd
  278 ?        Ss     0:00 /usr/sbin/apache2 -k start
  281 ?        S      0:00 /usr/sbin/apache2 -k start
  284 ?        Sl     0:00 /usr/sbin/apache2 -k start
  316 ?        Sl     0:00 /usr/sbin/apache2 -k start
  352 console  Ss     0:00 /bin/login --    
  353 tty1     Ss+    0:00 /sbin/getty 38400 tty1 linux
  354 tty2     Ss+    0:00 /sbin/getty 38400 tty2 linux
  355 tty3     Ss+    0:00 /sbin/getty 38400 tty3 linux
  356 tty4     Ss+    0:00 /sbin/getty 38400 tty4 linux
  357 console  R      0:00 -bash
  363 console  R+     0:00 ps ax

debian:~# netstat -lnp
Connexions Internet actives (seulement serveurs)
Proto Recv-Q Send-Q Adresse locale          Adresse distante        Etat        PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      264/sshd       
tcp6       0      0 :::80                   :::*                    LISTEN      278/apache2    
tcp6       0      0 :::22                   :::*                    LISTEN      264/sshd       
Sockets du domaine UNIX actives(seulement serveurs)
Proto RefCnt Flags       Type       State         I-Node   PID/Program name    Chemin
unix  2      [ ACC ]     STREAM     LISTENING     3866     281/apache2         /var/run/apache2/cgisock.278

debian:~# apt-get update
Reception de: 1 http://ftp.debian.org lenny Release.gpg [1032B]
Reception de: 2 http://ftp.debian.org lenny/main Translation-fr [940kB]
Atteint http://ftp.debian.org lenny Release                  
Ign http://ftp.debian.org lenny/main Packages/DiffIndex      
Atteint http://ftp.debian.org lenny/main Packages
941ko receptionnes en 1s (549ko/s)
Lecture des listes de paquets... Fait

Tout fonctionne au poil, du moins ce dont j'ai besoin.

Mise à jour 20/07/09: lorsqu'on démarre le serveur virtuel depuis l'hôte avec lxc-start -n <nom du container> on se retrouve sur la console du serveur virtuel sans possibilité de "retourner" dans l'hôte (à la différence de lxc-console mais cette commande n'est valide que pour les containers à l'état RUNNING). L'auteur m'a signalé que la prochaine version permettrait de daemoniser le lancement des containers.



On peut également se connecter sur un tty avec l'outil: lxc-console:

srvglus237:/tmp# lxc-console -n debian -t 1

Type <Ctrl+a q> to exit the console

Debian GNU/Linux 5.0 debian tty1

debian login:


Je me reconnecte donc sur l'hôte depuis mon poste et manipule un peu les commandes lxc:

srvglus237:~# lxc-ps -n debian
  PID TTY      STAT   TIME COMMAND
 1951 ?        Ss     0:00 init [3] 
 2237 ?        Ss     0:00 /usr/sbin/sshd
 2251 ?        Ss     0:00 /usr/sbin/apache2 -k start
 2254 ?        S      0:00 /usr/sbin/apache2 -k start
 2257 ?        Sl     0:00 /usr/sbin/apache2 -k start
 2289 ?        Sl     0:00 /usr/sbin/apache2 -k start
 2325 pts/0    Ss     0:00 /bin/login --    
 2326 pts/1    Ss+    0:00 /sbin/getty 38400 tty1 linux
 2327 pts/2    Ss+    0:00 /sbin/getty 38400 tty2 linux
 2328 pts/3    Ss+    0:00 /sbin/getty 38400 tty3 linux
 2329 pts/4    Ss+    0:00 /sbin/getty 38400 tty4 linux
 2330 pts/0    S+     0:00 -bash


srvglus237:~# lxc-checkconfig -n debian
--- Namespaces ---
Namespaces: enabled
Utsname namespace: enabled
Ipc namespace: enabled
Pid namespace: enabled
User namespace: enabled
Network namespace: enabled
Multiple /dev/pts instances: enabled

--- Control groups ---
Cgroup: enabled
Cgroup namespace: enabled
Cgroup device: enabled
Cgroup sched: disabled
Cgroup cpu account: enabled
Cgroup memory controller: enabled
Cgroup cpuset: enabled

--- Misc ---
Veth pair device: enabled
Macvlan: disabled

On peut également freezer la vm (ce qui correspond au mode suspend sur vmware) en cas de surcharge par exemple:

srvglus237:~#  lxc-freeze
lxc-freeze <command>
     -n <name>   : name of the container
srvglus237:~#  lxc-freeze -n debian
srvglus237:~#  lxc-info -n debian
'debian' is FROZEN
srvglus237:~# lxc-unfreeze -n debian
srvglus237:~# lxc-info -n debian
'debian' is RUNNING



On retrouve la "config" de la machine virtuelle ici (similitude encore une fois avec openvz et linux-vserver à ceci près que les chemins ne sont pas les mêmes évidemment)

srvglus237:/usr/local/var/lib/lxc/debian# ll
total 44
drwxr-sr-x 4 root staff 4096 jui  9 17:45 .
drwxrwsrwx 6 root staff 4096 jui  9 19:32 ..
-rw-r--r-- 1 root staff  283 jui  9 00:35 cgroup
-rw-r----- 1 root staff   72 jui  9 00:35 fstab
-rw------- 1 root staff    5 jui  9 17:45 init
drwxr-sr-x 3 root staff 4096 jui  9 00:35 network
lrwxrwxrwx 1 root staff   12 jui  9 17:45 nsgroup -> /cgroup/1951
-rwxr-xr-x 1 root staff    6 jui  9 00:35 pts
drwxr-sr-x 2 root staff 4096 jui  9 00:35 rootfs
-rw------- 1 root staff    7 jui  9 17:45 state
-rwxr-xr-x 1 root staff    3 jui  9 00:35 tty
-rwxr-xr-x 1 root staff    8 jui  9 00:35 utsname

Petit inconvénient par rapport à linux-vserver: tous les process de toutes les machines sont visibles sur l'hôte: exemple j'ai démarré un apache sur la machine virtuelle et j'en ai démarré un autre sur l'hôte:

=> Ajouté le 190709 suite à un mail reçu de l'auteur daniel.lezcano [at] free.fr: comme indiqué plus haut il est cependant possible de ne lister que les process d'un serveur virtuel particulier avec lxc-ps

srvglus237:/tmp# ps ax
  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:01 init [2] 
    2 ?        S<     0:00 [kthreadd]
    3 ?        S<     0:00 [ksoftirqd/0]
    4 ?        S<     0:00 [events/0]
    5 ?        S<     0:00 [cpuset]
    6 ?        S<     0:00 [khelper]
    9 ?        S<     0:00 [netns]
   12 ?        S<     0:00 [async/mgr]
   62 ?        S<     0:00 [kblockd/0]
   64 ?        S<     0:00 [kacpid]
   65 ?        S<     0:00 [kacpi_notify]
  113 ?        S<     0:00 [kseriod]
  162 ?        S      0:00 [pdflush]
  163 ?        S<     0:00 [kswapd0]
  211 ?        S<     0:00 [aio/0]
  221 ?        S<     0:00 [crypto/0]
  352 ?        S<     0:00 [scsi_tgtd/0]
  362 ?        S<     0:00 [mpt_poll_0]
  363 ?        S<     0:00 [scsi_eh_0]
  430 ?        S<     0:00 [kjournald]
  507 ?        S<s    0:00 udevd --daemon
 1105 ?        S<     0:00 [kjournald]
 1106 ?        S<     0:00 [kjournald]
 1107 ?        S<     0:00 [kjournald]
 1108 ?        S<     0:00 [kjournald]
 1368 ?        Ss     0:00 /sbin/syslogd -m 0
 1377 ?        Ss     0:00 /sbin/klogd -x
 1386 ?        Ss     0:00 /usr/sbin/acpid
 1396 ?        Ss     0:00 /usr/bin/dbus-daemon --system
 1415 ?        S      0:00 /usr/sbin/dnsmasq -u dnsmasq
 1426 ?        Ss     0:00 /usr/sbin/sshd
 1492 ?        Ss     0:00 /usr/sbin/cron
 1509 tty1     Ss+    0:00 /sbin/getty 38400 tty1
 1510 tty2     Ss+    0:00 /sbin/getty 38400 tty2
 1511 tty3     Ss+    0:00 /sbin/getty 38400 tty3
 1512 tty4     Ss+    0:00 /sbin/getty 38400 tty4
 1513 tty5     Ss+    0:00 /sbin/getty 38400 tty5
 1514 tty6     Ss+    0:00 /sbin/getty 38400 tty6
 1913 ?        Ss     0:00 sshd: root@pts/5
 1915 pts/5    Ss     0:00 -bash
 1928 ?        Ss     0:00 sshd: root@pts/0
 1930 ?        Ss     0:00 -bash
 1950 ?        S      0:00 lxc-start -n debian
 1951 ?        Ss     0:00 init [3] 
 2237 ?        Ss     0:00 /usr/sbin/sshd
 2251 ?        Ss     0:00 /usr/sbin/apache2 -k start
 2254 ?        S      0:00 /usr/sbin/apache2 -k start
 2257 ?        Sl     0:00 /usr/sbin/apache2 -k start
 2289 ?        Sl     0:00 /usr/sbin/apache2 -k start
 2325 pts/0    Ss     0:00 /bin/login --    
 2326 pts/1    Ss+    0:00 /sbin/getty 38400 tty1 linux
 2327 pts/2    Ss+    0:00 /sbin/getty 38400 tty2 linux
 2328 pts/3    Ss+    0:00 /sbin/getty 38400 tty3 linux
 2329 pts/4    Ss+    0:00 /sbin/getty 38400 tty4 linux
 2330 pts/0    S+     0:00 -bash
 2964 ?        S      0:00 [pdflush]
 3498 ?        Ss     0:00 /usr/sbin/apache2 -k start
 3504 ?        S      0:00 /usr/sbin/apache2 -k start
 3505 ?        S      0:00 /usr/sbin/apache2 -k start
 3506 ?        S      0:00 /usr/sbin/apache2 -k start
 3507 ?        S      0:00 /usr/sbin/apache2 -k start
 3508 ?        S      0:00 /usr/sbin/apache2 -k start
 3648 pts/5    R+     0:00 ps ax
srvglus237:/tmp#


Donc pour les différencier il faudra jouer du pstree -p par exemple:

srvglus237:/tmp# pstree -p -c
init(1)-+-acpid(1386)
        |-apache2(3498)-+-apache2(3504)
        |               |-apache2(3505)
        |               |-apache2(3506)
        |               |-apache2(3507)
        |               `-apache2(3508)
        |-cron(1492)
        |-dbus-daemon(1396)
        |-dnsmasq(1415)
        |-getty(1509)
        |-getty(1510)
        |-getty(1511)
        |-getty(1512)
        |-getty(1513)
        |-getty(1514)
        |-klogd(1377)
        |-sshd(1426)-+-sshd(1913)---bash(1915)---pstree(3653)
        |            `-sshd(1928)---bash(1930)---lxc-start(1950)---init(1951)-+-apache2(2251)-+-apache2(2254)
        |                                                                     |               |-apache2(2257)-+-{apache2}(2259)
        |                                                                     |               |               |-{apache2}(2260)
        |                                                                     |               |               |-{apache2}(2261)

............


Voilà c'est fini. Il faudra voir les évolutions mais déjà cela fournit une base de travail sympa pour faire du dev sur une machine dédiée à cela.

Pour info: je viens de remonter une nouvelle vmware lenny-x86_64 sur une autre machine en ayant suivi pas à pas ce billet: tout fonctionne et le temps d'install complet n'a pas excédé 1 heure .



Mise à jour le 21/07/09

Daniel Lezcano m'avait signalé que la verion de dev supporterait la daemonisation des containers: c'est chose faite  sachant qu'il s'agit d'une version de dev !!!

C'est un dépot git que j'ai récupéré comme ceci:

lxc:/usr/local# git clone git://lxc.git.sourceforge.net/gitroot/lxc

Initialized empty Git repository in /usr/local/lxc/.git/
remote: Counting objects: 2482, done.
remote: Compressing objects: 100% (1347/1347), done.
remote: Total 2482 (delta 1928), reused 1457 (delta 1123)
Receiving objects: 100% (2482/2482), 604.59 KiB | 553 KiB/s, done.
Resolving deltas: 100% (1928/1928), done.


Install d'un paquet manquant sur la machine:

lxc:/usr/local# apt-get install libtool
lxc:/usr/local# cd lxc
lxc:/usr/local/lxc# ./autogen.sh

puis la routine: ./configure && make && make install

Le démarrage d'un container peut donc désormais s'effectuer comme ceci:

lxc:~# lxc-start --name lxcvm1 -d -o /tmp/startlxcvm1  ou  lxc:~# lxc-start -n lxcvm1 -d -o /tmp/startlxcvm1

le -d daemonize le démarrage, le -o loggue celui-ci dans le fichier spécifié.

La commande lxc-ps semble également avoir été dotée de nouvelles fonctionnalités:

lxc:~# lxc-ps --lxc
CONTAINER    PID TTY          TIME CMD
lxcvm1     16580 ?        00:00:00 init
lxcvm1     16867 ?        00:00:00 syslogd
lxcvm1     16871 ?        00:00:00 klogd
lxcvm1     16878 ?        00:00:00 sshd
lxcvm1     16916 ?        00:00:00 mysqld_safe
lxcvm1     16955 ?        00:00:00 mysqld
lxcvm1     16957 ?        00:00:00 logger
lxcvm1     17014 ?        00:00:00 nullmailer-send
lxcvm1     17034 ?        00:00:00 cron
lxcvm1     17220 ?        00:00:00 apache2
lxcvm1     17233 pts/5    00:00:00 getty
lxcvm1     17234 pts/7    00:00:00 getty
lxcvm1     17235 pts/8    00:00:00 getty
lxcvm1     17236 pts/9    00:00:00 getty
lxcvm1     17238 ?        00:00:00 apache2
lxcvm1     17239 ?        00:00:00 apache2
lxcvm1     17240 ?        00:00:00 apache2
lxcvm1     17241 ?        00:00:00 apache2
lxcvm1     17242 ?        00:00:00 apache2
lxcvm2     17316 ?        00:00:00 init
lxcvm2     17604 ?        00:00:00 sshd
lxcvm2     17608 ?        00:00:00 lpd
lxcvm2     17621 pts/0    00:00:00 getty
lxcvm2     17622 pts/1    00:00:00 getty
lxcvm2     17623 pts/2    00:00:00 getty
lxcvm2     17624 pts/3    00:00:00 getty
lxcvm2     17676 ?        00:00:00 getty


REMARQUE: on peut être tenté de lancer dans une boucle le démarrage de tous les serveurs virtuels: Daniel recommande de temporiser avec un ping par exemple entre chaque machine:

Exemple en supposant que l'on dispose de 4 serveurs virtuels nommés lxcvm-1 lxcvm-2 lxcvm-3 lxcvm-4

for i in $(seq 1 4); do
    lxc-start -n lxcvm-$i;
   while $(true); do ping -q -c 1 192.168.0.0.$i 2>&1 > /dev/null && break; done
done

* Astuce (?): si vous créez plusieurs containers debian sur un hôte debian, il n'est pas nécessaire de stocker x fois les paquets téléchargés. Un montage en bind pourra vous faire gagner de la place: pour cela il suffira d'ajouter une ligne dans le fstab du container AVANT la ligne déclarant le rootfs:

lxc:/usr/local/var/lib/lxc/lxcvm2# cat fstab

/var/cache/apt/archives  /opt/rootfs.lxcvm2/var/cache/apt/archives none rbind 0 0
/opt/rootfs.lxcvm2 /usr/local/var/lib/lxc/lxcvm2/rootfs none rbind 0 0



Si vous souhaitez contribuer/poser des questions etc... vous pouvez aller sur l'irc : irc://irc.freenode.net#lxc-devel




Mise à jour le 31/08/09

J'ai constaté un petit problème avec la version 0.6.3 en fin de création d'un container:

lxc-create: No such file or directory - failed to create
/usr/local/var/lib/lxc directory
lxc-create: failed to create the container

En fait, renseignements pris auprès du dev, la création du répertoire /usr/local/var/lib/lxc n'est plus assurée par le script lxc-debian create ou lxc-create vu le nombre d'installs à gérer (tarball, rpm, deb...).

Donc au choix en attendant la correction:

1) Avant de lancer le script de création du container créer à la mano le répertoire nécessaire au stockage des fichiers de conf de celui-ci par un :

# mkdir -p /usr/local/var/lib/lxc


2) Lors de la configuration des outils lxc préciser lors du ./configure les options suivantes:

$ ./configure --prefix=/usr --localstatedir=/var --sysconfdir=/etc

Tout ceci ne concerne que ceux qui récupèrent les sources sur sourceforge. Pour ceux qui utilisent les paquets de la distrib ça doit être pris en compte.

Dans tous les cas, après avoir créé les répertoires-qui-vont-bien il suffit de relancer le script avec les mêmes params et la finalisation s'effectue sans reprendre toute l'install.






A noter un très bon article ici

Et un autre ici




Memo perso pour la maj en 0.7.4