Ir para o conteúdo principal

persistentvolumeclaim.yml

Descrição: este arquivo cria um PersistentVolumeClaim no Kubernetes.

Um PersistentVolumeClaim, também chamado de PVC, é usado para solicitar armazenamento persistente dentro de um namespace.

Ele não é o disco em si. O PVC é o pedido de armazenamento. O volume real pode ser criado dinamicamente por uma StorageClass ou já existir como um PersistentVolume.

Em termos simples:

Pod
  ↓ monta
PersistentVolumeClaim
  ↓ reivindica
PersistentVolume
  ↓ representa
armazenamento real

No arquivo de referência do cluster, o recurso aparece como:

Recurso: persistentvolumeclaims
Tipo: PersistentVolumeClaim
Versão: v1

TIPO:       PersistentVolumeClaim
VERSÃO:    v1

DESCRIÇÃO:
    PersistentVolumeClaim é a solicitação de um usuário e a reivindicação de uso de um
    volume persistente.

Quando usar PersistentVolumeClaim

Use PersistentVolumeClaim quando uma aplicação precisa de dados que devem continuar existindo mesmo se o Pod for removido, recriado ou reagendado para outro nó.

Use PVC quando precisa persistir:

  • uploads de usuários;
  • arquivos de aplicação;
  • dados de banco;
  • índice de busca;
  • cache que precisa sobreviver ao Pod;
  • diretório de trabalho persistente;
  • biblioteca de arquivos;
  • dados de sistema interno;
  • conteúdo gerado pela aplicação;
  • diretório usado por ferramenta administrativa;
  • armazenamento solicitado por um StatefulSet;
  • volume usado por um Deployment;
  • volume usado por um Job.

Exemplos comuns:

  • banco PostgreSQL em ambiente de teste;
  • banco MariaDB em ambiente de laboratório;
  • aplicação que salva arquivos enviados por usuários;
  • sistema web com diretório de uploads;
  • ferramenta interna que guarda configuração persistente;
  • aplicação de pesquisa que grava resultados;
  • serviço que precisa manter dados após atualização;
  • ambiente de homologação que precisa preservar arquivos entre rollouts.

Quando PersistentVolumeClaim não é o recurso indicado

PersistentVolumeClaim não é o melhor recurso quando o problema exige outro tipo de controle.

Necessidade Recurso mais indicado Motivo
Executar aplicação Deployment, StatefulSet, Job ou CronJob PVC apenas solicita armazenamento.
Criar o volume físico manualmente PersistentVolume PV representa o volume real disponível no cluster.
Definir classe/provisionador de armazenamento StorageClass StorageClass descreve como volumes são provisionados.
Guardar configuração pequena ConfigMap ConfigMap é próprio para configuração não sensível.
Guardar senha/token/certificado Secret Secret é próprio para dados sensíveis.
Criar armazenamento temporário do Pod emptyDir emptyDir existe apenas durante a vida do Pod.
Compartilhar configuração como arquivo ConfigMap montado como volume PVC não é necessário para configuração simples.
Publicar aplicação na rede Service ou Ingress PVC não expõe aplicação.
Isolar tráfego NetworkPolicy PVC não controla rede.
Controlar CPU/memória ResourceQuota, LimitRange ou resources PVC controla pedido de armazenamento, não CPU/memória.
Banco com identidade fixa por réplica StatefulSet + volumeClaimTemplates StatefulSet cria PVC por réplica de forma controlada.

Uso em cenário de universidade

Em uma universidade, um PersistentVolumeClaim pode ser usado para fornecer armazenamento persistente a sistemas acadêmicos, administrativos, laboratoriais e de pesquisa.

Exemplos:

  • diretório de uploads de um sistema administrativo;
  • dados persistentes de aplicação de laboratório;
  • banco de dados de homologação;
  • arquivos gerados por projeto de pesquisa;
  • armazenamento de ferramenta interna;
  • volume de trabalho para aplicação de disciplina;
  • diretório de dados de serviço usado por alunos;
  • armazenamento persistente de ambiente de teste;
  • volume para aplicação que precisa preservar estado entre atualizações.

