分享

NFS的介绍和一些问题的总结

 guli3057 2014-05-26
  1 NFS简介

网络文件系统(Network File System),通常我们都直接称呼其名为NFS,它可以在计算机间共享文件系统。NFS对用户几乎是透明的,并且是“无状态的”,这意味着当NFS服务器崩溃时不会丢失任何信息。客户机只是等着服务器恢复正常,然后就好像什么也没有发生过一样继续工作。


2 NFS服务器 

RPC(NFS服务需要依赖RPC服务,这个比较重要)

要想了解NFS,必然要提到RPC这个服务。
因为NFS支持的功能还是比较多的,并且不同的功能都会使用不同的程序来启动。每启动一个功能就会启用一些端口来传输数据,因此NFS的功能所对应的端口才没有固定,而是采用随机取用一些未被使用的小于1024的端口来作为传输之用。但如此一来又造成客户端要连接服务器时的困扰,因为客户端要知道服务器端的相关端口才能够联机,此时我们需要远程过程调用(RPC)的服务。
RPC最主要的功能就是指定每个NFS功能所对应的端口号,并且回报给客户端,让客户端可以连接到正确的端口上。当服务器在启动NFS时会随机选用数个端口,并主动地向RPC注册。因此RPC可以知道每个端口对应的NFS功能。然后RPC固定使用端口111来监听客户端的请求并回报客户端正确的端口,所以可以让NFS的启动更为容易。
注意,启动NFS之前,要先启动RPC服务;否则NFS无法向RPC注册。另外,重新启动RPC时原本注册的数据会不见,因此RPC重新启动后它管理的所有程序都需要重新启动以重新向RPC注册,比如NFS服务。

当客户端有NFS文件要存取请求时,它向服务器端访问数据,有如下几个步骤:
(1)客户端会向服务器端的RPC(port 111)发出NFS文件存取功能的询问请求。
(2)服务器端找到对应的已注册的NFS daemon端口后会回报给客户端。
(3)客户端了解正确的端口后,就可以直接与NFS守护进程来联机,然后访问数据。

其实,我们可以简单的理解为:NFS当作RPC服务中的一种,同时将RPC服务当作NFS服务器与NFS客户端的中间接口人,就是说NFS客户端访问NFS服务器,必须经过RPC这个接口人,才可以去访问,否则就直接死翘翘了。

注:NFS使用TCP/IP提供的协议和服务,并且位于OSI模型中的应用层,具体如下:
层    数 名    称 功    能
1 应用层 NFS
2 表示层 XDR
3 会话层 RPC
4 传输层 UDP,TCP
5 网络层 IP
6 数据链路层
7 物理层 Ethernet

3 安装和配置NFS服务(只介绍SUSE版本的NFS的安装)
3.1.1 安装NFS服务
此步骤就直接跳过了,具体需要哪些包,可以到已经安装NFS服务的环境上面查看。
执行命令即可查看:rpm -qa | grep nfs
 
配置NFS服务,分为客户端和服务端配置。
3.1.2 服务端配置,设定10.137.21.166为NFS服务器:
步骤如下:
1)服务端主要配置/etc/exports文件。
我们将需要共享出去的文件系统直接编辑到/etc/exports文件中,这样当NFS服务器重新启动时,系统就会自动读取/etc/exports文件,从而告诉内核要输出的文件系统和相关的存取权限。

查看一个已经配置好的exports文件,如下:
i2ksvr:~ # cat /etc/exports
/home/cabtimer/sharedisk/index/share 10.137.17.154(rw,async)
/home/impidx/sharedisk/searchidx *(rw,sync,anonuid=2900,all_squash)

注:下面介绍一些配置文件中常用的参数含义,以及客户端的IP地址的格式。
rw:可读写权限。
ro:只读权限。
no_root_squash:当登录NFS服务器主机使用共享目录的使用者是root时,其权限将被转换成为匿名使用者,通常它的UID与GID都会变成nobody身份。
root_squash;如果登录NFS主机使用共享目录的使用者是root,那么对于这个共享的目录来说,它具有root的权限,这样会涉及到安全性的问题。
all_squash:忽略登录NFS使用者的身份,其身份都会被转换为匿名使用者,通常即nobody。
anonuid:通常为nobody,也可以自行设定这个UID的值,UID必须存在于/etc/passwd中。 
anongid:同anonuid,但是变为Group ID。
sync:同步写入资料到内存与硬盘中。
async:资料会先暂存于内存中,而非直接写入硬盘。

