Pular para o conteúdo principal

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