Storage no Kubernetes – Revisão para a prova CKA

Quando comecei a estudar para a prova CKA (Certified Kubernetes Administrator), confesso que o tópico de storage eu sempre deixava para depois. Mas após passar alguns perrengues para resolver problemas com Volumes no k8s(Alô Kubecost!), percebi que dominar storage no K8s não é opcional – especialmente se você está se preparando para o CKA, onde representa 10% da prova. Neste artigo, vou revisar os três principais pontos que caem na prova: storage classes, tipos de volumes e persistent volumes.

volumes kubernetes

O Que é Storage no Kubernetes?

Antes de mergulharmos nos detalhes, é importante entender o básico. No Kubernetes, storage é o mecanismo que permite que os dados das aplicações persistam mesmo após a reinicialização de um pod. Isso é crucial para bancos de dados, sistemas de arquivos e qualquer aplicação que precise manter estado.

Na documentação oficial do k8s é possível obter detalhes de todos elementos que compõem a parte de Storage: https://kubernetes.io/docs/concepts/storage

O Kubernetes oferece várias formas de gerenciar storage, desde volumes temporários até volumes persistentes. E é aqui que entram os três tópicos principais que vamos revisar:

  1. Implementar Storage Classes e Dynamic Volume Provisioning
  2. Configurar Volume Types, Access Modes e Reclaim Policies
  3. Gerenciar Persistent Volumes e Persistent Volume Claims

Vamos começar pelo primeiro.


Implementando Storage Classes e Dynamic Volume Provisioning

Uma das coisas que mais me ajudou a entender storage classes foi pensar nelas como “templates” para provisionar volumes dinamicamente. Em vez de criar manualmente cada Persistent Volume (PV), você define uma StorageClass que o Kubernetes usa para provisionar volumes sob demanda quando um Persistent Volume Claim (PVC) é criado.

Por exemplo, imagine que você está usando um cluster na AWS. Você pode criar uma StorageClass no k8s para provisionar volumes EBS automaticamente:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: aws-ebs
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
reclaimPolicy: Delete
volumeBindingMode: Immediate

Aqui, o provisioner define o plugin de provisionamento (no caso, AWS EBS), e o reclaimPolicy define o que acontece com o volume quando o PVC é deletado (Delete ou Retain). O volumeBindingMode controla quando o volume é provisionado (Immediate ou WaitForFirstConsumer).

Dica para a prova: Saiba criar e aplicar uma StorageClass usando kubectl. Pratique também a criação de PVCs que referenciem uma StorageClass específica.

Dica extra

Outro ponto importante para saber sobre StorageClass

No k8s o StorageClass local-storage não suporta Dynamic Volume Provisioning porque ele usa o provisionador "kubernetes.io/no-provisioner". Esse provisionador indica que os volumes precisam ser criados manualmente pelo administrador, ao contrário de provisionadores como "kubernetes.io/aws-ebs" ou "kubernetes.io/gce-pd", que criam volumes dinamicamente quando um PVC é solicitado.

Isso significa que, se um PVC for criado referenciando local-storage, o Kubernetes não criará um novo PV automaticamente. O administrador deve garantir que os volumes já existam e estejam disponíveis para serem vinculados ao PVC.

Dynamic Volume Provisioning no Kubernetes

Primeiro, vamos entender por que precisamos dele. Em vez de criar manualmente cada PV (Persistent Volume), o dynamic provisioning permite que volumes sejam criados automaticamente quando um PVC é solicitado.

Vantagens do Provisionamento Dinâmico:
✔️ Reduz a necessidade de criar PVs manualmente.
✔️ Escala automaticamente conforme a demanda de armazenamento.
✔️ Suporta diferentes backends de armazenamento (AWS, GCP, Azure, etc.).

Aqui está um exemplo completo:

  1. Primeiro, criamos uma StorageClass que será responsável pelo provisionamento dinâmico:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-dynamic
provisioner: kubernetes.io/aws-ebs  # Mude conforme seu ambiente
parameters:
  type: gp2
  fsType: ext4
  encrypted: "true"
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer  # Importante para performance
  1. Agora, criamos um PVC que usará esta StorageClass:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: dynamicpvc
spec:
  storageClassName: fast-dynamic  # Referencia a StorageClass criada
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  1. Por fim, um Pod que usa este PVC:
apiVersion: v1
kind: Pod
metadata:
  name: dynamic-pod
spec:
  containers:
  - name: app
    image: nginx
    volumeMounts:
    - name: dynamic-storage
      mountPath: /data
  volumes:
  - name: dynamic-storage
    persistentVolumeClaim:
      claimName: dynamicpvc

Para verificar se está funcionando:

# Verifica a StorageClass
kubectl get sc fast-dynamic