共享给客户端的主机的IP地址可以使用以下格式。
单个机器:一个全限定域名(能够被服务器解析)、主机名(能够被服务器解析)或IP地址。 
使用通配符来指定的主机名或域名,使用 * 或 ?字符来指定一个字符串匹配。IP地址中不使用通配符。

IP网络:使用a.b.c.d/z,a.b.c.d是网络,z是子网掩码中的位数(如192.168.0.0/24)。另一种可以接受的格式是a.b.c.d/netmask,a.b.c.d是网络,netmask是子网掩码(如192.168.70.8/255.255.255.0)。
一般常用的是IP地址,或直接用*代替,共享给所有的机器。
如上面举例的配置,一个指定了共享给固定IP的机器,另一个共享给所有的机器。

2)启动RPC服务
用法: /etc/init.d/portmap {start|stop|restart|force-reload|reload|status}

i2ksvr:~ # /etc/init.d/portmap start
Starting RPC portmap daemon                                         done
   (或直接执行rcportmap start)

查看状态
i2ksvr:~ # /etc/init.d/portmap status
Checking for RPC portmap daemon:                                  running
   
   查看111号端口是否处于监听状态和详细信息
i2ksvr:~ # netstat -utln | grep 111
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      
udp        0      0 0.0.0.0:111             0.0.0.0:*     

i2ksvr:~ # lsof -i :111
COMMAND   PID   USER   FD   TYPE    DEVICE SIZE NODE NAME
portmap 23048 nobody    3u  IPv4 398290132       UDP *:sunrpc 
portmap 23048 nobody    4u  IPv4 398290133       TCP *:sunrpc (LISTEN)   
  
  可以看到会有TCP和UDP两个协议,之前NFS一直使用UDP协议,后来默认采用TCP协议了。

注:以上版本是SuSe 10或之前的版本,而SuSe 11版本开始有点不同,SuSe 11版本启动RPC服务的方式为/etc/init.d/rpcbind start

3)启动NFS Server服务
用法:/etc/init.d/nfsserver {start|stop|status|try-restart|restart|force-reload|reload}


   i2ksvr:~ # /etc/init.d/nfsserver start
Starting kernel based NFS server                                      done
  (或直接执行rcnfsserver start)

   查看状态:
i2ksvr:~ # /etc/init.d/nfsserver status
Checking for kernel based NFS server:                                running

4)查看共享出去的文件
执行showmount –e命令,查看共享的信息。查看本机时,不需要指定IP地址,此命令主要用在NFS客户端,用来查看NFS服务器共享出来的目录资源:

i2ksvr:~ # showmount –e 
Export list for i2ksvr:
/home/impidx/sharedisk/searchidx     *
/home/cabtimer/sharedisk/index/share 10.137.17.154

或执行
i2ksvr:~ # showmount -e 10.137.21.166
Export list for 10.137.21.166:
/home/impidx/sharedisk/searchidx     *
/home/cabtimer/sharedisk/index/share 10.137.17.154

以上都说明NFS服务器共享成功了。

5)介绍其他一些常用的命令和文件,有的很重要。
   exportfs命令
exportfs [-aruv]
参数说明如下:
-a:全部挂载(或卸载)/etc/exports文件内的内容。
-r:重新挂载/etc/exports中的设置,此外同步更新/var/lib/nfs/xtab文件中的内容。
-u:卸载某一目录。
-v:在export时将共享的目录显示在屏幕上。
   比较常用的命令是:
   exportfs –rv  使配置重新生效


   如果修改了/etc/exports文件,执行该exportfs命令重新读取/etc/exports文件,从而就不需要重启NFS服务了。
   


showmount命令:
 showmount [-ae] hostname
参数说明如下:
-a或-all:显示客户主机名和挂载点目录。
-d或-directories:仅显示被客户挂载的目录名。
-e或-exports:显示NFS服务器的输出清单。
-h或-help:显示帮助信息。
-v或-version:显示版本信息。
–no-headers:禁止输出描述头部的信息。


