¿Qué es NFS?
NFS o Network Filesystem es un sistema de archivos que se utiliza para compartir datos con otros servidores a través de la red.
El servidor NFS es el propietario del filesystem que va a compartir con otros servidores remotos o clientes.
NFS Linux utiliza un sistema de archivos centralizado para acceder al almacenamiento de red y proporciona protocolo de bloqueos y desbloqueos para evitar la corrupción de datos y permitir operaciones concurrentes de lectura y escritura sobre el filesystem.
Para usar NFS, debemos instalar el software del servidor (nfs-server), para poder exportar filesystems, y el software del cliente (nfs-client) para poder montar los filesystems en los servidores remotos (clientes). En las opciones de exportación podremos restringir los permisos, usuarios e IPs remotas que podrán acceder al sistema de archivos.
Para que un filesystem NFS se monte al iniciar el sistema cliente, deberemos configurar el fichero /etc/fstab o autofs.
Para exportar los filesystems en el lado del servidor, deberemos configurar el fichero /etc/exports, especifiando el filesystem a exportar, los servidores remotos que pueden acceder a él y con qué permisos.
En NFS 4, tanto el cliente como el servidor solamente utilizan el puerto 2049 TCP.
¿Cómo se instala un servidor NFS en Linux?
En Linux CentOS 8 instalaremos los siguientes paquetes:
[[email protected] ~]# dnf install -y nfs-utils
[[email protected] ~]# rpm -qa |grep -i nfs
nfs-utils-2.3.3-35.el8.x86_64
sssd-nfs-idmap-2.3.0-9.el8.x86_64
libnfsidmap-2.3.3-35.el8.x86_64
[[email protected] ~]#
Una vez instalado el software, habilitaremos el servicio:
[[email protected] ~]# systemctl enable nfs-server
[[email protected] ~]# systemctl start nfs-server
[[email protected] ~]# systemctl status nfs-server
● nfs-server.service - NFS server and services
Loaded: loaded (/usr/lib/systemd/system/nfs-server.service; enabled; vendor preset: disabled)
Drop-In: /run/systemd/generator/nfs-server.service.d
└─order-with-mounts.conf
Active: active (exited) since Fri 2021-04-23 19:04:53 UTC; 32min ago
Process: 1208 ExecStopPost=/usr/sbin/exportfs -f (code=exited, status=0/SUCCESS)
Process: 1205 ExecStopPost=/usr/sbin/exportfs -au (code=exited, status=0/SUCCESS)
Process: 1203 ExecStop=/usr/sbin/rpc.nfsd 0 (code=exited, status=0/SUCCESS)
Process: 1229 ExecStart=/bin/sh -c if systemctl -q is-active gssproxy; then systemctl reload gssproxy ; fi (code=exited, status=0/SUCCESS)
Process: 1219 ExecStart=/usr/sbin/rpc.nfsd (code=exited, status=0/SUCCESS)
Process: 1217 ExecStartPre=/usr/sbin/exportfs -r (code=exited, status=0/SUCCESS)
Main PID: 1229 (code=exited, status=0/SUCCESS)
Tasks: 0 (limit: 24941)
Memory: 0B
CGroup: /system.slice/nfs-server.service
Apr 23 19:04:53 ip-10-0-3-108.eu-west-1.compute.internal systemd[1]: Starting NFS server and services...
Apr 23 19:04:53 ip-10-0-3-108.eu-west-1.compute.internal systemd[1]: Started NFS server and services.
[[email protected] ~]#
¿Cómo compartimos un filesystem con otros servidores remotos con NFS?
Esta es una de las tareas más sencillas. En el servidor de NFS configuraremos el archivo /etc/exports con los servidores que deben tener acceso. Por ejemplo:
[[email protected] ~]# cat /etc/exports
/nfssrv 10.0.3.135(sync,rw) 10.0.3.136(sync,rw)
[[email protected] ~]#
[ro[email protected] ~]# exportfs -av
exporting 10.0.3.135:/nfssrv
En el lado del cliente, configuraremos el punto de montaje correspondiente en el fichero /etc/fstab. Ejemplo:
[[email protected] ~]# grep nfs /etc/fstab |grep -v "#"
10.0.3.108:/nfssrv /clntnfs nfs vers=4,noatime,async,rw,hard,timeo=600,retrans=30 0 0
[[email protected] ~]#
[[email protected] ~]# su - david
Last login: Fri Apr 23 19:07:45 UTC 2021 on pts/0
[[email protected] ~]$ cd /clntnfs/
[[email protected] clntnfs]$ ls -la
total 15728656
drwxr-xr-x 2 david david 296 Apr 23 19:23 .
dr-xr-xr-x. 18 root root 259 Apr 23 16:52 ..
-rw------- 1 david david 1073741824 Apr 23 19:26 test_file.0
-rw------- 1 david david 1073741824 Apr 23 19:26 test_file.1
[[email protected] clntnfs]$ df -hP .
Filesystem Size Used Avail Use% Mounted on
10.0.3.108:/nfssrv 20G 16G 4.9G 76% /clntnfs
[[email protected] clntnfs]$
Dependiendo del uso que le vayamos a dar a NFS, deberemos utilizar unas opciones de montaje u otras. Para ello, tendremos que echar un vistazo al man de nfs, de fstab y de mount.
Opciones de exportación en el fichero /etc/exports
ro
El sistema de archivos exportado sólo es de lectura, por lo que los hosts remotos no pueden modificar los datos compartidos.
rw
Para permitir la edición a través de los hosts remotos (leer y escribir), es necesario especificar la opción de ‘rw’.
sync
La sincronización por defecto significa que el servidor NFS no responderá a las solicitudes antes de que los cambios se escriban en el disco. Para permitir las escrituras asíncronas en su lugar, es necesario especificar la opción ‘async‘.
root_squash
Para evitar que los usuarios root conectados remotamente tengan privilegios de root, se puede usar la opción ‘root_squash’. Si queremos que el usuario root del servidor remoto tenga privilegios de root, usaremos no_root_squash.
wdelay
Las escrituras en disco se retrasan si el servidor NFS sospecha que hay otra escritura prioritara de forma inminente. Esta opción puede mejorar el rendimiento de escritura en disco al reducir el número de accesos al disco, reduciendo la sobrecarga de escritura.
Configuración de NFS para optimizar el rendimiento
Cliente de NFS
Cuando hablamos de rendimiento nos referimos a la velocidad de lectura y escritura de datos en el filesystem montado en los clientes NFS.
Os adelanto, que las opciones de montaje con «async» tanto en el lado del servidor como en el del cliente son las más rápidas pero no es la opción recomendada por temas de seguridad e integridad de los datos.
Mejor vemos una serie de pruebas de estrés y vemos las diferencias de rendimiento entre cada una de las opciones de montaje y, al final, decidimos cuáles son las que más nos convienen.
Pruebas de estrés de NFS con diferentes opciones de montaje y tipos de filesystems
Para ejecutar las pruebas de estrés he utilizado sysbench (ver tutorial).
Rendimiento de un filesystem EXT4 vs XFS
- Tamaño medio de los archivos:
- Opciones de montaje del FS: vers=3,rw,hard,timeo=600,retrans=30
- Comando lanzado:
- Preparación: sysbench fileio –file-total-size=15G prepare
- Test de rendimiento: sysbench fileio –file-total-size=15G –file-test-mode=rndrw run