# Verifica o PVC
kubectl get pvc dynamicpvc

# Verifica o PV criado dinamicamente
kubectl get pv

Pontos importantes que caem na prova CKA:

  1. A StorageClass precisa ter um provisioner válido para seu ambiente
  2. volumeBindingMode: WaitForFirstConsumer é uma best practice para otimizar recursos
  3. reclaimPolicy define o que acontece com o volume quando o PVC é deletado
  4. Os parameters variam conforme o provisioner usado

Em ambientes cloud, você pode ter diferentes StorageClasses para diferentes necessidades:

# StorageClass para alta performance
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: premium-dynamic
  annotations:
    storageclass.kubernetes.io/is-default-class: "false"
provisioner: kubernetes.io/aws-ebs
parameters:
  type: io1
  iopsPerGB: "50"
  encrypted: "true"
---
# StorageClass para uso geral
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard-dynamic
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
  encrypted: "true"

Para testar em um ambiente local como Minikube:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-dynamic
provisioner: k8s.io/minikube-hostpath
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer

Na prova CKA, é importante saber:

  • Como criar uma StorageClass para provisionamento dinâmico
  • Como definir uma StorageClass como default
  • Como verificar se o provisionamento dinâmico está funcionando
  • Como troubleshoot problemas comuns (verificar eventos, logs do provisioner)

Resumo – Funcionamento do Provisionamento Dinâmico

1️⃣ O PVC solicita um volume.
2️⃣ O Kubernetes verifica se há um PV manualmente disponível para essa solicitação.
3️⃣ Se não há um PV estático compatível, ele usa a StorageClass que cria o PV de forma dinâmica.
4️⃣ O Kubernetes cria automaticamente um PV no AWS EBS (ou outro provisionador configurado).
5️⃣ O volume é vinculado ao PVC e pode ser montado pelos Pods.


Configurando Volume Types, Access Modes e Reclaim Policies

Outro ponto importante é entender os tipos de volumes, modos de acesso e políticas de reclaim. Vamos falar de cada um:

Tipos de Volumes

Kubernetes suporta vários tipos de volumes, como:

  • AWS EBS: Para clusters na AWS.
  • NFS: Para sistemas de arquivos em rede.
  • HostPath: Usa um diretório do nó (não recomendado para produção).
  • EmptyDir: Volume temporário que dura enquanto o pod estiver ativo.

Modos de Acesso

Os modos de acesso definem como o volume pode ser montado:

  • ReadWriteOnce (RWO): Apenas um nó pode montar o volume para leitura e escrita.
  • ReadOnlyMany (ROX): Vários nós podem montar o volume apenas para leitura.
  • ReadWriteMany (RWX): Vários nós podem montar o volume para leitura e escrita.

Reclaim Policies

A política de reclaim define o que acontece com o volume quando o PVC é deletado:

  • Delete: O volume é removido.
  • Retain: O volume é mantido, mas precisa ser limpo manualmente.

Exemplo prático:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-example
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /mnt/data

Dica para a prova: Entenda as diferenças entre os modos de acesso e quando usar cada política de reclaim. Isso pode cair em questões teóricas ou práticas.


Gerenciando Persistent Volumes e Persistent Volume Claims

Persistent Volumes (PVs) e Persistent Volume Claims (PVCs) são o coração do sistema de storage no Kubernetes. Um PV é um recurso de armazenamento no cluster, enquanto um PVC é uma solicitação de armazenamento feita por um usuário.

Criando um PVC

Aqui está um exemplo de PVC que solicita 5Gi de armazenamento:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: aws-ebs

Quando você aplica esse PVC, o Kubernetes tenta encontrar um PV que corresponda aos requisitos ou provisiona um novo volume usando a StorageClass especificada.

Vinculando PVs e PVCs

Primeiramente, vamos criar o PV, considerando que não temos um Storage Class a ser utilizado e vamos gerenciar os Persistent Volumes manualmente:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-example
spec:
  storageClassName: manual
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/var/log/webapp"

Este manifesto cria um PV chamado pv-example com as seguintes características:

  • Armazena 10Gi de dados
  • Usa um caminho no host (/var/log/webapp) como backend de armazenamento
  • Apenas um Pod pode escrever ao mesmo tempo (ReadWriteOnce)
  • Associa-se à StorageClass manual, o que significa que não usa provisionamento dinâmico

Se você já tem um PV criado manualmente, pode vincular um PVC a ele usando o campo volumeName:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  volumeName: pv-example

Exemplo de Pod usando o PVC:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
    - name: my-container
      image: nginx
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: my-storage
  volumes:
    - name: my-storage
      persistentVolumeClaim:
        claimName: my-pvc

