Utilizar Volumes Efêmeros e Persistentes em Pods

KubernetesBeginner
Pratique Agora

Introdução

Os containers possuem sistemas de arquivos graváveis, mas esse armazenamento está vinculado ao próprio container. Os volumes do Kubernetes oferecem aos Pods uma maneira mais clara de gerenciar arquivos. Alguns volumes são efêmeros e destinados a dados temporários dentro de um único Pod. Outros volumes são persistentes e podem manter os dados disponíveis mesmo quando um Pod é excluído e recriado.

Neste laboratório, você utilizará um volume emptyDir para dados temporários locais do Pod e, em seguida, criará um PersistentVolumeClaim (PVC) e o montará em dois Pods diferentes para comprovar que os dados sobrevivem à substituição do Pod.

Preparar um Namespace para Prática de Volumes

Nesta etapa, você preparará um namespace limpo e confirmará que o cluster possui os recursos de armazenamento necessários para este laboratório.

Comece em /home/labex/project. Você escreverá os manifestos de Pod e PVC neste diretório.

mkdir -p /home/labex/project
cd /home/labex/project

Verifique se o servidor da API do Kubernetes está acessível. Se a VM acabou de iniciar e o nó ainda não está pronto, aguarde alguns segundos e execute o comando novamente.

kubectl get nodes --request-timeout=5s

A saída esperada inclui:

NAME         STATUS   ROLES           AGE   VERSION
labex-v135   Ready    control-plane   ...   v1.35...

Aguarde até que o Pod de rede do cluster esteja pronto (Ready):

kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s

Saída esperada:

pod/calico-node-... condition met

Este laboratório utiliza um PersistentVolumeClaim posteriormente. Confirme se a StorageClass padrão standard existe e, em seguida, aguarde o Pod do provisionador de armazenamento do minikube.

kubectl get storageclass standard
kubectl wait --namespace kube-system --for=condition=Ready pod/storage-provisioner --timeout=120s

A saída esperada inclui:

NAME                 PROVISIONER                RECLAIMPOLICY   VOLUMEBINDINGMODE   ...
standard (default)   k8s.io/minikube-hostpath   Delete          Immediate           ...
pod/storage-provisioner condition met

Crie um namespace chamado ckad-prep-volumes:

kubectl create namespace ckad-prep-volumes

Defina este namespace como o namespace do contexto atual:

kubectl config set-context --current --namespace=ckad-prep-volumes

Confirme o namespace atual:

kubectl config view --minify --output 'jsonpath={..namespace}'; echo

Saída esperada:

ckad-prep-volumes

Utilizar emptyDir para Dados Temporários Locais do Pod

Nesta etapa, você criará um Pod que utiliza um volume emptyDir.

Um volume emptyDir começa vazio quando o Pod é criado. Os containers no mesmo Pod podem utilizá-lo como espaço de trabalho compartilhado, cache ou diretório de trabalho temporário. Ele não foi projetado para preservar dados após a remoção do Pod.

Crie o arquivo emptydir-pod.yaml:

cat > emptydir-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: scratch-worker
  labels:
    app: scratch-worker
spec:
  terminationGracePeriodSeconds: 0
  volumes:
  - name: scratch-space
    emptyDir: {}
  containers:
  - name: worker
    image: busybox:1.36
    command:
    - /bin/sh
    - -c
    - 'echo scratch-ready > /scratch/status.txt; sleep 3600'
    volumeMounts:
    - name: scratch-space
      mountPath: /scratch
EOF

Aplique o manifesto:

kubectl apply -f emptydir-pod.yaml

Saída esperada:

pod/scratch-worker created

Aguarde até que o Pod esteja pronto (Ready):

kubectl wait --for=condition=Ready pod/scratch-worker --timeout=120s

Saída esperada:

pod/scratch-worker condition met

Leia o arquivo do volume emptyDir montado:

kubectl exec scratch-worker -c worker -- cat /scratch/status.txt

Saída esperada:

scratch-ready

Inspecione o tipo de volume do Pod. A expressão jsonpath imprime o nome do volume e confirma que se trata de um emptyDir.

kubectl get pod scratch-worker -o 'jsonpath={.spec.volumes[0].name}{" emptyDir\n"}'

Saída esperada:

scratch-space emptyDir

