# KVM: Virtualisation d'un système Ce Tutoriel présente comment virtualiser un serveur physique. ## Préparation de l'image disque Les images disques dans l'hyperviseur ont l'extension **.įmg** ``` find / -name *.img /boot/initramfs-2.6.32-573.12.1.el6.x86_64.img /usr/lib64/guestfs/supermin.d/init.img /usr/lib64/guestfs/supermin.d/udev-rules.img /usr/lib64/guestfs/supermin.d/daemon.img /usr/lib64/guestfs/supermin.d/base.img /root/.vagrant.d-back/boxes/demo-VAGRANTSLASH-centos6/1.0.0/libvirt/box.img /var/lib/libvirt/images/dgfip-VAGRANTSLASH-centos7_vagrant_box_image_0.img /var/lib/libvirt/images/ibm/centreon.img /var/lib/libvirt/images/sandbox_dgfip-rhel7.img /var/lib/libvirt/images/reseau/GLPI-new.img /var/lib/libvirt/images/reseau/redmine.img /var/lib/libvirt/images/reseau/hercule.img /var/lib/libvirt/images/reseau/GLPI.img /var/lib/libvirt/images/reseau/cftgcos.img /var/.vagrant.d/boxes/dgfip-VAGRANTSLASH-centos7/0/libvirt/box.img /var/.vagrant.d/boxes/dgfip-base/0/libvirt/box.img /var/.vagrant.d/boxes/demo-VAGRANTSLASH-centos6/1.0.0/libvirt/box.img ``` Il est possible de dupliquer une image disque existante comme base pour virtualiser le système d'un serveur. Il faut choisir une image contenant un système similaire (ou istaller la base du système sur une image disque vierge):\\ \\ `cat /mnt/etc/redhat-release\\ CentOS release 6.7 (Final)` Dand l'exemple on va utiliser l'image disque de centreon (Centos 6.7) car elle est plus petite (25G) que celle de GLPI (141G). ``` [root@s013e13p-snmp /]# dd if=/var/lib/libvirt/images/ibm/centreon.img of=/var/lib/libvirt/images/reseau/redmine.img 51094272+0 enregistrements lus 51094272+0 enregistrements écrits 26160267264 octets (26 GB) copiés, 320,91 s, 81,5 MB/s ``` ## Préparation du nouveau système Avant de démarrer le nouveau système il faut modifier quelques paramètres pour pouvoir utiliser le disque dans une nouvelle VM (adresse ip, compte root), il faut donc monter le système de fichier dans un répertoire du système hôte. ### Montage des partitions avec losetup et kpartx **libvirt** peut utiliser des images au format **raw**, et **qemu-img** permet d'identifier le type de l'image: ``` [root@s013e13p-snmp /]# qemu-img info /opt/images/centos7.img image: /opt/images/centos7.img file format: raw virtual size: 16G (17179869184 bytes) disk size: 4.2G ``` Une image disque au format **raw** peut être montée comme périphérique de type bloc avec **losetup**: ``` [root@s013e13p-snmp /]# losetup -f /opt/images/centos7.img [root@s013e13p-snmp /]# losetup -a /dev/loop0: [fd05]:2363831 (/opt/images/centos7.img) ``` Lorsqu'on utilise LVM avec des schémas communs pour construire les machines virtuelles il est probale qu'on se retrouve avec des noms de volumes identiques, cela peut être probèmatique lors de l'activation du volume group. Récupérer l'UUID du volume group de l'hôte ``` [root@s013e13p-snmp /]# vgdisplay | egrep -i "uuid|name" File descriptor 6 (/dev/pts/2) leaked on vgdisplay invocation. Parent PID 24194: -bash VG Name vg00 VG UUID cndaZQ-Wu30-iYXY-fbiA-mdXK-lXHR-L9EUFz ``` Créer les maps de périphérique depuis la table de partition périphérique de bloc, et récupérer l'UUID du volume group ajouté: ``` [root@s013e13p-snmp /]# kpartx -a /dev/loop0 [root@s013e13p-snmp /]# vgdisplay | egrep -i "uuid|name" File descriptor 6 (/dev/pts/2) leaked on vgdisplay invocation. Parent PID 24194: -bash VG Name vg00 VG UUID X1G903-dfKl-q09q-XbpD-OSSg-CJq0-a3BGS9 VG Name vg00 VG UUID cndaZQ-Wu30-iYXY-fbiA-mdXK-lXHR-L9EUFz ``` Dans l'exemple l'UUID du volume group ajouté est X1G903-dfKl-q09q-XbpD-OSSg-CJq0-a3BGS9. Renommer le volume group, par exemple **vg02**: ``` [root@s013e13p-snmp /]# vgrename -v X1G903-dfKl-q09q-XbpD-OSSg-CJq0-a3BGS9 vg02 File descriptor 6 (/dev/pts/2) leaked on vgrename invocation. Parent PID 24194: -bash Using volume group(s) on command line. Wiping cache of LVM-capable devices Cache: Duplicate VG name vg00: Prefer existing cndaZQ-Wu30-iYXY-fbiA-mdXK-lXHR-L9EUFz vs new X1G903-dfKl-q09q-XbpD-OSSg-CJq0-a3BGS9 Processing VG vg00 because of matching UUID X1G903-dfKl-q09q-XbpD-OSSg-CJq0-a3BGS9 Cache: Duplicate VG name vg00: Prefer existing cndaZQ-Wu30-iYXY-fbiA-mdXK-lXHR-L9EUFz vs new X1G903-dfKl-q09q-XbpD-OSSg-CJq0-a3BGS9 Cache: Duplicate VG name vg00: Prefer existing X1G903-dfKl-q09q-XbpD-OSSg-CJq0-a3BGS9 vs new cndaZQ-Wu30-iYXY-fbiA-mdXK-lXHR-L9EUFz Writing physical volume data to disk "/dev/mapper/loop0p2" Physical volume "/dev/mapper/loop0p2" successfully written Archiving volume group "vg00" metadata (seqno 4). Writing out updated volume group Cache: Duplicate VG name vg00: X1G903-dfKl-q09q-XbpD-OSSg-CJq0-a3BGS9 (created here) takes precedence over cndaZQ-Wu30-iYXY-fbiA-mdXK-lXHR-L9EUFz Renaming "/dev/vg00" to "/dev/vg02" Creating volume group backup "/etc/lvm/backup/vg02" (seqno 5). Volume group "X1G903-dfKl-q09q-XbpD-OSSg-CJq0-a3BGS9" successfully renamed to "vg02 ``` Vérifier que le nom de volume associé à l'UUID a bien changé ``` [root@s013e13p-snmp /]# vgdisplay | egrep -i "uuid|name" File descriptor 6 (/dev/pts/2) leaked on vgdisplay invocation. Parent PID 24194: -bash VG Name vg02 VG UUID X1G903-dfKl-q09q-XbpD-OSSg-CJq0-a3BGS9 VG Name vg00 VG UUID cndaZQ-Wu30-iYXY-fbiA-mdXK-lXHR-L9EUFz ``` Les volumes associés au volume group **vg02** sont **inactive** par défaut: ``` [root@s013e13p-snmp /]# lvscan File descriptor 6 (/dev/pts/2) leaked on lvscan invocation. Parent PID 24194: -bash inactive '/dev/vg02/lvswap' [1,00 GiB] inherit inactive '/dev/vg02/lvroot' [8,00 GiB] inherit ACTIVE '/dev/vg00/lvroot' [5,00 GiB] inherit ACTIVE '/dev/vg00/lvtmp' [1,00 GiB] inherit ACTIVE '/dev/vg00/lvvar' [30,00 GiB] inherit ACTIVE '/dev/vg00/lvvarlog' [10,00 GiB] inherit ACTIVE '/dev/vg00/lvapp' [48,94 GiB] inherit ACTIVE '/dev/vg00/lvproduits' [512,00 MiB] inherit ACTIVE '/dev/vg00/lvswap' [3,88 GiB] inherit -(mer. sept. 07 14:06:03)--(nessus:/opt/images)- [root] # vgchange -ay File descriptor 6 (/dev/pts/2) leaked on vgchange invocation. Parent PID 24194: -bash 2 logical volume(s) in volume group "vg02" now active 7 logical volume(s) in volume group "vg00" now active ``` Activer le volume group **vg02**: ``` [root@s013e13p-snmp /]# lvchange -ay /dev/vg02 ``` Les volumes associés au volume group **vg02** doivent passer **ACTIVE** ``` [root@s013e13p-snmp /]# lvscan File descriptor 6 (/dev/pts/2) leaked on lvscan invocation. Parent PID 24194: -bash ACTIVE '/dev/vg02/lvswap' [1,00 GiB] inherit ACTIVE '/dev/vg02/lvroot' [8,00 GiB] inherit ACTIVE '/dev/vg00/lvroot' [5,00 GiB] inherit ACTIVE '/dev/vg00/lvtmp' [1,00 GiB] inherit ACTIVE '/dev/vg00/lvvar' [30,00 GiB] inherit ACTIVE '/dev/vg00/lvvarlog' [10,00 GiB] inherit ACTIVE '/dev/vg00/lvapp' [48,94 GiB] inherit ACTIVE '/dev/vg00/lvproduits' [512,00 MiB] inherit ACTIVE '/dev/vg00/lvswap' [3,88 GiB] inherit ``` Monter le volume racine `/dev/vg00/lvroot` sur le dossier `/mnt` ``` mount /dev/vg00/lvroot /mnt ``` ### Montage des partitions avec libguestfs Les disques créés par l'hyperviseur étant au format **qcow2**, il faut utiliser les outils de libguestfs: ``` [root@s013e13p-snmp /]# qemu-img info /var/lib/libvirt/images/reseau/redmine.img image: /var/lib/libvirt/images/reseau/redmine.img file format: qcow2 virtual size: 70G (75161927680 bytes) disk size: 20G cluster_size: 65536 ``` Récupérer la liste des volumes dans l'image avec **virt-filesystems** ``` [root@s013e13p-snmp /]# virt-filesystems -a /var/lib/libvirt/images/reseau/redmine.img /dev/sda1 /dev/vg_s013centreon/lv_home /dev/vg_s013centreon/lv_root ``` Monter le volume racine `/dev/vg_s013centreon/lv_root` avec **guestmount**: ``` guestmount -a /var/lib/libvirt/images/reseau/redmine.img -m /dev/vg_s013centreon/lv_root /mnt ``` ### Adaptation des paramètres Le disque clôné embarque un système qui hérite des paramètres de la machine d'origine, il faut adapter ces paramères afin de personnaliser la VM avant de la démarrer. Adapter manuellement l'adresse ip essentiellement dans le script **ifcfg-eth0**: ``` [root@s013e13p-snmp /]# vi /mnt/etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 TYPE=Ethernet ONBOOT=yes NM_CONTROLLED=yes BOOTPROTO=none IPADDR=xx.xx.xxx.xxx PREFIX=24 GATEWAY=xx.xx.xxx.x DNS1=xx.xxx.xx.xxx DNS2=xx.xxx.xx.xx DEFROUTE=yes IPV4_FAILURE_FATAL=yes IPV6INIT=no NAME="System eth0" ``` Pour ne pas affecter l'association nom d'interface/adresse MAC désactiver le script **70-persistent-net.rules**: ``` [root@s013e13p-snmp /]# mv /mnt/etc/udev/rules.d/70-persistent-net.rules /mnt/etc/udev/rules.d/70-persistent-net.bkup ``` Remplacer le fichier `/etc/shadow` par celui du serveur à virtualiser: ``` -(ven. sept. 16 07:58:41)--(nessus:~)- [root] # scp /etc/shadow user@xx.xx.xxx.xxx:/mnt/etc/ ``` Une fois cela fait on peut démonter les sytème de fichier. ``` [root@s013e13p-snmp /]# umount /mnt ``` Si on a utilisé **losetup** et **kpartx** pour monter le système il faut également libérer les ressources:\\ `kpartx -d /dev/loop0`\\ `losetup -d /dev/loop0` ## Préparation du nouveau système ### Synchronisation des fichiers du système On doit exclure de la synchronisation les éléments attachés au serveur physique (ainsi que ceux qu'il n'est pas utile de virtualiser, par exemple le répertoire `/opt/image` qui ne contient que des images disques volumineuses) ``` -(ven. sept. 16 07:59:51)--(nessus:~)- [root] # cat > ~/exclude-rsync<< 'EOF' /dev /proc /sys /tmp /run /mnt /media /opt/images lost+found /etc/sysconfig/network-scripts /etc/sysconfig/network /etc/sysconfig/static-routes /etc/fstab /etc/udev/rules.d/70-persistent-net.rules EOF ``` La synchronisation peut prendre un temps plus ou moins long en fonction de la volumétrie sur le serveur que l'on veut virtualiser: ``` [root@s013e13p-snmp /]# rsync -aPKHxv -e ssh --exclude-from=exclude-rsync /opt user@xx.xx.xxx.xxx:/opt sent 4480728368 bytes received 5444641 bytes 8999344.05 bytes/sec total size is 5341445575 speedup is 1.19 ``` Après la synchronisation la taille du disque doit logiquement augmenter: ``` [root@s013e13p-snmp /]# ls -alh /var/lib/libvirt/images/ibm/redmine.img -rw------- 1 qemu qemu 36G 16 sept. 14:55 /var/lib/libvirt/images/ibm/redmine.img ```