Dica para a prova: Pratique a criação de PVs e PVCs, e entenda como eles se relacionam. Saiba também como verificar o status de um PVC usando kubectl get pvc.


Exercício prático – Integrando todos os conceitos

Para fixar o conhecimento, recomendo criar um ambiente de laboratório e praticar os seguintes cenários:

  1. Crie uma StorageClass para provisionamento dinâmico.
  2. Crie um PVC que use essa StorageClass.
  3. Monte o PVC em um pod e verifique se o volume foi provisionado corretamente.
  4. Teste diferentes políticas de reclaim e modos de acesso.

Vou criar todos os manifestos necessários para um exercício prático completo de storage no Kubernetes. Vamos usar o Minikube como ambiente de laboratório.

  1. Primeiro, a StorageClass para provisionamento dinâmico:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: lab-storage
provisioner: k8s.io/minikube-hostpath
reclaimPolicy: Delete
volumeBindingMode: Immediate
  1. PVC usando a StorageClass:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: lab-pvc
spec:
  storageClassName: lab-storage
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  1. Pod que monta o volume:
apiVersion: v1
kind: Pod
metadata:
  name: lab-pod
spec:
  containers:
  - name: app
    image: nginx
    volumeMounts:
    - name: data-volume
      mountPath: "/data"
    command: ["/bin/sh", "-c"]
    args: ["while true; do echo $(date) >> /data/test.txt; sleep 5; done"]
  volumes:
  - name: data-volume
    persistentVolumeClaim:
      claimName: lab-pvc

Aplicando todos os manifestos e validando o estado dos recursos:

k8s storageclass
  1. Para testar diferentes políticas de reclaim, aqui está uma StorageClass com Retain:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: lab-storage-retain
provisioner: k8s.io/minikube-hostpath
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
  1. PVC com modo de acesso ReadOnlyMany:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: lab-pvc-rom
spec:
  storageClassName: lab-storage
  accessModes:
    - ReadOnlyMany
  resources:
    requests:
      storage: 1Gi
  1. Deployment para testar múltiplos pods lendo o mesmo volume:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: lab-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: lab-app
  template:
    metadata:
      labels:
        app: lab-app
    spec:
      containers:
      - name: app
        image: nginx
        volumeMounts:
        - name: shared-data
          mountPath: "/data"
          readOnly: true
      volumes:
      - name: shared-data
        persistentVolumeClaim:
          claimName: lab-pvc-rom

Comandos para testar e verificar:

# Criar recursos
kubectl apply -f storage-class.yaml
kubectl apply -f pvc.yaml
kubectl apply -f pod.yaml

# Verificar status
kubectl get sc
kubectl get pvc
kubectl get pv
kubectl get pods

# Verificar se o volume está funcionando
kubectl exec lab-pod -- ls /data
kubectl exec lab-pod -- cat /data/test.txt

# Testar diferentes políticas
kubectl delete pod lab-pod
kubectl delete pvc lab-pvc
kubectl get pv  # Se reclaimPolicy=Retain, o PV permanecerá

# Testar modo ReadOnlyMany
kubectl apply -f deployment.yaml
kubectl get pods
kubectl describe pods  # Verificar se os volumes montaram corretamente

Exercícios adicionais que você pode fazer:

  1. Tente criar um PVC com tamanho maior que o disponível e observe o comportamento
  2. Delete um PVC com reclaimPolicy=Retain e veja o que acontece com o PV
  3. Tente montar um volume ReadWriteOnce em múltiplos pods e observe o resultado
  4. Crie um pod com volume ReadOnlyMany e tente escrever nele

Dominar o tópico de storage no Kubernetes é essencial não apenas para a prova CKA, mas também para o dia a dia de um administrador de clusters. Revisamos os principais conceitos, como storage classes, tipos de volumes, modos de acesso e persistent volumes, além de práticas que vão te ajudar a se preparar para a prova.


Siga revisando os conteúdos para a prova CKA, veja o post abaixo sobre o tópico prova CKA para o item “Monitor cluster and application resource usage“:

Compartilhe / Share
Fernando Müller Junior
Fernando Müller Junior

Eu sou o Fernando Müller, um Tech Lead SRE com 16 anos de experiência em TI, atualmente eu trabalho na Appmax, uma fintech localizada no Brasil. Apaixonado por trabalhar com arquiteturas e aplicações Cloud Native, ferramentas Open Source e tudo que existe no mundo SRE, sempre procurando se desenvolver e aprender constantemente(Lifelong learning), atuando em projetos inovadores!

Artigos: 47

Receba as notícias por email / Receive news by email

Insira seu endereço de e-mail abaixo e assine nossa newsletter / Enter your email address below and subscribe to our newsletter

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *