Introduction

L'objectif ici est de présenter l'installation de XEN 4 sur Debian 6 ou Squeeze. L'installation s'est faite en utilisant le CD minimal ( format carte de credit 40Mo ) de Squeeze version 6.0.5 pour 64bits et téléchargeable ici.

J'ai également pris le parti d'activer petit à petit les fonctionnalités de XEN afin de comprendre les différentes options de sa configuration.

Pour l'anecdote tous les tests ont été faits sur un ordinateur HP Pavillon G5410fr trouvé chez Leclerc pour 399€ TTC ayant les caractéristiques suivantes :

Pentium E6700 à 3,2Ghz

RAM 4Go

Disque Dur Sata de 1,5To

Installation de Debian Squeeze

Procéder à une installation basique de Debian Squeeze en prenant soin d'activer LVM ce qui sera très souple pour la manipulation des VM. Il est de plus important de bien prendre une image noyau générique et non celle proposant des modules optimisés pour le système, sans cette précaution XEN ne fonctionne pas correctement sur Debian Squeeze.

Installation de XEN

Article de référence

Après une installation basique de Squeeze, installer les packages suivants :

aptitude install xen-linux-system-2.6 xen-qemu-dm xen-tools

xen-linux-system-2.6, est le package xen 4 complet avec l'hyperviseur.

xen-qemu-dm, permet d'utiliser la virtualisation matérielle, attention processeur compatible indispensable, notamment pour virtualiser Windows. Ce package n'est pas indispensable pour virtualiser uniquement Linux.

xen-tools, est un ensemble de scripts PERL facilitant la gestion des VM.

Pour tester si la virtualisation matérielle est supportée par le processeur la commande suivante doit ramener quelque chose :

egrep '^flags.*(vmx|svm)' /proc/cpuinfo

Il faut parfois modifier le BIOS du serveur pour activer les fonctions VT-X (Intel) ou AMD-V (AMD).

La para-virtualisation est toutefois plus performante que la virtualisation matérielle.

Il faut aussi modifier l'ordre de démarrage des scripts grub ainsi

mv /etc/grub.d/10_linux /etc/grub.d/51_linux

Sans cela XEN ne démarre pas correctement. Le message d'erreur suivant apparait

WARNING! Can't find hypervisor information in sysfs!
Error: Unable to connect to xend: No such file or directory. Is xend running?

Par défaut, XEN sauvegarde une image dump d'une VM arrétée brutalement et tente de la restaurer au démarrage. Ceci peut saturer le répertoire /var très rapidement. Pour invalider cette fonction éditer le fichier /etc/default/xendomains et mettre les deux lignes suivantes avec ces valeurs :

XENDOMAINS_RESTORE=false
XENDOMAINS_SAVE=""

Si une commande update-grub est lancée et qu'il existe des VM, elles sont alors intégrées dans le menu de démarrage. Pour éviter cela éditer /etc/default/grub et ajouter la ligne suivante :

GRUB_DISABLE_OS_PROBER=true

Lancer alors la commande update-grub et rebooter le serveur. Les commandes uname -r et xm info permettent de vérifier le fonctionnement correct de XEN.

Gestion réseau

XEN autorise plusieurs modes de fonctionnement du réseau des VM

NAT

Pont

Routage

Le mode Pont ou bridge est le plus simple à configurer et permet de présenter les VM sur le réseau local. Pour activer le bridge il faut modifier le fichier /etc/xen/xend-config.sxp en décommentant la ligne (network-script network-bridge ) ainsi.

(network-script 'network-bridge antispoof=yes')

La clause antispoof=yes est conseillée au cas où l'IP de la VM serait, par erreur, déja affectée.

Par défaut les logs de xen sont dans syslog, afin de les mettre à part décommenter les lignes suivantes dans /etc/xen/xend-config.sxp

(logfile /var/log/xen/xend.log)
(loglevel WARN)

Il est aussi intéressant d'augmenter un peu la mémoire pour le Dom0 ainsi :

(dom0-min-mem 256)