Uso recomendado em ambiente universitário:

  • um Namespace por projeto, sistema, disciplina, laboratório ou ambiente;
  • um PersistentVolumeClaim por necessidade de armazenamento;
  • StorageClass definida conforme a política de armazenamento do cluster;
  • ResourceQuota limitando quantidade e tamanho de PVCs por namespace;
  • LimitRange quando houver política padrão de requests;
  • Deployment ou StatefulSet montando o PVC;
  • Backup ou política externa de cópia quando os dados forem importantes;
  • evitar usar PVC para dados temporários simples;
  • evitar usar PVC para senha ou configuração pequena;
  • documentar finalidade do PVC em labels/annotations;
  • cuidado ao apagar PVC, pois isso pode apagar ou liberar dados persistentes dependendo da política do volume.

Exemplo completo: persistentvolumeclaim.yml

apiVersion: v1
kind: PersistentVolumeClaim

metadata:
  name: minha-aplicacao-dados
  namespace: meu-projeto
  labels:
    app: minha-aplicacao
    ambiente: homologacao
    componente: armazenamento
  annotations:
    descricao: "PVC exemplo para dados persistentes da aplicação"

spec:
  accessModes:
    - ReadWriteOnce

  storageClassName: standard

  volumeMode: Filesystem

  resources:
    requests:
      storage: 10Gi

  selector:
    matchLabels:
      tipo: dados

  volumeName: ""

  dataSource: null

  dataSourceRef: null

Explicação linha por linha

apiVersion: v1

Define a versão da API usada pelo manifesto.

Para PersistentVolumeClaim, normalmente é:

apiVersion: v1

Significado:

  • v1: versão estável da API core do Kubernetes.

Use exatamente v1 para PersistentVolumeClaim.


kind: PersistentVolumeClaim

Define o tipo de recurso que será criado.

kind: PersistentVolumeClaim

Significado:

  • PersistentVolumeClaim: recurso que solicita armazenamento persistente.

Não confundir com:

  • PersistentVolume: volume real disponível ou provisionado no cluster;
  • StorageClass: classe/provisionador de armazenamento;
  • VolumeSnapshot: snapshot de volume;
  • ConfigMap: configuração não sensível;
  • Secret: dado sensível;
  • emptyDir: volume temporário do Pod.

metadata

metadata identifica e organiza o PVC.

metadata:
  name: minha-aplicacao-dados
  namespace: meu-projeto
  labels:
    app: minha-aplicacao
  annotations:
    descricao: "PVC exemplo"

metadata.name

Nome do PVC.

name: minha-aplicacao-dados

Uso:

  • identifica o PVC dentro do namespace;
  • aparece em kubectl get pvc;
  • é referenciado por Pods, Deployments, StatefulSets e Jobs;
  • deve ser único dentro do namespace.

Exemplos bons:

name: app-web-dados
name: banco-postgres-dados
name: uploads-sistema
name: laboratorio-resultados

Regras práticas:

  • use letras minúsculas;
  • use hífen;
  • evite acentos;
  • evite espaços;
  • escolha nome curto e claro;
  • use sufixos como -dados, -uploads, -cache ou -data quando fizer sentido.

metadata.namespace

Namespace onde o PVC será criado.

namespace: meu-projeto

Uso:

  • separa armazenamento por projeto;
  • evita mistura entre ambientes;
  • permite PVCs com o mesmo nome em namespaces diferentes;
  • define onde o Pod poderá referenciar o PVC.

Regra importante:

  • o Pod que monta o PVC precisa estar no mesmo namespace do PVC.

Se omitir:

  • Kubernetes usa o namespace atual do contexto;
  • isso pode criar o PVC no namespace errado.

Recomendação:

  • sempre declarar namespace.

metadata.labels

