# 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](https://pve.proxmox.com/wiki/Storage) pour ces disques. Nous utilisons actuellement (09 janvier 2020) les stockages suivants : * [LVM](https://pve.proxmox.com/wiki/Storage:_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](https://pve.proxmox.com/wiki/Storage:_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 VG `data`, sur lequel on créé deux LV : `docker` et `backup`. 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](https://pve.proxmox.com/wiki/Storage_Migration) 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](https://wiki.picasoft.net/doku.php?id=merge_pv_copy_lv#deplacer_les_donnees_d_un_pv_vers_un_autre_pv) 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). ```bash $ docker stop [...] $ umount $ lvremove $ vgremove $ pvremove $ nano /etc/fstab # Supprimer l'entrée correspondant à /dev/mapper/ ``` 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`. ```bash # Bouger tous les PE du PV vers d'autres PV $ pvmove # Enlever le PV du VG $ vgreduce $ pvremove ``` 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](https://wiki.picasoft.net/doku.php?id=infrastructure:hotplug_vm), il faudra la redémarrer (plus tard) pour que la modification soit prise en compte. {{ :infrastructure:proxmox_detach_disk.png?800 |}} 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](http://blog.roberthallam.org/2017/12/solved-logical-volume-is-used-by-another-device/comment-page-1/) 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. {{ :infrastructure:proxmox_remove_storage.png?900 |}} ## 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. ```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` : ```bash $ mount -a ``` Si tout s'est bien passé, on va maintenant créer un nouveau stockage local (ou Directory) dans Proxmox. {{ :infrastructure:proxmox_add_storage.png?900 |}} ## 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](https://fr.wikipedia.org/wiki/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. {{ :infrastructure:proxmox_new_disk.png?800 |}} 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. ```bash $ pvcreate /dev/sdaX $ vgcreate hdd /dev/sdX $ lvcreate -n -l 50%FREE hdd $ mkfs.ext4 /dev/mapper/hdd- ``` On ajoute ensuite la ligne suivante au fichier `/etc/fstab` : ``` /dev/mapper/hdd- 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. ```bash $ mount -a $ rsync -aP ``` 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é.