当要扫描某一主机所提供的NFS共享的目录时,使用showmount -e IP(或主机名称hostname)即可。


 /var/lib/nfs/xtab和/var/lib/nfs/etab文件:
/var/lib/nfs/etab,主要记录了NFS所分享出来的目录的完整权限设定值;
/var/lib/nfs/xtab,记录曾经连接到此NFS主机的相关客户端数据。


6)设置NFS Server开机自启动
  查看nfsserver服务的开机自启动状态,默认是任何启动状态都没有启动nfsserver的。
i2ksvr:~ # chkconfig --list nfsserver
nfsserver                 0:off  1:off  2:off  3:off  4:off  5:off  6:off
 
  设置nfsserver在开机为多用户模式和图形界面模式时,自启动nfsserver服务
i2ksvr:~ # chkconfig --level 35  nfsserver on
i2ksvr:~ # chkconfig --list nfsserver
nfsserver                 0:off  1:off  2:off  3:on   4:off  5:on   6:off




3.1.3 客户端配置,设定10.137.17.154为NFS客户端:


推荐客户端使用mount命令来挂载,也可以直接编辑/etc/fstab文件的方法。
下面会介绍这两种方法:


1)使用mount命令挂载
mount命令的格式如下:
mount[-t vfstype] [-o  options] device dir
mount命令参数非常多,下面就只列些常用的参数,红色标注的为重要部分:
(1)-a:把/etc/fstab中列出的路径全部挂载。
(2)-t:需要mount的类型,如nfs等。
(3)-r:将mount的路径定为read only。
(4)-v mount:过程的每一个操作都有message传回到屏幕上。
(5)rsize=n:在NFS服务器读取文件时NFS使用的字节数,默认值是1 024个字节。
(6)wsize=n:向NFS服务器写文件时NFS使用的字节数,默认值是1 024个字节。
(7)timeo=n:从超时后到第1次重新传送占用的1/7秒的数目,默认值是7/7秒。
(8)retry=n:在放弃后台mount操作之前可以尝试的次数,默认值是7 000次。
(9)soft:使用软挂载的方式挂载系统,若Client的请求得不到回应,则重新请求并传
错误信息。
(10)hard:使用硬挂载的方式挂载系统,该值是默认值,重复请求直到NFS服务器回应。
(11)intr:允许NFS中断文件操作和向调用它的程序返回值,默认不允许文件操作被中断。
(12)fg:一直在提示符下执行重复挂载,即前台继续执行挂载。
(13)bg:如果第1次挂载文件系统失败,继续在后台尝试执行挂载。
(14)tcp:对文件系统的挂载使用TCP,而不是默认的UDP。
(15)-w:将mount的路径定为read/write,这个是默认的配置参数。
  
   重点说明一下软挂载和硬挂载方式的不同:


对硬挂载文件系统来说,如果因为某种原因远程系统的响应失败,比如NFS服务端挂掉等,则NFS客户端将会持续地尝试建立连接,这样可能导致执行df等命令出现挂死的现象。
而对软挂载文件系统来说,同样情况下,在指定的时间间隔后NFS客户端将会放弃尝试建立连接而发送一个错误消息。
默认采用硬挂载文件系统,系统硬挂载尝试失败时,对用户输入的响应也会停止。正是因为这样,有的用户更喜欢采用软挂载,它会使系统在尝试挂载失败后停止尝试。


其实,使用hard还是soft主要取决于访问的信息。例如,要查看NFS服务器的视频文件,不会希望由于一些意外的情况(如网络速度变得很慢)而使系统输出大量的错误信息。如果此时使用hard方式,系统就会等待,直到能够重新与NFS服务器建立连接传输信息。另外,如果是非关键数据,也可以使用hard方式,如FTP一些数据等,这样在远程机器暂时连接不上或关闭时就不会挂起会话过程。


mount挂载的示例:
mount -t nfs -o rw,soft,timeo=1,retry=1  
10.137.21.166:/home/cabtimer/sharedisk/index/share /test
将NFS服务端的/home/cabtimer/sharedisk/index/share挂载到本地的/test目录下。