Labels são pares chave/valor usados para organização e filtros.

labels:
  app: minha-aplicacao
  ambiente: homologacao
  componente: armazenamento

Uso:

  • filtrar PVCs com kubectl;
  • organizar recursos;
  • permitir automações;
  • associar o PVC a uma aplicação;
  • ajudar GitOps, inventário e observabilidade.

Exemplo:

kubectl get pvc -l app=minha-aplicacao -n meu-projeto

metadata.annotations

Annotations são metadados livres.

annotations:
  descricao: "PVC da aplicação"

Uso:

  • documentação;
  • rastreabilidade;
  • integração com ferramentas;
  • automações;
  • registrar finalidade do volume.

Cuidado:

  • não coloque senha, token ou chave em annotation;
  • annotations também ficam armazenadas no objeto Kubernetes.

Campos de metadata normalmente gerenciados pelo Kubernetes

O kubectl explain mostra vários campos de metadata, mas muitos são preenchidos pelo próprio cluster.

Normalmente você não escreve manualmente:

creationTimestamp:
deletionTimestamp:
resourceVersion:
uid:
generation:
managedFields:
selfLink:
ownerReferences:

Eles servem para controle interno do Kubernetes.


spec

spec descreve o armazenamento desejado pelo PVC.

spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: standard
  volumeMode: Filesystem
  resources:
    requests:
      storage: 10Gi

Campos principais:

spec:
  accessModes
  dataSource
  dataSourceRef
  resources
  selector
  storageClassName
  volumeAttributesClassName
  volumeMode
  volumeName

spec.accessModes

Define como o volume pode ser montado.

accessModes:
  - ReadWriteOnce

Valores comuns:

ReadWriteOnce
ReadOnlyMany
ReadWriteMany
ReadWriteOncePod

A disponibilidade real depende do tipo de storage e do provisionador usado pelo cluster.


ReadWriteOnce

accessModes:
  - ReadWriteOnce

Também chamado de RWO.

Significado:

  • o volume pode ser montado como leitura/escrita por um único nó.

Uso comum:

  • banco de dados simples;
  • aplicação com uma réplica;
  • volume usado por um Pod por vez;
  • storage comum em muitos clusters.

Cuidado:

  • não significa necessariamente um único Pod;
  • significa restrição de montagem por nó;
  • para múltiplas réplicas em nós diferentes, normalmente não é adequado.

ReadOnlyMany

accessModes:
  - ReadOnlyMany

Também chamado de ROX.

Significado:

  • o volume pode ser montado como somente leitura por muitos nós.

Uso:

  • arquivos compartilhados somente leitura;
  • conteúdo estático;
  • datasets de referência.

ReadWriteMany

accessModes:
  - ReadWriteMany

Também chamado de RWX.

Significado:

  • o volume pode ser montado como leitura/escrita por muitos nós.

Uso:

  • armazenamento compartilhado;
  • múltiplas réplicas escrevendo/lendo;
  • workloads que precisam compartilhar arquivos.

Cuidado:

  • depende de storage compatível;
  • nem toda StorageClass suporta RWX;
  • concorrência de escrita precisa ser tratada pela aplicação.

ReadWriteOncePod

accessModes:
  - ReadWriteOncePod

Também chamado de RWOP.

Significado:

  • o volume pode ser montado como leitura/escrita por um único Pod.

Uso:

  • garantir que apenas um Pod use aquele PVC;
  • workloads que exigem exclusividade mais forte;
  • aplicações sensíveis a múltiplos montadores.

Cuidado:

  • depende de suporte do cluster e do driver CSI;
  • não é substituto para desenho correto de aplicação com estado.

spec.resources

Define recursos solicitados pelo PVC.

resources:
  requests:
    storage: 10Gi

Campos:

requests
limits

spec.resources.requests.storage

Define o tamanho de armazenamento solicitado.

resources:
  requests:
    storage: 10Gi

Este é o campo mais importante do PVC.

Exemplos:

storage: 1Gi
storage: 10Gi
storage: 100Gi
storage: 1Ti

Uso:

  • pedir tamanho mínimo necessário;
  • permitir provisionamento dinâmico;
  • permitir binding com um PV existente.

Cuidado:

  • pedir mais storage do que necessário consome quota;
  • pedir menos pode causar falta de espaço;
  • aumento de PVC depende da StorageClass e do suporte do driver.

spec.resources.limits

Campo de limite dentro de VolumeResourceRequirements.

resources:
  limits:
    storage: 20Gi

Uso:

  • não é comum em PVCs simples;
  • depende de suporte e interpretação do provisionador/cluster.

Na prática, o campo mais usado é:

requests:
  storage: 10Gi

spec.storageClassName

Define qual StorageClass será usada.

storageClassName: standard

Uso:

  • escolher tipo de armazenamento;
  • usar provisionamento dinâmico;
  • selecionar políticas de performance, replicação, backup ou retenção definidas pelo administrador.

Exemplos possíveis:

storageClassName: standard
storageClassName: fast
storageClassName: nfs
storageClassName: longhorn
storageClassName: local-path

O nome real depende do cluster.

Verificar classes disponíveis:

kubectl get storageclass

storageClassName omitido

Se storageClassName for omitido, o Kubernetes pode usar a StorageClass padrão, se existir.

spec:
  resources:
    requests:
      storage: 10Gi

Cuidado:

  • se não existir StorageClass padrão, o PVC pode ficar Pending;
  • o comportamento depende da configuração do cluster.

storageClassName: ""

Define explicitamente que o PVC não deve usar StorageClass.

storageClassName: ""

Uso:

  • binding manual com PersistentVolume sem StorageClass;
  • ambientes com PVs criados manualmente.

Cuidado:

  • não é o mesmo que omitir storageClassName;
  • se não houver PV compatível, o PVC fica Pending.

spec.volumeMode

Define se o volume será usado como filesystem ou bloco.

volumeMode: Filesystem

Valores aceitos:

volumeMode: Filesystem
volumeMode: Block

Filesystem

volumeMode: Filesystem

Uso:

  • modo padrão e mais comum;
  • monta o volume como diretório;
  • aplicações acessam arquivos normalmente.

Exemplo no Pod:

volumeMounts:
  - name: dados
    mountPath: /dados

Block

volumeMode: Block

Uso:

  • expõe volume como dispositivo de bloco;
  • aplicações que precisam acessar dispositivo diretamente;
  • bancos ou sistemas específicos que suportam bloco bruto.

Exemplo no Pod:

volumeDevices:
  - name: dados
    devicePath: /dev/xvda

Cuidado:

  • é mais avançado;
  • normalmente aplicações comuns usam Filesystem.

spec.selector

Seleciona um PersistentVolume existente por labels.

selector:
  matchLabels:
    tipo: dados

Uso:

  • binding manual com PV específico;
  • selecionar PVs que tenham labels compatíveis;
  • ambientes onde volumes são criados previamente.

Campos:

matchLabels
matchExpressions

Cuidado:

  • não é necessário em provisionamento dinâmico comum;
  • selector pode impedir binding se não houver PV compatível.

spec.selector.matchLabels

Seleção simples por labels.

selector:
  matchLabels:
    tipo: dados

Equivale a:

selecione PV com label tipo=dados

spec.selector.matchExpressions

Seleção avançada.

selector:
  matchExpressions:
    - key: ambiente
      operator: In
      values:
        - homologacao
        - producao

Campos:

Campo Função
key chave da label
operator operador
values valores aceitos

Operadores comuns:

In
NotIn
Exists
DoesNotExist

spec.volumeName

Força o PVC a reivindicar um PersistentVolume específico.

volumeName: pv-dados-01

Uso:

  • binding manual;
  • volume já criado pelo administrador;
  • recuperação de volume específico.

Cuidado:

  • o PV precisa existir;
  • o PV precisa ser compatível com o PVC;
  • se não houver compatibilidade, o PVC não faz bind;
  • não use em provisionamento dinâmico comum.

spec.dataSource

Define uma origem de dados para criar o volume.

dataSource:
  kind: PersistentVolumeClaim
  name: pvc-origem

Uso:

  • clonar PVC existente;
  • criar volume a partir de snapshot, quando suportado;
  • provisionamento com origem de dados.

Campos:

Campo Função
apiGroup grupo da API da origem
kind tipo da origem
name nome da origem

Exemplo de clone de PVC:

dataSource:
  kind: PersistentVolumeClaim
  name: pvc-origem

Cuidado:

  • depende de suporte do provisionador/driver;
  • origem e destino normalmente precisam obedecer regras do recurso usado;
  • para clone de PVC, a origem precisa estar no mesmo namespace em cenários comuns.

spec.dataSourceRef

Define referência de origem de dados mais flexível.

dataSourceRef:
  apiGroup: snapshot.storage.k8s.io
  kind: VolumeSnapshot
  name: snapshot-dados

Uso:

  • referência a origem de dados;
  • recursos de snapshot;
  • recursos customizados compatíveis;
  • casos onde é necessário informar namespace, quando suportado.

Campos:

Campo Função
apiGroup grupo da API
kind tipo do recurso
name nome do recurso
namespace namespace da origem, quando aplicável e suportado

Cuidado:

  • depende de suporte do cluster;
  • depende de CSI/provisionador;
  • para uso comum de PVC simples, pode ser omitido.

spec.volumeAttributesClassName

Define a classe de atributos de volume.

volumeAttributesClassName: fast-attributes

Uso:

  • alterar ou selecionar atributos de volume quando suportado;
  • integração com VolumeAttributesClass;
  • cenários com CSI e suporte a modificação de atributos de volume.

Cuidado:

  • depende da versão do Kubernetes e do suporte do driver CSI;
  • não é necessário para PVC comum;
  • use somente quando a infraestrutura do cluster fornecer essa funcionalidade.

status

status mostra o estado atual do PVC.

Você normalmente não escreve status no YAML.

O Kubernetes e os controladores de storage preenchem automaticamente.

No arquivo de referência aparecem campos como:

status:
  accessModes
  allocatedResourceStatuses
  allocatedResources
  capacity
  conditions
  currentVolumeAttributesClassName
  modifyVolumeStatus
  phase

Use para diagnóstico:

kubectl get pvc minha-aplicacao-dados -n meu-projeto -o yaml
kubectl describe pvc minha-aplicacao-dados -n meu-projeto

status.phase

Mostra a fase atual do PVC.

Valores possíveis:

Pending
Bound
Lost

Pending

O PVC ainda não foi vinculado a um PersistentVolume.

Causas comuns:

  • não existe StorageClass padrão;
  • storageClassName incorreto;
  • não existe PV compatível;
  • provisionador de storage não criou o volume;
  • selector restritivo;
  • quota de storage excedida.

Bound

O PVC foi vinculado a um PV.

Este é o estado esperado para uso normal.

Lost

O PVC estava vinculado, mas perdeu o volume.

Pode indicar problema sério com o PV ou storage.


status.capacity

Mostra a capacidade do volume vinculado.

capacity:
  storage: 10Gi

Uso:

  • confirmar tamanho real vinculado;
  • verificar se o PVC recebeu o tamanho solicitado.

status.accessModes

Mostra os modos de acesso efetivos do PVC.

accessModes:
  - ReadWriteOnce

Uso:

  • confirmar modo de acesso vinculado;
  • diagnosticar incompatibilidade com Pods e PVs.

status.conditions

Lista condições observadas no PVC.

conditions:
  lastProbeTime
  lastTransitionTime
  message
  reason
  status
  type

Uso:

  • diagnóstico;
  • expansão de volume;
  • problemas de binding;
  • mensagens do controlador de storage.

