Nvme-of - linux

De Wiki doc


Le Non-Volatile Memory express over Fabric (NVMe-oF) est un protocole permettant d'attacher un volume NVMe (un SSD PCIe) via le réseau (à l'image du iSCSI). Cette technologie a l'avantage, en plus de sa simplicité de mise en service, d'avoir des performances de dingue. En effet, le NVMe-of s’appuie sur le Remote Direct Memory Access (RDMA) over Converged Ethernet (RCoE). Il encapsule donc des trames Infiniband sur de l'Ethernet en exploitant les spécificités d'accès direct à la mémoire de l'hôte. Il en résulte des temps d'accès très proche d'une connexion standard au bus PCIe mais depuis le réseau... Ceci induit toutefois inconvénient d'obliger le recours à un matériel prenant en charge le RDMA. Oubliez donc le contrôleur réseau intégré à votre carte mère ainsi que toute les cartes additionnelles grand publique...

Pour cette documentation j'utilise deux ordinateurs équipés d'une carte réseau Mellanox Connectx 3 10Gbe chacun et connectés par l'intermédiaire d'un commutateur Cisco 3560CX-12PD-S (une connexion direct entre les deux machines revient au même).

INFORMATION

Les deux machines doivent impérativement faire partie du même LAN. Le couple IP/port définit plus loin dans la partie serveur ne sert que d'identifiant à la communication Infiniband. Le protocole IP n'est jamais utilisé avec RDMA et donc le routage ne peut fonctionner.

Définitions

Avant de commencer, nous allons définir quelques termes afin de savoir où nous mettons les pieds.

  • NVMe: Non-Volatile Memory express est un protocole réservé aux périphériques de stockage exploitant un bus PCI express et destiné aux volumes Solid State Drive (SSD) en lieu et place du Serial Advanced Technology Attachment (SATA). Exploitant la bande passante de celui-ci et utilisant des instructions adaptés aux mémoires flashs, il est bien plus performant que ce dernier
  • RDMA: l'accès direct à la mémoire à distance ou Remote Direct Memory Access permet de donner accès à la mémoire d'un hôte distant sans passer par le noyau de celui-ci (c'est l'adaptateur réseau qui communique avec la mémoire). Les informations n’étant pas copiées entre la mémoire d'application et les tampons de données du système d'exploitation (ainsi que toute fonction comme le pare-feu ou la QoS), une mise en réseau à haut débit et à faible latence est rendue possible
  • RCoE: l'accès direct à la mémoire à distance sur Ethernet convergent ou RDMA over Converged Ethernet est un protocole de niveau 2 OSI permettant l'accès direct à la mémoire à distance (RDMA) sur un réseau Ethernet. Cette opération est rendue possible en encapsulant une trame de transport Infiniband sur l'Ethernet.
  • Sous système: un sous système NVM (subsystem), est un groupe définissant les paramètres du partage NVMe (contrôleur, port, type d'interface, espace de nom...). C'est l'ensemble de la configuration pour un SSD donné. Il y a donc un sous système par disque à partager en NVMe-oF
  • Espace de noms: la notion d'espaces de noms NVMe (à ne pas confondre avec les espaces de noms Linux) permet d'adresser un ensemble de blocs logiques dans un groupe accessible au logiciel hôte (pilote NVMe). Elle présente au système une décomposition du support de stockage en autant de volume que d'espaces définis. Cela permet de segmenter un SSD afin d'en réserver des fractions pour divers usages comme l'isolation logique, le multi-tenant, l'isolation de sécurité (chiffrement par espace de noms), la protection en écriture d'un espace de noms à des fins de récupération ou encore le sur-provisionnement (pour améliorer les performances et l'endurance en écriture). Sous Linux, ils apparaissent chacun avec un identifiant unique dans les périphériques. Par exemple, /dev/nvme0n1 concerne le contrôleur 0 et l'espace de noms 1)

Partie serveur

Le serveur est également appelé "cible" (target).

Mise en œuvre

Une cible NVMe-oF se configure en créant un sous système lié à un SSD. En plus du module noyau gérant le NVMe (chargé de base), il faudra activer celui gérant le sujet de cette documentation.

Activation des modules noyau

modprobe nvmet-rdma

Note: le module gérant le NVMe s'active avec la commande modprobe nvme si celui ci n'est pas chargé automatiquement.

Création d'un sous système

