Capítulo 7.1 - StatefulSets Aprofundado
Objetivos de Aprendizagem
Ao final deste capítulo, você será capaz de:
- Compreender StatefulSets em profundidade
- Fazer deploy de bancos de dados com StatefulSets
- Gerenciar scaling e atualizações
- Entender os init containers em StatefulSets
- Implementar replicação master-slave
- Gerenciar quóruns e eleição de líder
Introdução
Os StatefulSets são essenciais para aplicações stateful. Este capítulo aprofunda os conceitos e apresenta casos de uso avançados.
Arquitetura de um StatefulSet
Componentes
Exemplo: Banco de Dados PostgreSQL
Etapa 1: Service Headless
apiVersion: v1
kind: Service
metadata:
name: postgres
spec:
clusterIP: None
selector:
app: postgres
ports:
- port: 5432
name: postgres
Etapa 2: ConfigMap para Configuração
apiVersion: v1
kind: ConfigMap
metadata:
name: postgres-config
data:
postgresql.conf: |
max_connections = 200
shared_buffers = 256MB
effective_cache_size = 1GB
Etapa 3: Secret para Credenciais
apiVersion: v1
kind: Secret
metadata:
name: postgres-secret
type: Opaque
data:
postgres-password: cG9zdGdyZXM= # base64
replication-password: cmVwbGljYXRpb24= # base64
Etapa 4: StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: postgres
replicas: 3
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
initContainers:
- name: init-postgres
image: postgres:14
command:
- /bin/bash
- -c
- |
set -e
if [[ $HOSTNAME == "postgres-0" ]]; then
echo "Initializing primary database..."
else
echo "Waiting for primary to be ready..."
until pg_isready -h postgres-0.postgres; do
sleep 1
done
fi
env:
- name: PGHOST
value: postgres-0.postgres
containers:
- name: postgres
image: postgres:14
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: postgres-password
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
ports:
- containerPort: 5432
name: postgres
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
- name: postgres-config
mountPath: /etc/postgresql
volumes:
- name: postgres-config
configMap:
name: postgres-config
volumeClaimTemplates:
- metadata:
name: postgres-data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "fast-ssd"
resources:
requests:
storage: 50Gi
Init Containers
Os init containers são executados antes dos containers principais e podem:
- Inicializar o banco de dados
- Esperar que outros serviços estejam prontos
- Configurar o ambiente
- Verificar dependências
Exemplo:
spec:
template:
spec:
initContainers:
- name: wait-for-db
image: busybox:1.35
command:
- sh
- -c
- |
until nc -z postgres-0.postgres 5432; do
echo "Waiting for database..."
sleep 2
done
containers:
- name: app
image: my-app:1.0
Replicação Master-Slave
Arquitetura
Configuração:
spec:
template:
spec:
containers:
- name: postgres
env:
- name: POSTGRES_REPLICATION_MODE
value: "master" # Para postgres-0
- name: POSTGRES_MASTER_HOST
value: "postgres-0.postgres" # Para postgres-1, postgres-2
Quórum e Eleição de Líder
Para aplicações que necessitam de quórum (ex: etcd, Consul):
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: etcd
spec:
serviceName: etcd
replicas: 3 # Quórum: (3/2) + 1 = 2
template:
spec:
containers:
- name: etcd
image: quay.io/coreos/etcd:v3.5.0
env:
- name: ETCD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: ETCD_INITIAL_CLUSTER
value: "etcd-0=http://etcd-0.etcd:2380,etcd-1=http://etcd-1.etcd:2380,etcd-2=http://etcd-2.etcd:2380"
Quórum: (N/2) + 1, onde N = número de réplicas
Scaling
Scaling Up
kubectl scale statefulset postgres --replicas=5
Processo:
- Cria
postgres-3 - Aguarda
postgres-3ficar Ready - Cria
postgres-4 - Aguarda
postgres-4ficar Ready
Scaling Down
kubectl scale statefulset postgres --replicas=2
Processo:
- Remove
postgres-4(último) - Aguarda
postgres-4ser finalizado - Remove
postgres-3 - Aguarda
postgres-3ser finalizado
Importante: Para bancos de dados, certifique-se de que os dados estejam salvos antes do scaling down.
Atualizações
Rolling Update
spec:
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 0 # Atualiza todos os Pods
Processo:
- Atualiza
postgres-2(último) - Atualiza
postgres-1 - Atualiza
postgres-0(primeiro)
Atualização Parcial (Canary)
spec:
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 2 # Mantém postgres-0 e postgres-1 na versão antiga
Resultado: Apenas postgres-2 é atualizado.
Comandos Úteis
Gerenciamento
# Ver StatefulSets
kubectl get statefulset
kubectl get sts
# Detalhes
kubectl describe statefulset postgres
# Ver Pods
kubectl get pods -l app=postgres
# Logs de um Pod específico
kubectl logs postgres-0
Scaling
# Scaling up
kubectl scale statefulset postgres --replicas=5
# Scaling down
kubectl scale statefulset postgres --replicas=2
Atualizações
# Atualizar a imagem
kubectl set image statefulset/postgres postgres=postgres:15
# Ver status da atualização
kubectl rollout status statefulset/postgres
# Rollback
kubectl rollout undo statefulset/postgres
Boas Práticas
1. Backups Regulares
Implemente backups automáticos dos volumes.
2. Monitoramento
Monitore o estado de cada Pod e as métricas de performance.
3. Quórum Apropriado
Use um número ímpar de réplicas para evitar empates.
4. Init Containers
Utilize init containers para inicialização e verificações.
5. Service Headless
Sempre crie um service headless para descoberta via DNS.
Resumo
Neste capítulo, você aprendeu:
StatefulSets aprofundados: Aplicações stateful com identidades estáveis
Bancos de dados: Deploy de PostgreSQL com replicação
Init containers: Inicialização antes dos containers principais
Replicação: Configuração master-slave
Quórum: Cálculo e configuração para aplicações distribuídas
Scaling: Ordem garantida (crescente/decrescente)
Atualizações: RollingUpdate e atualizações parciais
Boas práticas: Backups, monitoramento, quórum
Próximos Passos
Capítulo 7.2: DaemonSets
Capítulo 7.3: Jobs
Capítulo 7.4: CronJobs
Capítulo criado em: Dezembro 2024