Containers são efêmeros por design — quando um container morre, seus dados morrem junto. Para qualquer aplicação que precisa persistir dados (um banco de dados, um sistema de arquivos, logs estruturados), você precisa entender como o Kubernetes resolve isso. E resolver storage em K8s tem mais nuances do que parece.
O problema fundamental: containers são efêmeros
Quando um container é criado, ele inicia com o conteúdo da imagem — um sistema de arquivos imutável. Qualquer arquivo escrito dentro do container durante sua execução existe apenas na camada de escrita temporária, descartada quando o container para.
Isso é ótimo para aplicações stateless: cada instância é idêntica, pode ser substituída sem perda de estado. Mas é um problema para qualquer aplicação que precisa persistir dados entre reinicializações — bancos de dados, sistemas de upload de arquivos, caches persistentes.
O Kubernetes resolve isso com uma camada de abstração de storage que separa o que você precisa de onde os dados ficam fisicamente.
Os três objetos de storage no Kubernetes
PersistentVolume (PV)
Um PersistentVolume é um pedaço de armazenamento provisionado no cluster — pode ser um disco NFS, um volume Ceph RBD, um AWS EBS, ou qualquer backend suportado. O PV existe independentemente dos Pods que o usam.
Pense no PV como o “estoque de armazenamento disponível” — é criado pelo administrador do cluster (ou automaticamente via StorageClass) e fica disponível para ser reivindicado.
PersistentVolumeClaim (PVC)
Um PersistentVolumeClaim é a requisição de armazenamento feita pela aplicação. Você declara no PVC o quanto de espaço precisa, o modo de acesso e a StorageClass desejada. O Kubernetes faz o bind entre o PVC e um PV que atende os requisitos.
A analogia é clara: o PV é o apartamento disponível para alugar; o PVC é o contrato de aluguel que a aplicação assina. Uma vez feito o bind, aquele PV fica reservado para aquele PVC.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dados-mysql
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
storageClassName: standard
O Pod então monta o PVC como um volume:
volumes:
- name: dados
persistentVolumeClaim:
claimName: dados-mysql
StorageClass
A StorageClass define como os PVs são provisionados. Em vez de criar PVs manualmente, você define uma StorageClass que aponta para um provisionador — um componente que cria volumes automaticamente quando um PVC é criado.
Em cloud pública, as StorageClasses são pré-configuradas (AWS EBS, Azure Disk, GCP Persistent Disk). Em cloud privada, o administrador configura StorageClasses que apontam para os backends disponíveis: NFS, Ceph, Longhorn.
O provisionamento dinâmico é o resultado: quando uma aplicação cria um PVC, a StorageClass provisiona automaticamente um PV correspondente. Sem intervenção manual do administrador para cada volume.
Tipos de storage compatíveis
O Kubernetes suporta múltiplos backends via CSI (Container Storage Interface), o padrão de plug-ins de storage:
| Backend | Tipo | Melhor para |
|---|---|---|
| NFS | Filesystem compartilhado | Múltiplos Pods lendo/escrevendo (RWX) |
| Ceph RBD | Block storage | Bancos de dados, alta performance (RWO) |
| Ceph CephFS | Filesystem distribuído | Acesso compartilhado com melhor performance que NFS |
| Longhorn | Block storage (nativo K8s) | Clusters menores, fácil de operar |
| AWS EBS | Block storage | EC2/EKS — alto desempenho |
| Local Path | Disco local do Node | Desenvolvimento, performance máxima com restrições |
RWO vs RWX: a distinção que importa
Os modos de acesso definem como um volume pode ser montado:
ReadWriteOnce (RWO): o volume pode ser montado como leitura e escrita por um único Node por vez. É o modo mais comum e mais performático para block storage. A maioria dos bancos de dados usa RWO — um Pod escreve, os outros Pods da mesma aplicação (se houver réplicas) precisam de volumes separados.
ReadWriteMany (RWX): o volume pode ser montado como leitura e escrita por múltiplos Nodes simultaneamente. Necessário quando múltiplos Pods em diferentes Nodes precisam escrever no mesmo volume — sistemas de CMS, upload de arquivos compartilhados, sistemas legados que precisam de filesystem compartilhado.
O ponto crítico: block storage (Ceph RBD, AWS EBS) não suporta RWX. Para RWX, você precisa de um filesystem distribuído — NFS, CephFS ou similar. E NFS tem menor performance que block storage.
Se sua aplicação precisa de RWX com alta performance, a arquitetura precisa ser revista: o ideal é centralizar a escrita em um único serviço (com RWO) e usar object storage (S3-compatible) para dados compartilhados entre Pods.
StatefulSets para workloads com estado
Para aplicações que precisam de identidade estável — um banco de dados com réplicas, um Kafka com brokers identificados, um Elasticsearch — o Kubernetes tem o StatefulSet.
A diferença em relação ao Deployment:
- Nome de Pod previsível:
mysql-0,mysql-1,mysql-2em vez de hashes aleatórios. Os Pods são criados e destruídos em ordem. - Volume dedicado por Pod: cada réplica tem seu próprio PVC, que persiste mesmo se o Pod for recriado. O
mysql-0sempre monta o mesmo volume, independentemente de em qual Node roda. - Ordem de inicialização garantida: o StatefulSet sobe os Pods em ordem —
mysql-0antes demysql-1. Importante para clusters onde um nó precisa ser o “mestre” antes dos outros entrarem.
Bancos de dados em Kubernetes: considerações práticas
Rodar bancos de dados em Kubernetes é possível e cada vez mais comum, mas exige atenção:
- Snapshots de volume: configure backups dos PVs regularmente. Uma snapshot CSI pode ser feita sem parar o banco.
- Resource limits: bancos precisam de limites de CPU e memória bem definidos para não afetar outros Pods no Node.
- Anti-affinity: réplicas de banco (primário e réplica) devem ser forçadas a rodar em Nodes diferentes para que a falha de um Node não derrube ambos.
- Storage I/O: para bancos de produção com alto I/O, prefira block storage (RBD, EBS) a NFS. A latência e throughput do NFS raramente são adequados para banco de dados de produção.
Precisa de storage persistente para Kubernetes em cloud privada no Brasil? A Adentro integra Ceph e NFS ao ambiente K8s com suporte local. Fale com um arquiteto.