Uso de volúmenes efímeros y persistentes en Pods

KubernetesBeginner
Practicar Ahora

Introducción

Los contenedores tienen sistemas de archivos grabables, pero ese almacenamiento está vinculado al ciclo de vida del contenedor. Los volúmenes de Kubernetes ofrecen a los Pods una forma más clara de gestionar archivos. Algunos volúmenes son efímeros y están destinados a datos temporales dentro de un único Pod. Otros volúmenes son persistentes y pueden mantener los datos disponibles incluso cuando un Pod se elimina y se vuelve a crear.

En este laboratorio, utilizarás un volumen emptyDir para datos temporales locales del Pod y, posteriormente, crearás un PersistentVolumeClaim (PVC) para montarlo en dos Pods diferentes, demostrando así que los datos persisten tras el reemplazo del Pod.

Preparar un espacio de nombres para la práctica de volúmenes

En este paso, prepararás un espacio de nombres (namespace) limpio y confirmarás que el clúster cuenta con los componentes de almacenamiento necesarios para este laboratorio.

Comienza en /home/labex/project. Escribirás los manifiestos de los Pods y PVC en este directorio.

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

Verifica que el servidor de la API de Kubernetes sea accesible. Si la máquina virtual acaba de iniciarse y el nodo aún no está listo, espera unos segundos y vuelve a ejecutar el comando.

kubectl get nodes --request-timeout=5s

La salida esperada incluye:

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

Espera hasta que el Pod de red del clúster esté listo (Ready):

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

Salida esperada:

pod/calico-node-... condition met

Este laboratorio utiliza un PersistentVolumeClaim más adelante. Confirma que existe la StorageClass standard predeterminada y espera a que el Pod del aprovisionador de almacenamiento de minikube esté listo.

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

La salida esperada incluye:

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

Crea un espacio de nombres llamado ckad-prep-volumes:

kubectl create namespace ckad-prep-volumes

Establece este espacio de nombres como el contexto actual:

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

Confirma el espacio de nombres actual:

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

Salida esperada:

ckad-prep-volumes

Usar emptyDir para datos temporales locales del Pod

En este paso, crearás un Pod que utiliza un volumen emptyDir.

Un volumen emptyDir comienza vacío cuando se crea el Pod. Los contenedores dentro del mismo Pod pueden utilizarlo como espacio de trabajo compartido, caché o directorio de trabajo temporal. No está diseñado para preservar datos después de que el Pod sea eliminado.

Crea 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

Aplica el manifiesto:

kubectl apply -f emptydir-pod.yaml

Salida esperada:

pod/scratch-worker created

Espera hasta que el Pod esté listo:

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

Salida esperada:

pod/scratch-worker condition met

Lee el archivo desde el volumen emptyDir montado:

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

Salida esperada:

scratch-ready

Inspecciona el tipo de volumen del Pod. La expresión jsonpath imprime el nombre del volumen y confirma que es un emptyDir.

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

Salida esperada:

scratch-space emptyDir

Escribir datos en un PersistentVolumeClaim

En este paso, crearás un PersistentVolumeClaim (PVC) y lo montarás en un Pod de escritura.

Un PersistentVolumeClaim, o PVC, es una solicitud de almacenamiento realizada por una aplicación. En este laboratorio, la StorageClass standard proporciona almacenamiento dinámicamente para la solicitud. Tu Pod monta la reclamación en /data y escribe un archivo allí.

Crea 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

Aplica el PVC:

kubectl apply -f notes-pvc.yaml

Salida esperada:

persistentvolumeclaim/notes-pvc created

Espera hasta que el PVC esté en estado Bound:

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

Salida esperada:

persistentvolumeclaim/notes-pvc condition met

Crea un Pod de escritura que monte el 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

Aplica el Pod de escritura y espera hasta que esté listo:

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

Salida esperada:

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

Lee el archivo desde el montaje del PVC:

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

Salida esperada:

persistent-note

Reutilizar el PVC desde un nuevo Pod

En este paso, eliminarás el Pod de escritura, crearás un nuevo Pod de lectura que monte el mismo PVC y confirmarás que el archivo sigue allí.

Esta es la diferencia práctica entre los datos temporales locales del Pod y el almacenamiento persistente. El Pod de escritura puede eliminarse, pero el PVC permanece. Un nuevo Pod puede montar la misma reclamación y leer los datos.

Elimina el Pod de escritura:

kubectl delete pod pvc-writer

Salida esperada:

pod "pvc-writer" deleted

Crea un Pod de lectura que monte el mismo 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

Aplica el Pod de lectura y espera hasta que esté listo:

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

Salida esperada:

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

Lee el archivo desde el nuevo Pod:

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

Salida esperada:

persistent-note

Inspecciona el PVC. Debería seguir en estado Bound, incluso aunque el Pod de escritura original haya desaparecido.

kubectl get pvc notes-pvc

La salida esperada incluye:

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

Resumen

Has utilizado un volumen emptyDir para datos temporales locales del Pod, creado un PVC para almacenamiento persistente, escrito datos a través de un Pod, eliminado dicho Pod y leído los mismos datos desde un nuevo Pod que montó la misma reclamación. Ahora sabes cuándo utilizar almacenamiento efímero para datos temporales del Pod y cuándo solicitar almacenamiento persistente para datos que deben sobrevivir al reemplazo del Pod.