## page was renamed from CransTechnique/Services/Virtualisation/MigrationDomuVm ## page was renamed from CransTechnique/Virtualisation/MigrationDomuVm #acl +All:read Cette page a pour but d'expliquer comment migrer un DomU de Xen vers une VM sous Proxmox. <> = Création de la VM Proxmox = Premièrement, il faut créer une VM d'accueil sous Proxmox, vierge. == Création du volume logique == On crée le volume pour cette VM {{{ $ cd /usr/scripts/gestion/iscsi $ ipython In [1]: import nolslib In [2]: nols = nolslib.Nols() In [3]: nols.create_volume('apprentis', 6, 'GiB', 'vmdisk') Le volume apprentis a été créé, son numéro d'identification est 21 In [4]: nols.logout() Si vous avez effectué des modifications pensez à exécuter: /usr/scripts/gestion/iscsi/update.sh sur chacun des dom0 }}} Quittez alors ipython, et obéissez au script, en exécutant update.sh sur fy, fz, kdell et vo (qui sert de nœud redondant pour proxmox en attendant la fin des migrations). == Création de l'hôte sous Proxmox == Plusieurs choix s'offrent à vous, je vais tenter de les détailler. === Création en command line sur un des nœuds du cluster Proxmox === ==== Création du volume ==== Toutes les commandes sont à faire sur la machine sur laquelle vous voulez faire votre travail. Je ferai sans doute un script reprenant toutes ces étapes, quand j'en aurai le temps, en gros, il faut modifier un certain nombre de fichiers, et vérifier que Proxmox a bien pris en compte les changements. Ne faites pas ces changements si vous n'êtes pas sûrs de maîtriser l'intégralité des outils que Proxmox propose : vous pouvez juste péter l'intégralité des services, en command line. Idéalement, assurez-vous que tous les servers du cluster sont bien sur le réseau et arrivent à parler entre eux. Le plus simple reste toujours l'interface web. Premièrement, il faut repérer le disque iscsi à configurer en lvm. Pour cela, rien de plus simple, faîtes {{{ls -al /dev/disk/by-path | grep lun-21}}} (pensez à remplacer le 21 par le numéro que vous a donné ipython). {{{ $ ls -al /dev/disk/by-path | grep lun-21 lrwxrwxrwx 1 root root 10 août 14 12:23 ip-10.0.0.93:3260-iscsi-iqn.1986-03.com.hp:storage.p2000g3.114213a1f2-lun-21 -> ../../sddg lrwxrwxrwx 1 root root 10 août 14 12:23 ip-10.0.0.97:3260-iscsi-iqn.1986-03.com.hp:storage.p2000g3.114213a1f2-lun-21 -> ../../sddh }}} Cherchons donc sddg et sddh dans {{{/dev/disk/by-id}}}. {{{ $ ls -al /dev/disk/by-id | grep sdd[gh] lrwxrwxrwx 1 root root 10 août 14 12:43 scsi-3600c0ff00013da4eb0760b5201000000 -> ../../sddh lrwxrwxrwx 1 root root 10 août 14 12:43 wwn-0x600c0ff00013da4eb0760b5201000000 -> ../../sddh }}} On ne trouve qu'un des deux, normal. Je m'explique. J'aurais bien voulu utiliser directement ce qu'on a trouvé dans /dev/disk/by-path ou /dev/sddg, mais ce sont des valeurs qui dépendent, pour une, de l'ip que la baie de disques a prise (10.0.0.93 ou 10.0.0.97]), et pour l'autre, de l'ordre d'apparition des disques dans udev (sddg ou sddh). Ce sont des données changeantes. Proxmox n'aime pas les données qui peuvent changer. En revanche, l'id est une donnée immuable (sauf si vous détruisez le volume). Donc il faut trouver l'id. Comme celui-ci ne dépend pas de l'ip de l'interface de la baie, ou de l'ordre d'apparition, il ne peut exister deux liens avec le même id dans /dev/disk/by-id, donc on en a qu'un. Mais nous, on s'en fout. Notez cet id quelque part. (celui qui commence par scsi-). '''Attention''', maintenant {{{slon}}} a aussi des volume logiques avec {{{lun-}}}, donc si vous en trouvez plus de 2, ignorez celui dont l'IP n'est pas une des deux de nols : 10.0.0.93 et 10.0.0.97 (slon a pour IPs .30 et .31). Maintenant, créons un groupe de volumes sur le nouveau disque. On utilise pour cela la commande vgcreate. (vg = volume group) {{{ # vgcreate apprentis /dev/iscsi_apprentis }}} Pour les petits curieux qui se demandent pourquoi j'ai pas utilisé pvcreate avant, c'est parce que vgcreate crée le volume physique à la volée si ce n'est pas fait. Maintenant, on crée le stockage dans /etc/pve/storage.cfg {{{ # vim /etc/pve/storage.cfg }}} Ajoutez ça (en remplaçant 21 par le numéro de lun et en mettant le bon id scsi) : {{{ lvm: apprentis vgname apprentis base nols:0.0.21.scsi-3600c0ff00013da4eb0760b5201000000 shared content images }}} Sauvegardez, rechargez la page proxmox si vous faites du ouaibe en parallèle, et admirez. Maintenant, trouvez un id de vm libre. L'idée est d'avoir une suite continue, donc de prendre le premier libre en partant de 100. La config d'une VM n'est accessible que sur le nœud qui l'héberge actuellement. Il faut donc consulter tous les nœuds, et vérifier la liste des id pris dans {{{/etc/pve/qemu-server}}} et {{{/etc/pve/openvz}}} (a priori vide, on utilise pas openvz). Hint : {{{ ls -al /etc/pve/nodes/*/*/*.conf | cut -d "/" -f 7 | sort -n }}} Une fois l'id trouvé, créez le volume logique {{{vm-idtrouvé-disk-1}}} dans le volumegroup que vous avez créé précédemment, pour moi, l'id est 107. {{{-n}}} permet de donner un nom au disque et on utilise la convention de nommage qu'utilise l'interface web (le disque aurait eu ce nom si on l'avait fait avec le cliquodrome), {{{-l 100%FREE}}} signifie qu'on veut utiliser 100% de l'espace libre sur le groupe de volume {{{apprentis}}}. Ça donne donc : {{{ # lvcreate -n vm-107-disk-1 -l 100%FREE apprentis }}} ==== Création de la machine ==== Je crée donc /etc/pve/qemu-server/107.conf et j'y mets : {{{ args: -nographic -serial unix:/var/run/qemu-server/107.serial,server,nowait balloon: 128 bootdisk: virtio0 cores: 1 ide2: none,media=cdrom memory: 512 name: apprentis net0: e1000=EE:DC:7E:BB:48:3B,bridge=vmbr0 net1: e1000=EE:DC:7E:BB:48:3C,bridge=vmbr2 ostype: l26 virtio0: apprentis:vm-107-disk-1 sockets: 1 }}} * Modifiez args en mettant l'id voulu à la place de 107 * Changez le name * Mettez autant de netX que besoin est, en bridgant correctement. Attention, vmbr0 est le vlan 1, et ensuite, vmbrX est le vlan X. Mettez la mac de l'ancienne machine sur chaque interface. * Pour virtio0, mettez nomduvolumegroup:nomdulvmqu'onacréé * Ne touchez pas à sockets, sauf si vous avez lu la doc de proxmox. Enregistrez et quittez. On va maintenant mettre en place le contenu du disque. ==== Remplissage du disque ==== Bon, maintenant, bunches of fun comming. La suite se fait en root. Toujours pareil, remplacez apprentis par le vgname voulu, et 107 par l'id voulu. Vous arrivez dans le plus beau prompt du monde. Les parties importantes sont entre astérisques, le reste est là pour préserver le contexte {{{ # fdisk /dev/apprentis/vm-107-disk-1 Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel Building a new DOS disklabel with disk identifier 0x67a1fd65. Changes will remain in memory only, until you decide to write them. After that, of course, the previous content won't be recoverable. Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite) ***Command (m for help): n*** Partition type: p primary (0 primary, 0 extended, 4 free) e extended ***Select (default p): p*** ***Partition number (1-4, default 1): 1*** ***First sector (2048-12574719, default 2048): *** Using default value 2048 ***Last sector, +sectors or +size{K,M,G} (2048-12574719, default 12574719): *** Using default value 12574719 ***Command (m for help): t*** Selected partition 1 ***Hex code (type L to list codes): 8e*** Changed system type of partition 1 to 8e (Linux LVM) ***Command (m for help): a*** ***Partition number (1-4): 1*** ***Command (m for help): w*** The partition table has been altered! Calling ioctl() to re-read partition table. WARNING: Re-reading the partition table failed with error 22: Argument invalide. The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8) Syncing disks. }}} Le warning à la fin tombe bien, on va utiliser kpartx pour accéder au volume qu'on vient de créer. {{{ # kpartx -av /dev/apprentis/vm-107-disk-1 }}} kpartx sert à rendre accessibles les partitions qu'on vient de créer, qui ne le sont pas de base. kpartx vient, dans mon exemple, de créer /dev/mapper/apprentis-vm--107--disk--1p1, qui est un lien symbolique vers /dev/dm-11, comme on peut le voir ici : {{{ $ ls -al /dev/mapper total 0 drwxr-xr-x 2 root root 300 août 14 13:28 . drwxr-xr-x 23 root root 12720 août 14 13:28 .. lrwxrwxrwx 1 root root 8 août 14 13:23 apprentis-vm--107--disk--1 -> ../dm-10 ''lrwxrwxrwx 1 root root 8 août 14 13:28 apprentis-vm--107--disk--1p1 -> ../dm-11'' crw------- 1 root root 10, 61 juin 11 13:07 control lrwxrwxrwx 1 root root 7 août 14 01:52 irc-vm--106--disk--1 -> ../dm-8 lrwxrwxrwx 1 root root 7 août 10 15:06 kdell-slash -> ../dm-0 lrwxrwxrwx 1 root root 7 août 10 15:06 kdell-swap -> ../dm-2 lrwxrwxrwx 1 root root 7 août 10 15:06 kdell-var -> ../dm-1 lrwxrwxrwx 1 root root 7 août 10 16:54 pea-vm--105--disk--1 -> ../dm-9 lrwxrwxrwx 1 root root 7 juil. 3 22:23 pouhle_ouanne-vm--100--disk--1 -> ../dm-7 lrwxrwxrwx 1 root root 7 juin 17 18:54 pouhle_ouanne-vm--101--disk--1 -> ../dm-3 lrwxrwxrwx 1 root root 7 juin 22 14:28 pouhle_ouanne-vm--102--disk--1 -> ../dm-4 lrwxrwxrwx 1 root root 7 juin 22 15:31 pouhle_ouanne-vm--103--disk--1 -> ../dm-6 lrwxrwxrwx 1 root root 7 juin 17 18:57 pouhle_ouanne-vm--104--disk--1 -> ../dm-5 }}} On crée maintenant le lvm propre à la machine. Pour éviter les conflits, il faut nommer le lvm avec un nom qui n'est pas pris, ici, j'utiliserai apprentislv. {{{ # vgcreate apprentislv /dev/mapper/apprentis-vm--107--disk--1p1 # lvcreate -n slash -L 3000MB apprentislv # lvcreate -n var -L 3000MB apprentislv # lvcreate -n swap -l 100%FREE apprentislv }}} On crée les fs : {{{ # mkfs.ext4 /dev/apprentislv/slash # mkfs.ext4 /dev/apprentislv/var # mkswap -f /dev/apprentislv/swap # mkdir /mnt/apprentis # mount /dev/apprentislv/slash /mnt/apprentis # mkdir /mnt/apprentis/var # mount /dev/apprentislv/var /mnt/apprentis/var }}} On coupe le serveur à migrer sur fy ou fz, et on monte ses disques correctement (var peut ne pas exister, et d'autres partitions peuvent exister, penser à vérifier ce que donne {{{ls -al /dev | grep iscsi_apprentis}}}) {{{ $ sudo xm shutdown apprentis $ sudo mkdir /mnt/apprentis $ sudo mount /dev/iscsi_apprentis_slash /mnt/apprentis $ sudo mount /dev/iscsi_apprentis_var /mnt/apprentis/var }}} === Transfert à base de tar === On remplit une archive tar avec les données du domu. (on aurait pu utiliser un tunnel netcat, mais tous mes tests ont mené à des freezes, or la perte de données est à proscrire) {{{ # cd /mnt/apprentis # tar --numeric-owner -pscf /apprentis.tar . }}} Quand c'est plein, on l'envoie sur l'hôte proxmox, et on décompresse. {{{ # cd /mnt/apprentis # tar --numeric-owner -xpsf /apprentis.tar }}} === Transfert à base de rsync === En supposant que votre ancien système est monté dans {{{/mnt/old_apprentis}}} et le nouveau dans {{{/mnt/apprentis}}}, on peut faire un rsync récursif (noter la position des {{{/}}}) {{{ rsync -aXAH --numeric-ids /mnt/old_apprentis/ /mnt/apprentis }}} On peut avoir fait un premier transfert des partitions intéressantes, lorsque le serveur était up, à l'aide de ssh : {{{ rsync --rsh=ssh -aXAHx --numeric-ids root@apprentis.adm.crans.org:/ /mnt/apprentis rsync --rsh=ssh -aXAHx --numeric-ids root@apprentis.adm.crans.org:/var/ /mnt/apprentis/var }}} À noter que l'on a rajouté l'option {{{-x}}} (aka {{{--one-filesystem}}}) pour éviter de rsync des partitions nfs ({{{/usr/scripts}}} ou {{{/home/}}} …), cela nous oblige donc à rsync les différents points de montage. == Retour à l'install == Une fois que c'est fini, on un du -s dans /mnt/apprentis permet de voir si tout est bon des deux côtés. Puis, faites sur le dom0 : {{{ # umount /mnt/apprentis/var # umount /mnt/apprentis }}} Enfin, faites sur l'hôte proxmox : (PAS FINI) {{{ # mount -o bind /dev /mnt/apprentis/dev # mount -o bind /dev/pts /mnt/apprentis/dev/pts # mount -o bind /proc /mnt/apprentis/proc # mount -o bind /sys /mnt/apprentis/sys # chroot /mnt/apprentis/ /bin/bash # Faire ce qu'il faut pour que resolv.conf contienne 138.231.136.98 # apt-get update # apt-get install linux-image-amd64 # apt-get install lvm2 # apt-get install grub2 //refuser d'installer grub sur un disque, retrouver le bon est trop chiant. }}} Nettoyez les modifications que vous avez faites dans {{{/etc/resolv.conf}}}. Il faut maintenant trouver vers quel descripteur pointe {{{/dev/apprentis/vm-107-disk-1}}}, {{{ls -al /dev/apprentis}}} permet de répondre à cette question. Chez moi c'est /dev/dm-10. Activer le debug série dans la console linux en mettant à jour les variables suivantes dans {{{/etc/default/grub}}} : {{{ GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8" GRUB_CMDLINE_LINUX="console=tty0 console=ttyS0,115200n8" }}} Modifier alors {{{/boot/grub/device.map}}}, et en vider le contenu. Mettre {{{ (hd0) /dev/dm-10 }}} Exécuter {{{update-grub2}}}, puis taper {{{exit}}} pour sortir du chroot. Il reste à faire {{{grub-install --root-directory=/mnt/apprentis /dev/dm-10}}}, pour installer grub sur le disque dur. Puis enfin, modifiez {{{/mnt/apprentis/etc/fstab}}} et {{{/mnt/apprentis/etc/fstab.local}}} pour prendre en compte l'apparition du lvm sur votre nouvelle machine. En gros, les disques auront pour chemin {{{/dev/apprentislv/slash}}} etc. Enfin, modifier {{{/mnt/apprentis/etc/inittab}}}, et remplacer la ligne à la fin, de la forme {{{vc:2345:respawn:/sbin/getty 38400 hvc0}}} par : {{{ S0:12345:respawn:/sbin/agetty -L 115200 ttyS0 vt102 }}} Puis, finissez par : {{{ # umount /mnt/apprentis/var # umount /mnt/apprentis/proc # umount /mnt/apprentis/sys # umount /mnt/apprentis/dev/pts # umount /mnt/apprentis/dev # umount /mnt/apprentis # vgchange -a n apprentislv # kpartx -dv /dev/apprentis/vm-107-disk-1 # vgchange -a n apprentis }}} Enfin, tentez un {{{qm start 107}}} (comme d'habitude, remplacez 107 par le bon id)… Une fois la machine correctement démarrée (croisons les doigts), modifier nouveau {{{/etc/default/grub}}} : {{{ GRUB_TERMINAL=serial GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1" }}} (ceci active la console grub série) Enfin, recalculer le mapping de grub et regénérer sa config : {{{ # grub-mkdevicemap # update-grub2 }}} L'objectif est de remplader le {{{/dev/dm-10}}} qui est dans {{{/boot/grub/device.map}}}, et refaire la config. == Trucs à faire pour finaliser == * Changer les groupes dans bcfg2 * virer les fichiers de config xen {{{/etc/xen/[nom_de_la_vm]}}}, sur {{{fy}}} et {{{fz}}} pour éviter de lancer l'ancien domU * Virer le cron qui mettait à jour la date (kludge pour xen): {{{ sudo rm /etc/cron.d/ntpdate }}}