Almacenamiento OpenEBS para Kubernetes
OpenEBS es una solución de almacenamiento container-attached (CAS) para Kubernetes que ofrece múltiples motores de almacenamiento adaptados a distintas necesidades: desde volúmenes locales de alto rendimiento hasta almacenamiento distribuido replicado. Al ejecutarse completamente en el espacio de usuario como pods de Kubernetes, OpenEBS es fácil de instalar, escalar y operar sin depender de módulos del kernel especiales.
Requisitos Previos
- Kubernetes 1.23+
kubectlconfigurado con acceso al clústerhelmv3 instalado- Para iSCSI (Jiva/cStor):
open-iscsien nodos worker - Para Mayastor: kernel Linux 5.15+ y soporte para hugepages
# Instalar open-iscsi en todos los nodos worker (Ubuntu/Debian)
apt update && apt install -y open-iscsi
systemctl enable iscsid && systemctl start iscsid
# Para CentOS/Rocky Linux
yum install -y iscsi-initiator-utils
systemctl enable iscsid && systemctl start iscsid
# Verificar el estado del servicio iSCSI
systemctl status iscsid
Instalación de OpenEBS
# Agregar el repositorio Helm de OpenEBS
helm repo add openebs https://openebs.github.io/openebs
helm repo update
# Instalación completa de OpenEBS (todos los motores)
helm install openebs openebs/openebs \
--namespace openebs \
--create-namespace \
--set engines.local.lvm.enabled=true \
--set engines.replicated.mayastor.enabled=false # Deshabilitar Mayastor si no hay NVMe
# Instalación mínima (solo LocalPV Hostpath)
helm install openebs openebs/openebs \
--namespace openebs \
--create-namespace \
--set engines.replicated.mayastor.enabled=false \
--set engines.local.lvm.enabled=false \
--set engines.local.zfs.enabled=false
# Verificar la instalación
kubectl get pods -n openebs
kubectl get storageclass | grep openebs
LocalPV: Volúmenes Locales de Alto Rendimiento
LocalPV es el motor más simple y de mayor rendimiento de OpenEBS. Los datos residen en el nodo local sin replicación.
# Ver los StorageClass de LocalPV disponibles
kubectl get storageclass | grep local
# LocalPV Hostpath: usa un directorio en el sistema de archivos del nodo
cat > pvc-localpv-hostpath.yaml << 'EOF'
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: datos-locales
namespace: produccion
spec:
accessModes:
- ReadWriteOnce
storageClassName: openebs-hostpath
resources:
requests:
storage: 20Gi
EOF
kubectl apply -f pvc-localpv-hostpath.yaml
# Crear un StorageClass LocalPV personalizado con ruta específica
cat > storageclass-localpv-custom.yaml << 'EOF'
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: localpv-datos
annotations:
storageclass.kubernetes.io/is-default-class: "false"
provisioner: openebs.io/local
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
parameters:
# Directorio base en el nodo donde se crearán los volúmenes
basePath: "/mnt/datos-locales"
EOF
kubectl apply -f storageclass-localpv-custom.yaml
Jiva: Almacenamiento Replicado
Jiva proporciona replicación síncrana entre nodos usando iSCSI.
# Instalar el operador de Jiva (si no está incluido en la instalación base)
helm install jiva openebs/jiva \
--namespace openebs \
--create-namespace
# Verificar que Jiva está corriendo
kubectl get pods -n openebs | grep jiva
# Crear un StorageClass de Jiva con 3 réplicas
cat > storageclass-jiva.yaml << 'EOF'
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: jiva-replicado
provisioner: jiva.csi.openebs.io
allowVolumeExpansion: true
parameters:
cas-type: "jiva"
policy: "jiva-policy-default"
EOF
kubectl apply -f storageclass-jiva.yaml
# Crear un JivaVolumePolicy para configurar el número de réplicas
cat > jiva-policy.yaml << 'EOF'
apiVersion: openebs.io/v1alpha1
kind: JivaVolumePolicy
metadata:
name: jiva-policy-default
namespace: openebs
spec:
replicaSC: openebs-hostpath
target:
replicationFactor: 3
resources:
requests:
memory: 250Mi
cpu: 250m
limits:
memory: 500Mi
cpu: 500m
replica:
resources:
requests:
memory: 250Mi
cpu: 250m
limits:
memory: 1Gi
cpu: 500m
EOF
kubectl apply -f jiva-policy.yaml
cStor: Motor de Almacenamiento Avanzado
cStor ofrece características avanzadas como snapshots, clones y thin provisioning usando ZFS a nivel de usuario.
# Instalar el operador de cStor
helm install cstor openebs/cstor \
--namespace openebs \
--create-namespace
kubectl get pods -n openebs | grep cstor
# Identificar los discos disponibles en los nodos
kubectl get blockdevices -n openebs
# Crear un CStorPoolCluster con los discos identificados
cat > cspc.yaml << 'EOF'
apiVersion: cstor.openebs.io/v1
kind: CStorPoolCluster
metadata:
name: cstor-disk-pool
namespace: openebs
spec:
pools:
# Pool en el primer nodo worker
- nodeSelector:
kubernetes.io/hostname: "worker-01"
dataRaidGroups:
- blockDevices:
- blockDeviceName: "blockdevice-abc123"
poolConfig:
dataRaidGroupType: "stripe" # stripe, mirror, raidz
# Pool en el segundo nodo worker
- nodeSelector:
kubernetes.io/hostname: "worker-02"
dataRaidGroups:
- blockDevices:
- blockDeviceName: "blockdevice-def456"
poolConfig:
dataRaidGroupType: "stripe"
# Pool en el tercer nodo worker
- nodeSelector:
kubernetes.io/hostname: "worker-03"
dataRaidGroups:
- blockDevices:
- blockDeviceName: "blockdevice-ghi789"
poolConfig:
dataRaidGroupType: "stripe"
EOF
kubectl apply -f cspc.yaml
# Verificar el estado del pool
kubectl get cspc -n openebs
kubectl get cspi -n openebs # CStorPoolInstance por nodo
# Crear un StorageClass de cStor
cat > storageclass-cstor.yaml << 'EOF'
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: cstor-3-replicas
provisioner: cstor.csi.openebs.io
allowVolumeExpansion: true
parameters:
cas-type: cstor
cstorPoolCluster: cstor-disk-pool
replicaCount: "3"
EOF
kubectl apply -f storageclass-cstor.yaml
Mayastor: Almacenamiento NVMe
Mayastor es el motor más moderno de OpenEBS, diseñado para discos NVMe con latencias ultrabajas.
# Habilitar hugepages en los nodos (requerido por Mayastor)
echo 'vm.nr_hugepages = 1024' >> /etc/sysctl.d/99-mayastor.conf
sysctl -p /etc/sysctl.d/99-mayastor.conf
# Verificar hugepages
grep HugePages /proc/meminfo
# Instalar Mayastor
helm install mayastor openebs/mayastor \
--namespace mayastor \
--create-namespace \
--set etcd.replicaCount=3
# Verificar los nodos de almacenamiento (DiskPools)
kubectl get diskpools -n mayastor
# Crear un DiskPool en un nodo
cat > diskpool.yaml << 'EOF'
apiVersion: openebs.io/v1beta2
kind: DiskPool
metadata:
name: pool-worker-01
namespace: mayastor
spec:
node: worker-01
disks:
- uring:///dev/nvme0n1 # Disco NVMe usando io_uring
EOF
kubectl apply -f diskpool.yaml
# Crear StorageClass de Mayastor
cat > storageclass-mayastor.yaml << 'EOF'
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: mayastor-nvme
parameters:
ioTimeout: "30"
protocol: nvmf
repl: "3" # Número de réplicas NVMe-oF
provisioner: io.openebs.csi-mayastor
allowVolumeExpansion: true
reclaimPolicy: Delete
volumeBindingMode: Immediate
EOF
kubectl apply -f storageclass-mayastor.yaml
Instantáneas y Backups
# Instalar el VolumeSnapshot controller (si no está instalado)
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/main/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/main/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/main/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml
# Crear un VolumeSnapshotClass para cStor
cat > snapshot-class-cstor.yaml << 'EOF'
kind: VolumeSnapshotClass
apiVersion: snapshot.storage.k8s.io/v1
metadata:
name: cstor-snapshot-class
driver: cstor.csi.openebs.io
deletionPolicy: Delete
EOF
kubectl apply -f snapshot-class-cstor.yaml
# Tomar una instantánea de un PVC
cat > volumesnapshot.yaml << 'EOF'
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: snapshot-datos-app
namespace: produccion
spec:
volumeSnapshotClassName: cstor-snapshot-class
source:
persistentVolumeClaimName: datos-locales
EOF
kubectl apply -f volumesnapshot.yaml
kubectl get volumesnapshots -n produccion
Ajuste de Rendimiento
# Verificar las métricas de rendimiento de los volúmenes cStor
kubectl get cstorvolumes -n openebs
kubectl describe cstorvolume <volume-name> -n openebs
# Ver las estadísticas de E/S de un volumen
kubectl exec -n openebs <cstor-target-pod> -- \
cat /proc/$(pgrep iscsit)/io
# Para LocalPV, verificar el rendimiento con fio
kubectl run fio-test --image=ljishen/fio --restart=Never -- \
fio --name=randwrite --ioengine=libaio --iodepth=16 \
--rw=randwrite --bs=4k --direct=1 --size=1G \
--numjobs=1 --filename=/datos/test
# Configurar prioridad de I/O para pods críticos
cat >> pod-spec.yaml << 'EOF'
priorityClassName: system-cluster-critical
EOF
Solución de Problemas
PVC en estado Pending:
# Verificar eventos del PVC
kubectl describe pvc <nombre-pvc> -n <namespace>
# Verificar que el StorageClass existe
kubectl get storageclass
# Ver el estado de los operadores de OpenEBS
kubectl get pods -n openebs
# Logs del CSI controller
kubectl logs -n openebs -l openebs.io/component-name=openebs-controller -f
Volumen Jiva en estado Degraded:
# Ver el estado de las réplicas
kubectl get jivavolumes -n openebs
# Verificar conectividad iSCSI entre los nodos
iscsiadm -m session
# Reiniciar el target iSCSI
kubectl delete pod -n openebs -l openebs.io/component=jiva-controller
Conclusión
OpenEBS ofrece flexibilidad sin igual al proporcionar múltiples motores de almacenamiento para diferentes casos de uso: LocalPV para máximo rendimiento con datos locales, Jiva para replicación sencilla, cStor para características avanzadas, y Mayastor para entornos NVMe de ultra-baja latencia. Su naturaleza completamente containerizada lo hace fácil de instalar y operar, especialmente en entornos donde no hay un sistema de almacenamiento externo disponible.


