Aller au contenu
medium

OpenEBS : stockage Kubernetes natif avec Mayastor

34 min de lecture

logo openebs

OpenEBS transforme les disques locaux de vos nœuds Kubernetes en stockage persistant haute performance, répliqué via NVMe-oF (NVMe over Fabrics). Projet CNCF Sandbox, il suit le modèle Container Attached Storage (CAS) : le plan de données tourne dans des pods, au plus près des applications. Ce guide vous accompagne du déploiement d'un cluster 3 nœuds à la création de volumes répliqués, snapshots et LocalPV, avec toutes les commandes testées sur Ubuntu 24.04.

  • Architecture CAS : moteur io-engine, DiskPools, réplication NVMe-oF
  • Deux moteurs de stockage : Replicated PV Mayastor et LocalPV Hostpath
  • Lab complet : déployer OpenEBS 4.4 sur 3 VMs KVM avec k3s
  • Volumes répliqués : StorageClass, PVC, déploiement PostgreSQL
  • Snapshots : sauvegarder et restaurer un volume
  • Dépannage et bonnes pratiques : diagnostic, dimensionnement, sécurité

OpenEBS est une solution de stockage persistant pour Kubernetes créée en 2017 par MayaData (aujourd'hui DataCore). Contrairement aux solutions de stockage distribué traditionnelles (Ceph, GlusterFS) qui fonctionnent en dehors de Kubernetes, OpenEBS s'exécute entièrement dans le cluster sous forme de pods.

Ces six caractéristiques rangent OpenEBS dans une catégorie à part : le stockage n'est pas un service voisin du cluster, il tourne dans le cluster. La conséquence pratique tient en une ligne : ce sont vos nœuds Kubernetes qui paient le coût CPU et mémoire du stockage.

CaractéristiqueDescription
Container Attached StorageLe plan de données tourne dans des pods Kubernetes, pas sur un cluster externe
NVMe over FabricsRéplication via le protocole NVMe-oF, plus rapide que iSCSI
Moteurs multiplesReplicated PV Mayastor (HA), LocalPV Hostpath, LocalPV LVM, LocalPV ZFS
Kubernetes-natifInstallation via Helm, configuration via CRD (DiskPool, StorageClass)
CNCF SandboxProjet hébergé par la Cloud Native Computing Foundation
Open sourceLicence Apache 2.0, développé par DataCore

Le choix entre ces quatre approches se joue d'abord sur les prérequis noyau et sur le budget CPU. Mayastor est le seul à exiger des HugePages et le module nvme-tcp, ce qui l'écarte d'emblée des environnements où vous ne maîtrisez pas la configuration des nœuds.

CritèreOpenEBS (Mayastor)LonghornRook-CephNFS classique
ProtocoleNVMe-oFiSCSIRADOS (propriétaire)NFS
PerformanceTrès élevéeModéréeÉlevéeFaible
ComplexitéModéréeFaibleÉlevéeTrès faible
CPU par nœud2 cœurs dédiésFaibleVariableNégligeable
Prérequis noyauHugePages + nvme-tcpAucunAucunAucun
Interface webNonOuiDashboard CephNon
Cas d'usage idéalBases de données, performancePetits clusters, simplicitéCloud privé completPartages simples

Cette section pose le vocabulaire utilisé dans tout le reste du guide. OpenEBS sépare nettement le plan de contrôle, qui décide où placer les données, du plan de données, qui les écrit réellement sur les disques. Deux notions reviennent en permanence : le DiskPool, qui représente un disque physique confié à Mayastor, et le réplica, la copie d'un volume posée dans un DiskPool.

OpenEBS suit le modèle CAS (Container Attached Storage) : chaque volume est géré par son propre contrôleur, tournant dans un pod Kubernetes. Cette approche offre une isolation par workload et permet de configurer le stockage différemment pour chaque application.

Le plan de contrôle et le plan de données d'OpenEBS Mayastor s'articulent autour de plusieurs composants :

  • io-engine : le moteur de données Mayastor. Un DaemonSet qui tourne sur chaque nœud labellisé. Il gère les DiskPools, la réplication NVMe-oF et les I/O. Chaque pod io-engine réserve 2 cœurs CPU exclusifs et 2 GiB de HugePages.

  • agent-core : le composant central du plan de contrôle. Il orchestre la création des volumes, la répartition des réplicas et le basculement en cas de panne.

  • csi-controller / csi-node : les composants CSI (Container Storage Interface) qui font le lien entre Kubernetes (PVC, StorageClass) et Mayastor. Le controller gère le provisionnement, les csi-node montent les volumes dans les pods.

  • DiskPool : un CRD (Custom Resource Definition) qui représente un disque physique géré par Mayastor. Chaque DiskPool est associé à un nœud et un disque dédié. Les volumes répliqués répartissent leurs réplicas sur plusieurs DiskPools.

  • etcd : cluster etcd dédié à Mayastor pour stocker les métadonnées des volumes (indépendant de l'etcd de Kubernetes).

  • NATS : bus de messages pour la communication entre les composants du plan de contrôle.

  • localpv-provisioner : provisionne les volumes LocalPV Hostpath (stockage local sans réplication, pour les workloads tolérants aux pannes).

Le nom du moteur annonce son comportement : les moteurs LocalPV attachent le volume au disque d'un seul nœud, sans copie ailleurs. Un pod qui utilise un LocalPV ne peut donc pas être replanifié sur un autre nœud sans perdre l'accès à ses données, contrairement à un volume Mayastor répliqué.

MoteurRéplicationPerformanceCas d'usage
Replicated PV MayastorOui (1 à 3 réplicas)Très élevée (NVMe-oF)Bases de données, workloads critiques
LocalPV HostpathNon (local uniquement)Maximale (accès disque direct)Caches, données régénérables, CI/CD
LocalPV LVMNonÉlevéeThin provisioning, snapshots locaux
LocalPV ZFSNonÉlevéeCompression, déduplication, snapshots

Le lab monte trois VMs, y installe k3s, puis OpenEBS avec Mayastor. Trois nœuds constituent le minimum pour créer un volume à 3 réplicas posés sur des hôtes distincts. Prévoyez un disque supplémentaire vierge par machine : il deviendra le DiskPool du nœud, et Mayastor refuse tout disque déjà partitionné ou formaté.

  • 3 machines virtuelles Ubuntu 24.04 (KVM, Proxmox ou cloud)
  • 4 vCPU et 8 Go de RAM minimum par VM
  • 1 disque système (25 Go) + 1 disque dédié aux DiskPools (10 Go minimum) par VM
  • Noyau Linux 5.13+ avec le module nvme-tcp
  • HugePages 2 MiB configurés (1024 pages = 2 GiB)

Deux façons de créer les VMs : le script complet, ou le fichier cloud-init qu'il consomme. C'est ce dernier qui met en place les deux prérequis noyau de Mayastor, les HugePages et le module nvme-tcp. Sans eux, les pods io-engine ne démarreront jamais.

Le script suivant crée 3 VMs avec cloud-init, chacune avec 2 disques :

#!/bin/bash
# Créer 3 VMs pour le lab OpenEBS
IMAGE="/var/lib/libvirt/images/ubuntu-24.04-cloud.img"
for i in 1 2 3; do
# Disque système (backing file pour économiser de l'espace)
qemu-img create -f qcow2 -b "$IMAGE" -F qcow2 \
/var/lib/libvirt/images/openebs${i}.qcow2 25G
# Disque dédié aux DiskPools (vierge)
qemu-img create -f qcow2 \
/var/lib/libvirt/images/openebs${i}-data.qcow2 10G
virt-install --name openebs${i} \
--ram 8192 --vcpus 4 \
--disk /var/lib/libvirt/images/openebs${i}.qcow2 \
--disk /var/lib/libvirt/images/openebs${i}-data.qcow2 \
--os-variant ubuntu24.04 \
--cloud-init user-data=cloud-init.yaml \
--network network=default \
--graphics none --noautoconsole
done

Ces cinq étapes construisent un cluster k3s à trois nœuds, puis contrôlent les prérequis avant d'installer quoi que ce soit. La dernière est décisive : sans le label openebs.io/engine=mayastor, aucun pod io-engine ne sera planifié sur les nœuds.

  1. Installer k3s sur le premier nœud (control plane)

    k3s est une distribution Kubernetes légère, idéale pour les labs. On désactive Traefik pour alléger le cluster :

    Fenêtre de terminal
    curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable traefik" sh -

    Vérification :

    Fenêtre de terminal
    sudo kubectl get nodes
    # NAME STATUS ROLES AGE VERSION
    # openebs1 Ready control-plane,master 1m v1.34.4+k3s1
  2. Récupérer le token d'enregistrement

    Fenêtre de terminal
    sudo cat /var/lib/rancher/k3s/server/node-token
  3. Joindre les agents (sur openebs2 et openebs3)

    Fenêtre de terminal
    curl -sfL https://get.k3s.io | K3S_URL=https://openebs1:6443 \
    K3S_TOKEN="<token>" sh -

    Vérification (depuis openebs1) :

    Fenêtre de terminal
    sudo kubectl get nodes
    # NAME STATUS ROLES AGE VERSION
    # openebs1 Ready control-plane,master 5m v1.34.4+k3s1
    # openebs2 Ready <none> 1m v1.34.4+k3s1
    # openebs3 Ready <none> 1m v1.34.4+k3s1
  4. Vérifier les prérequis sur chaque nœud

    Avant d'installer OpenEBS, vérifiez que chaque nœud dispose des HugePages et du module nvme-tcp :

    Fenêtre de terminal
    # HugePages (doit afficher 1024)
    cat /proc/sys/vm/nr_hugepages
    # 1024
    # Module nvme-tcp chargé
    lsmod | grep nvme_tcp
    # nvme_tcp ...
    # Disque dédié disponible (vierge, sans partitions)
    lsblk /dev/vdb
    # NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
    # vdb 252:16 0 10G 0 disk
  5. Labelliser les nœuds pour Mayastor

    Le DaemonSet io-engine ne se déploie que sur les nœuds portant le label openebs.io/engine=mayastor :

    Fenêtre de terminal
    kubectl label node openebs1 openebs2 openebs3 \
    openebs.io/engine=mayastor

L'installation par Helm déploie d'un seul coup le plan de contrôle et le plan de données. La phase la plus longue est le démarrage des pods io-engine, qui doivent obtenir leurs cœurs CPU exclusifs et leurs HugePages avant de passer en Running.

  1. Ajouter le dépôt Helm et installer

    Fenêtre de terminal
    helm repo add openebs https://openebs.github.io/openebs
    helm repo update
    helm install openebs openebs/openebs \
    --namespace openebs --create-namespace \
    --version 4.4.0 \
    --set engines.replicated.mayastor.enabled=true \
    --set loki.enabled=false \
    --set alloy.enabled=false

    Les options loki.enabled=false et alloy.enabled=false désactivent la stack de logging intégrée, inutile en lab.

  2. Vérifier le déploiement

    Attendez 2 à 3 minutes que tous les pods démarrent :

    Fenêtre de terminal
    kubectl get pods -n openebs
    NAME READY STATUS AGE
    openebs-agent-core-5b7f8c5b9-x2g7k 2/2 Running 2m
    openebs-api-rest-6c8f5d4b7-7q9zv 1/1 Running 2m
    openebs-csi-controller-0 6/6 Running 2m
    openebs-csi-node-xxxxx 2/2 Running 2m (×3)
    openebs-etcd-0 1/1 Running 2m (×3)
    openebs-io-engine-xxxxx 2/2 Running 2m (×3)
    openebs-localpv-provisioner-xxx 1/1 Running 2m
    openebs-nats-0 3/3 Running 2m (×3)
    openebs-obs-callhome-xxx 2/2 Running 2m
    openebs-operator-diskpool-xxx 1/1 Running 2m

    Les pods io-engine (un par nœud labellisé) sont les plus critiques : ils gèrent les I/O et la réplication.

    Si les pods io-engine restent en Pending :

    Fenêtre de terminal
    kubectl describe pod -n openebs -l app=io-engine | grep -A5 Events

    Cause la plus fréquente : Insufficient cpu. Le io-engine exige 2 cœurs CPU exclusifs. Vos VMs doivent avoir au moins 4 vCPU.

Un DiskPool associe un disque physique à Mayastor. Chaque nœud héberge un ou plusieurs DiskPools, qui fournissent la capacité dans laquelle Mayastor place les réplicas de volumes.

apiVersion: openebs.io/v1beta3
kind: DiskPool
metadata:
name: pool-openebs1
namespace: openebs
spec:
node: openebs1
disks:
- uring:///dev/disk/by-path/virtio-pci-0000:05:00.0
---
apiVersion: openebs.io/v1beta3
kind: DiskPool
metadata:
name: pool-openebs2
namespace: openebs
spec:
node: openebs2
disks:
- uring:///dev/disk/by-path/virtio-pci-0000:05:00.0
---
apiVersion: openebs.io/v1beta3
kind: DiskPool
metadata:
name: pool-openebs3
namespace: openebs
spec:
node: openebs3
disks:
- uring:///dev/disk/by-path/virtio-pci-0000:05:00.0

Vérification :

Fenêtre de terminal
kubectl get dsp -n openebs
NAME NODE STATE POOL-STATUS CAPACITY USED AVAILABLE
pool-openebs1 openebs1 Created Online 10 GiB 0 B 10 GiB
pool-openebs2 openebs2 Created Online 10 GiB 0 B 10 GiB
pool-openebs3 openebs3 Created Online 10 GiB 0 B 10 GiB

Les trois pools sont Online avec 10 GiB de capacité chacun. Si un pool reste en état Creating, vérifiez les logs du pod io-engine correspondant :

Fenêtre de terminal
kubectl logs -n openebs -l app=io-engine --tail=20

Un volume répliqué Mayastor maintient plusieurs copies de la même donnée dans des DiskPools situés sur des nœuds différents, synchronisées par NVMe-oF. Le nombre de copies ne se déclare pas sur le volume mais sur le StorageClass, qui porte le paramètre repl. Changer de niveau de réplication revient donc à créer un autre StorageClass, pas à modifier un volume existant.

L'installation crée par défaut un StorageClass openebs-single-replica (1 réplica). Pour la haute disponibilité, créez un StorageClass avec 3 réplicas :

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: openebs-replicated
parameters:
protocol: nvmf
repl: "3"
provisioner: io.openebs.csi-mayastor
allowVolumeExpansion: true
reclaimPolicy: Delete
volumeBindingMode: Immediate

Le paramètre protocol: nvmf active le transport NVMe over Fabrics pour la réplication entre les nœuds. Le paramètre repl: "3" crée 3 copies de chaque volume, une par DiskPool.

PostgreSQL fait un bon cas de test : il écrit en continu et signale immédiatement toute corruption. Ces quatre étapes créent la demande de volume, vérifient que les trois DiskPools se remplissent, déploient la base, puis y écrivent des données réelles.

  1. Créer la PVC

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
    name: pgdata-replicated
    spec:
    accessModes:
    - ReadWriteOnce
    storageClassName: openebs-replicated
    resources:
    requests:
    storage: 2Gi

    Vérification :

    Fenêtre de terminal
    kubectl get pvc pgdata-replicated
    # NAME STATUS VOLUME CAPACITY STORAGECLASS
    # pgdata-replicated Bound pvc-044150cf-302d-44f5-8b8b-9b7ef66b2889 2Gi openebs-replicated
  2. Vérifier la réplication

    Chaque DiskPool consomme maintenant 2 GiB (une copie du volume par pool) :

    Fenêtre de terminal
    kubectl get dsp -n openebs
    # NAME NODE STATE POOL-STATUS CAPACITY USED AVAILABLE
    # pool-openebs1 openebs1 Created Online 10 GiB 2 GiB 8 GiB
    # pool-openebs2 openebs2 Created Online 10 GiB 2 GiB 8 GiB
    # pool-openebs3 openebs3 Created Online 10 GiB 2 GiB 8 GiB
  3. Déployer PostgreSQL

    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: postgres
    spec:
    replicas: 1
    selector:
    matchLabels:
    app: postgres
    template:
    metadata:
    labels:
    app: postgres
    spec:
    containers:
    - name: postgres
    image: postgres:16-alpine@sha256:57c72fd2a128e416c7fcc499958864df5301e940bca0a56f58fddf30ffc07777
    env:
    - name: POSTGRES_PASSWORD
    value: openebs-demo
    - name: PGDATA
    value: /var/lib/postgresql/data/pgdata
    ports:
    - containerPort: 5432
    volumeMounts:
    - name: pgdata
    mountPath: /var/lib/postgresql/data
    volumes:
    - name: pgdata
    persistentVolumeClaim:
    claimName: pgdata-replicated
  4. Tester l'écriture et la lecture

    Fenêtre de terminal
    kubectl exec -it deploy/postgres -- psql -U postgres -c "
    CREATE TABLE test_openebs (
    id SERIAL PRIMARY KEY,
    message TEXT,
    created_at TIMESTAMP DEFAULT NOW()
    );
    INSERT INTO test_openebs (message) VALUES ('Hello OpenEBS Mayastor!');
    INSERT INTO test_openebs (message) VALUES ('Réplication 3x NVMe-oF');
    SELECT * FROM test_openebs;
    "
    id | message | created_at
    ----+-------------------------+----------------------------
    1 | Hello OpenEBS Mayastor! | 2026-03-01 11:57:25.027307
    2 | Réplication 3x NVMe-oF | 2026-03-01 11:57:25.027307
    (2 rows)

Pour les workloads qui n'ont pas besoin de réplication (caches, données régénérables, CI/CD), OpenEBS fournit LocalPV Hostpath. Ce moteur crée des répertoires sur le système de fichiers local du nœud, sans surcoût de réplication.

Le StorageClass openebs-hostpath est créé automatiquement par Helm :

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: local-test
spec:
accessModes:
- ReadWriteOnce
storageClassName: openebs-hostpath
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
name: busybox-local
spec:
containers:
- name: busybox
image: busybox:1.36@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662
command: ["sh", "-c", "echo 'LocalPV Hostpath OK' > /data/test.txt && cat /data/test.txt && sleep 3600"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: local-test

Vérification :

Fenêtre de terminal
kubectl logs busybox-local
# LocalPV Hostpath OK

Les VolumeSnapshots permettent de sauvegarder l'état d'un volume à un instant donné. Combinés avec la réplication Mayastor, ils offrent une protection complète des données.

  1. Créer un VolumeSnapshotClass

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshotClass
    metadata:
    name: openebs-mayastor-snapshotclass
    driver: io.openebs.csi-mayastor
    deletionPolicy: Delete
  2. Prendre un snapshot

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshot
    metadata:
    name: pgdata-snapshot
    spec:
    volumeSnapshotClassName: openebs-mayastor-snapshotclass
    source:
    persistentVolumeClaimName: pgdata-replicated

    Vérification :

    Fenêtre de terminal
    kubectl get volumesnapshot pgdata-snapshot
    # NAME READYTOUSE SOURCEPVC RESTORESIZE SNAPSHOTCLASS
    # pgdata-snapshot true pgdata-replicated 2Gi openebs-mayastor-snapshotclass
  3. Restaurer depuis un snapshot

    Créez une nouvelle PVC avec le snapshot comme source de données :

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
    name: pgdata-restored
    spec:
    accessModes:
    - ReadWriteOnce
    storageClassName: openebs-replicated
    resources:
    requests:
    storage: 2Gi
    dataSource:
    name: pgdata-snapshot
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  4. Vérifier l'intégrité des données

    Montez la PVC restaurée dans un nouveau pod et vérifiez que les données sont intactes :

    Fenêtre de terminal
    kubectl exec postgres-restored -- psql -U postgres -c \
    "SELECT * FROM test_openebs;"
    id | message | created_at
    ----+-------------------------+----------------------------
    1 | Hello OpenEBS Mayastor! | 2026-03-01 11:57:25.027307
    2 | Réplication 3x NVMe-oF | 2026-03-01 11:57:25.027307
    (2 rows)

Ces commandes couvrent l'exploitation courante d'OpenEBS. Retenez l'abréviation dsp pour diskpool : c'est celle que vous taperez le plus souvent.

Le tableau renvoyé par kubectl get dsp est le premier endroit à consulter : il donne l'état de chaque pool et la capacité qui reste.

Fenêtre de terminal
# Lister les DiskPools avec leur capacité
kubectl get dsp -n openebs
# Détails d'un DiskPool (événements, erreurs)
kubectl describe dsp pool-openebs1 -n openebs
# Lister les StorageClasses OpenEBS
kubectl get sc | grep openebs
# Vérifier les PVC et leurs volumes
kubectl get pvc
# Inspecter un PV Mayastor (réplicas, protocole)
kubectl describe pv <nom-du-pv>
# Lister les snapshots
kubectl get volumesnapshot

Tous les pods d'OpenEBS vivent dans le namespace openebs. Les logs du plan de contrôle se trouvent dans agent-core, ceux du plan de données dans les pods io-engine.

Fenêtre de terminal
# État des pods OpenEBS
kubectl get pods -n openebs -o wide
# Logs du plan de contrôle
kubectl logs -n openebs deploy/openebs-agent-core -c agent-core
# Logs d'un io-engine spécifique
kubectl logs -n openebs -l app=io-engine \
--field-selector spec.nodeName=openebs1
# Logs de l'API REST Mayastor
kubectl logs -n openebs deploy/openebs-api-rest
# Version d'OpenEBS installée
helm list -n openebs

Le label openebs.io/engine=mayastor contrôle à lui seul la topologie de stockage : le retirer d'un nœud, avec la syntaxe suffixée d'un tiret, sort ce nœud du plan de données.

Fenêtre de terminal
# Vérifier les labels Mayastor
kubectl get nodes --show-labels | grep openebs
# Ajouter le label io-engine à un nouveau nœud
kubectl label node nouveau-noeud openebs.io/engine=mayastor
# Retirer le label (décommissionner un nœud)
kubectl label node ancien-noeud openebs.io/engine-

La sécurité d'OpenEBS s'appuie d'abord sur celle de Kubernetes : namespaces, RBAC et politiques réseau du cluster. Deux points lui sont propres, le chiffrement au repos des DiskPools et le trafic de réplication NVMe-oF, qu'il vaut mieux isoler sur un réseau dédié.

Depuis la version 4.3, Mayastor supporte le chiffrement au repos des DiskPools. Les données sont chiffrées avant d'être écrites sur le disque, protégeant contre le vol physique de disques :

apiVersion: openebs.io/v1beta3
kind: DiskPool
metadata:
name: pool-chiffre
namespace: openebs
spec:
node: openebs1
disks:
- uring:///dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-data
encryption:
enabled: true

Ces pratiques se décident au moment du déploiement. Le disque dédié et la séparation des réseaux, en particulier, sont pénibles à introduire sur un cluster déjà en production.

PratiqueDescription
Namespace dédiéOpenEBS tourne dans le namespace openebs, isolé des workloads applicatifs
RBAC KubernetesLes ServiceAccounts OpenEBS ont des droits minimaux configurés par le chart Helm
Réseau dédiéEn production, séparer le réseau de réplication NVMe-oF du réseau applicatif
Disques dédiésNe jamais partager un disque entre le système et un DiskPool
ChiffrementActiver le chiffrement au repos pour les données sensibles (v4.3+)
Mise à jourSuivre les releases de sécurité via helm upgrade

Presque toutes les pannes d'OpenEBS se produisent au démarrage et viennent de l'environnement des nœuds : CPU insuffisant, HugePages absents, module noyau manquant, ou disque référencé par un chemin instable. Le message d'erreur exact suffit en général à trancher entre ces quatre causes.

Repérez le message renvoyé par kubectl describe dans la colonne de gauche. Les deux premières lignes concernent le pod io-engine et représentent la majorité des blocages rencontrés en lab.

SymptômeCause probableSolution
Pod io-engine Pending : Insufficient cpuVM avec moins de 4 vCPUAugmenter les vCPU à 4 minimum (io-engine réserve 2 cœurs exclusifs)
Pod io-engine Init error : /run/udev is not a directoryConteneur Docker (k3d, Kind) au lieu d'une VMUtiliser des VMs ou du bare-metal, Mayastor nécessite un accès direct aux périphériques
DiskPool bloqué en Creating : InvalidDevlinkChemin /dev/vdb au lieu d'un lien persistantUtiliser /dev/disk/by-path/... ou /dev/disk/by-id/...
DiskPool : no matches for kind DiskPool in version v1beta2Mauvaise version d'APIUtiliser openebs.io/v1beta3 (vérifier avec kubectl api-resources)
PVC Pending : no capacity availablePas assez d'espace dans les DiskPoolsVérifier kubectl get dsp -n openebs et ajouter des disques
HugePages insuffisantsnr_hugepages non configuréecho "vm.nr_hugepages = 1024" > /etc/sysctl.d/99-hugepages.conf && sysctl -p
Module nvme-tcp absentPaquet kernel manquantapt install linux-modules-extra-$(uname -r) && modprobe nvme-tcp

Ces commandes qualifient la panne en partant de l'état du cluster pour descendre jusqu'au noyau des nœuds.

Fenêtre de terminal
# Vérifier la santé globale
kubectl get pods -n openebs -o wide
kubectl get dsp -n openebs
# Événements récents dans le namespace OpenEBS
kubectl get events -n openebs --sort-by='.lastTimestamp' | tail -20
# Logs détaillés du plan de contrôle
kubectl logs -n openebs deploy/openebs-agent-core -c agent-core --tail=50
# Vérifier les HugePages sur un nœud
ssh noeud "cat /proc/meminfo | grep HugePages"
# Vérifier le module nvme-tcp
ssh noeud "lsmod | grep nvme_tcp"

Trois sujets déterminent la tenue d'OpenEBS en production : le dimensionnement des nœuds, l'organisation des disques et des StorageClasses, et les choix de performance. Le premier ne se négocie pas : io-engine ne démarre pas du tout si les ressources exclusives qu'il réclame ne sont pas disponibles.

La colonne « minimum » sert à monter un lab, rien de plus. Gardez en tête que les deux cœurs CPU d'io-engine sont exclusifs : ils ne sont plus disponibles pour vos applications.

ComposantMinimum (test)Recommandé (production)
vCPU par nœud48+ (io-engine réserve 2 cœurs)
RAM par nœud8 Go16 Go+ (HugePages + workloads)
HugePages 2 MiB1024 (2 GiB)1024+ (2 GiB)
Disque DiskPool10 Go (SSD)100 Go+ (NVMe dédié)
Réseau1 Gbps10 Gbps (25 Gbps idéal pour NVMe-oF)
Nœuds Mayastor33+ (toujours impair pour le quorum)

Ces règles écartent les deux erreurs les plus coûteuses : un DiskPool posé sur un disque partagé avec le système, et une capacité calculée sans tenir compte du facteur de réplication.

  • Un disque dédié par DiskPool : ne jamais partager avec le système d'exploitation.
  • Utiliser des liens persistants : toujours référencer les disques via /dev/disk/by-id/ ou /dev/disk/by-path/, jamais /dev/sdX ou /dev/vdX.
  • Séparer les StorageClasses par usage : un SC répliqué (3 réplicas) pour les bases de données, un SC single-replica pour les logs, un SC LocalPV pour les caches.
  • Labelliser les nœuds : seuls les nœuds portant openebs.io/engine=mayastor exécutent io-engine. Gérez ce label pour contrôler la topologie de stockage.
  • Prévoir la capacité : un volume répliqué 3× consomme 3× sa taille dans les DiskPools. Un volume de 10 GiB avec repl: "3" utilise 30 GiB au total.

Ces quatre points expliquent les performances annoncées, et aussi ce qui les fait s'effondrer. Le réseau reste le facteur le plus souvent sous-estimé, puisque chaque écriture doit être transmise à tous les réplicas avant d'être acquittée.

  • NVMe dédié : utilisez des disques NVMe pour les DiskPools en production. Mayastor tire parti du protocole NVMe nativement.
  • Réseau 10-25 Gbps : la réplication NVMe-oF est limitée par la bande passante réseau. En 1 Gbps, les performances chutent significativement.
  • HugePages : les 2 GiB de HugePages sont utilisés comme cache I/O par io-engine, améliorant la latence.
  • CPU exclusif : les 2 cœurs réservés par io-engine fonctionnent en polling mode (pas d'interruptions), maximisant le débit I/O.
  • OpenEBS = stockage Kubernetes-natif : tout tourne dans des pods, pas de cluster de stockage externe à gérer.
  • Mayastor réplique les données via NVMe-oF, plus rapide que le iSCSI de Longhorn.
  • DiskPool = un disque dédié par nœud, référencé par un lien persistant (/dev/disk/by-id/ ou /dev/disk/by-path/).
  • io-engine réserve 2 cœurs CPU exclusifs + 2 GiB de HugePages par nœud : prévoyez au moins 4 vCPU et 8 Go de RAM.
  • LocalPV Hostpath pour les données régénérables (zéro overhead), Replicated PV pour la haute disponibilité.
  • Les VolumeSnapshots permettent de sauvegarder et restaurer un volume en quelques secondes.
  • API openebs.io/v1beta3 pour les DiskPools (v4.4), vérifiez avec kubectl api-resources.
  • Mayastor nécessite des VMs ou du bare-metal : les conteneurs Docker (k3d, Kind) ne fournissent pas l'accès aux périphériques requis.

Les références officielles pour approfondir et suivre les évolutions d'OpenEBS.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn