- ArgoCD via Helm com recursos mínimos (~1Gi) - GitLab Runner com executor Kubernetes - Exemplo node-bugado com Dockerfile e .gitlab-ci.yml - Manifests K8s para repositório GitOps - README.md da aula-03 (liveness + readiness probes)
Aula 03 - Alta Disponibilidade com Replicas e Readiness Probe
Evolução da aula-02 adicionando múltiplas réplicas e readiness probe para zero-downtime.
Conceitos
Liveness vs Readiness Probe
| Probe | Função | Quando Falha |
|---|---|---|
| Liveness | "O container está vivo?" | Reinicia o container |
| Readiness | "O container está pronto para receber tráfego?" | Remove do Service (sem reiniciar) |
Por que 5 Réplicas?
Cenário: MAX_REQUESTS=3, 5 réplicas
Tempo 0s: [Pod1: OK] [Pod2: OK] [Pod3: OK] [Pod4: OK] [Pod5: OK]
↑ Service distribui tráfego entre todos
Tempo 5s: [Pod1: HANG] [Pod2: OK] [Pod3: OK] [Pod4: OK] [Pod5: OK]
↑ readinessProbe falha → removido do Service
↑ livenessProbe falha → reiniciando...
Tempo 7s: [Pod1: RESTART] [Pod2: OK] [Pod3: OK] [Pod4: OK] [Pod5: OK]
↑ Pod1 reiniciou, readiness OK → volta ao Service
Resultado: Usuário NUNCA vê erro 503
Arquitetura
LoadBalancer (:3000)
│
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Pod 1 │ │ Pod 2 │ │ Pod 3 │ ... (5 réplicas)
│ :3000 │ │ :3000 │ │ :3000 │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
readinessProbe readinessProbe readinessProbe
livenessProbe livenessProbe livenessProbe
Execução
cd aula-03
# Aplicar recursos
kubectl apply -f configmap.yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
# Verificar pods
kubectl get pods -w
# Acessar a aplicação
# Docker Desktop: http://localhost:3000
# Minikube: minikube service node-bugado --url
Configuração das Probes
# Readiness - remove do Service rapidamente
readinessProbe:
httpGet:
path: /health
port: 3000
periodSeconds: 1 # Verifica a cada 1 segundo
failureThreshold: 1 # 1 falha = remove do Service
# Liveness - reinicia o container
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 2 # Espera app iniciar
periodSeconds: 1 # Verifica a cada 1 segundo
failureThreshold: 2 # 2 falhas = reinicia
Teste de Resiliência
# Terminal 1: Monitorar pods
kubectl get pods -w
# Terminal 2: Fazer requisições contínuas
while true; do curl -s http://localhost:3000 && echo; sleep 0.5; done
# Observar:
# 1. Pods recebem requisições e eventualmente "travam"
# 2. readinessProbe remove pod do Service (sem interromper requests)
# 3. livenessProbe reinicia o pod
# 4. Pod volta ao Service quando ready
# 5. Usuário NÃO vê erros durante todo o processo
Diferença da Aula 02
| Aspecto | Aula 02 | Aula 03 |
|---|---|---|
| Réplicas | 1 | 5 |
| Probes | Liveness apenas | Liveness + Readiness |
| Downtime | Sim (durante restart) | Não (outras réplicas atendem) |
| Service | NodePort | LoadBalancer |
Fluxo de Eventos
- Pod recebe requisições → contador incrementa
- MAX_REQUESTS atingido → app para de responder
- readinessProbe falha (1s) → pod removido do Service
- Tráfego redirecionado → outros pods atendem
- livenessProbe falha (2s) → Kubernetes reinicia container
- Pod reinicia → contador zerado, app responde
- readinessProbe OK → pod volta ao Service
Lições
- Réplicas = Resiliência: Múltiplas cópias garantem disponibilidade
- Readiness ≠ Liveness: Propósitos diferentes, ambos importantes
- Graceful Degradation: Sistema continua funcionando com capacidade reduzida
- Self-Healing: Kubernetes detecta e corrige problemas automaticamente
Cleanup
./cleanup.sh
# ou
kubectl delete -f .
Próxima Aula
Aula 04: NGINX Ingress com Keep Request (Lua) para zero-downtime ainda mais robusto, segurando requisições durante a janela de restart.