Dans un premier temps le fichier /etc/xen/xend-config.sxp peut être très succinct.

(logfile /var/log/xen/xend.log)
(loglevel WARN)
(network-script 'network-bridge antispoof=yes')
(vif-script vif-bridge)
(dom0-min-mem 256)
(enable-dom0-ballooning yes)
(total_available_memory 0)
(dom0-cpus 0)
(vncpasswd '')

Redémarrer le démon xend et vérifier la présence du bridge

# /etc/init.d/xend restart
# brctl show
bridge name	bridge id	STP enabled	interfaces
eth0	8000.2c27d7337c00	no	peth0

Création des VM

Il existe plusieurs façons de procéder, ci-dessous la méthode utilisant les scripts xen-tools. Dans un premier temps éditer le fichier /etc/xen-tools/xen-tools.conf pour activer les options par défaut :

lvm = vg01
install-method = debootstrap
size = 10Gb
memory = 512Mb
swap = 1024Mb
fs = ext3 .
dist = `xt-guess-suite-and-mirror --suite`
image = full
gateway = 192.168.1.1
netmask = 255.255.255.0
broadcast = 192.168.1.255
nameserver = 192.168.1.1
passwd = 1
kernel = /boot/vmlinuz-`uname -r`
initrd = /boot/initrd.img-`uname -r`
mirror = `xt-guess-suite-and-mirror --mirror`
ext3_options = noatime,nodiratime,errors=remount-ro
ext2_options = noatime,nodiratime,errors=remount-ro
xfs_options = defaults
reiserfs_options = defaults
btrfs_options = defaults
pygrub=1

Lancer la création de la première VM ainsi

xen-create-image --hostname adi051.concarnux.fr --ip 192.168.1.51

La création utilise la méthode debootstrap, chargeant un système minimal. Ensuite lors de la phase "Running hooks" différents scripts sont lancés, notamment la mise en place de ssh. Ces scripts sont sous /usr/lib/xen-tools/debian.d.

On trouve parfois la clause –role=udev qui est nécessaire si la VM ne boote pas correctement, à titre personnel avec l'option pygrub=1 je n'ai pas eu besoin de cette option.

Si la VM existe déjà, il faut utiliser en plus –force afin de la recréer.

L'image sera créée sous forme de 2 volumes logiques

/dev/vg01/adi051.concarnux.fr-disk, taille 10Go

/dev/vg01/adi051.concarnux.fr-swap, taille de 1Go

Par défaut sera installé la même version en VM qu'en Dom0. La RAM est de 512Mo et en configuration IP fixe. Il est possible de surchager les options par défaut de ce fichier par la ligne de commande. Un appel xen-create-image -h donne les différentes options.

Le mot de passe du root sera demandé intéractivement.

Lancer la VM ainsi :

xm create /etc/xen/adi051.concarnux.fr

Il est possible d'y accéder via ssh comme un serveur ordinaire ou en mode console ainsi:

xm console adi051.concarnux.fr

La sortie du mode console se fait avec la combinaison de touches "Ctrl" et "]".

La visualisation des VM se fait via la commande xm list.

L'arrêt de la VM utilise la commande xm shutdown

Exemple de sortie écran lors d'une création

root@adi100:~# xen-create-image --hostname adi051.concarnux.fr --ip 192.168.1.51
General Information
--------------------
Hostname : adi051.concarnux.fr
Distribution : squeeze
Mirror : http://ftp.fr.debian.org/debian/
Partitions : swap 1024Mb (swap)
/ 10Gb (ext3)
Image type : full
Memory size : 512Mb
Kernel path : /boot/vmlinuz-2.6.32-5-xen-amd64
Initrd path : /boot/initrd.img-2.6.32-5-xen-amd64
Networking Information
----------------------
IP Address 1 : 192.168.1.51 [MAC: 00:16:3E:41:63:80]
Netmask : 255.255.255.0
Broadcast : 192.168.1.255
Gateway : 192.168.1.1
Nameserver : 192.168.1.1
Creating swap on /dev/vg01/adi051.concarnux.fr-swap
Done
Creating ext3 filesystem on /dev/vg01/adi051.concarnux.fr-disk
Done
Installation method: debootstrap
Done
Running hooks
Done
No role scripts were specified. Skipping
Creating Xen configuration file
Done
Setting up root password
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
All done
Logfile produced at:
/var/log/xen-tools/adi051.concarnux.fr.log
Installation Summary
---------------------
Hostname : adi051.concarnux.fr
Distribution : squeeze
IP-Address(es) : 192.168.1.51
RSA Fingerprint : f3:5b:fa:2d:aa:08:42:6e:f1:8e:11:e5:e5:69:17:d6
Root Password : N/A
root@adi100:~#

