Migrer une installation Linux

Migrer une installation Linux

(image générée par IA)

Dans la mesure oĂą tu as installĂ© les pilotes gĂ©nĂ©riques lors du dĂ©ploiement de ta distro, Linux se contrefout du matĂ©riel sur lequel il tourne et c’est probablement pour ça qu’il existe depuis plus longtemps des LiveCD pour utiliser les distros Linux que des WinPe.

Pour faire simple, migrer une install Linux d’une machine Ă  une autre c’est :

  • Recopier (tout sauf /proc, /sys et, /dev) le contenu du disque dur de la machine source vers le disque dur vide d’une machine cible dĂ©marrĂ©e avec un LiveCD.
  • Bind /proc, /sys et, /dev depuis le LiveCD vers le disque dur et chroot.
  • Modifier le fstab et mettre Ă  jour Grub.

De cette manière, tu peux rĂ©aliser des migrations d’une machine Ă  une autre que ce soit du physique -> vm, vm -> physique, vm -> vm.

La migration

Dans Linux – Le b.a.-ba du shell, je t’ai pas parlĂ© des dossiers /proc, /sys et /dev pour ne pas trop te noyer d’informations (il y a encore beaucoup de choses Ă  ce sujet). Le contenu de ces dossiers est créé au dĂ©marrage du système ; c’est un système de fichiers virtuel volatile.
/proc correspond aux processus en cours d’exĂ©cution, /sys Ă  une interface avec le noyau et /dev aux pĂ©riphĂ©riques vus par le système.

Pour faire simple, on va migrer la vm source vers l’autre vm destination (qui est une vm totalement vide sans installation). OuĂ© je me suis pas foulĂ© pour les noms de machine.

Préparation de la vm destination

On va dĂ©marrer notre machine destination sur un LiveCD de la mĂŞme version de la distribution que l’on migre, changer la disposition du clavier et enfin, installer et paramĂ©trer les outils nĂ©cessaires ou utiles (vim, rsync, openssh-server) Ă  la migration.

En fait c’est mieux mais c’est pas obligatoire d’utiliser un LiveCD de la mĂŞme version. Par contre t’Ă©viteras absolument de mĂ©langer 32 et 64 bits.

destination
# En console
user@debian:~$ sudo -i
root@debian:~# hostname destination
root@debian:~# echo "destination" > /etc/hostname
[...]
root@destination:~# apt install vim openssh-server rsync
root@destination:~# sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config
root@destination:~# systemctl restart ssh
root@destination:~# passwd

# Et voilĂ  plus besoin de tout retaper Ă  la main, on reprend en ssh
antoine@dressing:~$ ssh root@destination

Partitionnement

LĂ  va falloir que tu créé tes partitions Ă  l’identique (je fais un sed pour frimer mais surtout pour limiter la verbositĂ©) alors relève l’existant sur la source.

source
root@source:~# fdisk -l | sed -n "9,13p"
Device     Boot   Start      End  Sectors  Size Id Type
/dev/sda1          2048   976895   974848  476M 82 Linux swap / Solaris
/dev/sda2  *     976896  1953791   976896  477M 83 Linux
/dev/sda3       1953792 41940991 39987200 19,1G 8e Linux LVM

root@source:~# lvs
  LV      VG      Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  lv_home vg_main -wi-ao---- <1,91g                                                    
  lv_root vg_main -wi-ao---- 17,16g

Cherche sur quel disque tu vas bosser et ouvre fdisk pour ce disque.

destination
root@destination:~# fdisk -l | grep "/dev"
Disk /dev/sda: 20 GiB, 21474836480 bytes, 41943040 sectors
Disk /dev/loop0: 984.42 MiB, 1032241152 bytes, 2016096 sectors

# Ton disque est /dev/sda alors
root@destination:~# fdisk /dev/sda

Créé une table de partition gpt et une première partition de 80 Mo de type BIOS boot si tu boot en mode BIOS (c’est pas nĂ©cessaire si t’es en UEFI).

destination > fdisk > bios boot
Command (m for help): g # créé une table de partition GPT
Created a new GPT disklabel (GUID: 23E71E7F-E36C-F54B-9028-36FEE57A4761).

Command (m for help): n # créé la partition de boot bios (je suis en GPT sans EFI, alors il faut une partition en début de disque)
Partition number (1-128, default 1): 
First sector (2048-41943006, default 2048): 
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-41943006, default 41940991): +80M

Created a new partition 1 of type 'Linux filesystem' and of size 80 MiB.

Command (m for help): t # règle le format de la parition
Selected partition 1
Partition type or alias (type L to list all): 4 # c'est le format BIOS boot. J'ai utilisé "L" qui m'a listé les formats dans `less`.
Changed type of partition 'Linux filesystem' to 'BIOS boot'.

Créé ensuite ta swap.

destination > fdisk > swap
Command (m for help): n # créé la parition de la swap
Partition number (1-128, default 2): 
First sector (165888-41943006, default 165888): 
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-41943006, default 41940991): +476M

Created a new partition 2 of type 'Linux filesystem' and of size 476 MiB.

Command (m for help): t
Partition number (1,2, default 2): 2
Partition type or alias (type L to list all): 19 # c'est le format Linux swap.
Changed type of partition 'Linux filesystem' to 'Linux swap'.

Puis /boot. Par défaut fdisk créé des partitions Linux filesystem alors celle là tu touches pas au type.

destination > fdisk > boot
Command (m for help): n # créé la partition /boot
Partition number (3-128, default 3): 3
First sector (1140736-41943006, default 1140736): 
Last sector, +/-sectors or +/-size{K,M,G,T,P} (1140736-41943006, default 41940991): +477M

Created a new partition 3 of type 'Linux filesystem' and of size 477 MiB.

Enfin, créé ton lvm et applique les modifications.

destination > fdisk > lvm
Command (m for help): n # créé la partition LVM (pas touche au format de /boot c'est déjà bien reglé)
Partition number (4-128, default 4): 4
First sector (2117632-41943006, default 2117632): 
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2117632-41943006, default 41940991): 

Created a new partition 4 of type 'Linux filesystem' and of size 19 GiB.

Command (m for help): t
Partition type or alias (type L to list all): 43
# n'oublie pas que "L" te permet de less la liste et donc que la liste est potentiellement plus longue que ce que tu as à l'écran.

Changed type of partition 'Linux filesystem' to 'Linux LVM'.

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

Tu as créé tes partitions Ă  la bonne taille, tu peux formater la partition de swap et /boot. Ne formate pas la première partition /dev/sda1 elle n’est lĂ  que pour gĂ©rer la table de partition gpt (elle est nĂ©cessaire pour utiliser gpt sur une installation non UEFI).

destination
# Formatage de la swap
root@destination:~# mkswap /dev/sda2
Setting up swapspace version 1, size = 476 MiB (499118080 bytes)
no label, UUID=fa566364-1bde-4fd7-b6de-0fda58ab5761

# Formatage de /boot
root@destination:~# mkfs.ext4 /dev/sda3
mke2fs 1.47.0 (5-Feb-2023)
Creating filesystem with 488448 1k blocks and 121920 inodes
Filesystem UUID: da53ae9a-40a7-4669-bd91-590620ad50d6
Superblock backups stored on blocks: 
        8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done 

Un peu de LVM

Maintenant tu vas pouvoir crĂ©er tes Ă©lĂ©ments lvm : le Volume Group et les Logical Volumes. Utilise un lv linĂ©aire (-L) pour la /home parce que tu la dĂ©finie avec une taille fixe et un lv striped (-l) pour la / pour lui attribuer tout l’espace libre restant.

destination
# créé le Volume Group
root@destination:~# vgcreate vg_main /dev/sda4
  Physical volume "/dev/sda4" successfully created.
  Volume group "vg_main" successfully created
  