mkdir /sys/noyau/config/nvmet/subsystems/toto
echo 1 > /sys/noyau/config/nvmet/subsystems/toto/attr_allow_any_host

Création de l'espace de noms dans le sous système

mkdir /sys/noyau/config/nvmet/subsystems/toto/namespaces/1
echo -n /dev/nvme0n1 > /sys/noyau/config/nvmet/subsystems/toto/namespaces/1/device_path
echo 1 > /sys/noyau/config/nvmet/subsystems/toto/namespaces/1/enable

Arborescence à ce stade

tree /sys/noyau/config/nvmet/
/sys/noyau/config/nvmet/
├── hosts
├── ports
└── subsystems
    └── toto
        ├── allowed_hosts
        ├── attr_allow_any_host
        ├── attr_serial
        ├── attr_version
        └── namespaces
            └── 1
                ├── ana_grpid
                ├── buffered_io
                ├── device_nguid
                ├── device_path
                ├── device_uuid
                └── enable

7 répertoires, 9 fichiers

Création d'un port

Cette étape permet de définir les paramètres de connexion à la cible.

mkdir /sys/noyau/config/nvmet/ports/1
echo "ipv4" > /sys/noyau/config/nvmet/ports/1/addr_adrfam
echo "rdma" > /sys/noyau/config/nvmet/ports/1/addr_trtype
# Adresse du serveur
echo 192.168.1.32 > /sys/noyau/config/nvmet/ports/1/addr_traddr
echo 4420 > /sys/noyau/config/nvmet/ports/1/addr_trsvcid

Activation du partage

ln -s /sys/noyau/config/nvmet/subsystems/toto/ /sys/noyau/config/nvmet/ports/1/subsystems/

Note: pour désactiver momentanément le partage, il suffit de supprimer ce lien.

Arborescence à ce stade

tree /sys/noyau/config/nvmet/
/sys/noyau/config/nvmet/
├── hosts
├── ports
│   └── 1
│       ├── addr_adrfam
│       ├── addr_traddr
│       ├── addr_treq
│       ├── addr_trsvcid
│       ├── addr_trtype
│       ├── ana_groups
│       │   └── 1
│       │       └── ana_state
│       ├── param_inline_data_size
│       ├── referrals
│       └── subsystems
│           └── toto -> ../../../../nvmet/subsystems/toto
└── subsystems
    └── toto
        ├── allowed_hosts
        ├── attr_allow_any_host
        ├── attr_serial
        ├── attr_version
        └── namespaces
            └── 1
                ├── ana_grpid
                ├── buffered_io
                ├── device_nguid
                ├── device_path
                ├── device_uuid
                └── enable

13 répertoires, 16 fichiers

Le volume est acccible via le réseau.

Suppression du sous système

Pour revenir à l'état initial et donc supprimer notre sous système, il faut effectuer les quelques étapes suivantes:

rm -f /sys/noyau/config/nvmet/ports/1/subsystems/toto

Note: il ne faut surtout pas mettre le dernier / à la fin du répertoire "toto" sinon la commande rm refusera de le supprimer. De plus, le paramètre -r ne doit pas être précisé car le noyau l'interdit.

rmdir /sys/noyau/config/nvmet/ports/1/
rmdir /sys/noyau/config/nvmet/subsystems/toto/namespaces/1/
rmdir /sys/noyau/config/nvmet/subsystems/toto/

Le déchargement du module noyau peut se faire de la façon suivante mais se fera de toute façon au redémarrage:

rmmod nvmet-rdma

Il ne reste plus aucune trace de notre partage.

Partie cliente

Le client est aussi appelé "initiateur" (initiator).

Connexion à la cible

Activation du module et installation

Il est nécessaire d'activer le module noyau suivant:

modprobe nvme-rdma

et d'installer le paquet permettant la gestion du NVMe:

apt install nvme-cli

Pour voir les périphériques NVMe reconnus pas le système:

nvme list

Note: le disque partage n’apparaît pas.

Connexion à la cible

nvme connect -t rdma -a 192.168.1.32 -s 4420 -n toto

Un nouveau listage montre le disque fraîchement ajouté:

nvme list

Il est visible et utilisable au niveau blocs comme s'il était branché directement à la carte mère:

lsblk

Déconnexion de la cible

nvme disconnect -n toto

ou

nvme disconnect -d /dev/nvme0n1

Sources