Introduction Link to heading
J’ai récemment fait l’acquisition d’une nouvelle machine pour mon homelab. Cette machine, plus puissante que celles que j’avais pu acheter par le passé, aura pour vocation de remplacer plusieurs petits appareils de ma baie, libérant ainsi de l’espace et quelques ports de mon onduleur.
C’est une machine que j’ai choisie pour son faible encombrement, ses multiples ports réseaux et ses 3 slots m.2 me permettant d’y mettre une quantité raisonnable de stockage.
Ce sont aussi ces trois slots qui m’ont donnés envie de gérer mon stockage de la « bonne manière ». Là où habituellement je chiffre seulement mes disques et pose du lvm dessus, j’ai décidé cette fois d’ajouter de la fiabilité à mon installation en configurant deux des disques en miroir.
Il existe différentes solutions permettant de faire cette configuration en miroir (via ZFS, LVM, etc.), j’ai choisi
de le faire via mdadm
pour la simplicité de sa mise en place et de son utilisation.
Configuration du RAID Link to heading
Sur chacun des deux disques, j’ai créé une partition dont la taille est <espace complet du plus petit disque>-100M. En cas de problème ou si je décidais de rajouter un disque dans l’array, il faudrait que la partition sur le nouveau disque ait exactement la même taille que celles des autres disques et il peut arriver qu’entre deux disques de même capacité chez un même constructeur, l’espace disponible soit légèrement différent, d’où les 100M de marge.
# sgdisk -o -n 1:0:+1862900M -t 1:FD00 /dev/nvme0n1
# sgdisk -o -n 1:0:+1862900M -t 1:FD00 /dev/nvme1n1
FD00
est le code hexadécimal correspondant à une partition de type Linux RAID
pour gdisk.
La commande pour créer l’array est ensuite
# mdadm --create --verbose --level=1 --metadata=1.2 --raid-devices=2 /dev/md/gullintanni /dev/nvme0n1p1 /dev/nvme1n1p1
Il faut ensuite ajouter l’array à la configuration de mdadm :
# mdadm --detail --scan
ARRAY /dev/md/gullintanni metadata=1.2 name=heimdallr:gullintanni UUID=abeec7d2:221a1c72:528275a5:5984f735
# mdadm --detail --scan >> /etc/mdadm.conf
Vous pouvez suivre l’état de la réplication des disques via la commande : watch -n 30 cat /proc/mdstat
.
Configuration de luks Link to heading
Il s’agit maintenant de chiffrer ce nouveau disque :
# cryptsetup luksFormat /dev/md/gullintanni
Je souhaite aussi qu’il soit déchiffré au démarrage de son hôte. Il faut pour ça que je crée une clef à ajouter au luks pour déchiffrer le volume :
# mkdir -p /etc/cryptsetup-keys.d/
# chmod 700 /etc/cryptsetup-keys.d/
# dd if=/dev/random bs=512 count=1 of=/etc/cryptsetup-keys.d/gullintanni.key
# chmod 600 /etc/cryptsetup-keys.d/gullintanni.key
# cryptsetup luksAddKey /dev/md/gullintanni /etc/cryptsetup-keys.d/gullintanni.key
Je n’ai plus qu’à ajouter au fichier /etc/crypttab
une entrée correspondante à ce volume, sous la forme <nom> UUID=<uuid>
. Je peux récupérer l’uuid
du volume via la commande lsblk -f
.
# echo "gullintanni UUID=06331d26-0f0c-4a40-9672-06bfe4d7d5ae" >> /etc/crypttab
Pas besoin de renseigner le chemin de la clef : au démarrage systemd-cryptsetup
cherchera dans le dossier
/etc/cryptsetup-keys.d/
une clef au nom de <nom du volume>.key
.
Il est conseillé de faire une sauvegarde des entêtes luks (et de la stocker hors du volume chiffré dont elle est issue) :
# cryptsetup luksHeaderBackup /dev/md/gullintanni --header-backup-file ~vianney/gullintanni-luks-headers.img
Pour le déchiffrer manuellement cette première fois :
# cryptsetup luksOpen /dev/md/gullintanni gullintanni
Configuration de lvm Link to heading
La configuration de lvm est simple : il suffit de créer un PV (physical volume) depuis
/dev/mapper/gullintanni
, de l’associer à un VG (Volume Group) et de tailler selon son besoin des LV (Logical
Volume) dedans.
# pvcreate /dev/mapper/gullintanni
# vgcreate gullintanni /dev/mapper/gullintanni
Dans ce VG, je compte utiliser des LV en thin provisioning comme disques pour mes machines virtuelles. Ici par exemple pour une VM nommée paperless :
# lvcreate --type thin-pool -n libvirt -L 250G gullintanni
# lvcreate -n libvirt-paperless -V 30G --thinpool libvirt gullintanni
Un autre LV en thin-pool me servira à stocker les dossiers des utilisateurs :
# lvcreate --type thin-pool -n home -L 50G gullintanni
# lvcreate -n home-vianney -V 30G --thinpool home gullintanni
# lvcreate -n home-<autre utilisateur> -V 30G --thinpool home gullintanni
Il s’agit maintenant de formatter ces LV et de les monter à l’endroit désiré.
# mkfs.ext4 /dev/gullintanni/home-vianney
# echo "/dev/gullintanni/home-vianney /home/ldap/vianney ext4 rw,relatime,discard 0 2" >> /etc/fstab
# mkdir -p /home/ldap/vianney
# mount -a
# chown vianney: /home/ldap/vianney
# chmod 700 /home/ldap/vianney
Pas besoin de rajouter de hook particulière dans l’initramfs
: le volume que j’ai créé peut être déchiffré puis
monté tardivement dans processus de démarrage. systemd
saura gérer les dépendances entre la mise en place de
l’array, le déchiffrement du disque puis le montage du LV au démarrage.
En conclusion Link to heading
Si la configuration de ce stockage a pu me demander plus de travail que d’habitude, celui-ci me fournira plus de souplesse pour la gestion des quotas de disque par application ainsi que plus de fiabilité.
# lsblk
[...]
nvme1n1 259:0 0 1.8T 0 disk
└─nvme1n1p1 259:2 0 1.8T 0 part
└─md127 9:127 0 1.8T 0 raid1
└─gullintanni 254:0 0 1.8T 0 crypt
├─gullintanni-libvirt_tmeta 254:1 0 128M 0 lvm
│ └─gullintanni-libvirt-tpool 254:3 0 250G 0 lvm
│ ├─gullintanni-libvirt 254:4 0 250G 1 lvm
│ └─gullintanni-libvirt--paperless 254:5 0 30G 0 lvm
├─gullintanni-libvirt_tdata 254:2 0 250G 0 lvm
│ └─gullintanni-libvirt-tpool 254:3 0 250G 0 lvm
│ ├─gullintanni-libvirt 254:4 0 250G 1 lvm
│ └─gullintanni-libvirt--paperless 254:5 0 30G 0 lvm
├─gullintanni-home_tmeta 254:6 0 52M 0 lvm
│ └─gullintanni-home-tpool 254:8 0 50G 0 lvm
│ ├─gullintanni-home 254:9 0 50G 1 lvm
│ └─gullintanni-home--vianney 254:10 0 30G 0 lvm /home/ldap/vianney
└─gullintanni-home_tdata 254:7 0 50G 0 lvm
└─gullintanni-home-tpool 254:8 0 50G 0 lvm
├─gullintanni-home 254:9 0 50G 1 lvm
└─gullintanni-home--vianney 254:10 0 30G 0 lvm /home/ldap/vianney
nvme0n1 259:1 0 1.8T 0 disk
└─nvme0n1p1 259:3 0 1.8T 0 part
└─md127 9:127 0 1.8T 0 raid1
└─gullintanni 254:0 0 1.8T 0 crypt
├─gullintanni-libvirt_tmeta 254:1 0 128M 0 lvm
│ └─gullintanni-libvirt-tpool 254:3 0 250G 0 lvm
│ ├─gullintanni-libvirt 254:4 0 250G 1 lvm
│ └─gullintanni-libvirt--paperless 254:5 0 30G 0 lvm
├─gullintanni-libvirt_tdata 254:2 0 250G 0 lvm
│ └─gullintanni-libvirt-tpool 254:3 0 250G 0 lvm
│ ├─gullintanni-libvirt 254:4 0 250G 1 lvm
│ └─gullintanni-libvirt--paperless 254:5 0 30G 0 lvm
├─gullintanni-home_tmeta 254:6 0 52M 0 lvm
│ └─gullintanni-home-tpool 254:8 0 50G 0 lvm
│ ├─gullintanni-home 254:9 0 50G 1 lvm
│ └─gullintanni-home--vianney 254:10 0 30G 0 lvm /home/ldap/vianney
└─gullintanni-home_tdata 254:7 0 50G 0 lvm
└─gullintanni-home-tpool 254:8 0 50G 0 lvm
├─gullintanni-home 254:9 0 50G 1 lvm
└─gullintanni-home--vianney 254:10 0 30G 0 lvm /home/ldap/vianney