Pour démarrer automatiquement une VM lors du boot serveur, créer le répertoire /etc/xen/auto et placer un lien symbolique vers le fichier de configuration de la VM.

mkdir /etc/xen/auto
ln -s /etc/xen/adi051.concarnux.fr.cfg /etc/xen/auto/adi051.concarnux.fr.cfg
...A répéter pour chaque VM

Voici un exemple sur la machine de test avec 4Go de RAM et la création de 5 VM identiques.

La commande brctl show montre bien les 5 interfaces réseau bridgées vers eth0.

La commande iptables -L sur la chaine FORWARD permet de voir le transfert des paquets IP vers la bonne interface.

root@adi100:~# xm list
Name ID Mem VCPUs State Time(s)
Domain-0 0 1499 2 r----- 21.0
adi051.concarnux.fr 1 512 1 -b---- 1.4
adi052.concarnux.fr 2 512 1 -b---- 1.2
adi053.concarnux.fr 3 512 1 -b---- 1.4
adi054.concarnux.fr 4 512 1 -b---- 1.4
adi055.concarnux.fr 5 512 1 -b---- 1.2
root@adi100:~# brctl show
bridge name	bridge id	STP enabled	interfaces
eth0	8000.2c27d7337c00	no	peth0
vif1.0
vif2.0
vif3.0
vif4.0
vif5.0
root@adi100:~# iptables -L
Chain FORWARD (policy DROP)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED PHYSDEV match --physdev-out vif5.0
ACCEPT udp -- anywhere anywhere PHYSDEV match --physdev-in vif5.0 udp spt:bootpc dpt:bootps
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED PHYSDEV match --physdev-out vif5.0
ACCEPT all -- adi055.concarnux.fr anywhere PHYSDEV match --physdev-in vif5.0
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED PHYSDEV match --physdev-out vif4.0
ACCEPT udp -- anywhere anywhere PHYSDEV match --physdev-in vif4.0 udp spt:bootpc dpt:bootps
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED PHYSDEV match --physdev-out vif4.0
ACCEPT all -- adi054.concarnux.fr anywhere PHYSDEV match --physdev-in vif4.0
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED PHYSDEV match --physdev-out vif3.0
ACCEPT udp -- anywhere anywhere PHYSDEV match --physdev-in vif3.0 udp spt:bootpc dpt:bootps
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED PHYSDEV match --physdev-out vif3.0
ACCEPT all -- adi053.concarnux.fr anywhere PHYSDEV match --physdev-in vif3.0
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED PHYSDEV match --physdev-out vif2.0
ACCEPT udp -- anywhere anywhere PHYSDEV match --physdev-in vif2.0 udp spt:bootpc dpt:bootps
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED PHYSDEV match --physdev-out vif2.0
ACCEPT all -- adi052.concarnux.fr anywhere PHYSDEV match --physdev-in vif2.0
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED PHYSDEV match --physdev-out vif1.0
ACCEPT udp -- anywhere anywhere PHYSDEV match --physdev-in vif1.0 udp spt:bootpc dpt:bootps
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED PHYSDEV match --physdev-out vif1.0
ACCEPT all -- adi051.concarnux.fr anywhere PHYSDEV match --physdev-in vif1.0
ACCEPT all -- anywhere anywhere PHYSDEV match --physdev-in peth0

