03 November 2016

NFS是network file ststem的缩写,中文意思是网络文件系统。主要功能是通过网路让不同的主机系统之间可以共享文件或目录。NFS的客服端可以通过挂载(mount)的方式将NFS服务器端共享的数据目录挂载到客户端本地系统中(某个挂载点下)。在客户端本地看来就好像自己的磁盘分区或目录一样。

NFS在生产环境中的应用场景

一般用来存储共享视频,图片,附件等静态资源文件,通常用户上传的文件都会放在NFS共享里,然后前端服务器访问这些静态资源的时直接从nfs上读取资源。这种文件共享形式在中小规模的网站应用的比较频繁,在大型门户网站除了使用nfs外,还可能使用moosefs,GlusterFS,fastDFS等分布式文件系统。


NFS系统工作原理

nfs系统挂载结构介绍

在nfs服务器端设置好一个共享目录/video 后,有权限访问该服务器的客户端都可以挂载该目录,挂载点可以任意指定。

假如: server端目录为:/video ,client1挂载点为:/dev/video ,client2挂载点为:/dev/v

client1 端:
df -h
mount 10.20.0.254:/video /dev/video    #10.20.0.254 是服务端ip
-----------------------------------
client2 端:
df -h
mount 10.20.0.254:/video /dev/v    

nfs系统是通过网络进行数据传输的,nfs必然会使用端口来传输数据,那么nfs客户端是怎么知道nfs服务器使用的是哪个端口的呢?

答案就是RPC协议。

什么是RPC协议

RPC 是remote proceduce call 的缩写,称为远程过程调用。

因为nfs支持的功能比较多,不同的功能会使用不同的程序来启动,就会占用不同的端口,由于端口是不固定的,所以就会造成nfs客户端和服务端通信障碍。

RPC的功能就是记录每个nfs程序所对应的端口号,并且在nfs客户端请求时将该端口和功能对应的信息传递给请求数据的nfs客户端,从而实现数据传输的目的。

当nfs服务启动时会随机取若干端口,并主动向rpc服务注册相关端口和功能信息。然后rpc服务使用固定的111端口来监听nfs客户端提交的请求,并将正确的nfs端口信息返回给请求的nfs客户端。

在启动nfs 服务之前,先要启动rpc服务(centos5.8下为portmap,centos6.6下为rpcbind),另外,如果rpc服务重新启动,原来已经注册好的nfs端口数据就会丢失,因此,启动了rpc服务后nfs服务也需要重新启动以重新向rpc服务注册端口信息。

ps : 修改nfs配置文件,是不需要重启nfs,执行:/etc/init.d/nfs reload 或者exportfs -rv 可以使修改的/etc/exports生效。


NFS系统搭建

nfs服务器端环境搭建

安装环境

centos6.8 x86_64 redhat2.6

需要安装的软件

nfs-utils :nfs主程序,包括rpc.nfsd,rpc.mountd等。 rpcbind:centos6.X下的rpc主程序。

安装

rpm -qa nfs-utils rpcbind
yum install nfs-utils rpcbind -y
rpm -qa nfs-utils rpcbind

启动rpcbind

LANG=en     #调整系统字符集
/etc/init.d/rpcbind status      #检查状态
rpcinfo -p localhost    #rpc服务未启动检查
/etc/init.d/rpcbind start      #启动服务
lsof -i:111
netstat -lntup | grep rpcbind
chkconfig --list rpcbind    #查看是否开机启动

启动NFS服务

LANG=en
/etc/init.d/rpcbind status      #先检查rpcbind是否启动
/etc/init.d/nfs status          #检查nfs的状态
/etc/init.d/nfs start           #启动nfs服务
/etc/init.d/nfs status          #检查nfs的状态

配置rpcbind和nfs开机启动

chkconfig rpcbind on
chkconfig nfs on

建议把所有的开机启动项,都写入/etc/rc.local文件中,做好注释,便于管理。
vim /etc/rc.local

#start rpcbind and nfs
/etc/init.d/rpcbind start       #启动rpcbind服务
/etc/init.d/nfs start           #启动nfs服务

创建共享目录并授权

mkdir -p /share
touch /share/dnzhu.txt      #测试文件
chown -R nfsnobody.nfsnobody /share  
ls -ld /share

配置nfs服务配置文件

vim /etc/exports
#shared /share 
/share 10.0.0.0/24(rw.sync)
exports -rv
sed -i 's#rw.sync#rw,sync#g' /etc/exports
exports -rv     #使配置生效
showmount -e localhost   #nfs本地查看挂载情况
cat /var/lib/nfs/etab    #查看nfs server配置文件参数
mount -t nfs  10.20.0.254:/share /mnt   #将目录挂载到本地/mnt上测试
df -h

NFS client端配置

安装相关软件

yum install rpcbind nfs-utils -y
rpm -qa nfs-utils rpcbind

启动rpc服务(无需启动nfs)

/etc/init.d/iptables stop   #先关闭防火墙
LANG=en
/etc/init.d/rpcbind status
/etc/init.d/rpcbind start
showmount -e 10.20.0.254    

客户端挂载共享目录

showmount -e 10.20.0.254    
mount -t nfs 10.20.0.254:/share /mnt
df -h   #查看磁盘目录
mount   #查看挂载情况

将rpcbind服务和挂载加入开机启动

vim /etc/rc.local

#rpcbind service start on boot
/etc/init.d/rpcbind start
/bin/mount -t nfs 10.20.0.254:/share /mnt

NFS系统优化

指定固定用户配置nfs共享

useradd nfsuser -u 888 -g nfsuser
mkdir -p /data
chown -R /nfsuser.nfsuser /data
ls -ld /data

mount挂载参数优化

参数说明:

  • 1.atime ,在每次数据访问时,会同步更新访问文件的inode时间戳,在高并发下,建议加上noatime。
  • 2.nodiratime,不更新文件系统上的directory inode时间戳。
  • 3.nosuid,不允许set-user-identifier or set-group-identifier生效。
  • 4.noexec,是否具有执行文件的权限,设置为noexec。
  • 5.nodev,是否可以保留装置文件的特殊功能,选择nodev。
  • 6.rsize和wrize,读出和写入的区块大小,数据缓冲区的大小。
mount -t nfs -o noatime,nodiratime,nosuid,noexec,nodev,rsize=131072,wsize=131072 10.20.0.254:/share /mnt

nfs系统内核优化

cat >>/et/systcl.cnf<<EOF
net.core.wmem_default = 8388608     #发送套接字缓冲区大小,默认124928
net.core.rmem_default = 8388608     #接收套接字缓冲区大小,默认124928
net.core.rmem_max = 16777216        #接收套接字缓冲区大小最大值,默认124928
net.core.wmem_max = 16777216        #发送套接字缓存区大小最大值,默认是124928字节
EOF
sysctl -p      #使配置生效


NFS服务端防火墙设置

允许内网某ip段访问,设置如下:

iptables -A INPUT -s 10.0.0.0/24 -j ACCEPT