Table of Contents

Comment convertir une image KVM en conteneur LXC

KVM (Kernel-based Virtual Machine) est une technologie de virtualisation Open Source intégrée à Linux. Avec KVM, on peut transformer Linux en un hyperviseur qui permet à une machine hôte d'exécuter plusieurs environnements virtuels isolés, appelés invités ou machines virtuelles, mais pour de nombreux cas d'utilisation, LXC est une alternative plus performante et légère.

En passant à LXC, on peu réduire l'utilisation globale de la mémoire - le principal avantage est que les processus au sein d'un conteneur LXC sont des processus distincts au sein du système hôte. Cela devrait permettre au système hôte de gérer la mémoire (cache, tampons, swap, etc.) plus efficacement.

Étape 1 : créer un nouveau conteneur lxc vide

Tout d'abord, créer un nouveau conteneur LXC vide avec une configuration par défaut, nommé par exemple 'imap':

lxc-create --name imap

Les conteneurs de LXC sont créés dans /var/lib/lxc, où un nouveau conteneur /var/lib/lxc/imap peut être trouvé. Le conteneur contient pour l'instant deux entrées : config pour sa configuration et un répertoire rootfs vide qui contiendra bientôt le système de fichiers du conteneur.

Étape 2 : copier l'image KVM dans le conteneur LXC

Chaque volume LVM reflète un disque dur physique, y compris les tables de partition, etc. Cela empêche de simplement monter l'image racine du KVM.

Tout d'abord, récupérer la table de partition de l'image KVM :

sudo fdisk -l /dev/vg0/imap.img

Disk /dev/vg0/imap.img: 107.4 GB, 107374182400 bytes
255 heads, 63 sectors/track, 13054 cylinders, total 209715200 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00022ea3

            Device Boot      Start         End      Blocks   Id  System
/dev/vg0/imap.img1   *        2048   209713151   104855552   83  Linux

Ainsi, le véritable système de fichiers commence au secteur 2048 et chaque secteur a une longueur de 512 octets. Cela permet de calculer le décalage de ces partitions dans l'image et de monter la partition en boucle dans le système de fichiers hôtes :

mount -o loop,offset=$((2048*512)) /dev/vg0/imap.img /mnt-source

On peut maintenant copier le contenu de l'ancienne image KVM dans le nouveau conteneur :

rsync -av /mnt-source/* /var/lib/lxc/imap/rootfs

Étape 3 : préparer les nœuds de périphérique du conteneur et corriger fstab

LXC ne prend pas en charge udev, il faut donc créer les nœuds de périphérique du conteneur. Pour simplifier cela, on peut utiliser le script bash suivant et le copier dans /usr/local/sbin/create-lxc-nodes.sh

#!/bin/bash
ROOT=$(pwd)
DEV=${ROOT}/dev
mv ${DEV} ${DEV}.old
mkdir -p ${DEV}
mknod -m 666 ${DEV}/null c 1 3
mknod -m 666 ${DEV}/zero c 1 5
mknod -m 666 ${DEV}/random c 1 8
mknod -m 666 ${DEV}/urandom c 1 9
mkdir -m 755 ${DEV}/pts
mkdir -m 1777 ${DEV}/shm
mknod -m 666 ${DEV}/tty c 5 0
mknod -m 600 ${DEV}/console c 5 1
mknod -m 666 ${DEV}/tty0 c 4 0
mknod -m 666 ${DEV}/tty1 c 4 1
mknod -m 666 ${DEV}/tty2 c 4 2
mknod -m 666 ${DEV}/tty3 c 4 3
mknod -m 666 ${DEV}/tty4 c 4 4
mknod -m 666 ${DEV}/tty5 c 4 5
mknod -m 666 ${DEV}/tty6 c 4 6
mknod -m 666 ${DEV}/full c 1 7
mknod -m 600 ${DEV}/initctl p
mknod -m 666 ${DEV}/ptmx c 5 2

Utiliser ce script pour créer tous les nœuds de devices nécessaires :

cd /var/lib/lxc/imap/rootfs
/usr/local/sbin/create-lxc-nodes.sh

Comme tous les systèmes de fichiers ont déjà été préparés par le système hôte, le système d'initialisation du système invité n'a pas besoin d'effectuer de travail pendant le démarrage (en fait, cela pourrait plutôt être nuisible). Pour éviter tout problème, commenter chaque ligne dans le fichier de configuration “etc/fstab” des invités.

Étape 4 : créer le fichier de configuration LXC

La configuration de chaque conteneur LXC est stockée dans le fichier “config” qui se trouve autour du répertoire “rootfs”. Crée un nouveau :

# Modèle utilisé pour créer ce conteneur : (null)
# Paramètres passés au modèle :
lxc.mount.entry = proc proc proc nodev,noexec,nosuid 0 0
lxc.mount.entry = sysfs sys sysfs defaults  0 0
lxc.tty = 2
lxc.pts = 1024
lxc.cgroup.devices.deny = a
lxc.cgroup.devices.allow = c 1:3 rwm
lxc.cgroup.devices.allow = c 1:5 rwm
lxc.cgroup.devices.allow = c 5:1 rwm
lxc.cgroup.devices.allow = c 5:0 rwm
lxc.cgroup.devices.allow = c 4:0 rwm
lxc.cgroup.devices.allow = c 4:1 rwm
lxc.cgroup.devices.allow = c 1:9 rwm
lxc.cgroup.devices.allow = c 1:8 rwm
lxc.cgroup.devices.allow = c 136:* rwm
lxc.cgroup.devices.allow = c 5:2 rwm
lxc.cgroup.devices.allow = c 254:0 rm
lxc.utsname = imap
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = virbr0
lxc.network.hwaddr = 00:16:3e:f1:35:ab
lxc.network.ipv4.gateway = 192.168.122.1
lxc.network.ipv4 = 192.168.122.15
lxc.cap.drop = sys_module
lxc.cap.drop = mac_admin
lxc.cap.drop = mac_override
lxc.cap.drop = sys_time
lxc.rootfs = /var/lib/lxc/imap/rootfs

Étape 5 : démarrer le conteneur

Démarrer le conteneur en arrière-plan

lxc-start --name imap -d

On peut alors s'y connecter en SSH

ssh 192.168.122.15

Annexe 1 : améliorer le conteneur..

Il y a des choses qui ne sont plus nécessaires. Toutes les commandes sont entrées dans le conteneur (qui est un système Debian 7.0 BTW) !

apt-get remove --purge acpid acpi
update-rc.d -f hwclock.sh remove
update-rc.d -f mountall.sh remove
update-rc.d -f checkfs.sh remove
update-rc.d -f udev remove