Volumes, PV e PVC: persistência em k8s
2 min de leitura
Pod é efêmero. Pra ter disco que sobrevive ao Pod morrer, k8s
oferece 3 camadas: Volume (declaração no Pod), PersistentVolume
(o disco em si) e PersistentVolumeClaim (o pedido do app).
A diferença entre os três
Volume- mount dentro do Pod.emptyDir(some com o Pod),hostPath(pasta do node),configMap,secret. Tudo que já vimos em Docker.PersistentVolume(PV) - um recurso de storage provisionado no cluster. Pode ser um disco EBS na AWS, um NFS, um Ceph, um disco local. O cluster admin cria; o dev só pede.PersistentVolumeClaim(PVC) - o "pedido" do dev. "Preciso de 10 GB read-write-once." O k8s casa o pedido com um PV disponível e vincula.
Exemplo: Postgres com PVC dinâmico
# 1. StorageClass (geralmente já existe no cluster gerenciado)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gp3
provisioner: ebs.csi.aws.com
parameters:
type: gp3
# 2. O dev pede o disco
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-data
spec:
accessModes:
- ReadWriteOnce # RWO = montado em 1 node
storageClassName: gp3
resources:
requests:
storage: 20Gi
# 3. O Pod usa o PVC
apiVersion: apps/v1
kind: StatefulSet # StatefulSet, não Deployment
metadata:
name: postgres
spec:
serviceName: postgres
replicas: 1
template:
spec:
containers:
- name: postgres
image: postgres:16-alpine
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates: # cria 1 PVC por réplica automaticamente
- metadata:
name: data
spec:
accessModes: [ReadWriteOnce]
storageClassName: gp3
resources:
requests:
storage: 20Gi
Repare: StatefulSet em vez de Deployment. StatefulSet garante
identidade estável por réplica (postgres-0, postgres-1, ...) e
cria um PVC por réplica via volumeClaimTemplates. Pra banco, é
o controller certo.
Access Modes
ReadWriteOnce(RWO) - 1 node monta, vários Pods desse node leem/escrevem. Bom pra disco de block (EBS, GCP PD).ReadOnlyMany(ROX) - vários nodes montam read-only. Bom pra conteúdo estático distribuído.ReadWriteMany(RWX) - vários nodes montam read-write. Precisa de filesystem distribuído (NFS, CephFS, EFS). Caro.ReadWriteOncePod(RWOP) - 1 Pod específico monta. K8s 1.22+.
Bancos quase sempre usam RWO. Compartilhamento de arquivos entre vários Pods exige RWX.
Três conceitos que você acabou de aprender:
- PV = disco, PVC = pedido. O dev pede via PVC; o cluster provisiona (estático ou dinâmico) via PV.
- StorageClass permite provisionar PVs dinamicamente (sem o admin criar manualmente). Cluster gerenciado (EKS/GKE/AKS) já traz uma padrão.
- StatefulSet é o controller pra apps com estado. Garante identidade fixa por réplica e volume por réplica.
Dica:
kubectl get pvcmostra todos os PVCs e o status (Bound,Pending,Lost). Se ficarPendingmuito tempo, o cluster não tem PV disponível que case - chequekubectl describe pvc.
No próximo nó, vamos expor o cluster pro mundo com Ingress - o "reverse proxy" do k8s.