- Pocos archivos grandes:
- Opciones de montaje del FS: vers=3,rw,hard,timeo=600,retrans=30
- Comando lanzado:
- Preparación de sysbench: sysbench fileio –file-total-size=15G prepare –file-num=15
- Test de rendimiento: sysbench fileio –file-num=15 –file-test-mode=rndrw run

Por lo tanto XFS tiene un mejor rendimiento que EXT4.
Rendimiento de un filesystem montado con NFS3 vs NFS4
- Tamaño medio de los archivos:
- Opciones de montaje del FS: vers=4,rw,hard,timeo=600,retrans=30
- Comando lanzado:
- Preparación: sysbench fileio –file-total-size=15G prepare
- Test de rendimiento: sysbench fileio –file-total-size=15G –file-test-mode=rndrw run

Me ha sorprendido que en estas pruebas NFS4 haya rendido un poco menos que NFS3, ya que, según la documentación oficial, NFS4 ha de rendir mejor que NFS3. En cualquier caso, la robustez y mecanismos de seguridad de las nuevas versiones es superior en la v4 que la v3.
- Pocos archivos grandes
- Opciones de montaje del FS: vers=4,rw,hard,timeo=600,retrans=30
- Comando lanzado
- Preparación de sysbench: sysbench fileio –file-total-size=15G prepare –file-num=15
- Test de rendimiento: sysbench fileio –file-num=15 –file-test-mode=rndrw run

De nuevo, NFS3 ofrece un ligero mejor rendimiento que NFS4.
Modificamos los parámetros rsize=8192,wsize=8192
- Tamaño medio de los archivos
- Opciones de montaje del FS: vers=4,rsize=8192,wsize=8192,rw,hard,timeo=600,retrans=30
- Comando lanzado:
- Preparación: sysbench fileio –file-total-size=15G prepare
- Test de rendimiento: sysbench fileio –file-total-size=15G –file-test-mode=rndrw run

- Pocos archivos grandes:
- Opciones de montaje del FS: vers=4,rsize=8192,wsize=8192,rw,hard,timeo=600,retrans=30
- Comando lanzado
- Preparación de sysbench: sysbench fileio –file-total-size=15G prepare –file-num=15
- Test de rendimiento: sysbench fileio –file-num=15 –file-test-mode=rndrw run

Añadimos el parámetro noatime y eliminamos rsize y wsize
- Tamaño medio de los archivos
- Opciones de montaje del FS: vers=4,noatime,rw,hard,timeo=600,retrans=30
- Comando lanzado:
- Preparación: sysbench fileio –file-total-size=15G prepare
- Test de rendimiento: sysbench fileio –file-total-size=15G –file-test-mode=rndrw run

- Pocos archivos grandes
- Opciones de montaje del FS: vers=4,noatime,rw,hard,timeo=600,retrans=30
- Comando lanzado
- Preparación de sysbench: sysbench fileio –file-total-size=15G prepare –file-num=15
- Test de rendimiento: sysbench fileio –file-num=15 –file-test-mode=rndrw run

Aunque no hay mucha diferencia de rendimiento si añadimos “noatime” es recomendable añadir esta opción porque sirve para guardar la información del último acceso al fichero. Con que esto solamente lo haga el servidor de NFS es suficiente. No hace falta que lo hagan el servidor y el cliente.
Añadimos el parámetro async
- Tamaño medio de los archivos
- En el servidor de NFS exportamos el FS con async (/etc/exports)
- Opciones de montaje del FS: vers=4,noatime,async,rw,hard,timeo=600,retrans=30
- Comando lanzado:
- Preparación: sysbench fileio –file-total-size=15G prepare
- Test de rendimiento: sysbench fileio –file-total-size=15G –file-test-mode=rndrw run

Con async en el lado del servidor y en el del cliente, el rendimiento tanto de lectura como de escritura supera el 83%.
- Pocos archivos grandes:
- En el servidor de NFS exportamos el FS con async (/etc/exports)
- Opciones de montaje del FS: vers=4,noatime,async,rw,hard,timeo=600,retrans=30
- Comando lanzado:
- Preparación: sysbench fileio –file-total-size=15G prepare
- Test de rendimiento: sysbench fileio –file-num=15 –file-test-mode=rndrw run

La mejora de rendimiento no es tan pronunciada cuando trabajamos con archivos grandes pero sigue siendo superior.
Sustitución de hard por soft
- Tamaño medio de los archivos
- En el servidor de NFS exportamos el FS con async (/etc/exports)
- Opciones de montaje del FS: vers=4,noatime,async,rw,soft,timeo=600,retrans=30
- Comando lanzado:
- Preparación: sysbench fileio –file-total-size=15G prepare
- Test de rendimiento: sysbench fileio –file-total-size=15G –file-test-mode=rndrw run

- Pocos archivos grandes:
- Opciones de montaje del FS: vers=4,noatime,rw,soft,timeo=600,retrans=30
- Comando lanzado
- Preparación de sysbench: sysbench fileio –file-total-size=15G prepare –file-num=15
- Test de rendimiento: sysbench fileio –file-num=15 –file-test-mode=rndrw run

No se ven mejoras de rendimiento demasiado pronunciadas pero es mejor utilizar hard por una mejor integridad de los datos.
En el servidor NFS sustituimos async por sync
- Tamaño medio de los archivos:
- En el servidor de NFS exportamos el FS con sync (/etc/exports)
- Opciones de montaje del FS: vers=4,noatime,async,rw,hard,timeo=600,retrans=30
- Comando lanzado:
- Preparación: sysbench fileio –file-total-size=15G prepare
- Test de rendimiento: sysbench fileio –file-total-size=15G –file-test-mode=rndrw run

La opción async en el lado del servidor NFS mejora el rendimiento respecto a sync en un 49% para lectura y un 45% para escritura, sin embargo, la integridad de los datos puede verse comprometida.
- Pocos archivos grandes:
- Opciones de montaje del FS: vers=4,noatime,async,rw,hard,timeo=600,retrans=30
- Comando lanzado:
- Preparación: sysbench fileio –file-total-size=15G prepare –file-num=15
- Test de rendimiento: sysbench fileio –file-num=15 –file-test-mode=rndrw run

Servidor de NFS
He hecho algunas pruebas de estrés tanto en el lado del cliente como del servidor de NFS modificando el número de threads del servidor de NFS, modificando el tipo de disco en el servidor de NFS y comprobando el rendimiento en el cliente NFS de un servidor virtual con uno físico.
Veamos el resultado de las pruebas:
- El servidor NFS es físico con 32 cores y 377GB de RAM
- Comandos de rendimiento utilizados:
sysbench fileio --file-total-size=15G --file-test-mode=rndrw --time=300 --max-requests=0 prepare
sysbench fileio --file-total-size=15G --file-test-mode=rndrw --time=300 --max-requests=0 run 1 thread
sysbench fileio --file-total-size=15G --file-test-mode=rndrw --time=300 --max-requests=0 run --threads=8 8 threads
sysbench fileio --file-total-size=15G --file-test-mode=rndrw --time=300 --max-requests=0 cleanup