Augmenter le disque de la VM

Utiliser LVM pour la gestion des VM permet d'augmenter très facilement l'espace disque, il suffit de redimensionner le volume logique. L'exemple suivant montre l'extention de +10Go de la VM adi051.concarnux.fr.

xm shutdown adi051.concarnux.fr
lvextend /dev/vg01/adi051.concarnux.fr-disk +L 10G
e2fsck -f /dev/vg01/adi051.concarnux.fr-disk
resize2fs /dev/vg01/adi051.concarnux.fr-disk
xm create /etc/xen/adi051.concarnux.fr

Dupliquer des VM

Une fois le principe assimilé, il est simple de dupliquer des VM. Ici encore il existe de nombreuses méthodes, la plus simple est de créer une première VM en appliquant certaines personnalisations communes et de créer une image tar.

A titre personnel, j'installe les package suivants :

aptitude install vim ntpdate

J'edite aussi le .bashrc du root ainsi :

export LS_OPTIONS='--color=auto'
eval "`dircolors`"
alias ls='ls $LS_OPTIONS'
alias ll='ls $LS_OPTIONS -hl'
alias l='ls $LS_OPTIONS -lA'
alias df='df -h'

Création d'une image tar de la VM

Stopper la VM et monter son volume logique sur un point de montage.

xm shutdown adi051.concarnux.fr
mkdir /mnt/img
mount /dev/vg01/adi051.concarnux.fr-disk /mnt/img
cd /mnt/img
tar -cvpsf /home/vm_modele.tar *
cd /
umount /mnt/img

Editer ensuite le fichier /etc/xen-tools/xen-tools.conf et modifier la ligne install-method ainsi :

#install-method = debootstrap
install-method = tar
install-source = /home/vm_modele.tar

Bien rajouter la ligne install-source.

La commande de création des VM est identique à celle utilisée précédement. Les scripts hooks du package xen-tools faisant les corrections type IP, hostname…

Cluster avec des VM

L'objectif ici est de simuler un cluster avec des VM, il est ainsi facile de tester le cluster et ensuite de la passer en production sur des serveurs réels. Debian propose 95% des fonctions disponibles sous REDHAT en matière de gestion des clusters. Il ne manque que quelques utilitaires, type ricci et luci ou encore pirhana qui simplifie simplement la mise en place de la configuration.

PDF de présentation de Redhat cluster en français

Administration du cluster, doc REDHAT en anglais

Pour information la gestion d'un cluster se fait dans un unique fichier au format XML et nommé /etc/cluster/cluster.conf.

Important

Les packages redhat-cluster-suite permettent de gérer des clusters jusqu'a 16 noeuds.

Seul le protocole IPV4 est actuellement utilisable.

A partir de la VM exemple rajouter les packages suivants :

aptitude install redhat-cluster-suite ipvsadm open-iscsi

redhat-cluster-suite, contient l'ensemble des fonction de cluster ( cman, rgmanager, GFS… )

ipvsadm, permet de gérer la répartition de charge.

open-iscsi permet d'utiliser des disques via le protocole iscsi.

une fois cette opération faite, stopper la VM et créer une image tar pour la duplication.

xm shutdown adi051.concarnux.fr
mkdir /mnt/img
mount /dev/vg01/adi051.concarnux.fr-disk /mnt/img
tar -cvpsf /home/vm_cluster_modele.tar *
cd /
umount /mnt/img

Le cluster exemple comportera 3 noeuds, créer donc les deux VM supplementaires.

xen-create-image --hostname adi052.concarnux.fr --ip 192.168.1.52 --install-source /home/vm_cluster_modele.tar
xen-create-image --hostname adi053.concarnux.fr --ip 192.168.1.53 --install-source /home/vm_cluster_modele.tar

Lancer ensuite les 3 VM

