Almacenamiento persistente: volúmenes, PersistentVolumes y claims
Mantén los datos vivos entre reinicios de Pods con PVCs y entiende cómo las StorageClasses unen las piezas.
El sistema de archivos de un contenedor dura solo lo que dura el contenedor. Cuando se reemplaza un Pod, todo lo que escribió desaparece. Eso está bien para servidores web sin estado y es un problema para bases de datos, subidas de archivos y todo lo demás que debe sobrevivir. Esta guía muestra cómo Kubernetes adjunta almacenamiento duradero a los Pods.
Por qué el almacenamiento del contenedor no basta
Los contenedores están pensados para ser pequeños y desechables, así que poner datos dentro de ellos derrota el modelo. Los datos tienen que vivir fuera del contenedor y fuera del Pod, en almacenamiento que Kubernetes adjunta cuando arranca un Pod. Kubernetes es agnóstico sobre qué es ese almacenamiento: un disco en la nube, un recurso compartido de red o una unidad local. Tampoco hace copias de seguridad de los datos por ti. Eso sigue siendo tu trabajo.
La cadena de almacenamiento
Cuatro objetos trabajan juntos:
- Una StorageClass describe un tipo de almacenamiento y cómo crearlo bajo demanda (por ejemplo, “volúmenes SSD rápidos del proveedor de nube”).
- Un PersistentVolume (PV) es una pieza real de almacenamiento en el clúster.
- Un PersistentVolumeClaim (PVC) es una petición de almacenamiento por parte de un usuario o una aplicación: “necesito 1 GiB que un nodo pueda leer y escribir”.
- El Pod referencia el claim como un volumen y lo monta en un contenedor.
Contenedor ─ mountPath ─▶ Volumen del Pod ─▶ PVC ─ se enlaza con ─▶ PV ─▶ almacenamiento real
▲
La StorageClass crea PV bajo demanda
Un PVC se enlaza exactamente con un PV. El Pod nunca hace referencia al PV, solo al claim, que es lo que mantiene a las aplicaciones independientes de los detalles del almacenamiento.
Solicita almacenamiento con un PVC
La mayoría de los clústeres tienen una StorageClass predeterminada que crea volúmenes bajo demanda (llamado aprovisionamiento dinámico), y minikube incluye una. Comprueba la tuya:
kubectl get storageclass
Luego pide almacenamiento:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
kubectl apply -f pvc.yaml
kubectl get pvc,pv
El claim debería pasar a Bound, y aparece un PV correspondiente. Algunas clases de almacenamiento esperan a que un Pod use realmente el claim antes de crear el volumen, así que Pending en este punto no es necesariamente un error.
Móntalo en un Pod y demuestra la persistencia
apiVersion: v1
kind: Pod
metadata:
name: storage-demo
spec:
containers:
- name: app
image: busybox:1.36
command: ["sh", "-c", "sleep 3600"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: data
Escribe un archivo, destruye el Pod, vuelve a crearlo y comprueba que el archivo sobrevivió:
kubectl apply -f pod.yaml
kubectl exec storage-demo -- sh -c 'echo persisted > /data/proof.txt'
kubectl delete pod storage-demo
kubectl apply -f pod.yaml
kubectl exec storage-demo -- cat /data/proof.txt
El nuevo Pod es un contenedor completamente distinto, pero el claim, y los datos que hay detrás, se volvieron a adjuntar.
Modos de acceso, política de reclamación y volúmenes estáticos
- Los modos de acceso indican cómo se puede montar un volumen.
ReadWriteOncesignifica lectura-escritura por un solo nodo, así que varios Pods de ese nodo aún pueden compartirlo.ReadOnlyManyyReadWriteManypermiten muchos nodos, si el almacenamiento lo soporta.ReadWriteOncePodlo restringe a un solo Pod. - La política de reclamación (reclaim policy) decide qué ocurre con el volumen cuando se elimina el claim. Los volúmenes aprovisionados dinámicamente suelen tener
Deletepor defecto, lo que elimina el almacenamiento subyacente y sus datos. UsaRetaincuando quieras conservar los datos. - El aprovisionamiento estático significa que un administrador crea los PV a mano y los claims se enlazan con el que encaje. Un PV de tipo
hostPath, que usa un directorio de un nodo, es una demo habitual, pero ata los datos a una sola máquina y solo es adecuado para desarrollo en un solo nodo.
Bases de datos y StatefulSets
Puedes montar un claim en los Pods de un Deployment, pero las réplicas de un Deployment son intercambiables e idénticas, y la mayoría de las bases de datos no funcionan así. Un StatefulSet está pensado para cargas de trabajo con estado. Da a cada Pod una identidad estable (db-0, db-1), los inicia y actualiza en orden y puede crear un PVC separado para cada réplica:
spec:
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 5Gi
Un StatefulSet gestiona la identidad y el almacenamiento, no la replicación de datos. Hacer que las réplicas sean consistentes entre sí es trabajo de la base de datos, razón por la cual ejecutar bases de datos en Kubernetes es más difícil que ejecutar servicios sin estado. Muchos equipos usan una base de datos administrada o un operator de base de datos, y mantienen las aplicaciones sin estado en el clúster.
Guías populares
-
Qué es Kubernetes y los problemas que resuelve Por qué los contenedores por sí solos dejan de escalar y cómo Kubernetes convierte un grupo de máquinas en una sola plataforma. -
Cómo funciona un clúster de Kubernetes: plano de control y nodos Los componentes que hacen funcionar un clúster y qué ocurre entre kubectl apply y un contenedor en ejecución. -
Deployments: escalado, autorreparación y rolling updates Ejecuta réplicas de un Pod, actualízalas sin tiempo de inactividad y revierte cuando un despliegue sale mal. -
Services: networking estable para Pods efímeros Dale a los Pods una dirección estable, exponlos dentro y fuera del clúster y restringe quién puede hablar con quién. -
Depura un Pod que falla: describe, logs, exec y port-forward Una lista de comprobación repetible para averiguar por qué un Pod está Pending, se cae o no responde.