
Hace unas semanas me topé con lo que en su momento creí que era un caso de uso bastante particular al migrar varias VMs de mi home lab a Kubernetes: montar automáticamente un volumen NFS en una máquina Linux o un contenedor Docker.
La idea era mover el almacenamiento de InfluxDB, MySQL y Grafana a mi NAS, en lugar de dejarlo en el sistema de archivos local del equipo donde corrían. Uso bastante NFS en mi red para compartir archivos entre varios dispositivos, por su simplicidad y por la compatibilidad que tiene.
Después de dejarlo andando en mi home lab, me di cuenta de que en realidad no era un caso tan particular, dada la enorme cantidad de usos que tiene NFS hoy en día. Se puede usar en un entorno cloud para montar un share NFS on-premise y traer datos, para que ciertos procesos accedan a un share NFS y lean o escriban información, para montar los directorios home de los usuarios desde NFS, y un sinfín de escenarios más.
El problema del auto-montaje y la clave para que funcione
Primero fui por el camino que mejor conocía: usar fstab, con el que vengo trabajando de forma intermitente desde hace un par de décadas. Pero descubrí muy rápido que no montaba el NFS con la velocidad suficiente para que los daemons de las bases de datos lo detectaran, y eso terminaba causando problemas serios.
Ahí fue cuando me crucé con un paquete de Linux llamado autofs. Ponerlo a funcionar me costó bastante experimentación, porque muchas guías en internet estaban desactualizadas o se saltaban detalles muy importantes de la configuración. Esta guía te muestra directamente cómo hacerlo, así no pierdes medio día tratando de averiguarlo, porque el tiempo es algo que en esta industria nunca nos sobra.
En esencia, autofs es un daemon que monta y desmonta shares automáticamente, según se necesiten, en segundo plano. A diferencia de fstab, lo hace bajo demanda, así que puede actuar durante el arranque sin que tengas que preocuparte por el orden en que se inician los daemons.
Requisitos previos
Para simplificar este ejercicio, voy a asumir que ya tienes un servidor NFS configurado en tu NAS o máquina Linux, o que estás usando algo como Filestore de Google Cloud para que cumpla esa función.
Asegúrate de tener las rutas completas de cada share NFS que quieras agregar. A veces no son las que uno espera, así que conviene revisarlas dos veces. Por ejemplo, en los NAS de Synology llevan el volumen como prefijo, algo del estilo /volume1/share_path.
También voy a usar comandos específicos de distribuciones derivadas de Debian, así que esto debería funcionar en Debian, Ubuntu, Kali, etc. En cada sección voy a incluir además el comando equivalente para distribuciones derivadas de Red Hat, para que quienes corran RHEL o CentOS no tengan que andar traduciendo.
Ten en cuenta que en esta guía no voy a cubrir prácticas de seguridad de NFS, ya que es un tema enorme. Sumaría un nivel de complejidad que tranquilamente podría duplicar el largo de la guía, así que lo dejo afuera. SÍ es muy importante, no me malinterpretes, pero no lo trato en este artículo y te recomiendo investigarlo para integrarlo a esta configuración una vez que la tengas armada de la manera que mejor le sirva a tu organización. Si quieres profundizar, te recomiendo empezar con este excelente artículo de Red Hat que cubre los fundamentos aquí.
El proceso
Instala el paquete autofs ejecutando los siguientes comandos según tu distribución:
Ubuntu: `sudo apt -y install nfs-common autofs
Red Hat:sudo yum -y install nfs-common autofs`Abre el archivo
/etc/auto.masteren tu editor favorito.Ve hasta el final del archivo y agrega una línea como esta por cada mount que quieras añadir, cambiando la palabra
sharedeauto.sharepor el nombre que prefieras para el share:`/- /etc/auto.share -nosuid,noowners
`(Si lo prefieres, agrega más espacios entre los elementos para que se lea mejor; Medium no permite más de un espacio en un bloque de código dentro de una lista numerada.)
Después tendrás que crear cada archivo que mencionaste en el paso anterior. Todos van en
/etcy siguen el formatoauto.[share_name]. Así que por cada líneaauto.shareque agregaste arriba, tendrás que abrir ese archivo en tu editor de texto favorito para crearlo. Una vez dentro, agrega esta línea reemplazando el nombre del share (mi preferencia personal es mantener todo en /mnt, pero puedes cambiarlo a tu gusto), el nombre del servidor y la ruta del share:`/mnt/[share_name] -fstyle=nfs,user,nolock,nosuid,rw [server_name]:[share_path]
`(De nuevo, si lo prefieres, agrega más espacios para que se lea mejor. Y si quieres que sea de solo lectura en vez de lectura-escritura, cambia el rw de arriba por ro.)
Una vez listo esto, toca reiniciar el servicio autofs con el siguiente comando:
Ubuntu:
sudo service autofs restartRed Hat:
sudo systemctl restart autofsDespués hay que confirmar que el servicio arrancó bien y que no hubo errores de sintaxis, de red ni de ningún otro tipo durante el inicio. Ejecuta el siguiente comando para ver el estado:
Ubuntu:
sudo service autofs statusRed Hat:
sudo systemctl status autofsEn la salida del paso anterior te debería indicar que el estado es running y que todo está bien. Si no, la salida mostrará las últimas líneas de los logs para ayudarte a debuggear el problema. Al final de esta guía también agregué una sección con algunos pasos básicos de debugging.
Llegado este punto, puedes usar el comando
cdpara entrar a los directorios que pusiste en los archivos anteriores y acceder a los shares. Ten en cuenta que no hace falta crear esos directorios: el daemon autofs los crea automáticamente.Una última verificación que puedes hacer es ejecutar el comando
mount, que lista todos los mounts de la instancia. Una forma fácil de filtrar los que creó autofs es ejecutarmount | grep autofs.De aquí en adelante, los mounts se cargarán solos en el sistema y se reconectarán cuando haga falta.
En este punto, te recomiendo encarecidamente que investigues sobre seguridad en NFS, asegures tus mounts e implementes el método de seguridad que mejor se adapte a tu uso.
Debugging de problemas comunes
A lo largo de este aprendizaje me crucé con algunos inconvenientes que quiero listar, junto con la forma en que los debuggié.
El primero fue que el daemon arrojaba todo tipo de errores diciendo que no podía conectarse a NFS. Resultó que Synology antepone el número de volumen al nombre del share, algo que en ese momento yo no sabía. Lo diagnostiqué intentando montar el share NFS manualmente en una carpeta de mi directorio home con el siguiente comando: mkdir tmp_mnt && sudo mount -v -r -o user,nolock,nosuid [server_name]:[share_path] tmp_mnt, que monta el share en un directorio local. Esto te devuelve un éxito o un error que indica qué está pasando. Para desmontarlo, ejecuta sudo umount tmp_mnt.
Otro error que me apareció fue que el servidor no era accesible por su hostname. Resultó ser un tema de DNS interno: no se estaba resolviendo el hostname. Lo diagnostiqué porque sí podía llegar al share por su dirección IP, y después corrí un nslookup hostname para confirmar que no podía traducir la IP al hostname. Ten en cuenta que para esto quizás tengas que instalar los paquetes bind-utils (en Red Hat sudo yum -y install bind-utils) o dnsutils (en Debian sudo apt install -y dnsutils).
El último problema fue específico de Kubernetes. No lograba acceder a ningún servicio externo, incluidos los shares NFS, que estuviera fuera del cluster desde ningún pod del cluster. Terminó siendo que no se podía resolver el hostname desde DNS, porque el cluster no tenía conocimiento de mi servidor DNS interno, que vivía fuera del cluster. La teoría detrás de todo esto excede el alcance de esta guía, así que voy a dar simplemente una solución y un enlace para que puedas profundizar.
- Edita el configmap de CoreDNS con el siguiente comando:
kubectl edit configmap coredns -n kube-system. - Esto abrirá un editor de texto con el archivo yaml de CoreDNS. Dentro hay una sección llamada Corefile con un bloque de yaml que empieza con
.:53. - Define tu dominio interno. Esto dependerá de cómo esté configurado tu servidor DNS interno; si no tienes uno, usa simplemente
local. - Define la dirección IP de tu servidor DNS. Si no tienes uno, lo más probable es que sea la IP de tu router.
- Agrega el siguiente bloque de código, reemplazando con tu información, debajo en una línea nueva (¡asegúrate de usar espacios y no tabs!), guarda y sal del editor:
[domain_name]:53 { errors cache 30 forward . [dns_server] }
Puedes encontrar más información sobre por qué esto funciona aquí.