# créé le Logical Volume linéaire lv_home
root@destination:~# lvcreate -L 2G vg_main -n lv_home
  Logical volume "lv_home" created.
  
# créé le LV striped lv_root
root@destination:~# lvcreate -l +100%FREE vg_main -n lv_root
  Logical volume "lv_root" created.

Formate alors tes partitions lvm.

destination
# Fais un effort de compréhension, on l'a vu juste au dessus
root@destination:~# mkfs.ext4 /dev/vg_main/lv_home
mke2fs 1.47.0 (5-Feb-2023)
Creating filesystem with 524288 4k blocks and 131072 inodes
Filesystem UUID: 39135a06-293e-4cd7-8849-47f02e283a2d
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376, 294912

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done 

# Meehhh
root@destination:~# mkfs.ext4 /dev/vg_main/lv_root 
mke2fs 1.47.0 (5-Feb-2023)
Creating filesystem with 4453376 4k blocks and 1114112 inodes
Filesystem UUID: f8ef3138-0492-4402-a12a-35ee117a90e3
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
        4096000

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

Montage des partitions

Pour commencer à préparer le rsync du système de source il faut monter notre future /. Perso, je vais monter mon lv_root dans /mnt/root mais tu peux le monter où tu veux tant que tu gères la cohérence pour la suite. Créé alors les réceptacles des dossiers /boot, /home, /dev, /proc et, /sys.

destination
# Créé le point de montage
root@destination:~# mkdir /mnt/root

# Monte lv_root dessus
root@destination:~# mount /dev/vg_main/lv_root /mnt/root

# Créé tes dossiers
rLinux filesystemoot@destination:~# mkdir /mnt/root/boot /mnt/root/home /mnt/root/dev/ /mnt/root/proc/ /mnt/root/sys/

Monte alors tes partitions /boot et /home.

destination
root@destination:~# mount /dev/sda3 /mnt/root/boot
root@destination:~# mount /dev/vg_main/lv_home /mnt/root/home

Montage bind

Vu que le LiveCD a peuplé les dossiers /dev, /proc et, /sys de façon adaptée pour destination, tu vas les réutiliser dans notre future /. Pour ça, tu vas faire un montage bind des existants vers /mnt/root/... et tu adaptes. Si tu veux te faire une fausse idée des montages bind, tu peux imaginer ça comme un mélange entre un lien physique et un raccourci. Le but est de partager un dossier à plusieurs endroits.

destination
root@destination:~# mount -o bind /dev /mnt/root/dev
root@destination:~# mount -o bind /proc /mnt/root/proc
root@destination:~# mount -o bind /sys /mnt/root/sys

Migration de l’OS source

La transplantation de l’OS de source vers destination est prĂŞte ! Mais ne rĂ©cupère pas /dev, /proc et, /sys et tant qu’Ă  faire ne rĂ©cupère pas non plus /lost+found.

destination
root@destination:~# rsync -avz source:/ /mnt/root/ --exclude=/dev --exclude=/proc --exclude=/sys --exclude=/lost+found

Sur des machines un peu dodues, tu pourras prĂ©fixer ta commande par un time pour connaĂ®tre après coup combien de temps l’opĂ©ration a durĂ©. Également, tu pourras exclure tes dossiers de donnĂ©es lourds pour gagner du temps et les rsync après.

Entre dans le terrier de lapin : le chroot

Passons maintenant du LiveCD au système que l’on vient de recopier depuis source sur destination.

destination
root@destination:~# chroot /mnt/root/
root@destination:/# 

# Quoi ? C'est tout ?!

A partir de lĂ , on est sur la copie de l’OS de source mais sur le hardware de destination.

destination
root@destination:/# cat /etc/hostname 
source

