Lab 6.4 - StatefulSet con Almacenamiento Persistente
Objetivos del Lab
Al final de este laboratorio, usted será capaz de:
- Crear un StatefulSet con volúmenes persistentes.
- Comprender el aprovisionamiento de volúmenes para cada Pod.
- Verificar la identidad estable de los Pods y volúmenes.
- Probar la persistencia de los datos durante reinicios.
- Entender las diferencias entre StatefulSet y Deployment para el almacenamiento.
Duración Estimada
60-75 minutos
Prerrequisitos
- kubectl instalado y configurado.
- Un clúster de Kubernetes local funcional (minikube o kind).
- Conocimientos sobre StatefulSets y almacenamiento persistente (Capítulos 6.4 y 7.1).
Parte 1: Preparación de la StorageClass
Para un StatefulSet, cada Pod necesita su propio volumen persistente. Usaremos una StorageClass para el aprovisionamiento dinámico.
Paso 1.1: Crear una StorageClass
Cree un archivo storageclass-statefulset.yaml:
# storageclass-statefulset.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: statefulset-storage
provisioner: k8s.io/minikube-hostpath # Para minikube, o kubernetes.io/no-provisioner para kind
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete
allowVolumeExpansion: false
Nota: Si utiliza kind o un clúster sin provisionador, deberá crear los PVs manualmente. Para este laboratorio, suponemos minikube.
Aplique la StorageClass:
kubectl apply -f storageclass-statefulset.yaml
Parte 2: Creación de un StatefulSet con Almacenamiento
Crearemos un StatefulSet sencillo que almacena datos en volúmenes persistentes.
Paso 2.1: Crear el StatefulSet
Cree un archivo statefulset-with-storage.yaml:
# statefulset-with-storage.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web-app
spec:
serviceName: web-app-service # Nombre del Service headless (requerido para StatefulSet)
replicas: 3 # Crear 3 Pods
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: nginx
image: nginx:1.20
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html # Montaje del volumen persistente
command: ["/bin/sh", "-c"]
args:
- |
echo "Pod $(hostname) - $(date)" > /usr/share/nginx/html/index.html
echo "Datos persistentes del Pod $(hostname)" >> /usr/share/nginx/html/data.txt
nginx -g "daemon off;"
volumeClaimTemplates: # Plantilla para crear un PVC para cada Pod
- metadata:
name: www # Nombre del volumen (será usado en volumeMounts)
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: statefulset-storage # Usa nuestra StorageClass
resources:
requests:
storage: 100Mi # Tamaño del volumen para cada Pod
Explicación:
serviceName: web-app-service: Un StatefulSet requiere un Service headless para la resolución DNS.volumeClaimTemplates: Crea automáticamente un PVC para cada Pod del StatefulSet. Cada Pod tendrá su propio volumen persistente.- Los Pods serán nombrados
web-app-0,web-app-1,web-app-2de manera ordenada.
Paso 2.2: Crear el Service Headless
Un StatefulSet requiere un Service headless (ClusterIP con clusterIP: None) para la resolución DNS:
# service-headless.yaml
apiVersion: v1
kind: Service
metadata:
name: web-app-service
spec:
clusterIP: None # Service headless
selector:
app: web-app
ports:
- port: 80
name: web
Aplique el Service:
kubectl apply -f service-headless.yaml
Aplique el StatefulSet:
kubectl apply -f statefulset-with-storage.yaml
Parte 3: Observación del Aprovisionamiento
Paso 3.1: Verificar la Creación de los Pods
Los Pods de un StatefulSet se crean de manera secuencial (uno por uno):
kubectl get pods -l app=web-app -w
Debería ver los Pods crearse en orden: web-app-0, luego web-app-1, luego web-app-2.
Paso 3.2: Verificar los PVCs Creados
Cada Pod tiene su propio PVC:
kubectl get pvc
Debería ver tres PVCs:
www-web-app-0www-web-app-1www-web-app-2
Cada PVC está vinculado a su propio PV:
kubectl get pv
Paso 3.3: Verificar los Datos en Cada Pod
Cada Pod tiene sus propios datos persistentes:
# Pod 0
kubectl exec web-app-0 -- cat /usr/share/nginx/html/index.html
kubectl exec web-app-0 -- cat /usr/share/nginx/html/data.txt
# Pod 1
kubectl exec web-app-1 -- cat /usr/share/nginx/html/index.html
kubectl exec web-app-1 -- cat /usr/share/nginx/html/data.txt
# Pod 2
kubectl exec web-app-2 -- cat /usr/share/nginx/html/index.html
kubectl exec web-app-2 -- cat /usr/share/nginx/html/data.txt
Cada Pod debería mostrar su propio hostname y sus propios datos.
Parte 4: Prueba de Persistencia
Paso 4.1: Agregar Datos Únicos
Agregue datos únicos a cada Pod:
kubectl exec web-app-0 -- sh -c "echo 'Datos únicos Pod 0 - $(date)' >> /usr/share/nginx/html/data.txt"
kubectl exec web-app-1 -- sh -c "echo 'Datos únicos Pod 1 - $(date)' >> /usr/share/nginx/html/data.txt"
kubectl exec web-app-2 -- sh -c "echo 'Datos únicos Pod 2 - $(date)' >> /usr/share/nginx/html/data.txt"
Verifique los datos:
kubectl exec web-app-0 -- cat /usr/share/nginx/html/data.txt
Paso 4.2: Eliminar un Pod
Elimine un Pod para probar la persistencia:
kubectl delete pod web-app-0
El StatefulSet recreará automáticamente el Pod con el mismo nombre (web-app-0).
Espere a que el nuevo Pod esté en estado Running:
kubectl get pods -l app=web-app
Paso 4.3: Verificar la Persistencia
Verifique que los datos sigan presentes después del reinicio:
kubectl exec web-app-0 -- cat /usr/share/nginx/html/data.txt
Debería ver todos los datos anteriores, incluyendo los "Datos únicos Pod 0", lo que prueba que el volumen persistente fue montado nuevamente con los mismos datos.
Parte 5: Escalado del StatefulSet
Paso 5.1: Aumentar el Número de Réplicas
Aumente el número de Pods:
kubectl scale statefulset web-app --replicas=5
Verifique que se creen nuevos Pods y PVCs:
kubectl get pods -l app=web-app
kubectl get pvc
Debería ver web-app-3 y web-app-4 con sus respectivos PVCs.
Paso 5.2: Reducir el Número de Réplicas
Reduzca el número de Pods:
kubectl scale statefulset web-app --replicas=2
Verifique que los Pods se eliminen en orden inverso (del más alto al más bajo):
kubectl get pods -l app=web-app -w
Importante: Los PVCs NO se eliminan automáticamente. Verifique:
kubectl get pvc
Los PVCs de los Pods eliminados (www-web-app-2, www-web-app-3, www-web-app-4) siguen presentes, preservando los datos.
Parte 6: Limpieza
Elimine los recursos creados:
kubectl delete statefulset web-app
kubectl delete service web-app-service
kubectl delete pvc -l app=web-app # Eliminar todos los PVCs del StatefulSet
# Los PVs serán eliminados automáticamente si reclaimPolicy: Delete
kubectl delete -f storageclass-statefulset.yaml
Resumen del Lab
En este laboratorio, usted exploró el uso de StatefulSets con almacenamiento persistente. Aprendió a crear un StatefulSet con volumeClaimTemplates, a observar el aprovisionamiento secuencial de Pods y volúmenes, a probar la persistencia de los datos durante reinicios, y a comprender el comportamiento del escalado con volúmenes persistentes.
Próximos Pasos
Este módulo sobre almacenamiento está ahora completo. Puede continuar con el Módulo 7 sobre Workloads Avanzados.
Módulo 7: Workloads Avanzados
Lab creado el: Diciembre 2024