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 |
|