Las conclusiones que saco de estas pruebas son:
- El rendimiento tanto de lectura como de escritura es mejor en local que a través de NFS, tal y como cabía esperar.
- El disco Ultraperformance puede ser hasta un 44% más rápido, en función de la carga del momento.
- Los clientes NFS en los servidores físicos son tres veces más rápidos que los clientes NFS en servidores virtuales.
- Cuántas más CPUs y velocidad de red tenga el servidor de NFS, más threads de NFS se pueden arrancar y, por lo tanto, mayores velocidades de lectura y escritura se pueden alcanzar cuando hay muchos clientes NFSs realizando operaciones de lectura y escritura de manera simultánea.
Entonces, ¿con qué opciones de montaje nos quedamos?
Servidor NFS
El filesystem lo crearemos de tipo XFS, pues hemos visto que rinde mejor que EXT4.
Lo exportaremos con las opciones sync y rw. Aunque async tiene un rendimiento muy superior a sync, sync es mucho más seguro cuando se trata de almacenar los datos.
async significa que las escrituras en disco no se realizan inmediatamente, sino que se encolan para ser escritas lo antes posible. Los comandos encargados de escribir datos no tienen que esperar a que se complete la escritura. En caso de una caída del servicio, podríamos tener corrupción de datos.
En el man del propio exports podemos ver la siguiente advertencia:

Aumentaremos el número de threads en la configuración del servidor de NFS en función de los recursos de CPU, memoria, velocidad de red y velocidad de disco. Se estima que podemos configurar unos 16 threads por CPU.
Cliente NFS
Las opciones de montaje que recomiendo son:
vers=4,sync,noatime,rw,hard,timeo=600,retrans=30
- async: En caso de caída del cliente, en el servidor NFS no habrá ningún impacto porque todavía no se habrán escrito los datos, por lo que no tendremos corrupción de datos. No obstante, dependiendo del tipo de aplicación, podríamos tener alguna incongruencia, pues la aplicación podría creer que sí se ha escrito el dato pero realmente no lo ha hecho y podríamos obtener un mal funcionamiento de la aplicación.
- noatime: Se utiliza para guardar un registro del último acceso a un archivo. No hace falta que el cliente NFS controle este parámetro, ya que es redundante, pues el servidor NFS ya lo controla.
- hard: No hemos visto grandes diferencias de rendimiento entre hard y soft pero hard es la opción conveniente para asegurar la integridad de los datos en caso de caída del servicio. Lo que hace hard es bloquear el estado de la petición escritura en disco hasta que el servicio vuelva a estar operativo de nuevo para continuar en el punto exacto en que la operación quedó congelada. La desventaja de soft es que, en caso de caída, la aplicación no sepa qué datos se pudieron escribir realmente en disco.
- vers=4: se refiere al uso de NFS4
- timeo=600,retrans=30: se refiere a que el cliente NFS realizará 30 intentos de 60 segundos para volver a conectar con el servidor de NFS. timeo se escribe en decenas de segundos.
Como podemos comprobar, las opciones recomendadas no son las que mejor rendimiento dan pero suponen un equilibrio entre rendimiento y seguridad.
Opciones de montaje NFS para Oracle RMAN
Algunos servicios o aplicaciones requieren unas opciones de montaje especiales en el lado del cliente NFS como, por ejemplo, RMAN de Oracle. Las opciones a utilizar en este caso son:
vers=4,rw,bg,hard,rsize=32768,wsize=32768,proto=tcp,timeo=600,nolock
¿Cómo modificar el número de threads en el servidor de NFS?
En Linux RedHat 6 y 7, lo haremos modificando la directiva RPCNFSDCOUNT=16, del fichero /etc/sysconfig/nfs, sustituyendo el número 16 por el que hayamos calculado, según lo explicado anteriormente.
En RedHat 8, modificaremos la directiva threads=8 del fichero /etc/nfs.conf.
Tras modificar el fichero de configuración, reiniciaremos el servicio de NFS.
Configurar un directorio virtual con NFS4
Con la llegada de NFS4, existe un nuevo concepto a la hora de compartir filesystems por red, que consiste en la creación de un filesystem o directorio virtual que se utiliza para enjaular todos los subdirectorios que se van a exportar vía NFSv4.
Es decir, tenemos un directorio raíz, por ejemplo /NFS y todos los subdirectorios que hay por debajo son los que se exportan a los servidores remotos. Por ejemplo: /NFS/directorio1 /NFS/directorio2 /NFS/directorio3… /NFS/directorioN
El problema de esta estructura es que no puedes exportar por NFS4 un filesystems que no esté por debajo del directorio raíz.
Lo he probado en un RedHat 6.9 y el funcionamiento es el siguiente.
Configuración del servidor NFS
En el fichero /etc/exports incluímos el parámetro «fsid=0» en el filesystem ráiz que va a contener todos los subdirectorios que vamos a exportar:
/Nombre_FS_NFS_ROOT servidor1(sync,rw,fsid=0)
/Nombre_FS_NFS_ROOT/subdirectorio1_a_exportar servidor1(sync,rw) servidor2(sync,rw) servidor3(sync,rw)
Configuración del cliente NFS
En el cliente de NFS, por ejemplo, servidor1, montaremos el filesystem por NFS4 de la siguiente manera:
mount -t nfs -o vers=4 servidor_nfs:/ /mnt –> Este comando monta el FS raíz y cuando montamos “/” estamos haciendo referencia al FS enjaulado en el servidor de NFS, es decir, /Nombre_FS_NFS_ROOT.
mount -t nfs -o vers=4 servidor_nfs:/subdirectorio1 /mnt/subdirectorio1 –> Este comando estaría montando el FS /Nombre_FS_NFS_ROOT/subdirectorio1, pero estamos apuntando al path relativo debido al enjaulamiento comentado anteriormente.
Error mounting XXX failed, reason given by server: No such file or directory
Con este error me volví loco hasta que me di cuenta de una tontería… Como suele pasar.
El parámetro fsid=0 debe ser único y no se puede duplicar pero resulta que en el fichero /etc/exports estaba configurado sólo en algunos filesystems y en otros no. Eso está mal porque fsid=0 sólo debe aparece una sola vez en todo el fichero /etc/exports.
Cuando está configurada esta directiva y se intenta montar el FS con NFS4, el protocolo entiende que tiene que ir a buscar el filesystem que intentamos montar en el cliente, dentro de path de enjaulamiento del servidor (de NFS4, se entiende). Si el directorio no está en ese path relativo, pues el comando «mount» no lo va a encontrar y devolverá el error.
Ejemplo del error:
[[email protected] ~]# mount -vvv -t nfs -o vers=4 lensnax0:/serveis/dades/PRO/NAS02/TME_FS /serveis/dadesnfs/PRO/TME_FS
mount: fstab path: «/etc/fstab»
mount: mtab path: «/etc/mtab»
mount: lock path: «/etc/mtab~»
mount: temp path: «/etc/mtab.tmp»
mount: UID: 0
mount: eUID: 0
mount: spec: «lensnax0:/serveis/dades/PRO/NAS02/TME_FS»
mount: node: «/serveis/dadesnfs/PRO/TME_FS»
mount: types: «nfs»
mount: opts: «vers=4»
final mount options: ‘vers=4’
mount: external mount: argv[0] = «/sbin/mount.nfs»
mount: external mount: argv[1] = «lensnax0:/serveis/dades/PRO/NAS02/TME_FS»
mount: external mount: argv[2] = «/serveis/dadesnfs/PRO/TME_FS»
mount: external mount: argv[3] = «-v»
mount: external mount: argv[4] = «-o»
mount: external mount: argv[5] = «rw,vers=4»
mount.nfs: timeout set for Tue Feb 26 13:00:47 2019
mount.nfs: trying text-based options ‘vers=4,addr=172.24.12.17,clientaddr=10.48.25.20’
mount.nfs: mount(2): No such file or directory
mount.nfs: mounting lensnax0:/serveis/dades/PRO/NAS02/TME_FS failed, reason given by server: No such file or directory
[[email protected] ~]#
Lo que hice para solucionarlo fue eliminar todas las directivas fsid=0 del fichero /etc/exports porque en este servidor de NFS no tengo un único directorio raíz. Este servidor NFS exporta filesystems a muchos servidores y aplicaciones distintas, cada una con su arquitectura heredada de hace años, por lo que enjaular todos los filesystems a exportar en otra ruta, representa un cambio de arquitectura y una parada de servicio que afecta a los usuarios finales.
Dicho esto, la incidencia se produjo porque, a nivel de comunicaciones hubo un problema que impedía montar los filesystems por NFS3, que no tiene en cuenta la directiva fsid=0 y, al intentar montar con NFS4, me encontré con el error.
Escribir un fichero desde el cliente NFS con un usuario que no existe
Sabemos que el filesystem en el cliente NFS se montará con el mismo UID y GID de los usuarios y grupos propietarios en el servidor NFS. Si no es así, obtendremos un error de permiso denegado.
Por lo tanto, el usuario o grupo que escriba un fichero desde el cliente NFS deberá tener el mismo UID y GID que en el servidor.
[[email protected] ~]# df -hP /mnt/nas/csw_pro/csw
Filesystem Size Used Avail Use% Mounted on
server2:/serveis/dades/PRO/NAS01/1104/1104 4.8G 10M 4.6G 1% /mnt/nas/csw_pro/csw
[[email protected] ~]# ls -ld /mnt/nas/csw_pro/csw
drwxr-xr-x 3 54220 grp_csw 4096 Feb 28 11:59 /mnt/nas/csw_pro/csw
[[email protected] ~]# id
uid=0(root) gid=0(root) groups=0(root),45005(uxsup3)
[[email protected] ~]# touch /mnt/nas/csw_pro/csw/test
touch: cannot touch ‘/mnt/nas/csw_pro/csw/test’: Permission denied
[[email protected] ~]#
El usuario con UID «54220» es el que puede escribir en el filesystem pero no está dado de alta en el sistema cliente NFS. En este caso es porque escribe un usuario de un contenedor y ese usuario existe dentro del contenedor pero no en el sistema operativo.
Por lo tanto, para poder escribir con el usuario con UID 54220 desde el sistema operativo cliente, podremos utilizar sudo:
[[email protected] ~]# sudo -u \#54220 touch /mnt/nas/csw_pro/csw/test
[[email protected] ~]# ls -la /mnt/nas/csw_pro/csw/test
-rw-r--r-- 1 54220 nfsnobody 0 Feb 28 11:59 /mnt/nas/csw_pro/csw/test
[[email protected] ~]#
Si queremos ejecutar un comando con el usuario inexistente en el cliente NFS:
[[email protected] ~]# sudo -u \#54220 sh -c "echo test > /mnt/nas/csw_pro/csw/test"
[[email protected] ~]# ll /mnt/nas/csw_pro/csw/test
-rw-r--r-- 1 54220 nfsnobody 5 Mar 3 10:03 /mnt/nas/csw_pro/csw/test
[[email protected] ~]#
Errores comunes con el servicio de NFS
El montaje de un filesystem NFS no tiene ningún secreto pero, a veces, el servicio no funciona como lo debería hacer.
En este artículo explicaré los errores que me he ido encontrando con el servicio de NFS, durante la administración profesional de entornos Linux.
Error de NFS – server XXX not responding, timed out
Recientemente he tenido una incidencia con un servidor de NFS de preproducción en el que durante unos segundos el cliente de NFS perdía la conectividad, afectando a una aplicación muy sensible o, traduciéndolo de otra manera, mal desarrollada:
May 10 06:02:07 servidor2 kernel: nfs: server servidor1 not responding, timed out
May 10 06:02:07 servidor2 kernel: nfs: server servidor1 not responding, timed out
May 10 06:02:08 servidor2 kernel: nfs: server servidor1 not responding, timed out
May 10 06:02:09 servidor2 kernel: nfs: server servidor1 not responding, timed out
May 10 06:02:11 servidor2 kernel: nfs: server servidor1 not responding, timed out
May 10 06:02:11 servidor2 kernel: nfs: server servidor1 not responding, timed out
May 10 06:02:13 servidor2 kernel: nfs: server servidor1 not responding, timed out
May 10 06:02:15 servidor2 kernel: nfs: server servidor1 not responding, timed out
Para solucionarlo, aumenté el timeout en el que el cliente de NFS va a seguir intentando acceder al servidor antes de dar el error, consiguiendo que el proceso de la aplicación quede bloqueado o interrumpido por IO hasta que reciba respuesta del sistema operativo. Las opciones de montaje configuradas en el /etc/fstab han sido:
ServidorNFS:/FS_SERVIDOR_NFS /PUNTO_DE_MONTAJE nfs vers=4,timeo=60,retrans=60,rw,intr,suid 0 0
Destacar los parámetros timeo=60 y retrans=60.
- timeo: Es el tiempo en decenas de segundos que el cliente de NFS espera antes de realizar un nuevo intento.
- retrans: Es el número de reintentos que el cliente de NFS hace para conectarse al servidor.
El motivo de este problema se debió a que el servidor de NFS es un servidor virtual de VMWare (preproducción) que quedaba congelado unos segundos cuando se realizaba un snapshot para la copia de seguridad diaria. Como vemos, las horas coinciden con las de los mensajes de error.

