Saltar al contenido principal

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-2 de 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-0
  • www-web-app-1
  • www-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