--- title: "Cómo instalar OpenEBS en Kubernetes: LocalPV y Mayastor" description: "Instala OpenEBS 4 con Helm, crea volúmenes LocalPV Hostpath para datos locales y activa Mayastor para tener volúmenes replicados en tres nodos de Kubernetes." category: "Ecosistema Kubernetes" language: es source: https://cubepath.com/es/docs/ecosistema-kubernetes/almacenamiento-openebs-para-kubernetes updated: 2026-09-25 --- # Cómo instalar OpenEBS en Kubernetes: LocalPV y Mayastor OpenEBS es un proyecto de la CNCF que proporciona almacenamiento persistente para Kubernetes ejecutándose como pods dentro del propio clúster. Desde la versión 4 se organiza en dos familias: **Local PV** (Hostpath, LVM y ZFS), que guarda los datos en el disco del nodo donde corre el pod, y **Replicated PV Mayastor**, que replica cada volumen entre varios nodos y lo sirve por NVMe over TCP. En este tutorial instalarás OpenEBS con Helm en nodos Ubuntu 24.04, crearás volúmenes Local PV Hostpath y después activarás Mayastor para tener volúmenes replicados. > Nota: los antiguos motores Jiva y cStor ya no forman parte de OpenEBS 4 y sus repositorios están archivados. Si encuentras guías que los usan, son para versiones anteriores; para almacenamiento replicado la opción actual es Mayastor. ## Requisitos previos Para seguir esta guía necesitas: - Un clúster Kubernetes 1.23 o superior con nodos Ubuntu 24.04 LTS, por ejemplo sobre VPS de CubePath. Para Mayastor, al menos tres nodos worker x86_64. - `kubectl` con permisos de administrador del clúster y Helm 3 en tu equipo. - Acceso SSH con un usuario con `sudo` a los nodos. - Solo para Mayastor: en cada nodo de almacenamiento, 2 núcleos de CPU libres para el motor de E/S, al menos 4 GB de RAM (de los que 2 GiB se reservan como hugepages) y un disco o partición vacío dedicado, sin sistema de archivos ni particiones montadas. ## Paso 1: Instalar OpenEBS con Local PV Hostpath Añade el repositorio del chart oficial: ```bash helm repo add openebs https://openebs.github.io/openebs helm repo update ``` Instala OpenEBS empezando solo con los motores locales. Mayastor se activa en el paso 4, cuando los nodos estén preparados; si lo activas sin hugepages sus pods no arrancan: ```bash helm install openebs openebs/openebs \ --namespace openebs \ --create-namespace \ --set engines.replicated.mayastor.enabled=false ``` Comprueba que los pods están en `Running`: ```bash kubectl -n openebs get pods ``` Deberías ver el provisionador `openebs-localpv-provisioner` y, si no los has desactivado, los controladores y pods de nodo de LVM y ZFS Local PV, todos en `Running`. El chart crea la StorageClass `openebs-hostpath`: ```bash kubectl get storageclass ``` ```output NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE openebs-hostpath openebs.io/local Delete WaitForFirstConsumer false 70s ``` Los drivers LVM y ZFS solo se usan si creas StorageClasses para ellos, así que puedes dejarlos instalados. Si prefieres no tenerlos, añade `--set engines.local.lvm.enabled=false --set engines.local.zfs.enabled=false` al comando de instalación. ## Paso 2: Crear un volumen Local PV Hostpath Local PV Hostpath crea un directorio por volumen en el nodo, por defecto bajo `/var/openebs/local`. Ofrece el rendimiento del disco local sin sobrecarga, pero los datos no se replican: si el nodo se pierde, el volumen también. Es adecuado para bases de datos que ya replican por su cuenta (PostgreSQL con réplicas, Kafka, Elasticsearch) o para cachés. Crea un namespace de pruebas: ```bash kubectl create namespace demo-openebs ``` Crea un manifiesto con un PVC y un pod que lo usa: ```bash nano hostpath-demo.yaml ``` ```yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: datos-locales namespace: demo-openebs spec: accessModes: - ReadWriteOnce storageClassName: openebs-hostpath resources: requests: storage: 5Gi --- apiVersion: v1 kind: Pod metadata: name: escritor namespace: demo-openebs spec: containers: - name: app image: busybox:1.36 command: ["sh", "-c", "date >> /datos/log.txt && sleep 3600"] volumeMounts: - name: datos mountPath: /datos volumes: - name: datos persistentVolumeClaim: claimName: datos-locales ``` ```bash kubectl apply -f hostpath-demo.yaml kubectl -n demo-openebs wait --for=condition=Ready pod/escritor --timeout=120s ``` La StorageClass usa `WaitForFirstConsumer`, así que el PV no se crea hasta que el pod se programa en un nodo. Comprueba que el PVC está enlazado y en qué nodo está el pod: ```bash kubectl -n demo-openebs get pvc datos-locales kubectl -n demo-openebs get pod escritor -o wide ``` ```output NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE datos-locales Bound pvc-0b7c2f3e-91a4-4d0e-8f7a-5e2c6d1b3a90 5Gi RWO openebs-hostpath 30s ``` En ese nodo, el directorio del volumen contiene el archivo que escribió el pod: ```bash sudo ls /var/openebs/local/ ``` > Nota: Hostpath no aplica límites de tamaño. El valor `5Gi` del PVC es informativo, y un volumen puede llenar el sistema de archivos del nodo. Si necesitas cuotas reales, usa Local PV LVM o ZFS. ### StorageClass Hostpath en otro directorio Si tienes un disco de datos montado, por ejemplo en `/mnt/datos`, crea una StorageClass que guarde ahí los volúmenes. La ruta se define en la anotación `cas.openebs.io/config`: ```bash nano storageclass-hostpath-datos.yaml ``` ```yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: hostpath-datos annotations: openebs.io/cas-type: local cas.openebs.io/config: | - name: StorageType value: hostpath - name: BasePath value: /mnt/datos provisioner: openebs.io/local reclaimPolicy: Delete volumeBindingMode: WaitForFirstConsumer ``` ```bash kubectl apply -f storageclass-hostpath-datos.yaml ``` El directorio indicado en `BasePath` debe existir en todos los nodos donde puedan programarse pods que usen esta clase. ## Paso 3: Preparar los nodos para Mayastor Mayastor necesita hugepages de 2 MiB, el módulo del kernel `nvme_tcp` y una etiqueta que indique en qué nodos debe ejecutarse su motor de E/S. Ejecuta en **cada nodo de almacenamiento**: ```bash echo 'vm.nr_hugepages = 1024' | sudo tee /etc/sysctl.d/20-openebs-hugepages.conf sudo sysctl --system ``` Carga el módulo `nvme_tcp` y déjalo configurado para el arranque: ```bash sudo modprobe nvme_tcp echo nvme_tcp | sudo tee /etc/modules-load.d/nvme_tcp.conf ``` Comprueba ambos: ```bash grep HugePages_Total /proc/meminfo lsmod | grep nvme_tcp ``` ```output HugePages_Total: 1024 nvme_tcp 53248 0 ``` El kubelet solo detecta las hugepages al arrancar, así que reinícialo en cada nodo (en k3s el servicio es `k3s` o `k3s-agent`, y en RKE2 `rke2-server` o `rke2-agent`): ```bash sudo systemctl restart kubelet ``` Desde tu equipo, etiqueta los nodos que ejecutarán Mayastor y verifica que el kubelet anuncia las hugepages: ```bash kubectl label node worker-1 worker-2 worker-3 openebs.io/engine=mayastor kubectl get node worker-1 -o jsonpath='{.status.allocatable.hugepages-2Mi}{"\n"}' ``` ```output 2Gi ``` ## Paso 4: Activar Mayastor Actualiza la release existente para activar el motor replicado, conservando el resto de valores: ```bash helm upgrade openebs openebs/openebs \ --namespace openebs \ --reuse-values \ --set engines.replicated.mayastor.enabled=true ``` Mayastor despliega bastantes componentes (API REST, agentes, etcd, el `io-engine` en cada nodo etiquetado y el driver CSI). Espera unos minutos y comprueba que los pods `io-engine` están listos: ```bash kubectl -n openebs get pods -o wide | grep io-engine ``` Todos deben estar en `Running` con todos sus contenedores listos, uno por nodo etiquetado. ## Paso 5: Crear un DiskPool en cada nodo Mayastor no usa directorios: gestiona dispositivos de bloque completos agrupados en `DiskPool`, uno por nodo. Localiza el identificador estable del disco vacío en cada nodo, ya que los nombres como `/dev/sdb` pueden cambiar entre reinicios: ```bash ls -l /dev/disk/by-id/ ``` Crea un manifiesto con un pool por nodo, sustituyendo los identificadores de ejemplo por los tuyos: ```bash nano diskpools.yaml ``` ```yaml apiVersion: openebs.io/v1beta2 kind: DiskPool metadata: name: pool-worker-1 namespace: openebs spec: node: worker-1 disks: ["aio:///dev/disk/by-id/tu_disco_worker_1"] --- apiVersion: openebs.io/v1beta2 kind: DiskPool metadata: name: pool-worker-2 namespace: openebs spec: node: worker-2 disks: ["aio:///dev/disk/by-id/tu_disco_worker_2"] --- apiVersion: openebs.io/v1beta2 kind: DiskPool metadata: name: pool-worker-3 namespace: openebs spec: node: worker-3 disks: ["aio:///dev/disk/by-id/tu_disco_worker_3"] ``` > Advertencia: Mayastor toma el control total del disco indicado. Cualquier dato que contenga se perderá. ```bash kubectl apply -f diskpools.yaml kubectl -n openebs get diskpools ``` Al cabo de unos segundos, los tres pools deben mostrar el estado `Online` y su capacidad total. Si alguno se queda en otro estado, revisa los eventos con `kubectl -n openebs describe diskpool `. ## Paso 6: Crear una StorageClass replicada y probarla Crea una StorageClass con tres réplicas servidas por NVMe over TCP: ```bash nano storageclass-mayastor-3r.yaml ``` ```yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: mayastor-3r provisioner: io.openebs.csi-mayastor parameters: protocol: nvmf repl: "3" allowVolumeExpansion: true reclaimPolicy: Delete volumeBindingMode: Immediate ``` ```bash kubectl apply -f storageclass-mayastor-3r.yaml ``` Crea un PVC de prueba y un pod que lo monte: ```bash nano mayastor-demo.yaml ``` ```yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: datos-replicados namespace: demo-openebs spec: accessModes: - ReadWriteOnce storageClassName: mayastor-3r resources: requests: storage: 5Gi --- apiVersion: v1 kind: Pod metadata: name: escritor-replicado namespace: demo-openebs spec: containers: - name: app image: busybox:1.36 command: ["sh", "-c", "date >> /datos/log.txt && sleep 3600"] volumeMounts: - name: datos mountPath: /datos volumes: - name: datos persistentVolumeClaim: claimName: datos-replicados ``` ```bash kubectl apply -f mayastor-demo.yaml kubectl -n demo-openebs wait --for=condition=Ready pod/escritor-replicado --timeout=180s kubectl -n demo-openebs exec escritor-replicado -- cat /datos/log.txt ``` ```output Thu Sep 25 10:42:17 UTC 2026 ``` Comprueba que la capacidad usada ha aumentado en los tres pools, lo que indica que cada nodo tiene una réplica: ```bash kubectl -n openebs get diskpools ``` ## Solución de problemas **PVC Hostpath en `Pending`.** Es normal hasta que un pod lo usa, por el modo `WaitForFirstConsumer`. Si sigue así con el pod creado, revisa los eventos con `kubectl -n demo-openebs describe pvc datos-locales` y los logs del provisionador con `kubectl -n openebs logs deploy/openebs-localpv-provisioner`. **Los pods `io-engine` no arrancan o no se crean.** Comprueba que el nodo tiene la etiqueta `openebs.io/engine=mayastor`, que `allocatable` muestra `hugepages-2Mi: 2Gi` y que has reiniciado el kubelet tras configurar las hugepages. Revisa los eventos con `kubectl -n openebs describe pod `. **El pod con un volumen Mayastor no monta.** El nodo donde corre el pod necesita el módulo `nvme_tcp` aunque no tenga pool. Cárgalo como en el paso 3 en todos los nodos worker. **DiskPool que no pasa a `Online`.** Suele ser un disco con particiones o firmas de un sistema de archivos anterior, o una ruta `by-id` incorrecta. Verifica la ruta en el nodo y limpia el disco con `sudo wipefs -a /dev/disk/by-id/` si estás seguro de que no contiene nada que necesites. ## Conclusión Has instalado OpenEBS con Local PV Hostpath para volúmenes locales rápidos y Mayastor para volúmenes replicados en tres nodos, y has comprobado ambos con un pod real. A partir de aquí puedes marcar `mayastor-3r` como StorageClass predeterminada, probar la tolerancia a fallos apagando uno de los nodos mientras el pod escribe, o configurar snapshots CSI con una `VolumeSnapshotClass` del driver `io.openebs.csi-mayastor`.