NVMe/TCP : partagez vos SSD depuis Ubuntu Server, notre script pour vous y aider
Share kiddie
Notre dossier sur NVMe-oF :
Le 21 septembre 2021 à 15h42
8 min
Hardware
Hardware
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.
- 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é.
NVMe/TCP : partagez vos SSD depuis Ubuntu Server, notre script pour vous y aider
-
D'iSCSI à NVMe/TCP : la révolution du block storage
-
On prépare le terrain
-
Partage du périphérique NVMe sur le réseau
-
Accès depuis la machine distante
-
Créer simplement un partage NVMe via un script
Commentaires (22)
Vous devez être abonné pour pouvoir commenter.
Déjà abonné ? Se connecter
Abonnez-vousLe 21/09/2021 à 17h36
Je suis un fier abonné NextInpact depuis des années, je serais encore là pour les prochaines années.
Le 21/09/2021 à 17h40
Le 21/09/2021 à 17h47
Classe! Je ne connaissais pas ce protocole.
Bon, vu que je suis en Wifi, pour le moment je vais rester sur mon mix SMB / (minio)[https://www.nextinpact.com/article/30308/106520-minio-creez-simplement-votre-propre-service-stockage-objet-compatible-s3-et-distribue]
Pour ceux qui ne pratiquent pas trop: iSCSI était super pour partager des disques entre VM, notamment dans le cadre d’un cluster avec continuité de service.
Le 21/09/2021 à 19h29
C’est vraiment top de faire des tutoriels technique pour Ubuntu.
Le 21/09/2021 à 19h30
Ça n’est pas une erreur donc je ne signale pas, mais il est plus élégant de faire un “grep pattern /path/to/file” plutôt que “cat /path/to/file | grep pattern”
De même que “tee -a” peut être facilement remplacé par “echo >>”
A part ces commentaires de Bash nazi, super intéressant cet article, je pense que je vais expérimenter ça !
Le 21/09/2021 à 19h41
Avec ces articles de fond, je vois tout l’intérêt d’être abonné. Merci !
Le 21/09/2021 à 19h57
tee remplace echo parce qu’il faut un sudo, pour grep je regarderais ça
Le 21/09/2021 à 20h14
sysadmin ici :-)
Pour l’explication détaillée : “echo” est un shell builtin, donc ce n’est pas une commande que l’on peut lancer en sudo, c’est pourquoi tee est nécessaire.
Pour “cat … | grep”, je vois un avantage, c’est la lisibilité, particulièrement pour chaîner les grep.
“grep pattern file” est utile pour trouver dans quel fichier se trouve le pattern (-h)
Sinon pour les débutants en shell, je conseille de regarder du côté de “set -eu -o pipefail”, qui permettent respectivement (e) de quitter le script en cas de code de retour différent de 0, (u) et de quitter en cas de variable non définie, et (-o pipefail) de quitter le script si l’une des commandes dans une série de pipe échoue. Il est parfois nécessaire de revoir certaines constructions dans les scripts, mais c’est indispensable pour des scripts utilisés en prod.
Article très sympa !
Le 21/09/2021 à 20h21
Un pti bench’ ?
Le 21/09/2021 à 20h29
Chaque chose en son temps ;)
En général dans les scripts “publics” j’évite de mettre des commandes de ce type pour ne pas avoir à les expliquer vu qu’elles ne sont pas en rapport avec le sujet traité.
Après pour la gestion d’erreur “automatisée” ça peut être une bonne béquille, mais c’est un peu comme le “catch” général dans certains langages, ça sauve dans certains cas (parce que c’est simple et que ça va vite) mais ce n’est pas forcément l’usage recommandé en pratique (où il vaut mieux une gestion plus fine des erreurs éventuelles même si ça peut prendre un peu de temps au développement).
De mémoire, set -e (et ses dérivés) peut parfois poser problème donc je n’irais pas forcément le recommander à quelqu’un qui ne sait pas trop ce qu’il fait parce qu’il débute, ou alors en le prévenant des potentiels soucis.
Le 21/09/2021 à 20h46
Merci pour ces précisions :)
Le 22/09/2021 à 06h16
Est-ce qu’il existe des mécanismes de sécurité (mot de passe, chiffrement de la communication par TLS avec authentification mutuelle…) sur ce protocole ?
Ou doit-on encapsuler le flux dans un tunnel TLS, SSH… ?
Merci!
Le 22/09/2021 à 06h24
De mémoire oui on peut encapsuler dans du TLS (ne serait-ce que si on veut transporter hors d’un réseau “de confiance”) mais je n’ai pas regardé comment le faire pour le moment (ce qui aurait potentiellement complexifié par mal l’explication avec la mécanique de certificats). SSH je ne sais pas je n’ai pas regardé.
Tu as aussi des mécaniques d’auth via les IP des hôtes ou de type “CHAP” (je n’ai plus les références exactes en tête) qui sont en général implémenté dans les appliances qui proposent du NVMe/TCP, mais de mémoire le travail est encore en cours sur certaines, là aussi ça demande de creuser (on en reparlera).
J’ai cru comprendre que Facebook utilisait déjà pas mal NVMe/TCP, donc c’est de toutes façons qu’il doit y avoir toutes les mécaniques suffisante à de la mise en prod, d’une manière ou d’une autre
Le 22/09/2021 à 08h11
Certes, mais Facebook l’utilise sans doute dans ses datacenters, c’est-à-dire un environnement très contrôlé. Alors que par exemple sur un réseau d’entreprise, tu n’es jamais sûr qu’il n’y aura pas un stagiaire un peu indiscret qui écoute ce qui passe sur le LAN de sa station de travail.
Le 22/09/2021 à 13h43
David_L le nouveau Jeff Geerling de NXi!!!!
Youppi, je passerais plus de temps sur NXi que sur YouTube!! hihi
Continuez, c’est trop cool!!
Le 22/09/2021 à 14h19
J’imagine qu’on ne peut pas partager l’accès au disque pour plusieurs machines pour des risques de corruption de données n’est-ce pas ?
Le 22/09/2021 à 16h50
je me pose la question : le NVME-oF est-il utilisable seulement avec un périphérique NVMe ou bien on peut accéder aussi à une pool zfs/raid et si oui, est-ce que cela fonctionne avec une pool utilisant que du NVMe ou bien ça fonctionne avec des périphériques dédiés au cache ?
Le 22/09/2021 à 17h48
Le principe est de partager des périphériques, comme expliqué, le formatage se fait côté client. Donc si tu veux faire du ZFS/RAID, tu peux.
Le 22/09/2021 à 18h23
oui je sais mais par exemple avec iSCSI tu peux partager un périphérique virtuel. Avec zfs/mdadm tu crées une pool qui est vu par le système comme un volume de stockage au même titre qu’un DD & cie, c’est celui là que tu partages. Ma question est donc : est-ce que ça marche aussi ou volume physique only ?
Le 27/09/2021 à 08h58
ça doit être possible mais j’ai du mal à capter l’intérêt de faire ça dans cet ordre, parce que ça revient à faire passer un ZFS/RAID pour un NVMe natif, ce que ça n’est pas pour l’utiliser de manière distante comme un seul périphérique alors qu’on aurait pu tout gérer correctement côté client.
Le 27/09/2021 à 12h20
Après faudrait que je me renseigne déjà pour savoir comment est géré un pool/raid de péripéhriques mixtes SATA et NVMe.
Le 27/09/2021 à 14h23
L’esprit du block storage c’est de partager un périphérique de stockage brut. Si tu veux tout gérer côté serveur avec un gros niveau de redondance, il y a l’objet/fichier. Certes les NAS nous ont habitué à faire du RAID côté serveur avec des LUN partagés, mais ce n’est pas leur “intérêt” parce qu’on s’éloigne du protocole (ne serait-ce que parce que le périphérique n’est pas SCSI). Avec NVMe-oF le but c’est quand même de passer les commandes brutes au périphérique.
Comme dit plus haut, ça n’empêchera pas la segmentation, mais elle sera gérée de manière plus native, le protocole ayant été pensé pour ça.