root@adi100:~# xm create /etc/xen/adi051.concarnux.fr.cfg
root@adi100:~# xm create /etc/xen/adi052.concarnux.fr.cfg
root@adi100:~# xm create /etc/xen/adi053.concarnux.fr.cfg
root@adi100:~# xm list
Name ID Mem VCPUs State Time(s)
Domain-0 0 2514 2 r----- 144.6
adi051.concarnux.fr 9 512 1 -b---- 1.8
adi052.concarnux.fr 10 512 1 -b---- 1.9
adi053.concarnux.fr 11 512 1 -b---- 1.7
root@adi100:~#

Sur chaque VM mettre en place la résolution de nom via /etc/hosts

192.168.1.51 adi051.concarnux.fr adi051
192.168.1.52 adi052.concarnux.fr adi052
192.168.1.53 adi053.concarnux.fr adi053

Fichier /etc/cluster/cluster.conf

Afin de vérifier le fonctionnement correct du cluster, nous allons mettre en place une configuration simple des 3 noeuds. Attention ce fichier n'est pas complet et ne pose que les bases du cluster. Il doit être copié à l'identique sur les 3 noeuds.

<?xml version="1.0" ?>
<cluster name="alpha" config_version="1">
<cman>
<multicast addr="224.0.0.1" />
</cman>
<clusternodes>
<clusternode name ="adi051.concarnux.fr" votes="1" nodeid="1">
<fence>
<method name="single">
<device name="manual" />
</method>
</fence>
</clusternode>
<clusternode name ="adi052.concarnux.fr" votes="1" nodeid="2">
<fence>
<method name="single">
<device name="manual" />
</method>
</fence>
</clusternode>
<clusternode name ="adi053.concarnux.fr" votes="1" nodeid="3">
<fence>
<method name="single">
<device name="manual" />
</method>
</fence>
</clusternode>
</clusternodes>
<fencedevices>
<fencedevice name="manual" agent="fence_manual" />
</fencedevices>
<fence_daemon clean_start="0" post_fail_delay="0" post_join_delay="3" />
<rm>
<failoverdomains>
<failoverdomain name="dom01" restricted="1" ordered="1" nofailback="0">
<failoverdomainnode name="adi051.concarnux.fr" priority="10" />
<failoverdomainnode name="adi052.concarnux.fr" priority="20" />
<failoverdomainnode name="adi053.concarnux.fr" priority="30" />
</failoverdomain>
</failoverdomains>
</rm>
</cluster>

Le cluster se nomme alpha et comprend 3 noeuds.

L'isolation des noeuds ( fence ) est faite manuellment.

Un seul failoverdomain est défini ( dom01 ) avec la priorité de chaque noeud.

Sur chaque noeud lancer les commandes suivantes :

/etc/init.d/cman start
/etc/init.d/rgmanager start

Sur n'importe quel noeud du cluster lancer la commande clustat pour vérifier le démarrage correct du cluster.

clustat
Cluster Status for alpha @ Wed Aug 24 12:21:27 2011
Member Status: Quorate
Member Name ID Status
------ ---- ---- ------
adi051.concarnux.fr 1 Online, Local
adi052.concarnux.fr 2 Online
adi053.concarnux.fr 3 Online

Mise en place d'un service

Pour l'exemple nous allons utiliser le serveur Web apache, qui sera donc démarré en priorité sur adi051.concarnux.fr et en cas de défaillance redemarrer sur adi052.concarnux.fr et enfin sur adi053.concarnux.fr. De plus nous associerons un IP flottante ( 192.168.1.200 ) au service WEB.

Installer apache sur chaque noeud et désactiver son démarrage au boot.

aptitude install apache2
/etc/init.d/apache2 stop
update-rc.d apache2 remove

Note : J'ai eu sur les VM des messages d'erreurs debconf qui peuvent être ignorés, sans doute un mauvais paramétrage de la console…

Modifier sur chaque noeud le fichier /etc/cluster/cluser.conf en prenant soin d'incrémenter le numéro de version

