Lab 6.4 - StatefulSet com Armazenamento Persistente
Objetivos do Lab
Ao final deste lab, você será capaz de:
- Criar um StatefulSet com volumes persistentes.
- Entender o provisionamento de volumes para cada Pod.
- Verificar a identidade estável dos Pods e volumes.
- Testar a persistência dos dados durante reinicializações.
- Compreender as diferenças entre StatefulSet e Deployment para armazenamento.
Duração Estimada
60-75 minutos
Pré-requisitos
- kubectl instalado e configurado.
- Cluster Kubernetes local funcional (minikube ou kind).
- Conhecimentos sobre StatefulSets e armazenamento persistente (Capítulos 6.4 e 7.1).
Parte 1: Preparação da StorageClass
Para um StatefulSet, cada Pod precisa de seu próprio volume persistente. Vamos usar uma StorageClass para provisionamento dinâmico.
Etapa 1.1: Criar uma StorageClass
Crie um arquivo storageclass-statefulset.yaml:
# storageclass-statefulset.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: statefulset-storage
provisioner: k8s.io/minikube-hostpath # Para minikube, ou kubernetes.io/no-provisioner para kind
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete
allowVolumeExpansion: false
Nota: Se você estiver usando kind ou um cluster sem provisionador, será necessário criar os PVs manualmente. Para este lab, assumimos minikube.
Aplique a StorageClass:
kubectl apply -f storageclass-statefulset.yaml
Parte 2: Criação de um StatefulSet com Armazenamento
Vamos criar um StatefulSet simples que armazena dados em volumes persistentes.
Etapa 2.1: Criar o StatefulSet
Crie um arquivo statefulset-with-storage.yaml:
# statefulset-with-storage.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web-app
spec:
serviceName: web-app-service # Nome do Service headless (necessário para StatefulSet)
replicas: 3 # Cria 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 # Montagem do volume persistente
command: ["/bin/sh", "-c"]
args:
- |
echo "Pod $(hostname) - $(date)" > /usr/share/nginx/html/index.html
echo "Dados persistentes do Pod $(hostname)" >> /usr/share/nginx/html/data.txt
nginx -g "daemon off;"
volumeClaimTemplates: # Template para criar um PVC para cada Pod
- metadata:
name: www # Nome do volume (será usado em volumeMounts)
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: statefulset-storage # Usa nossa StorageClass
resources:
requests:
storage: 100Mi # Tamanho do volume para cada Pod
Explicação:
serviceName: web-app-service: Um StatefulSet requer um Service headless para descoberta DNS.volumeClaimTemplates: Cria automaticamente um PVC para cada Pod do StatefulSet. Cada Pod terá seu próprio volume persistente.- Os Pods serão nomeados
web-app-0,web-app-1,web-app-2de forma ordenada.
Etapa 2.2: Criar o Service Headless
Um StatefulSet requer um Service headless (ClusterIP com clusterIP: None) para descoberta 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 o Service:
kubectl apply -f service-headless.yaml
Aplique o StatefulSet:
kubectl apply -f statefulset-with-storage.yaml
Parte 3: Observação do Provisionamento
Etapa 3.1: Verificar a Criação dos Pods
Os Pods de um StatefulSet são criados de forma sequencial (um por vez):
kubectl get pods -l app=web-app -w
Você deve ver os Pods sendo criados na ordem: web-app-0, depois web-app-1, depois web-app-2.
Etapa 3.2: Verificar os PVCs Criados
Cada Pod tem seu próprio PVC:
kubectl get pvc
Você deve ver três PVCs:
www-web-app-0www-web-app-1www-web-app-2
Cada PVC está vinculado ao seu próprio PV:
kubectl get pv
Etapa 3.3: Verificar os Dados em Cada Pod
Cada Pod possui seus próprios dados 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 deve exibir seu próprio hostname e seus próprios dados.
Parte 4: Teste de Persistência
Etapa 4.1: Adicionar Dados Únicos
Adicione dados únicos a cada Pod:
kubectl exec web-app-0 -- sh -c "echo 'Dados únicos Pod 0 - $(date)' >> /usr/share/nginx/html/data.txt"
kubectl exec web-app-1 -- sh -c "echo 'Dados únicos Pod 1 - $(date)' >> /usr/share/nginx/html/data.txt"
kubectl exec web-app-2 -- sh -c "echo 'Dados únicos Pod 2 - $(date)' >> /usr/share/nginx/html/data.txt"
Verifique os dados:
kubectl exec web-app-0 -- cat /usr/share/nginx/html/data.txt
Etapa 4.2: Excluir um Pod
Exclua um Pod para testar a persistência:
kubectl delete pod web-app-0
O StatefulSet irá recriar automaticamente o Pod com o mesmo nome (web-app-0).
Aguarde até que o novo Pod esteja Running:
kubectl get pods -l app=web-app
Etapa 4.3: Verificar a Persistência
Verifique se os dados ainda estão presentes após o reinício:
kubectl exec web-app-0 -- cat /usr/share/nginx/html/data.txt
Você deve ver todos os dados anteriores, incluindo os "Dados únicos Pod 0", o que prova que o volume persistente foi remontado com os mesmos dados.
Parte 5: Scaling do StatefulSet
Etapa 5.1: Aumentar o Número de Réplicas
Aumente o número de Pods:
kubectl scale statefulset web-app --replicas=5
Verifique se novos Pods e PVCs foram criados:
kubectl get pods -l app=web-app
kubectl get pvc
Você deve ver web-app-3 e web-app-4 com seus respectivos PVCs.
Etapa 5.2: Reduzir o Número de Réplicas
Reduza o número de Pods:
kubectl scale statefulset web-app --replicas=2
Verifique se os Pods são removidos na ordem inversa (do maior para o menor):
kubectl get pods -l app=web-app -w
Importante: Os PVCs NÃO são removidos automaticamente. Verifique:
kubectl get pvc
Os PVCs dos Pods removidos (www-web-app-2, www-web-app-3, www-web-app-4) ainda estão presentes, preservando os dados.
Parte 6: Limpeza
Remova os recursos criados:
kubectl delete statefulset web-app
kubectl delete service web-app-service
kubectl delete pvc -l app=web-app # Remove todos os PVCs do StatefulSet
# Os PVs serão removidos automaticamente se reclaimPolicy: Delete
kubectl delete -f storageclass-statefulset.yaml
Resumo do Lab
Neste lab, você explorou o uso de StatefulSets com armazenamento persistente. Você aprendeu a criar um StatefulSet com volumeClaimTemplates, a observar o provisionamento sequencial dos Pods e volumes, a testar a persistência dos dados durante reinicializações e a entender o comportamento do scaling com volumes persistentes.
Próximos Passos
Este módulo sobre armazenamento está agora completo. Você pode avançar para o Módulo 7 sobre Workloads Avançados.
Módulo 7: Workloads Avançados
Lab criado em: Dezembro de 2024