El cliente de NFS era un RedHat 7.3 y el servidor un RedHat 6.5.
RPC: fragment too large
En este caso me encontré con que el servicio de NFS había dejado de funcionar puntualmente y luego se recuperó solo sin que tuviese que hacer nada.
[[email protected] ~]# dmesg |tail
RPC: fragment too large: 1090519040
RPC: fragment too large: 469762048
RPC: fragment too large: 1247096314
RPC: fragment too large: 369295616
RPC: fragment too large: 1224736768
RPC: fragment too large: 1404416
RPC: fragment too large: 1986359923
RPC: fragment too large: 870215
RPC: fragment too large: 1701738089
RPC: fragment too large: 2130706432
[[email protected] ~]#
En el lado del cliente NFS, al ejecutar un simple df -h la salida del comando se quedaba bloqueada permanentemente sin mostrar ninguna información.
Causa del problema
En este caso la tarjeta de red que estaba dando el servicio había perdido link. El servicio se recuperó automáticamente, gracias a la configuración del bonding.
Sin embargo, este problema puede tener otra causa derivada de una reducción de la memoria del servidor NFS.
Cuando arranca el sistema operativo, el parámetro max_block_size, se calcula automáticamente en función de la memoria que tiene el servidor.
[[email protected] ~]# cat /proc/fs/nfsd/max_block_size
524288
[[email protected] ~]#
En base a este valor, los clientes NFS pueden leer y escribir en los filesystems compartidos con este tamaño de bloque máximo.
Ahora bien, si se reduce la memoria del servidor NFS y el tamaño de bloque máximo es menor al que hay configurado en los clientes NFS, obtendremos el error RPC: fragment too large.
Lo que tenemos que hacer si disminuimos la memoria del servidor NFS, es volver a montar los filesystems en los clientes para que vuelvan a adquirir los nuevos valores de rsize y wsize (tamaños de bloque de lectura y escritura).
mount.nfs: Protocol not supported
No nada como empezar la jornada laboral con una serie de filesystems NFS desmontados sin saber por qué. Pero, tirando del hilo, vemos que el equipo de comunicaciones ha cerrado las comunicaciones de los puertos NFS v3 así que, decido montarlo como NFS v4 modificando el fichero /etc/fstab de la siguiente manera:
10.48.40.30:/usr/sap/trans_RIX /usr/sap/trans_RIX nfs vers=4,rw,soft,intr,timeo=14 0 0
Pero, para mi sorpresa, el filesystem no monta, dando el siguiente error:
[[email protected] ~]# mount /usr/sap/trans_RIX
mount.nfs: Protocol not supported
[[email protected] ~]#
Solución
Tras estar un rato investigando, me doy cuenta de que en el servidor de NFS, alguien había deshabilitado el protocolo NFS v4, lo vuelvo a habilitar y reinicio el servicio de NFS:
[[email protected] ~]# grep RPCNFSDARGS /etc/sysconfig/nfs
#RPCNFSDARGS="-N 2 -N 3"
#RPCNFSDARGS="-N 4"
[[email protected] ~]#
Luego, reinicio el servidor de NFS:
service nfs restart
Y monto el filesystem desde el cliente, esta vez, sin problemas (mount /usr/sap/trans_RIX).
kernel: nfsd: peername failed (err 107)
El equipo de aplicaciones me comentaba que, de vez en cuando y de manera aleatoria, la aplicación sufría una breve desconexión y no sabían el motivo. Resulta que esta aplicación utiliza un filesystem NFS ubicado en un servidor de NFS que ha ido creciendo con el tiempo y, cada vez más, compartía más filesystems con más servidores.
Revisando el log del sistema operativo (/var/log/messages), aparecían de manera puntual, los siguientes mensajes de error de NFS:
May 22 19:01:33 lensnax1 kernel: nfsd: peername failed (err 107)!
May 22 19:02:07 lensnax1 kernel: nfsd: peername failed (err 107)!
May 22 19:02:07 lensnax1 kernel: nfsd: peername failed (err 107)!
May 22 19:02:07 lensnax1 kernel: nfsd: peername failed (err 107)!
May 22 19:02:07 lensnax1 kernel: nfsd: peername failed (err 107)!
May 22 19:02:07 lensnax1 kernel: nfsd: peername failed (err 107)!
Las horas coincidían con las desconexiones sufridas por la aplicación.
Origen del problema
Por lo visto, como el servicio de NFS ha ido creciendo, de vez en cuando, los diferentes clientes de NFS realizaban operaciones de lectura y escritura simultáneamente y se llenaba el buffer de memoria TCP del servidor NFS, causando los errores comentados anteriormente.
Revisando el problema en la WEB de RedHat, encontré este enlace https://access.redhat.com/solutions/63171, que decía que este error puede deberse a:
- Problemas de red
- Alto tráfico de red
- Problemas en el servidor de NFS
En mi caso, el problema estaba en el servidor NFS.
Solución
Para solucionarlo, modifqué los siguientes parámetros del kernel (RedHat 6 – /etc/sysctl.conf):
Valores originales del fichero sysctl.com
net.core.wmem_max = 124928
net.core.rmem_max = 124928
net.core.wmem_default = 124928
net.core.rmem_default = 124928
net.core.netdev_max_backlog = 1000
Nuevos valores
net.core.wmem_max = 1048576
net.core.rmem_max = 4194304
net.core.wmem_default = 1048576
net.core.rmem_default = 4194304
net.core.netdev_max_backlog = 3000
rmem y wmem es el tamaño en bytes de los bufferes de memoria para o escribir (wmem) y enviar (rmem) paquetes TCP, mientras que netdev es el número máximo de paquetes TCP que pueden encolarse antes de ser procesados.
Después de este cambio, ya no he vuelto a volver a ver estos mensajes de error.
Stale file handle
Me he encontrado con un servidor que no podía acceder un filesystem por NFS, pero este mismo FS sí que estaba accesible por otros cuatro servidores diferentes.
El error que daba era el siguiente:
[[email protected] ~]# ls -la /mnt/nas/jtc_pre/pscp
ls: cannot access /mnt/nas/jtc_pre/pscp: Stale file handle
[[email protected] ~]#
Por mi parte he intentado varias cosas para tratar de solucionarlo pero ninguna de ellas ha funcionado:
- Desmontar y volver a montar el FS:
umount -f /mnt/nas/jtc_pre/pscp
mount /mnt/nas/jtc_pre/pscp
- Eliminar la caché de filesystems y volver a montar el FS:
# To free pagecache
echo 1 > /proc/sys/vm/drop_caches
# To free dentries and inodes
echo 2 > /proc/sys/vm/drop_caches
# To free pagecache, dentries and inodes
echo 3 > /proc/sys/vm/drop_caches
- Reiniciar el servidor de NFS
Solución
Este FS se estaba montando con NFSv4 en las opciones de fstab. Lo que he hecho ha sido montarlo manualmente con NFSv3 y ha funcionado. Desconozco el motivo. Probablemente se deba a algún bug de NFS4.
[[email protected]~]# mount -t nfs -o vers=3,rw,suid,soft,intr,timeo=300,retrans=5 lcttnat1:/serveis/dades/PRE/NAS01/857_pre_psp/pscp_pre /mnt/nas/jtc_pre/pscp
[[email protected] ~]# ls -la /mnt/nas/jtc_pre/pscp
total 5860
drwxrwxr-x 26 pscp_pre pscp_pre 4096 Dec 15 16:34 .
drwxr-xr-x 4 root root 46 Dec 4 10:00 ..
drwxrwx--- 4 pscp_pre pscp_pre 4096 Apr 28 2010 customizedProfiles
drwxrwx--- 2 pscp_pre pscp_pre 4096 Jun 1 2016 dogcTemplates
Los ficheros se ven con el propietario nobody:nobody en el cliente NFS con NFS4
Según podemos ver en este artículo de RedHat, el problema se soluciona configurando el servicio idmapd con el mismo dominio en el lado del cliente y del servidor NFS:
[[email protected] etc]# grep Domain /etc/idmapd.conf
#Domain = local.domain.edu
Domain = midominio.com
[[email protected] etc]#
Luego tenemos que deshabilitar el idmapping:
Cliente NFS
# echo 'Y' > /sys/module/nfs/parameters/nfs4_disable_idmapping
Servidor NFS
# echo 'Y' > /sys/module/nfsd/parameters/nfs4_disable_idmapping
Una vez configurado el fichero, reiniciamos el servicio rpcidmapd (systemctl restart rpcidmapd) y hacemos el umount y el mount del FS para que monte con el usuario correcto (no sirve el remount). Es posible que tengamos que limpiar la caché de NFS (nfsidmap -c) o, incluso, reiniciar el servidor.
El servidor de NFS no responde pero hay comunicación
He tenido algunas incidencias con el montaje de filesystems NFS que me ha costado mucho tiempo resolver o averiguar su causa. Como ejemplo:
- Tengo un filesystem en un cliente NFS que apunta a un servidor de NFS que se ha quedado colgado. Esto quiere decir, que si intento hacer un «cd» o un «df» del FS el comando se queda colgado eternamente.
- En el mismo cliente NFS tengo otro filesystem NFS que sí monta correctamente hacia el mismo servidor NFS.
- Obviamente, el /etc/exports del servidor está configurado correctamente y no hay problemas de enrutamiento y reglas de firewall.
- En el log del sistema veo errores del tipo «kernel: nfs: server servidor_nfs not responding, timed out» pero el servidor de NFS está arrancado, el servicio también y NO hay problemas de reglas de firewalls.
- El comando mount nunca monta el filesystem. Se queda colgado eternamente.
Para volverse loco, ¿verdad? Pues bien, según podemos leer en el siguiente documento de SUSE y en este otro de RedHat, los elementos de red más modernos, como pueden ser routers, switches o firewalls tienen un cierto nivel de inteligencia que puede considerar maliciosos ciertos tipos o comportamientos de conexiones y las pueden bloquear automáticamente por seguridad.
La solución a esto pasa por reiniciar el elemento de red (router, etc.) o el cliente de NFS. Hacer un «umount -f -l » del FS afectado en el cliente no servirá para nada.
Como sabemos, una conexión tiene cuatro elementos básicos:
- IP del cliente NFS
- Puerto origen del cliente NFS
- IP del servidor NFS
- Puerto destino del servidor NFS
Algunas aplicaciones, como NFS, reutilizan la misma conexión. De hecho, es una práctica recomendada en la normativa RFC 1122. Pero si esta conexión se interrumpe por cualquier motivo y el cliente NFS la vuelve a reutilizar (mismo puerto origen), el elemento de red inteligente podría interpretarla como maliciosa y bloquearla.