Skip to main content

Volúmenes

image.png

En Kubernetes, un volumen es una forma de proporcionar almacenamiento persistente a los pods y sus contenedores. Los volúmenes permiten que los datos persistan más allá de la vida de un pod individual (ya que los pods son efímeros y sus datos locales se pierden cuando son eliminados).

📦 Tipos de volúmenes en Kubernetes

Kubernetes soporta distintos tipos de volúmenes dependiendo del caso de uso y del proveedor de infraestructura.

  1. emptyDir:

    • Crea un volumen vacío cuando el pod se inicializa.

    • Se borra cuando el pod muere.

    • Útil para almacenamiento temporal (caches, etc.).

  2. hostPath:

    • Monta una carpeta del nodo físico (host) dentro del contenedor.

    • No es recomendable para producción, pero útil para pruebas locales.

  3. nfs:

    • Monta un volumen compartido a través de un servidor NFS externo.

  4. persistentVolumeClaim (PVC):

    • Solicita almacenamiento persistente a través de un PersistentVolume.

    • Es la forma estándar de montar almacenamiento duradero en Kubernetes.

  5. configMap / secret:

    • Permiten montar configuraciones o secretos como archivos dentro de los pods.

  6. cloud-specific (AWS EBS, GCE Persistent Disk, Azure Disk):

    • Volúmenes gestionados por proveedores cloud que pueden ser montados como almacenamiento persistente.


✅ Ejemplos

📝 Pod con volumen emptyDir
apiVersion: v1
kind: Pod
metadata:
  name: mypod-emptydir
spec:
  containers:
  - name: app
    image: httpd
    volumeMounts:
    - mountPath: /usr/local/apache2/htdocs  # Aquí se montará el volumen
      name: web-content
  volumes:
  - name: web-content
    emptyDir: {}   # Volumen tipo "directorio vacío"
  • Cuando el pod se crea, Kubernetes genera un directorio temporal en el nodo donde corre el pod.

  • Ese directorio está disponible en /usr/local/apache2/htdocs/ dentro del contenedor de httpd.

  • Los datos se mantienen mientras el pod esté vivo, pero se eliminan cuando el pod muere o se borra.

Para almacenamiento temporal de archivos o cachés.

Para compartir datos entre múltiples contenedores dentro del mismo pod.

Como espacio de trabajo para procesos batch o temporales.

📝 Pod con hostPath
apiVersion: v1
kind: Pod
metadata:
  name: mypod-hostpath
spec:
  containers:
  - name: app
    image: httpd
    volumeMounts:
    - mountPath: /usr/local/apache2/htdocs   # Dentro del contenedor
      name: web-content
  volumes:
  - name: web-content
    hostPath:
      path: /data/httpd                  # Ruta en el nodo físico
      type: DirectoryOrCreate            # Crea el directorio si no existe
  • El contenedor de httpd montará el directorio /data/nginx del host físico en /usr/local/apache2/htdocs/ dentro del contenedor.

  • Todo lo que escribas o leas dentro de /usr/local/apache2/htdocs/ se reflejará en /data/httpddel nodo.

  • Si el directorio /data/httpdno existe, Kubernetes lo creará automáticamente porque usamos type: DirectoryOrCreate.

Es útil para entornos de desarrollo o pruebas locales.

En producción, no es recomendable, ya que acopla los pods a un nodo específico.

hostPath puede ser peligroso si no se controla bien, ya que accede directamente al sistema de archivos del host.

📝 Pod con volumen nfs
apiVersion: v1
kind: Pod
metadata:
  name: mypod-nfs
spec:
  containers:
  - name: app
    image: httpd
    volumeMounts:
    - mountPath: /usr/local/apache2/htdocs  # Ruta dentro del contenedor
      name: nfs-volumen
  volumes:
  - name: nfs-volumen
    nfs:
      server: 192.168.1.100       # IP del servidor NFS
      path: /exports/web-content  # Ruta compartida en el NFS
  • El pod monta el directorio remoto /exports/web-content de un servidor NFS con IP 192.168.1.100.

  • Todo lo que el contenedor httpd lea o escriba en /usr/local/apache2/htdocs/ se guardará en el servidor NFS.

  • Este volumen puede ser compartido por varios pods al mismo tiempo, lo que lo hace útil para entornos donde múltiples aplicaciones necesitan acceder al mismo almacenamiento.

Servir archivos estáticos desde un punto común.

Compartir configuraciones, datos o resultados entre diferentes pods.

Montar un almacenamiento distribuido simple para apps legacy.

🗂️ Relación entre PersistentVolume (PV) y PersistentVolumeClaim (PVC)

  • PersistentVolume (PV):
    Es el recurso que representa un bloque de almacenamiento real en el clúster, como un disco EBS, un disco local o un volumen NFS.

  • PersistentVolumeClaim (PVC):
    Es una petición de almacenamiento por parte de un pod o aplicación. El PVC "reclama" un PV disponible según el tamaño y las características que necesita.