<?xml version="1.0" ?>
<cluster name="alpha" config_version="2">
<cman>
<multicast addr="224.0.0.1" />
</cman>
<clusternodes>
<clusternode name ="adi051.concarnux.fr" votes="1" nodeid="1">
<fence>
<method name="single">
<device name="manual" />
</method>
</fence>
</clusternode>
<clusternode name ="adi052.concarnux.fr" votes="1" nodeid="2">
<fence>
<method name="single">
<device name="manual" />
</method>
</fence>
</clusternode>
<clusternode name ="adi053.concarnux.fr" votes="1" nodeid="3">
<fence>
<method name="single">
<device name="manual" />
</method>
</fence>
</clusternode>
</clusternodes>
<fencedevices>
<fencedevice name="manual" agent="fence_manual" />
</fencedevices>
<fence_daemon clean_start="0" post_fail_delay="0" post_join_delay="3" />
<rm>
<failoverdomains>
<failoverdomain name="dom01" restricted="1" ordered="1" nofailback="0">
<failoverdomainnode name="adi051.concarnux.fr" priority="10" />
<failoverdomainnode name="adi052.concarnux.fr" priority="20" />
<failoverdomainnode name="adi053.concarnux.fr" priority="30" />
</failoverdomain>
</failoverdomains>
<service name="web" autostart="1" domain="dom01" recovery="relocate" >
<script name="start_web" file="/etc/init.d/apache2" />
<ip address="192.168.1.200" monitor_link="1"/>
</service>
</rm>
</cluster>

Relancer le cluster, sur chaque noeud

/etc/init.d/rgmanager stop
/etc/init.d/cman restart
/etc/init.d/rgmanager start

Puis lancer la commande clustat pour vérifier le fonctionnement correct

root@adi051:~# clustat
Cluster Status for alpha @ Wed Aug 24 10:45:28 2011
Member Status: Quorate
Member Name ID Status
------ ---- ---- ------
adi051.concarnux.fr 1 Online, Local, rgmanager
adi052.concarnux.fr 2 Online, rgmanager
adi053.concarnux.fr 3 Online, rgmanager
Service Name Owner (Last) State
------- ---- ----- ------ -----
service:web adi051.concarnux.fr started
root@adi051:~#

Pour tester la bascule stopper la VM adi051.concarnux.fr et relancer la commande clustat sur adi052.concarnux.fr pour vérifier que le service apache a bien migré.

root@adi052:~# clustat
Cluster Status for alpha @ Wed Aug 24 10:54:05 2011
Member Status: Quorate
Member Name ID Status
------ ---- ---- ------
adi051.concarnux.fr 1 Offline
adi052.concarnux.fr 2 Online, Local, rgmanager
adi053.concarnux.fr 3 Online, rgmanager
Service Name Owner (Last) State
------- ---- ----- ------ -----
service:web adi052.concarnux.fr started
root@adi052:~#

Si adi051.concarnux.fr revient dans le cluster, le service est stoppé sur adi052.concarnux.fr et redémarré sur adi051.concarnux.fr.

Il est possible de migrer manuellement le service ainsi :

root@adi052:~# clusvcadm -r web -m adi053.concarnux.fr
Trying to relocate service:web to adi053.concarnux.fr...Success
service:web is now running on adi053.concarnux.fr
root@adi052:~# clustat
Cluster Status for alpha @ Wed Aug 24 10:57:10 2011
Member Status: Quorate
Member Name ID Status
------ ---- ---- ------
adi051.concarnux.fr 1 Online, rgmanager
adi052.concarnux.fr 2 Online, Local, rgmanager
adi053.concarnux.fr 3 Online, rgmanager
Service Name Owner (Last) State
------- ---- ----- ------ -----
service:web adi053.concarnux.fr started
root@adi052:~#

Pour tester le serveur web, mettre une page diférente sur chaque VM et pointer un navigateur sur l'IP flotante ( 192.168.1.200 ) en prenant soin de purger le cache.

Vérifier avec la commande ip addr la présence sur la VM faisant tourner le serveur apache la présence en IP secondaire de 192.168.1.200.