Le blog de LDD

Toujours un truc à lire
ou à relire, des liens de
qualité et plus encore...

Linux-VServer —> LXC : migrer en douceur vers les containers sous Debian Squeeze

L’annonce de l’abandon du noyau Linux-VServer dans Debian après Squeeze a conduit beaucoup de monde à s’intéresser à LXC comme remplacement de VServer. Mais pour sauvegarder les nuits des admins sys, la transition VServer->LXC sur des serveurs en prod ne peut pas s’improviser ! Alors, profitons de ce que Squeeze offre à la fois un noyau patché vserver et des outils pour mettre en place un container LXC.

Certes, l’implémentation de LXC de Squeeze est un peu immatures (pas de gestion des quotas de mémoire dans le noyau 2.6.32, scripts pas toujours au top), mais mieux vaut faire la transition sous Squeeze sans risque, quitte à migrer vers Wheezy dès que les containers fonctionnent !

À LDD, le cas de la migration de nos vservers s’est posé, alors voici un petit guide inspiré de notre démarche de migration. Évidemment, il va sans dire que vous devrez comprendre et adapter ce guide à votre situation et non l’appliquer sans réfléchir...

I : Préparer son hôte

Tout d’abord, la configuration de l’hôte :

Installer les paquets lxc et bridge-utils
Il y a bien un paquet lxc plus récent dans les dépôts squeeze-backports, mais celui-ci ne fonctionnait pas dans notre cas avec le noyau 2.6.32-vserver. Or ce noyau est le plus récent noyau Debian patché vserver.

Pour le réseau, 2 cas :

  • soit notre container va utiliser l’IP de l’hôte, dans ce cas aucune modification n’est nécessaire.
  • soit le container a son IP, alors on doit modifier la configuration du réseau pour y ajouter une interface bridge. Ce sera le cas de notre exemple.

Ajout d’un bridge

Prenons le cas d’une config avec 1 interface physique, IP statique.

Avant tout :

cp /etc/network/interfaces /etc/network/interfaces.backup

Puis dans /etc/network/interfaces, on commente les lignes correspondant à l’interface physique, on les remplace par celles du bridge. Exemple :

Là où on avait :

auto eth0
iface eth0 inet static
  address xxx.xxx.xxx.xxx
  netmask xxx.xxx.xxx.xxx
  gateway xxx.xxx.xxx.xxx

On remplace par :

auto br0
iface br0 inet static
  address xxx.xxx.xxx.xxx
  netmask xxx.xxx.xxx.xxx
  gateway xxx.xxx.xxx.xxx
  bridge_ports eth0
  bridge_stp off
  bridge_maxwait 5
  bridge_fd 0

(Les 3 dernières lignes sont optionnelles : si vous voulez en savoir plus man bridge-utils-interfaces).

Attention !
Avant de lancer un /etc/init.d/networking restart qui prendra en compte la nouvelle config réseau, 3 avertissements en 1 :

  • Si le seul accès que vous avez à la machine se fait en SSH, vérifiez à trois fois avant de lancer le networking restart
  • Une fois le bridge fonctionnel (après un networking restart) ne tentez pas de revenir à l’ancienne conf (attribuer une IP à l’interface physique) tant que le bridge est up, au risque de perdre la connexion réseau !
  • Si vos vservers ne sont plus joignable suite au networking restart : pas de panique, cf. ci-dessous.

Lorsque cette nouvelle config réseau sera utilisée, l’interface physique n’aura plus d’IP, c’est le bridge qui la prendra. Les vservers qui utilisaient l’interface physique n’auront donc plus accès au réseau, il faudra les redémarrer.

Lorsque tous les avertissements ci-dessus ont été pris en compte, vous pouvez lancer le networking restart et redémarrer vos vservers.
Si vous craignez une erreur qui vous ferait perdre l’accès SSH, vous pouvez toujours programmer un at now + 5min ou un cron du style : cp /etc/network/interfaces.backup /etc/network/interfaces && /sbin/reboot. Mais n’oubliez pas de les arrêter à temps si tout se passe bien !

Montage de cgroups

On va devoir monter un répertoire spécial, "cgroup" :

echo "cgroup        /sys/fs/cgroup        cgroup        defaults    0    0" >> /etc/fstab
mount cgroup

On retrouvera dans ce répertoire tous les processus, qui peuvent être rangés dans des groupes distincts. Cette capacité à créer et isoler des "groupes de contrôle" de processus est justement la base de l’isolation des processus entre containers.

Adaptation du script de création

Dans la version LXC de Squeeze, le script pour créer un container Debian propose de créer une Lenny... Bon, on va l’éditer pour corriger ça : remplacer toutes les occurrences de « lenny » par « squeeze » dans /usr/lib/lxc/templates/lxc-debian (avec vim %s/lenny/squeeze/gc)
Remplacer dchp-client par isc-dhcp-client.

Si vous lancez un lxc-checkconfig, tout doit être bon, hormis Cgroup memory controller (non disponible dans le noyau 2.6.32).

II : Créer un container modèle

On crée le dossier qui accueillera le container et lancer le script

mkdir -p /var/lib/lxc/modele
/usr/lib/lxc/templates/lxc-debian -p /var/lib/lxc/modele

On ajoute le nom de machine et la config réseau au fichier /var/lib/lxc/modele/config :

