K8s em Exemplos: Volumes Persistentes

PersistentVolumes (PVs) são recursos de storage cluster-wide provisionados por admins ou dinamicamente. Eles abstraem o storage subjacente (discos cloud, NFS, local). Pods reclamam storage via PersistentVolumeClaims sem conhecer detalhes.

pv.yaml

PV define uma peça de storage no cluster. capacity especifica tamanho. accessModes controla como pode ser montado. persistentVolumeReclaimPolicy controla limpeza.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-data
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: standard
  hostPath:
    path: /data/pv-data
pv-access-modes.yaml

Access modes definem como volumes podem ser montados. RWO (ReadWriteOnce): único node leitura-escrita. ROX (ReadOnlyMany): múltiplos nodes somente leitura. RWX (ReadWriteMany): múltiplos nodes leitura-escrita. RWOP (ReadWriteOncePod, 1.22+): único Pod apenas. AWS EBS/Azure Disk: apenas RWO. NFS: RWO, ROX, RWX.

spec:
  accessModes:
    - ReadWriteOnce
pv-reclaim.yaml

Políticas de reclaim controlam o que acontece quando um PVC é deletado. Retain: PV permanece, dados preservados, limpeza manual necessária. Delete: PV e storage subjacente deletados automaticamente. Após deleção do PVC com Retain, status do PV muda para “Released”. Admin deve deletar PV ou remover claimRef para reusar.

spec:
  persistentVolumeReclaimPolicy: Retain
pv-cloud.yaml

Volumes de cloud provider usam fontes de volume específicas. Primeiro exemplo: AWS EBS. Segundo exemplo: GCE Persistent Disk. Terceiro exemplo: NFS. Para produção, use provisionamento dinâmico via StorageClass em vez de criar PVs manualmente.

spec:
  capacity:
    storage: 100Gi
  accessModes: [ReadWriteOnce]
  awsElasticBlockStore:
    volumeID: vol-0123456789abcdef0
    fsType: ext4
---
spec:
  gcePersistentDisk:
    pdName: my-disk
    fsType: ext4
---
spec:
  nfs:
    server: nfs-server.example.com
    path: /exports/data
pv-local.yaml

Node affinity restringe quais nodes podem acessar o PV. Necessário para volumes locais e alguns tipos de storage. O PV só pode ser usado por Pods agendados em nodes correspondentes.

spec:
  capacity:
    storage: 100Gi
  accessModes: [ReadWriteOnce]
  persistentVolumeReclaimPolicy: Delete
  storageClassName: local-storage
  local:
    path: /mnt/disks/ssd1
  nodeAffinity:
    required:
      nodeSelectorTerms:
        - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
                - node-1
pv-block.yaml

Modos de volume: Filesystem (padrão) monta como diretório. Block expõe dispositivo de bloco raw sem filesystem. Segundo exemplo mostra volume Block em Pod usando volumeDevices (não volumeMounts). Modo Block é para bancos de dados que gerenciam seu próprio formato de storage.

spec:
  volumeMode: Filesystem
  capacity:
    storage: 10Gi
---
spec:
  containers:
    - name: app
      volumeDevices:
        - name: data
          devicePath: /dev/xvda
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: block-pvc
terminal

Debug problemas de PV verificando status e eventos. Problemas comuns: access mode errado, mismatch de capacidade, mismatch de storage class, node affinity prevenindo binding.

$ kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS
pv-data   10Gi       RWO            Retain           Available
pv-db     50Gi       RWO            Delete           Bound

$ kubectl describe pv pv-data

$ kubectl patch pv pv-data -p '{"spec":{"claimRef":null}}'
persistentvolume/pv-data patched

$ kubectl get pv pv-data -o yaml | grep -A10 status
status:
  phase: Available

$ kubectl get pvc --all-namespaces | grep Pending
default   db-data   Pending   <none>

$ kubectl get storageclass
NAME                 PROVISIONER
standard (default)   ebs.csi.aws.com

Índice | GitHub | Use as setas do teclado para navegar |