📝 1️⃣ PersistentVolume (PV)

Manifiesto PV NFS -> nfs-pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    path: /mnt/nfs_share
    server: <IP_DEL_SERVIDOR_NFS>

Manifiesto PVC que usa PV anterior -> nfs-pvc.yaml

📝 2️⃣ PersistentVolumeClaim (PVC)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

📝 3️⃣ Pod que usa el PVC
apiVersion: v1
kind: Pod
metadata:
  name: mypod-pvc
spec:
  containers:
  - name: app
    image: httpd
    volumeMounts:
    - mountPath: /usr/local/apache2/htdocs
      name: volumen-persistente
  volumes:
  - name: volumen-persistente
    persistentVolumeClaim:
      claimName: mypvc
  • El PV define el volumen físico (en este caso /data/mypv en el host).

  • El PVC es la solicitud que hace el Pod para "reclamar" ese volumen.

  • El Pod monta ese PVC en /usr/local/apache2/htdocs/ y todo lo que escriba allí será persistente, incluso si el pod es eliminado y recreado.

Este ejemplo usa hostPath para el PV (solo recomendable para entornos de pruebas o dev).

En producción lo ideal es que el PV sea de un tipo como: nfsawsElasticBlockStore, gcePersistentDisk, cephfs, etc.

StorageClass

StorageClasses permiten almacenamiento dinámico en Kubernetes.
✅ Diferentes provisioners ofrecen distintas opciones de almacenamiento.
✅ Facilitan la gestión automática de volúmenes sin intervención manual.

📦 StorageClass con NFS en Kubernetes

Si quieres usar NFS (Network File System) como almacenamiento en Kubernetes, puedes definir una StorageClass con un provisioner adecuado.


1. Opciones para usar NFS en Kubernetes

Kubernetes no tiene un provisioner de NFS incorporado, pero puedes usar varias opciones de aprovisionamiento:

  1. Manualmente: Creas un PersistentVolume (PV) con una ruta NFS y luego un PersistentVolumeClaim (PVC) lo usa.

  2. Dynamic Provisioning con NFS Subdir External Provisioner: Usa un controlador que aprovisione dinámicamente volúmenes en un servidor NFS.


📌 2. Opción 1: StorageClass con aprovisionamiento manual (Static Provisioning)

En este caso, el StorageClass no es obligatorio, pero puede ayudar a organizar el almacenamiento.

📝 Paso 1: Crear un PersistentVolume (PV) manualmente

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: manual-nfs
  nfs:
    path: /exported/path
    server: 192.168.1.100  # IP de tu servidor NFS
📝 Paso 2: Crear un PersistentVolumeClaim (PVC)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-nfs
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: manual-nfs
  resources:
    requests:
      storage: 5Gi

 

🔹 Aquí, el PVC buscará un PV con storageClassName: manual-nfs.


📌 3. Opción 2: Aprovisionamiento dinámico con NFS Subdir External Provisioner

Para evitar crear manualmente PVs, puedes usar el NFS Subdir External Provisioner, que crea automáticamente directorios en un servidor NFS.

🛠 Paso 1: Instalar el NFS Provisioner

Si usas Helm, instala el provisioner:

# añade el repositorio helm
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
helm repo update
# instalar "nfs-provisioner"
helm install nfs-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
  --set nfs.server=192.168.1.100 \
  --set nfs.path=/exported/path
📝 Paso 2: StorageClass con NFS Provisioner

Después de instalarlo, el provisioner crea una StorageClass como esta:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-storage
provisioner: nfs-subdir-external-provisioner
parameters:
  archiveOnDelete: "false"  # Si es "true", mantiene datos tras borrar el PVC
reclaimPolicy: Retain
volumeBindingMode: Immediate
📝 Paso 3: PVC usando esta StorageClass
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-dynamic-nfs
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: nfs-storage
  resources:
    requests:
      storage: 5Gi

🔹 Aquí, el PVC creará automáticamente un subdirectorio en el servidor NFS.


🚀 ¿Cuál opción elegir?

MétodoVentajasDesventajas
Manual (Static Provisioning)Control total, útil si ya tienes PVs definidosHay que crear cada PV manualmente
Dinámico (NFS Provisioner)Crea volúmenes automáticamente, menos gestión manualRequiere instalar el provisioner

Si tu infraestructura soporta un servidor NFS y necesitas escalabilidad, usar aprovisionamiento dinámico es la mejor opción.


🎯 Conclusión

  • NFS es una excelente opción para almacenamiento compartido en Kubernetes porque permite ReadWriteMany (RWX).

  • Puedes usar PVs estáticos o un provisioner dinámico para manejar el almacenamiento más eficientemente.

  • El NFS Subdir External Provisioner es una herramienta útil para facilitar la gestión.