Capitulo 11: Volumenes Persistentes
Capitulo 11: Volumenes Persistentes
< Volver al Indice del Tutorial
El Problema del Almacenamiento Efimero
Los contenedores son efimeros por diseno. Cuando un pod se reinicia, se elimina o se reprograma en otro nodo, todo su sistema de archivos se destruye y se crea uno nuevo desde la imagen.
Esto significa que cualquier dato escrito dentro del contenedor (base de datos, archivos subidos, logs) desaparece con el pod. Para aplicaciones que necesitan persistir datos, Kubernetes ofrece el sistema de volumenes persistentes.
Local-Path Provisioner en K3s
K3s incluye el local-path provisioner de Rancher preinstalado. Este provisioner crea volumenes en el sistema de archivos local del nodo, especificamente en:
/var/lib/rancher/k3s/storage/
Verifica que esta disponible:
kubectl get storageclass
Veras una StorageClass llamada local-path marcada como (default):
NAME PROVISIONER RECLAIMPOLICY AGE
local-path (default) rancher.io/local-path Delete 30d
Esto significa que cualquier PVC que crees sin especificar StorageClass usara local-path automaticamente.
Conceptos Fundamentales
PersistentVolume (PV)
Un PersistentVolume es un recurso de almacenamiento en el cluster, similar a un nodo que provee computo. Es el “disco” fisico (o logico) disponible.
Con el local-path provisioner, los PV se crean automaticamente cuando un PVC los solicita. No necesitas crearlos manualmente en la mayoria de los casos.
PersistentVolumeClaim (PVC)
Un PVC es una solicitud de almacenamiento hecha por un pod. Especifica cuanto espacio necesita y con que modo de acceso. Es la “peticion” que un pod hace para obtener un disco.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: datos-app
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
Al crear este PVC, el local-path provisioner automaticamente crea un PV y lo asocia (binding).
kubectl apply -f datos-app-pvc.yaml
kubectl get pvc
La columna STATUS debe mostrar Bound.
StorageClass
Una StorageClass define el tipo de almacenamiento disponible y como se provisiona. El local-path provisioner tiene su propia StorageClass que soporta provisionamiento dinamico: los PV se crean bajo demanda cuando aparece un PVC.
En clusters con almacenamiento externo (NFS, Longhorn, Ceph), tendrias multiples StorageClasses. En K3s con local-path solo tienes una por defecto.
Si necesitas especificar la StorageClass explicitamente:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: datos-app
spec:
storageClassName: local-path
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
Access Modes
Los modos de acceso determinan como los pods pueden usar el volumen:
| Modo | Abreviatura | Descripcion |
|---|---|---|
| ReadWriteOnce | RWO | Un solo nodo puede montar el volumen en lectura/escritura |
| ReadOnlyMany | ROX | Multiples nodos pueden montar el volumen en solo lectura |
| ReadWriteMany | RWX | Multiples nodos pueden montar en lectura/escritura |
El local-path provisioner de K3s solo soporta ReadWriteOnce porque los datos viven en el disco local de un nodo especifico. Para RWX necesitarias soluciones como NFS o Longhorn.
Reclaim Policies
La politica de reclamacion define que pasa con el PV cuando se elimina el PVC asociado:
- Delete: el PV y sus datos se eliminan automaticamente. Es el default de local-path.
- Retain: el PV se conserva en estado
Released. Los datos persisten pero el PV debe ser liberado manualmente para reutilizarse.
Para datos criticos, cambia la politica a Retain:
kubectl patch pv <nombre-pv> -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'
Montar un PVC en un Pod
Para usar un PVC en un pod, lo declaras en volumes y lo montas en un contenedor con volumeMounts:
apiVersion: v1
kind: Pod
metadata:
name: app-con-datos
spec:
containers:
- name: app
image: nginx:alpine
volumeMounts:
- name: almacenamiento
mountPath: /datos
volumes:
- name: almacenamiento
persistentVolumeClaim:
claimName: datos-app
El contenedor vera el volumen montado en /datos. Todo lo que escriba ahi persiste aunque el pod se reinicie.
Ejemplo Completo
Vamos a crear una aplicacion que escribe datos y demuestra que sobreviven a reinicios del pod.
Primero el PVC:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: contador-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
Ahora un Deployment que usa el PVC:
apiVersion: apps/v1
kind: Deployment
metadata:
name: contador-app
spec:
replicas: 1
selector:
matchLabels:
app: contador
template:
metadata:
labels:
app: contador
spec:
containers:
- name: contador
image: busybox
command: ["/bin/sh", "-c"]
args:
- |
if [ ! -f /datos/contador.txt ]; then
echo "0" > /datos/contador.txt
fi
while true; do
VALOR=$(cat /datos/contador.txt)
NUEVO=$((VALOR + 1))
echo "$NUEVO" > /datos/contador.txt
echo "Contador: $NUEVO"
sleep 5
done
volumeMounts:
- name: almacenamiento
mountPath: /datos
volumes:
- name: almacenamiento
persistentVolumeClaim:
claimName: contador-pvc
Aplica ambos archivos:
kubectl apply -f contador-pvc.yaml
kubectl apply -f contador-app.yaml
Verifica que el PVC este vinculado:
kubectl get pvc contador-pvc
Observa los logs del pod para ver el contador incrementando:
kubectl logs -f deployment/contador-app
Ahora elimina el pod para simular un reinicio:
kubectl delete pod -l app=contador
El Deployment crea un nuevo pod automaticamente. Revisa los logs nuevamente:
kubectl logs -f deployment/contador-app
El contador continua desde donde quedo, no empieza en 0. Los datos persisten en el PVC a traves del reinicio del pod.
Para ver donde se almacenan fisicamente los datos en el nodo:
ls /var/lib/rancher/k3s/storage/
Veras un directorio con el nombre del PVC que contiene el archivo contador.txt.
Limitaciones del Local-Path Provisioner
El local-path provisioner es simple y funcional pero tiene limitaciones:
- Sin replicacion: los datos estan en un solo nodo. Si el nodo falla, los datos se pierden.
- Sin RWX: solo un nodo puede montar el volumen a la vez.
- Sin redimensionamiento: no puedes expandir un PVC despues de crearlo.
- Afinidad al nodo: el pod debe correr en el nodo donde esta el PV.
Para produccion con requisitos de alta disponibilidad, considera Longhorn (de Rancher) o soluciones NFS.
Siguiente: Capitulo 12: Bases de Datos en K3s —>