lxc.utsname = modele
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.hwaddr = 00:10:1b:28:00:01

Si votre container à l’IP de son hôte, alors ne mettez pas de ligne lxc.network : il récupèrera la pile réseau de l’hôte.
Attention : l’adresse MAC que vous spécifiez ne doit pas se trouver sur votre réseau local ! Faites preuve d’inventivité, et renseignez vous sur la page Wikipedia dédiée pour savoir comment se compose une adresse MAC.
Chez OVH, vous devrez passer par le manager pour créer des "MAC virtuelles" qui seront associées à vos IP. Renseignez dans lxc.network.hwaddr la MAC virtuelle proposée par OVH et correspondant à l’IP du serveur visé.

Notre container est prêt, mais il vaut mieux le démarrer pour le vérifier. Attention aux éventuels conflits d’IP !
Vous pouvez modifier rootfs/etc/network/interfaces pour ne pas configurer l’interface réseau votre container, ou au contraire lui attribuer l’IP d’un de vos vserver. Dans ce cas, pensez à stopper le vserver avant de démarrer le container. Si le réseau est bien configuré (vérifiez à 2 fois pour ne pas, par exemple, voler l’IP de l’hôte...), on peut démarrer le container :

lxc-start -n modele

login/mot de passe : root/root
Vous pouvez changer ça de suite avec passwd et éventuellement tester le réseau avec, par exemple apt-get update. Pas la peine de plus s’attarder ici : on a un container qui fonctionne, ça suffit !
Si vous avez une config réseau distincte de l’hôte, vous pouvez lancer un :
halt
Si vous avez récupéré la pile réseau de l’hôte (en omettant les paramètres lxc.network dans la config), ouvrez un autre terminal sur l’hôte pour lancer un :
lxc-stop -n modele
Ca évitera de désactiver les interfaces réseau du serveur :-)

Vous aurez remarqué que nous n’avions plus accès à l’hôte après le lxc-start. On peut lancer celui-ci dans un screen pour éviter ce problème, ou le lancer comme daemon : lxc-start -n modele -d

Puisque notre modèle fonctionne, plus qu’à l’archiver :

cd /var/lib/lxc/modele
tar czf ../modele.tar.gz *

On a un tar.gz qui nous permettra de cloner ce container autant qu’on voudra ! On peut supprimer /var/lib/lxc/modele.

III : Transformer un vserver en container

Notre vserver "server1" est en marche, LXC est installé et configuré, notre container modèle nous attend dans son archive. Migrons !

Créer et configurer le container "server1"

mkdir /var/lib/lxc/server1
cd /var/lib/lxc/server1
tar xzf ../modele.tar.gz

On met de côté son système de fichiers pour l’instant :

mv rootfs/ temp/

Et on édite la conf pour :

  • remplacer le nom du container
  • paramétrer le réseau
vim config
%s/modele/server1/c

Les lignes à changer doivent être :

lxc.rootfs
lxc.utsname
lxc.mount.entry
lxc.network.hwaddr

Copier et adapter le contenu du vserver

vserver server1 stop
cp -a /var/lib/vservers/server1/ /var/lib/lxc/server1/rootfs

Si on veut gagner du temps, on peut copier d’abord les dossiers qui ne sont pas modifiés par les programmes en cours, et ensuite arrêter le vserver pour copier les dossiers volatils comme /var.
Un simple mv au lieu de cp -a sera instantané (si cible et destination sont sur la même partition). Mais dans ce cas, faites une sauvegarde de /dev et /etc/inittab du vserver avant d’exécuter les lignes qui vont suivre.

La suite va très vite :

cp -a temp/etc/inittab rootfs/etc/inittab
rm -r rootfs/dev
cp -a temp/dev rootfs/

Editer la conf réseau dans rootfs/etc/network/interfaces et rootfs/etc/resolv.conf si besoin

Démarrage

Pour le démarrer :

lxc-start -n server1 -d

Et si tout fonctionne, plus qu’à supprimer le système de fichier du modèle :

rm -r /var/lib/lxc/server1/temp

On peut ensuite ajouter le lancement automatique au démarrage de l’hôte :

ln -s /var/lib/lxc/server1/config /etc/lxc/server1.conf
vim /etc/default/lxc

On met dans /etc/default/lxc

RUN=yes
CONF_DIR=/etc/lxc
CONTAINERS="server1"

Ouf ! L’admin satisfait contemple son nouveau jouet et sourit en pensant à la migration en Wheezy de son serveur de prod : sa nuit est sauvée !

Liens : Notre migration s’est largement appuyée sur plusieurs documents, en particulier LXC on Debian Squeeze et Migrating from vserver to lxc. Un grand merci à leurs auteurs !

Mise à jour : Le paramètre lxc.network.ipv4 dans le fichier de config ne sert à rien si /etc/network/interfaces est présent dans le container, et peut générer de mauvaises routes.

Réagir

Répondre à cet article

Qui êtes-vous ?
Ajoutez votre commentaire ici
  • Ce formulaire accepte les raccourcis SPIP [->url] {{gras}} {italique} <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Suivre les commentaires : RSS 2.0 | Atom

Les Développements Durables
2 bis, rue des Visitandines
64100 Bayonne

Tél : 09 50 52 42 42

© Les Développements Durables, 2003-2013, tous droits réservés : notice légale.