status.allocatedResources

Mostra recursos alocados ao PVC.

allocatedResources:
  storage: 20Gi

Uso:

  • acompanhar expansão;
  • verificar recurso alocado pelo controlador.

status.modifyVolumeStatus

Mostra status de modificação de atributos do volume.

modifyVolumeStatus:
  status
  targetVolumeAttributesClassName

Valores de status:

Pending
InProgress
Infeasible

Uso:

  • diagnóstico de alteração de atributos de volume;
  • integração com VolumeAttributesClass.

Manifesto mínimo funcional

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: dados
  namespace: meu-projeto
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

Aplicar:

kubectl apply -f persistentvolumeclaim.yml

Verificar:

kubectl get pvc -n meu-projeto
kubectl describe pvc dados -n meu-projeto

Manifesto recomendado para aplicação web simples

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-web-dados
  namespace: meu-projeto
  labels:
    app: app-web
    componente: armazenamento
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: standard
  volumeMode: Filesystem
  resources:
    requests:
      storage: 10Gi

Este modelo é adequado para uma aplicação web/API com uma réplica que precisa persistir arquivos.


Manifesto para armazenamento compartilhado

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: arquivos-compartilhados
  namespace: meu-projeto
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: nfs
  volumeMode: Filesystem
  resources:
    requests:
      storage: 50Gi

Uso:

  • compartilhamento entre múltiplos Pods;
  • dados acessados por mais de uma réplica;
  • storage compatível com RWX.

Cuidado:

  • depende da StorageClass suportar ReadWriteMany.

Manifesto para volume de bloco

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: bloco-dados
  namespace: meu-projeto
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: bloco
  volumeMode: Block
  resources:
    requests:
      storage: 20Gi

Uso:

  • aplicações que precisam de dispositivo de bloco;
  • cenários específicos de banco ou storage.

Cuidado:

  • no Pod, o consumo usa volumeDevices, não volumeMounts.

Manifesto usando StorageClass padrão

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: dados-padrao
  namespace: meu-projeto
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi

Neste caso, storageClassName foi omitido.

Uso:

  • usar StorageClass padrão do cluster, se existir.

Verificar padrão:

kubectl get storageclass

A StorageClass padrão geralmente aparece marcada como:

(default)

Manifesto sem StorageClass

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: dados-manual
  namespace: meu-projeto
spec:
  storageClassName: ""
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

Uso:

  • binding manual com PersistentVolume sem StorageClass;
  • ambientes onde o administrador criou PVs manualmente.

Cuidado:

  • se não houver PV compatível, o PVC ficará Pending.

Manifesto com clone de PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: clone-dados
  namespace: meu-projeto
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: standard
  resources:
    requests:
      storage: 10Gi
  dataSource:
    kind: PersistentVolumeClaim
    name: dados-origem

Uso:

  • criar novo PVC a partir de outro PVC;
  • clonar dados para teste ou homologação.

Cuidado:

  • depende de suporte do driver CSI/provisionador;
  • a origem precisa atender às regras de clone do cluster;
  • volumeMode da origem e do destino precisam ser compatíveis.

Exemplo de Pod montando PVC como filesystem

apiVersion: v1
kind: Pod
metadata:
  name: app-com-pvc
  namespace: meu-projeto
spec:
  containers:
    - name: app
      image: nginx:1.27
      volumeMounts:
        - name: dados
          mountPath: /usr/share/nginx/html
  volumes:
    - name: dados
      persistentVolumeClaim:
        claimName: app-web-dados

Exemplo de Pod usando PVC como bloco

apiVersion: v1
kind: Pod
metadata:
  name: app-com-bloco
  namespace: meu-projeto
spec:
  containers:
    - name: app
      image: busybox:1.36
      command:
        - sh
        - -c
      args:
        - "sleep 3600"
      volumeDevices:
        - name: dados
          devicePath: /dev/xvda
  volumes:
    - name: dados
      persistentVolumeClaim:
        claimName: bloco-dados