umount命令执行卸载的示例:
umount /test


注:如果umount挂载点时,出现长时间不返回,挂死的情况,如下解决:
通过lsof | grep /test找出哪个进程在访问挂载点;
确定该挂载目录不再访问的情况下,使用kill -9命令清理前面找出的访问挂载点的进程,再重新执行umount命令就可以了;


2)直接配置/etc/fstab文件
   (1)编辑/etc/fstab文件,加入挂载NFS服务端的共享的目录到本地目录上,如下,加入了最下面的两行共享内容。


  rcs_solution:~ # cat /etc/fstab
/dev/sda2          /                    reiserfs   acl,user_xattr        1 1
/dev/sda5          /home                reiserfs   acl,user_xattr        1 2
/dev/sda6          /opt                 reiserfs   acl,user_xattr        1 2
/dev/sda7          /var                 reiserfs   acl,user_xattr        1 2
/dev/sda1          swap                 swap       defaults              0 0
proc               /proc                proc       defaults              0 0
sysfs              /sys                 sysfs      noauto                0 0
debugfs            /sys/kernel/debug    debugfs    noauto                0 0
usbfs              /proc/bus/usb        usbfs      noauto                0 0
devpts             /dev/pts             devpts     mode=0620,gid=5       0 0
shm              /dev/shm             tmpfs      size=16348644K        0 0
10.137.21.166:/home/cabtimer/sharedisk/index/share /test nfs soft,timeo=1 0 0
  
(2)配置/etc/fstab文件后,直接启动NFS客户端,即可挂载NFS服务器共享的目录。
     启动NFS Client:
     /etc/init.d/nfs start
     (或直接执行rcnfs start启动)
   
(3)执行df -h查看挂载的信息:
rcs_solution:~ # df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2              61G   14G   47G  24% /
udev                   16G  140K   16G   1% /dev
/dev/sda5              41G   21G   20G  51% /home
/dev/sda6              41G   35G  5.9G  86% /opt
/dev/sda7              11G  878M  9.2G   9% /var
shm                    16G  6.3G  9.4G  41% /dev/shm
/dev/sda8             387G   25G  363G   7% /home1
10.137.21.166:/home/cabtimer/sharedisk/index/share
                         41G   21G   20G   51% /test
 
4 NFS的常见故障的解决方案
4.1.1 NFS如果出现了问题,可以从以下几个方面去考虑:
(1)/etc/exports文件配置是否正确
(2)RPC和NFS服务是否启动正常
(3)mount命令和/etc/fstab中的参数是否正确
(4)服务端的IP地址是否正常,能否ping通。
(5)执行rpcinfo命令查看系统的RPC相关的信息。
在服务端执行命令,可以看到如下的信息:
2ksvr:~ # rpcinfo -p
    100000    2   tcp    111  portmapper
    100000    2   udp    111  portmapper
    100003    2   udp   2049  nfs
    100003    3   udp   2049  nfs
    100003    4   udp   2049  nfs
    100003    2   tcp   2049  nfs
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100024    1   udp  45347  status
    100021    1   udp  45347  nlockmgr
    100021    3   udp  45347  nlockmgr
    100021    4   udp  45347  nlockmgr
    100024    1   tcp  38193  status
    100021    1   tcp  38193  nlockmgr
    100021    3   tcp  38193  nlockmgr
    100021    4   tcp  38193  nlockmgr
    100005    1   udp    785  mountd
    100005    1   tcp    786  mountd
    100005    2   udp    785  mountd
    100005    2   tcp    786  mountd
    100005    3   udp    785  mountd
    100005    3   tcp    786  mountd
在NFS客户端,至少应该有portmapper。




4.1.2 NFS中的一些错误信息的具体含义:
错误信息 具体描述
Too many levels of remote in path 试图挂载一个存在的文件系统
Permission denied                             客户端没有权限去挂载NFS服务器的共享目录,也可能是因为用户在服务器上不存在
No such file or directory 通常是访问的目录不存在
NFS server is not responding 通常是NFS已经超过负载或者NFS已经停止工作
Stale file handle 在NFS客户端关闭之前客户端访问的文件被删除


