Migrer du stockage LVM vers un stockage local sur Proxmox
Cette page est un tutoriel pour une maintenance “historique” des machines. Il n’est pas nécessaire de la suivre lors de la mise en place de nouvelles machines.
Contexte
Proxmox permet de créer des “images disques” qui stockent le contenu des machines virtuelles et qui sont ensuite exposés comme des périphériques bloc aux machines virtuelles (disques virtuels).
Il existe plusieurs types de stockages pour ces disques. Nous utilisons actuellement (09 janvier 2020) les stockages suivants :
- LVM : il suffit de spécifier à Proxmox un Volume Group (VG), et chaque fois qu’un disque est créé, un Logical Volume (LV) est créé sur ce VG et sera monté sur la machine virtuelle.
- Directory (ou stockage local) : il s’agit d’un dossier utilisé pour stocker des images de disques. Chaque fois qu’un disque est créé, un fichier est créé dans ce dossier et sera “monté” sur la machine virtuelle.
En ce qui nous concerne, nous utilisions :
- Le stockage local pour le SSD,
- Le stockage LVM pour le HDD.
Et nous utilisons également LVM dans les machines virtuelles. Par exemple, un disque alloué sur le SSD pour une machine virtuelle pourra ensuite être partitionné en plusieurs LV : un pour Docker, un pour la racine, un pour le SWAP… Similairement, un disque alloué sur le HDD pourra être partitionné : un pour Docker si la vitesse de lecture n’est pas critique, un pour les backups…
Nous avons rencontré un problème gênant : quand le stockage LVM est utilisé, le LVM à l’intérieur de la machine virtuelle n’est pas encapsulé. Reprenons étape par étape :
- On créé un disque pour une VM
A
sur le stockage LVM. - Proxmox créé un LV et le monte dans
A
comme, e.g./dev/sdb
. - Dans la VM, on crée un PV depuis
/dev/sdb
, puis on lui assigne un VGdata
, sur lequel on créé deux LV :docker
etbackup
.
Et bien, on aura la surprise de voir que sur l’hôte, un PV a été créé partir du LV monté sur /dev/sdb
, et ainsi de suite. On se retrouve donc avec VG pour le stockage LVM
→ LV pour le disque de la VM
→ PV
→ VG
→ LV docker et data
directement sur l’hôte.
C’est tordu et ça peut amener à des confusions ! Par exemple, si on créé un VG sur la machine virtuelle qui a le même nom qu’un VG sur l’hôte (true story).
Objectifs
Considérant que nous n’avons pas besoin d’avoir ce double niveau de LVM, on va tout simplement décider de passer le stockage du HDD en stockage local.
Le dossier dans lequel seront stockées les images sera monté depuis un LV créé sur l’hôte, ce qui veut dire que si on ajoute un disque dur sur la machine physique, on pourra étendre ce LV et augmenter la taille du stockage. On ne perd aucun avantage, et on peut continuer d’utiliser LVM sur les machines.
Le processus va donc être le suivant :
- Bouger toutes les données des disques créés sur le HDD sur des disques créés sur le SSD
- Supprimer l’ensemble des disques, et finalement supprimer le stockage local LVM
- Créer un stockage local basé sur un LV utilisant le HDD
- Créer des disques sur ce stockage local, qui remplacent les anciens disques
- Copier les anciennes données sur ces disques
Une fois ces étapes terminées, on aura un état clair et compréhensible : deux stockages, un pour le SSD, un pour le HDD. Même gestion des disques. LVM sur les machines pour la souplesse.
Notez qu’on ne peut pas utiliser la fonction de migration de Proxmox puisque le stockage LVM n’utilise pas les images disques RAW ou QCow2.
Déplacer les données
On déplace les données depuis le HDD (tous les PV sur /dev/sdb
) vers le SSD (tous les PV sur /dev/sda
), par exemple.
Rien de plus simple : on se rend sur la machine virtuelle et :
- Si les données dans les LV ne sont pas susceptibles d’être modifiées pendant la copie, on va simplement les copier au niveau du système de fichiers (e.g.
rsync
) - Sinon, on pourra utiliser les snapshot LVM pour réduire le downtime.
Supprimer les disques
Deux cas s’offrent à nous.
Premier cas : le PV correspondant au HDD était dans un VG à part, dans ce cas on on démonte le LV, on supprime le VG et ses LV puis on supprime l’entrée dans /etc/fstab
. Pour ce faire il ne suffit pas de démonter le LV, il faut aussi éteindre tous les conteneurs ayant un bind mount le concernant (dans le cas de /DATA/BACKUP
, on éteindra db-backup
et backup-rotation
, puis on démontera /DATA/BACKUP
, par exemple).
- snippet.bash
$ docker stop [...] $ umount <lv-target> $ lvremove <lv> $ vgremove <vg> $ pvremove <pv> $ nano /etc/fstab # Supprimer l'entrée correspondant à /dev/mapper/<lv>
Deuxième cas : le PV correspondant au HDD faisait partie d’un VG contenant d’autres PV, dans ce cas on supprime uniquement le PV : les PE (Physical Extents) des LV auront été transférés sur un autre PV grâce à la commande pvmove
.
- snippet.bash
# Bouger tous les PE du PV vers d'autres PV $ pvmove <pv> # Enlever le PV du VG $ vgreduce <vg> <pv> $ pvremove <pv>
Si les fichiers à déplacer sont importants pour le fonctionnement de l’infrastructure (e.g. /DATA/docker
sur monitoring
est sur le HDD), on pourra, après démontage de l’ancien LV, recréer le dossier sur le SSD et y copier les données, puis relancer les services (temporairement).
On peut ensuite détacher le disque depuis l’interface Proxmox, puis le supprimer. Si le disque était exposé en SATA ou si la machine virtuelle ne supporte pas le hotplug, il faudra la redémarrer (plus tard) pour que la modification soit prise en compte.
Si le hotplug n’est pas activé, il faudra redémarrer la machine avant de pouvoir supprimer le disque (il apparaîtra en rouge barré). Notez que si la suppression du disque n’est pas possible alors qu’il est en état détaché, cela peut être du à ce problème et m’est arrivé sur un des disques. On passe alors sur un shell et on résoud le problème.
On ré-itère l’opération sur l’ensemble des machines virtuelles utilisant le stockage LVM du HDD.
Suppression du stockage LVM
Une fois que l’ensemble des données sur le stockage HDD LVM de Proxmox ont été mises dans un endroit sûr, et que tous les disques attachés à ce stockage ont été détachés et supprimés, alors on peut supprimer le stockage lui-même.
Pour ce faire, on se rend dans l’interface Proxmox, au niveau de la gestion du stockage global (Datacenter), et on supprime le stockage LVM.
Création d'un nouveau stockage local
Sur les machines (hôtes), on a deux VG : un correspondant au SSD (pve
), et un correspondant au HDD (hdd
).
On créé donc un nouveau LV sur le VG hdd
qui servira de stockage local pour les images disques. On pourra le redimensionner plus tard. On créé aussi un système de fichiers et on modifie /etc/fstab
pour automatiser le montage au démarrage.
- snippet.bash
# LV de 300G nommé vm_storage sur le VG hdd $ lvcreate -n vm_storage -L 300g hdd # Création d'un système de fichier ext4 sur le nouveau LV $ mkfs.ext4 /dev/mapper/hdd-vm_storage # Création du dossier sur lequel sera monté le LV $ mkdir /var/lib/vm_storage
On ajoute cette ligne dans /etc/fstab
, attention à la correspondance des chemins.
/dev/mapper/hdd-vm_storage /var/lib/vm_storage ext4 defaults 0 2
Enfin, on vérifie que la syntaxe est correcte en montant le LV à partir de l’entrée dans /etc/fstab
:
- snippet.bash
$ mount -a
Si tout s’est bien passé, on va maintenant créer un nouveau stockage local (ou Directory) dans Proxmox.
Créer les nouveaux disques et restaurer les données
On va globalement faire les opérations inverses.
Pour chaque machine virtuelle dont on a supprimé un disque sur le stockage LVM, on va re-créer nouveau disque. On choisira :
- Le bus
SCSI
, qui est pris en charge par la fonctionnalité hotplug, contrairement a SATA, - Le stockage
vm_hdd
, qui correspond au stockage créé précédemment, - Le format Qcow2, qui contrairement au format RAW, n’utilise que l’espace disque vraiment utilisé. Ainsi, les machines virtuelles verront un disque de taille fixe, tandis que l’hôte n’utilisera que l’espace réellement occupé.
Voir un exemple ci-dessous.
Avec le hotplug, le disque est directement accessible sur la machine. On va donc suivre la procédure habituelle : créer un PV, puis un VG, puis un LV avec par exemple une taille de 50% de l’espace disponible, puis un système de fichiers.
- snippet.bash
$ pvcreate /dev/sdaX $ vgcreate hdd /dev/sdX $ lvcreate -n <nom du lv, e.g. backup si pour /DATA/BACKUP...> -l 50%FREE hdd $ mkfs.ext4 /dev/mapper/hdd-<nom du LV>
On ajoute ensuite la ligne suivante au fichier /etc/fstab
:
/dev/mapper/hdd-<nom du lv> <point de montage> ext4 defaults 0 2
Ensuite, on vérifie que tout s’est bien passé en montant le LV à partir de /etc/fstab
et on copie les données sauvegardée ailleurs à la première étape.
- snippet.bash
$ mount -a $ rsync -aP <chemin de la sauvegarde> <point de montage>
On redémarre ensuite les services pouvant écrire ou lire sur ce dossier.
On répète l’opération pour toutes les machines virtuelles.
Le transfert des données d’un stockage LVM à un stockage local est terminé.