Exemplo de Deployment montando PVC

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-web
  namespace: meu-projeto
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-web
  template:
    metadata:
      labels:
        app: app-web
    spec:
      containers:
        - name: app
          image: registry.exemplo.local/projeto/app-web:1.0.0
          volumeMounts:
            - name: dados
              mountPath: /app/dados
      volumes:
        - name: dados
          persistentVolumeClaim:
            claimName: app-web-dados

Cuidado:

  • se usar ReadWriteOnce, avalie o número de réplicas e a capacidade do storage;
  • para múltiplas réplicas escrevendo no mesmo volume, normalmente é necessário ReadWriteMany e aplicação compatível.

Comandos úteis

Aplicar

kubectl apply -f persistentvolumeclaim.yml

Ver PVCs

kubectl get pvc -n meu-projeto

Ver PVC específico

kubectl get pvc app-web-dados -n meu-projeto

Ver detalhes

kubectl describe pvc app-web-dados -n meu-projeto

Ver YAML real aplicado

kubectl get pvc app-web-dados -n meu-projeto -o yaml

Ver StorageClasses

kubectl get storageclass

Ver PersistentVolumes

kubectl get pv

Ver eventos do namespace

kubectl get events -n meu-projeto --sort-by=.lastTimestamp

Ver Pods que montam PVC

kubectl get pods -n meu-projeto -o wide

Procurar PVC no YAML dos Pods

kubectl get pods -n meu-projeto -o yaml | grep -A5 -B5 claimName

Expandir PVC

kubectl patch pvc app-web-dados \
  -n meu-projeto \
  -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'

Cuidado:

  • expansão depende da StorageClass e do driver;
  • reduzir tamanho de PVC normalmente não é suportado.

Apagar PVC

kubectl delete pvc app-web-dados -n meu-projeto

Cuidado:

Apagar um PVC pode remover, liberar ou preservar o volume real, dependendo da política de reclaim do PersistentVolume/StorageClass.

Relação com outros manifestos

Um PVC normalmente faz parte de um conjunto de manifestos.

Uso típico:

Namespace
  ├── PersistentVolumeClaim
  ├── ConfigMap
  ├── Secret
  ├── Deployment
  │   └── Pod monta PVC
  ├── Service
  ├── Ingress
  ├── ResourceQuota
  └── LimitRange

PVC + Pod

Pod monta o PVC como volume.

PVC + Deployment

Deployment cria Pods que montam o PVC.

PVC + StatefulSet

StatefulSet normalmente cria PVCs por réplica usando volumeClaimTemplates.

PVC + PersistentVolume

PVC reivindica um PV compatível.

PVC + StorageClass

StorageClass pode provisionar dinamicamente um PV para atender ao PVC.

PVC + ResourceQuota

ResourceQuota pode limitar quantidade e tamanho total de PVCs no namespace.

PVC + VolumeSnapshot

PVC pode ser origem ou destino de operações de snapshot, quando o cluster suporta.


Erros comuns

PVC preso em Pending

Sintoma:

kubectl get pvc -n meu-projeto

Mostra:

Pending

Possíveis causas:

  • não existe StorageClass padrão;
  • storageClassName errado;
  • provisionador de storage não está funcionando;
  • não existe PV compatível;
  • selector restritivo;
  • quota de storage excedida;
  • accessMode não suportado pela StorageClass.

Verificar:

kubectl describe pvc app-web-dados -n meu-projeto
kubectl get storageclass
kubectl get pv
kubectl get events -n meu-projeto --sort-by=.lastTimestamp

StorageClass inexistente

Errado:

storageClassName: fast

Mas não existe StorageClass chamada fast.

Verificar:

kubectl get storageclass

Corrigir:

storageClassName: nome-existente

Usar ReadWriteMany sem suporte

Errado assumir que todo storage suporta:

accessModes:
  - ReadWriteMany