解决问题如下:
(1)如果启动NFS服务器失败,如下
i2ksvr:~ # /etc/init.d/nfsserver start
Starting kernel based NFS serverCannot register service: RPC: Unable to receive; errno = Connection refused
startproc:  exit status of parent of /usr/sbin/rpc.mountd: 1
                                                                      failed
则说明,RPC服务没有启动。如果已经启动,则可能是被防火墙所屏蔽。
解决方案是:执行/etc/init.d/portmap start后,再启动nfsserver即可。或者关闭防火墙。


(2)如果执行如下的mount命令失败,如下
i2ksvr:~# mount -t nfs 10.137.21.166:/home/cabtimer/sharedisk/index/share /test
rpcbind: server localhost not responding, timed out
RPC: failed to contact local rpcbind server (errno 5).
rpcbind: server localhost not responding, timed out
RPC: failed to contact local rpcbind server (errno 5).


解决方案是:在mount命令中加入-o nolock选项就可以了。


 (3)当在客户端执行mount挂载NFS服务器共享目录时,如果错误信息是“Permission denied”,则表示NFS服务器不允许客户机挂载。


解决方案是:更改服务端上的/etc/exports文件来解决问题,并使用exportfs-rv命令重新导出共享目录。


  (4)如果出现的错误是“Program not registed”,则是NFS服务可能没有启动或者运行不正常。
解决方案是:重新启动NFS服务。


(5)挂载共享目录的时候,如果客户端没有任何反应,则可能为客户端没有启动RPC服务。
解决方案是:启动portmap服务,然后再执行挂载的操作。


(6)显示“设备正忙”无法卸载。
在使用umount命令卸载共享目录时,出现“device is busy”等卸载失败消息。通常可能的原因是有一个进程仍然在使用这个目录。
解决方案是:可以使用lsof命令来查看是否有进程正在使用该共享目录,然后执行kill -9操作,杀掉这些进程,最后再执行umount操作。


(7)NFS请求挂起
如果客户端正在执行写操作,而此时服务器无法响应或者在网络上变得不可访问,那么在默认情况下(使用hard选项进行挂载)客户端进程将挂起直到写操作完成。如果不中止写操作,进程就不能从请求中退出。
解决方案是:这个需要根据实际的应用场合来考虑。一般情况下,为了避免NFS请求挂起,在网络状况不稳定情况下可以在挂载目录时指定soft选项以允许操作因超时而退出,或者指定intr选项以允许用户在命令行上通过按下Ctrl+C组合键退出挂起的操作。


(8)NFS挂载在引导时挂起。
如果在/etc/fstab文件中设置了自动挂载NFS,但在系统引导时NFS共享目录暂时不可用,那么默认情况下引导进程将进入等待状态,直到NFS目录变得可用为止。如果所需等待的NFS目录是系统必须的,那么这种等待可能还可以接受。然而在很多情况下,用户只想让系统把挂载请求放在后台并继续引导系统。可以把bg选项添加到/etc/fstab文件中,这样在首次挂载请求超时之后,挂载请求会转入后台,系统继续引导。当需要在前台挂载NFS共享目录时可以将fg选项添加到/etc/fstab文件的挂载选项中。




5 NFS客户端参数的优化
在一些业务当中,出现过因为NFS服务器的IP地址down掉,或者异常等情况,导致了NFS客户端访问进程的长时间处于挂死的状态,没有响应。


查看了NFS的官方网站,里面介绍了一些优化的参数,比如说,客户端需要加入
参数:soft,timeo=1,retry=1,tcp(默认就是采用tcp协议),其实就是采用软连接的方式去挂载NFS服务器共享的目录,这样NFS客户端就不会出现挂死的现象。


举例:
mount -t nfs -o rw,soft,timeo=1,retry=1 
10.137.21.166: /home/cabtimer/sharedisk/index/share /test




6 附录:设置系统防火墙,开放portmap端口号
打开portmap的端口号
iptables -A INPUT -p TCP --dport 111 -j ACCEPT
iptables -A INPUT -P UDP --dport 111 -j ACCEPT
iptables-save > /etc/sysconfig/iptables


在文件/etc/hosts.allow文件中加入如下内容,允许这些服务访问:
portmap:ALL
nfsserver:ALL
nfs:ALL  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多