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.