Se a StorageClass não suportar RWX, o PVC pode ficar Pending.

Verificar documentação do storage/provisionador usado no cluster.


Montar PVC no namespace errado

PVC e Pod precisam estar no mesmo namespace.

Verificar:

kubectl get pvc -A | grep app-web-dados
kubectl get pod -A | grep app-web

Correção:

  • criar PVC no mesmo namespace do Pod;
  • ou corrigir metadata.namespace.

Deployment com várias réplicas usando PVC RWO sem entender o storage

Exemplo problemático:

replicas: 3

Com PVC:

accessModes:
  - ReadWriteOnce

Cuidado:

  • dependendo do storage e dos nós, múltiplas réplicas podem não conseguir montar o mesmo volume;
  • para múltiplas réplicas escrevendo no mesmo volume, normalmente use storage RWX e aplicação preparada;
  • para banco ou estado por réplica, use StatefulSet com PVC por réplica.

Apagar PVC achando que os dados sempre ficam

A retenção dos dados depende da política de reclaim do PV/StorageClass.

Possibilidades:

Delete
Retain
Recycle

Na prática moderna, os mais comuns são:

Delete
Retain

Cuidado:

  • Delete pode apagar o volume real;
  • Retain pode preservar o volume, mas exigir limpeza manual.

Tentar reduzir tamanho do PVC

Aumentar PVC pode ser suportado.

Reduzir PVC normalmente não é suportado.

Errado:

storage: 5Gi

quando antes era:

storage: 10Gi

Caminho comum:

  • criar novo PVC menor;
  • copiar dados;
  • trocar montagem;
  • remover PVC antigo depois de validar.

Usar PVC para dado temporário simples

Se o dado não precisa sobreviver à remoção do Pod, talvez seja melhor:

emptyDir

em vez de PVC.


Usar PVC para configuração pequena

Se a necessidade é apenas configuração, use:

ConfigMap

Para segredo, use:

Secret

Checklist para uso em produção

Antes de aplicar um PVC em ambiente compartilhado:

  • namespace definido;
  • name claro;
  • labels claras;
  • finalidade do PVC documentada;
  • tamanho solicitado é adequado;
  • accessModes compatível com a aplicação;
  • storageClassName existe;
  • StorageClass suporta o modo de acesso desejado;
  • volumeMode correto;
  • quota do namespace permite o PVC;
  • Pod/Deployment monta o PVC no mesmo namespace;
  • aplicação está preparada para persistência;
  • múltiplas réplicas foram avaliadas;
  • backup foi planejado se os dados forem importantes;
  • política de reclaim é conhecida;
  • expansão de volume foi avaliada;
  • exclusão do PVC não causará perda inesperada;
  • PVC não está sendo usado para senha/configuração pequena;
  • StatefulSet foi considerado para aplicações com estado por réplica.

Resumo

Use PersistentVolumeClaim para solicitar armazenamento persistente no Kubernetes.

O PVC controla:

  • pedido de armazenamento;
  • tamanho solicitado;
  • modo de acesso;
  • classe de armazenamento;
  • modo de volume;
  • seleção ou binding com PersistentVolume;
  • origem de dados para clone/snapshot quando suportado;
  • estado de binding com o volume.

O PVC não é:

  • a aplicação;
  • o Pod;
  • o disco físico em si;
  • a StorageClass;
  • backup automático;
  • garantia de múltiplas réplicas escrevendo corretamente;
  • substituto de ConfigMap ou Secret.

Para aplicação web comum com arquivos persistentes, o conjunto mínimo geralmente é:

Namespace + PersistentVolumeClaim + Deployment + Service + Ingress

Para ambiente institucional compartilhado, o conjunto recomendado é:

Namespace + ResourceQuota + LimitRange + ServiceAccount + Role/RoleBinding
+ ConfigMap + Secret + PersistentVolumeClaim + Deployment + Service + Ingress
+ NetworkPolicy + PDB