Gravar Dados em um PersistentVolumeClaim

Nesta etapa, você criará um PersistentVolumeClaim (PVC) e o montará em um Pod de escrita.

Um PersistentVolumeClaim, ou PVC, é uma solicitação de armazenamento feita por uma aplicação. Neste laboratório, a StorageClass standard fornece armazenamento dinamicamente para a solicitação. Seu Pod monta a solicitação em /data e grava um arquivo lá.

Crie o arquivo notes-pvc.yaml:

cat > notes-pvc.yaml <<'EOF'
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: notes-pvc
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: standard
  resources:
    requests:
      storage: 1Mi
EOF

Aplique o PVC:

kubectl apply -f notes-pvc.yaml

Saída esperada:

persistentvolumeclaim/notes-pvc created

Aguarde até que o PVC esteja no estado Bound:

kubectl wait --for=jsonpath='{.status.phase}'=Bound pvc/notes-pvc --timeout=120s

Saída esperada:

persistentvolumeclaim/notes-pvc condition met

Crie um Pod de escrita que monta o PVC:

cat > pvc-writer-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: pvc-writer
  labels:
    app: pvc-writer
spec:
  terminationGracePeriodSeconds: 0
  volumes:
  - name: notes-storage
    persistentVolumeClaim:
      claimName: notes-pvc
  containers:
  - name: writer
    image: busybox:1.36
    command:
    - /bin/sh
    - -c
    - 'echo persistent-note > /data/note.txt; sleep 3600'
    volumeMounts:
    - name: notes-storage
      mountPath: /data
EOF

Aplique o Pod de escrita e aguarde até que ele esteja pronto (Ready):

kubectl apply -f pvc-writer-pod.yaml
kubectl wait --for=condition=Ready pod/pvc-writer --timeout=120s

Saída esperada:

pod/pvc-writer created
pod/pvc-writer condition met

Leia o arquivo da montagem do PVC:

kubectl exec pvc-writer -c writer -- cat /data/note.txt

Saída esperada:

persistent-note

Reutilizar o PVC em um Novo Pod

Nesta etapa, você excluirá o Pod de escrita, criará um novo Pod de leitura que monta o mesmo PVC e confirmará que o arquivo ainda está lá.

Esta é a diferença prática entre dados temporários locais do Pod e armazenamento persistente. O Pod de escrita pode ser removido, mas o PVC permanece. Um novo Pod pode montar a mesma solicitação e ler os dados.

Exclua o Pod de escrita:

kubectl delete pod pvc-writer

Saída esperada:

pod "pvc-writer" deleted

Crie um Pod de leitura que monta o mesmo PVC:

cat > pvc-reader-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: pvc-reader
  labels:
    app: pvc-reader
spec:
  terminationGracePeriodSeconds: 0
  volumes:
  - name: notes-storage
    persistentVolumeClaim:
      claimName: notes-pvc
  containers:
  - name: reader
    image: busybox:1.36
    command:
    - /bin/sh
    - -c
    - 'cat /data/note.txt; sleep 3600'
    volumeMounts:
    - name: notes-storage
      mountPath: /data
EOF

Aplique o Pod de leitura e aguarde até que ele esteja pronto (Ready):

kubectl apply -f pvc-reader-pod.yaml
kubectl wait --for=condition=Ready pod/pvc-reader --timeout=120s

Saída esperada:

pod/pvc-reader created
pod/pvc-reader condition met

Leia o arquivo do novo Pod:

kubectl exec pvc-reader -c reader -- cat /data/note.txt

Saída esperada:

persistent-note

Inspecione o PVC. Ele ainda deve estar Bound, mesmo que o Pod de escrita original tenha sido removido.

kubectl get pvc notes-pvc

A saída esperada inclui:

NAME        STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
notes-pvc   Bound    ...      1Mi        RWO            standard       <unset>                 ...

Resumo

Você utilizou um volume emptyDir para dados temporários locais do Pod, criou um PVC para armazenamento persistente, gravou dados através de um Pod, excluiu esse Pod e leu os mesmos dados a partir de um novo Pod que montou a mesma solicitação. Agora você sabe quando utilizar armazenamento efêmero para dados temporários do Pod e quando solicitar armazenamento persistente para dados que devem sobreviver à substituição do Pod.