Il va falloir ĂŞtre mĂ©ticuleux : ne surtout pas oublier de modifier le hostname et l’adresse IP de la machine pour ne pas avoir de doublon. ARP Storm quand tu nous guette… Parce que ta nouvelle machine va probablement devoir cohabiter quelques temps avec l’ancienne toujours en prod, le temps par exemple de faire les derniers rsync. Bon moi mes vm sont en DHCP alors je ne passe que sur le hostname.

destination
root@destination:/# echo "source-new" > /etc/hostname
root@destination:/# hostname source-new

Partitions et UUID

A partir de lĂ  il te reste deux choses Ă  traiter : fstab et grub.
Dans fstab ce qui va nous dĂ©ranger ce sont les UUID, il connaĂ®t ceux des partitions de source mais maintenant tu veux qu’il prĂ©sente ceux de destination.

destination
# UUID de source
root@destination:/# grep UUID /etc/fstab 
# device; this may be used with UUID= as a more robust way to name devices
UUID=f96c7db6-9354-48ce-af9b-04df025da015 /boot           ext4    defaults        0       2
UUID=b8bce0d7-4e4d-4fc0-b8b5-bcf6c67dace1 none            swap    sw              0       0

# UUID de destination
root@destination:/# lsblk -o NAME,SIZE,TYPE,MOUNTPOINTS,UUID
NAME                  SIZE TYPE MOUNTPOINTS UUID
loop0               984.4M loop             
sda                    20G disk             
|-sda1                 80M part             b8bce0d7-4e4d-4fc0-b8b5-bcf6c67dace1
|-sda2                476M part             f96c7db6-9354-48ce-af9b-04df025da015
|-sda3                477M part /boot       90icDI-eyvU-7L4H-W214-YaM2-kPQh-w1pwLh
`-sda4                 19G part             
  |-vg_main-lv_home     2G lvm  /home       6390fdc8-b9dc-46c1-80d9-c7442302a1d4
  `-vg_main-lv_root    17G lvm  /           0071373a-3160-480a-a977-fbe68728d824
sr0                   1.4G rom

Tu as deux possibilités pour la suite :

  • modifier le fstab pour remplacer les UUID de source par celles de destination,
  • modifier les UUID de destination pour reprendre celles de source.

Pour la première possibilitĂ©, bah tu t’armes de sed ou de vi et puis tu remplaces en faisant gaffe de ne pas te tromper. Je pense que c’est la meilleure solution mais j’ai envie d’explorer la seconde : swaplabel permet de modifier l’UUID d’une partition de swap et, tune2fs permet de modifier un UUID d’un système de fichiers ext.

destination
# Applique l'UUID source de ta swap
root@destination:/# swaplabel --uuid b8bce0d7-4e4d-4fc0-b8b5-bcf6c67dace1 /dev/sda2

# Applique l'UUID source de ta boot
# d'abord, démontes la partition et check le filesystem
root@destination:/# umount /dev/sda3
root@destination:/# e2fsck -f /dev/sda3
e2fsck 1.47.0 (5-Feb-2023)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/sda3: 352/121920 files (0.6% non-contiguous), 100770/488448 blocks

# puis, modifie l'UUID et remonte la (oublie pas que t'es chroot !)
root@destination:/# tune2fs -U f96c7db6-9354-48ce-af9b-04df025da015 /dev/sda3
tune2fs 1.47.0 (5-Feb-2023)
Setting the UUID on this filesystem could take some time.
Proceed anyway (or wait 5 seconds to proceed) ? (y,N) y<proceeding>
root@destination:/# mount /dev/sda3 /boot

Bon lĂ  t’as la pression, il faut vĂ©rifier les UUID…

destination
# La swap
root@destination:/# blkid /dev/sda2
/dev/sda2: UUID="b8bce0d7-4e4d-4fc0-b8b5-bcf6c67dace1" TYPE="swap" PARTUUID="2fbbab31-45a1-6843-b01c-c2ecddf9e990"

# /boot
root@destination:/# blkid /dev/sda3
/dev/sda3: UUID="f96c7db6-9354-48ce-af9b-04df025da015" BLOCK_SIZE="1024" TYPE="ext4" PARTUUID="0d734c03-66c5-fe4b-a95f-aece8d7ef253"

A ce moment j’ai fait un peu d’huile parce que lsblk prĂ©sentait toujours les anciens UUID.

Reconfiguration de Grub

Tu dois maintenant rĂ©gĂ©nĂ©rer la configuration de grub et l’installer.

destination
# Ecris la conf de grub dans son fichier
root@destination:/# grub-mkconfig > /boot/grub/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-6.1.0-18-amd64
Found initrd image: /boot/initrd.img-6.1.0-18-amd64
Warning: os-prober will not be executed to detect other bootable partitions.
Systems on them will not be added to the GRUB boot configuration.
Check GRUB_DISABLE_OS_PROBER documentation entry.
done

# Et installe le pépère
root@destination:/# grub-install /dev/sda
Installing for i386-pc platform.
Installation finished. No error reported.

Pour finir, redémarre la machine en éjectant le LiveCD (la console attendra que tu valides la bonne éjection du CD).

destination
root@destination:/# exit
exit
root@destination:~# reboot

Profit !

ContrĂ´le que tout va bien parce que normalement c’est fini, ta machine est migrĂ©e.

source-new
root@source-new:~# lsblk -o NAME,SIZE,TYPE,MOUNTPOINTS,UUID
NAME                 SIZE TYPE MOUNTPOINTS UUID
sda                   20G disk             
├─sda1                80M part             
├─sda2               476M part [SWAP]      b8bce0d7-4e4d-4fc0-b8b5-bcf6c67dace1
├─sda3               477M part /boot       f96c7db6-9354-48ce-af9b-04df025da015
└─sda4                19G part             12dmBX-Qa6C-pjPj-nTo4-hrAi-fIso-OW7f8G
  ├─vg_main-lv_home    2G lvm  /home       39135a06-293e-4cd7-8849-47f02e283a2d
  └─vg_main-lv_root   17G lvm  /           f8ef3138-0492-4402-a12a-35ee117a90e3
sr0                 1024M rom              
root@source-new:~# 
root@source-new:~# 
root@source-new:~# 
root@source-new:~# 
root@source-new:~# df -h
Sys. de fichiers            Taille Utilisé Dispo Uti% Monté sur
udev                          961M       0  961M   0% /dev
tmpfs                         197M    572K  197M   1% /run
/dev/mapper/vg_main-lv_root    17G    1,1G   15G   7% /
tmpfs                         984M       0  984M   0% /dev/shm
tmpfs                         5,0M       0  5,0M   0% /run/lock
/dev/mapper/vg_main-lv_home   2,0G     24K  1,8G   1% /home
/dev/sda3                     437M     59M  351M  15% /boot
tmpfs                         197M       0  197M   0% /run/user/0

Conclusion

Dans cet article tu auras vu quelques notions intĂ©ressantes. Je t’ai fait jouer avec du lvm et tu as mĂŞme pu voir que pour utiliser des partitions gpt sur une machine non UEFI il te faut crĂ©er une petite partition au tout dĂ©but du disque.

Tu auras aussi pu modifier les UUID de tes partoches mais surtout : tu sauras comment migrer n’importe quelle installation Linux d’un hardware Ă  un autre. Tant que le disque de ta source est lisible tu pourras toujours sauver ton installation sans avoir Ă  tout reconfigurer.

MalgrĂ© mes choix dans cet article, je te recommande vivement de modifier les UUID dans le fstab plutĂ´t que de modifier ceux des partitions. Si tu te vautres, c’est plus simple de rsync Ă  nouveau le fichier que de recrĂ©er les partoches.

Comme d’hab, j’ai pu Ă©crire des Ă©normitĂ©s. Si t’en vois une et que le cĹ“ur t’en dit, n’hĂ©site pas Ă  me l’indiquer.

2 réflexions sur « Migrer une installation Linux »

Répondre à antoine Annuler la réponse

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *