Le protocole NVMe a été pensé pour un accès depuis le réseau (over Fabrics). Si cela nécessite du matériel spécifique lorsque l'on exploite du Fibre Channel ou RDMA, il existe une solution accessible à tous : NVMe sur TCP. Elle est désormais exploitable depuis différentes distributions, dont Ubuntu. Voici comment faire.
S'il est courant de partager des données sur un réseau local via des protocoles comme NFS ou SMB/CIFS, ce n'est pas la méthode la plus efficace ou à utiliser pour donner accès à des HDD/SSD. Présents par exemple dans un serveur afin de les rendre exploitables depuis des clients ultra-compacts ou une machine virtuelle.
D'iSCSI à NVMe/TCP : la révolution du block storage
Pour cela, il faut passer au block storage, le protocole le plus connu étant iSCSI qui est notamment géré par les différents NAS du marché, tels que ceux vendus par ASUSTOR, QNAP ou Synology. Le serveur met alors à disposition une portion de HDD/SSD que le client voit comme un périphérique de stockage local.
- DAS, NAS, SAN, stockage en blocs, fichiers ou objets : qu'est-ce que ça signifie ?
- Comment déporter le stockage de votre PC sur un NAS via iSCSI
Il peut le formater et y créer des partitions comme il le souhaite. On peut même l'utiliser pour installer un système entier comme nous l'avions vu dans un précédent article. Les performances sont plutôt bonnes puisque ce sont des commandes SCSI qui sont envoyées du client au serveur et inversement, encapsulées dans des paquets TCP/IP.
Mais voilà, à l'heure des SSD PCIe, SCSI n'est plus vraiment la solution de référence pour gérer un périphérique de stockage. C'est pour cela qu'est né NVMe-oF (over Fabrics) pour faire transiter des commandes du protocole NVMe (créé pour gérer efficacement les SSD PCIe) sur un réseau. Différentes solutions existent, plus ou moins coûteuses et simples à implémenter. Mais une est désormais facilement exploitable, accessible à tous : NVMe/TCP.
Pour l'utiliser, il vous faut seulement un serveur avec au moins un SSD et un client sous Linux. L'installation ne demande que très peu de manipulations avec une distribution récente. On vous guide sur la manière de faire sous Ubuntu 21.04 Server, avec un script qui vous permettra d'automatiser entièrement le processus.
Notre dossier sur NVMe-oF :
- NVMe-over-Fabrics (NVMe-oF) : partagez vos SSD NVMe sur le réseau
- NVMe/TCP : partagez vos SSD depuis Ubuntu Server, notre script pour vous y aider
On prépare le terrain
Nous partirons du principe que vous disposez déjà d'une machine sous Ubuntu Server dans sa dernière version. C'est important, car avant la 21.04 les modules nécessaires à l'utilisation de NVMe/TCP n'étaient pas toujours activés. On commence assez logiquement par mettre le système à jour, et installer ce qu'il faut :
sudo apt update && sudo apt full-upgrade -y && sudo apt autoremove
sudo apt install nvme-cli
L'application installée permet de gérer les périphériques NVMe en ligne de commandes (CLI). On vérifie d'ailleurs que nous avons bien un tel SSD au sein du système, on relève au passage le dossier qui lui correspond :
sudo nvme list
Qui sur notre système donne le résultat suivant :
Node SN Model Namespace Usage Format FW Rev
------------ ------------ ----------- --------- --------------------- ----------- -------
/dev/nvme0n1 2039******** CT500P5SSD8 1 500.11 GB / 500.11 GB 512 B + 0 B P4CR311
/dev/nvme1n1 2039******** CT500P5SSD8 1 500.11 GB / 500.11 GB 512 B + 0 B P4CR311
Le SSD accessible via /dev/nvme0n1
est celui où le système est installé, nous partagerons donc /dev/nvme1n1
sur le réseau via NVMe/TCP. On vérifie pour cela que nous avons les bons modules présents au sein du noyau :
cat /boot/config-`uname -r` | grep NVME_TARGET
Si tout se passe bien, vous devriez voir les lignes suivantes apparaître :
CONFIG_NVME_TARGET=m"
CONFIG_NVME_TARGET_TCP=m"
En langage NVMe/TCP, un serveur contenant des périphériques de stockage partagé est une « target », identifiée par son NQN (NVMe Qualified Name) que nous définirons plus loin.
Partage du périphérique NVMe sur le réseau
Pour continuer la configuration, il nous faut connaître l'adresse IP de la machine, affichez-là avec cette commande :
ip a
Parfois, plusieurs interfaces peuvent être connectées et configurées, notez l'IP de celle de votre choix. Privilégiez des connexions avec un bon débit, une faible latence et évitez bien entendu le Wi-Fi (même si en pratique, ça fonctionne). On peut désormais passer aux choses sérieuses, en activant les modules « nvmet » (t pour target).
sudo modprobe nvmet
sudo modprobe nvmet-tcp
Cela nous permet de créer un NQN (nvme.server.1n1
dans notre cas) :
cd /sys/kernel/config/nvmet/subsystems
sudo mkdir nvme.server.1n1
cd nvme.server.1n1
On permet ensuite à tous les hôtes du réseau de s'y connecter :
echo 1 | sudo tee -a attr_allow_any_host > /dev/null
Notez que NVMe/TCP permet différents modes d'identifications que nous ne couvrirons pas ici. On créé ensuite un espace de noms où l'on déclare et on active notre périphérique de stockage NVMe :
sudo mkdir namespaces/1
cd namespaces/1
echo -n /dev/nvme1n1 | sudo tee -a device_path > /dev/null
echo 1 | sudo tee -a enable > /dev/null
On créé le port (4420) et on l'active pour un transport via TCP en précisant l'IP d'accès (192.168.0.42 dans notre cas) :
sudo mkdir /sys/kernel/config/nvmet/ports/1
cd /sys/kernel/config/nvmet/ports/1
echo 192.168.0.42 | sudo tee -a addr_traddr > /dev/null
echo tcp | sudo tee -a addr_trtype > /dev/null
echo 4420 | sudo tee -a addr_trsvcid > /dev/null
echo ipv4 | sudo tee -a addr_adrfam > /dev/null
Enfin, on créé le lien entre le périphérique et le port créé :
sudo ln -s /sys/kernel/config/nvmet/subsystems/nvme.server.1n1 /sys/kernel/config/nvmet/ports/1/subsystems/nvme.server.1n1
On peut alors vérifier si tout s'est passé correctement via les messages du noyau :
sudo dmesg | grep "nvmet_tcp"
Qui donne dans notre cas le résultat suivant :
[ 416.988452] nvmet_tcp: enabling port 1 (192.168.0.42:4420)
Accès depuis la machine distante
Passons maintenant sur le client, qui n'a pas forcément besoin d'être sous Ubuntu 21.04 Server. Ici nous utilisons la version de bureau et il nous faut à nouveau vérifier que les modules nécessaires sont présents :
cat /boot/config-`uname -r` | grep NVME
Cette fois cherchez les lignes suivantes :
CONFIG_NVME_CORE=m
CONFIG_NVME_TCP=m
Si elles s'affichent, chargez les modules, mettez à jour le système et installez les outils NVMe :
sudo modprobe nvme
sudo modprobe nvme-tcp
sudo apt update && sudo apt full-upgrade -y && sudo apt autoremove
sudo apt install nvme-cli
On peut alors se connecter à une target NVMe-oF. La première étape est de la découvrir via l'IP du serveur :
sudo nvme discover -t tcp -a 192.168.0.42 -s 4420
Dans notre cas cela donne le retour suivant :
Discovery Log Number of Records 1, Generation counter 2
=====Discovery Log Entry 0======
trtype: tcp
adrfam: ipv4
subtype: nvme subsystem
treq: not specified, sq flow control disable supported
portid: 1
trsvcid: 4420
subnqn: nvme.server.1n1
traddr: 192.168.0.42
sectype: none
On peut alors s'y connecter en précisant le NQN de la target :
sudo nvme connect -t tcp -a 192.168.0.42 -s 4420 -n nvme.server.1n1
Si tout s'est bien passé, vous devriez désormais voir le périphérique distant comme un SSD NVMe local. Vous pouvez désormais le formater comme bon vous semble et l'utiliser. Pour qu'il soit accessible dès le démarrage de la machine, vous devrez répéter le chargement des modules et la connexion manuellement ou via un script.
Un SSD NVMe de 500 Go accessible dans une machine virtuelle, partagé depuis un serveur via NVMe/TCP
Créer simplement un partage NVMe via un script
Les étapes de création de la target, du port et son activation étant fastidieuse voir répétitives lorsque vous avez plusieurs SSD NVMe à partager, nous avons créé un script Bash pour l'automatiser dans Debian et ses dérivés (dont Ubuntu). Il est accessible ici. Il vous suffit de le télécharger et de le lancer. Adaptez-le à votre distribution si nécessaire :
curl -LO https://gist.github.com/davlgd/cab2506b82c9825ddc05e3cb43fc87f7/raw/2a38e128c7da3ed11b288c5cf9ff354b55f1d86b/nvmeTarget.sh
chmod +x nvmeTarget.sh
./nvmeTarget.sh
Il commence par afficher les modules NVME_TARGET du noyau vous permettant de quitter s'ils ne sont pas présents, installe ensuite les outils NVMe et vous demande de préciser l'IP de la machine, le dossier du périphérique à partager et le NQN désiré. Ces valeurs peuvent être précisées dans le fichier pour éviter cette étape.
Vous devrez ensuite préciser si c'est une création de target (C) ou une mise à jour avec de nouveaux périphériques (M). En effet, on peut partager plusieurs SSD NVMe de la sorte et pourquoi pas les monter en RAID ? Une fois ces trois questions posées, tout sera automatiquement activé et le message noyau de confirmation devrait être affiché.