nfs网络文件系统
-
什么是NFS系统?
NFS是Network File System 的缩写,它的主要功能是通过网络让不同的机器系统之间可以彼此共享文件和目录。
NFS服务器可以允许NFS客户端,将远端NFS服务器端的共享目录,挂载到本地NFS客户端中。(注NFS客户端一般为应用服务器如:web)
NFS服务器端共享的目录就好像NFS客户端自己的磁盘分区和目录一样。
一般客户端挂载到本地目录的名字可以随便,但为方便管理,建议和服务器端一样比较好。
NFS一般是用来存储共享视频、图片等静态数据(对于用户上传的文件都存放在NFS共享里,图片、视频),是当前互联网系统架构中最常用的数据存储服务之一,特别是中小公司应用频率很高。(注大公司或门户使用:MFS,GFS FASTFS,分布式系统)
-
NFS挂载结构图
1、客户端/data/shard 目录里面的内容最好为空,要不挂载之后会暂时查找不到
2、客户端要想存放文件成功必须服务端有把共享文件的权限打开
3、客户端本地持载的时候,也是有权限设置 -
NFS挂载原理详细介绍
当我们在NFS服务器端设置好共享存储目录/data/shard的后,其它的有权限访问NFS服务器端的NFS客户端可以将这个服务器上/data/shard共享目录,挂载到NFS客户端本地系统上的某个挂载点(其实就是一个目录,这个目录可以自己随意指定),上图中两个NFS客户端本地的挂载点都是/data/shard,
当正确挂载完毕后,进入到指定nfs客户端的/data/shard目录,就可以看到NFS服务器端/data/shard共享出来的目录下的所有数据,几乎感觉不到区别,根据NFS服务端授予的NFS共享权限,只要在指定的NFS客户端操作挂载点/data/shard的目录,就可以将数据轻松的存取到NFS服务器端上的/data/shard目录中
挂载NFS后,NFS客户端本地的挂载内容显示如下,使用命令:df –h
在客户端查看挂载详细信息的命令:cat /proc/mounts
在服务器端看挂载默认的参数:使用命令:cat /var/lib/nfs/etab
NFS是通过网络来进行服务端和客户端之间的数据传输。两者之间要传输数据就要有想对应的网络端口来进行传输。NFS服务器到底使用什么网络端口来传输数据的,NFS服务器端其实是随机选择端口来进行数据传输。那NFS客户端又是如何知道NFS服务器端到底使用的是哪个端口呢?其实NFS服务器时通过远程过程调用(remote procedure call 简称RPC)协议/服务来实现的。也就是说RPC服务会统一管理NFS的端口,客户端和服务端通过RPC来先沟通NFS使用了哪些端口,之后再利用这些端口(小于1024)来进行数据的传输。
(注:原来是RPC管理服务端的NFS端口分配,客户端要传数据,那客户端的RPC会先跟服务端的RPC去要服务器的端口,要到端口后再建立连接,然后传输数据)
这个rpc服务的应用在门户级的网站无处不在,(百度) -
《rpc与nfs》
rpc(注在centos5.x系统里面是portmap服务、centos6.x系统里面是rpcbind服务)就是用来统一管理NFS端口的服务,并且统一对外的端口是111。NFS服务端需要先启动rpc,再启动NFS,这样NFS才能够到RPC去注册端口信息。客户端的RPC可以通过向服务端的RPC请求获取服务端的NFS端口信息。当获取到了NFS端口信息后,就会以实际端口进行数据的传输。(由于NFS端口为随机的。) -
《RPC和NFS如何通讯》
因为NFS有很多功能,不同的功能需要使用不同的端口。因此NFS无法固定端口。而RPC会记录NFS端口的信息,这样我们就能够通过RPC实现服务端和客户端的RPC来沟通端口信息。
那RPC和NFS之间又是如何之间相互通讯的?
首先当NFS启动后,就会随机的使用一些端口,然后NFS就会向RPC去注册这些端口。RPC就会记录下这些端口。并且RPC会开机111端口,等待客户端RPC的请求,如果客户端有请求,那服务端的RPC就会将记录的NFS端口信息告知客户端。
提示:在启动NFS SERVER之前,首先要启动RPC服务(即portmap或rpcbind服务,下同)否则NFS SERVER就无法向RPC服务区注册,另外,如果RPC服务重新启动,原来已经注册好的NFS端口数据就会全部丢失。因此此时RPC服务管理的NFS程序也要重新启动以重新向RPC注册。特别注意:一般修改NFS配置文档后,是不需要重启NFS的,直接在命令执行/etc/init.d/nfs reload或exportfs –rv即可使修改的/etc/exports生效。
(注:这里有个启动顺序的点,先给大家讲清楚。因为NFS要向RPC注册端口信息。所以RPC一定要先于NFS早启动。我给大家比喻一个左手叠右手的游戏,此时就是一定要确保NFS的手掌(左)在RPC手掌(右)的上面。正常顺序是要RPC先叠上去,然后NFS再叠上去。如果RPC重启了,就相当于手掌抽出来了,然后重新叠上去。这样RPC就在NFS上面了,所以不行。此时我们的NFS就需要再重新启动一次。这样NFS抽出来然后再叠上去之后,NFS就在RPC上面了。如果NFS修改了配置,就直接reload就好了) -
《客户端NFS和服务端NFS通讯过程》
1、首先服务器端启动RPC服务,并开启111端口
2、启动NFS服务,并向RPC注册端口信息
3、客户端启动RPC(portmap服务),向服务端的RPC(portmap)服务请求服务端的NFS端口
4、服务端的RPC(portmap)服务反馈NFS端口信息给客户端。
5、客户端通过获取的NFS端口来建立和服务端的NFS连接并进行数据的传输。
nfs实战
1、首先在nfs服务端及客户端安装nfs-utils和rpcbind
yum install nfs-utils rpcbind -y
安装好后启动rpcbind和nfs服务,这里强调一下,一定要先启动rpcbind再启动nfs,因为nfs的发布依赖于rpcbind
/etc/init.d/rpcbind start
chkconfig rpcbind on
rpcinfo -p localhost
/etc/init.d/nfs start
chkconfig nfs on
rpcinfo -p localhost
最好将这两个服务都加到开机启动的脚本里
[root@NFS ~]# cat /etc/rc.local #!/bin/sh # # This script will be executed *after* all the other init scripts. # You can put your own initialization stuff in here if you don't # want to do the full Sys V style init stuff. touch /var/lock/subsys/local /etc/init.d/rpcbind start /etc/init.d/nfs start
那么如何保证服务器重启后rpcbind优先于nfs先启动呢
可以通过查看他们的程序脚本,就可以看到他们的启动顺序了
[root@lamp01 ~]# less /etc/init.d/rpcbind #! /bin/sh # # rpcbind Start/Stop RPCbind # # chkconfig: 2345 13 87 # description: The rpcbind utility is a server that converts RPC program \ # numbers into universal addresses. It must be running on the \ # host to be able to make RPC calls on a server on that machine. # # processname: rpcbind # probe: true # config: /etc/sysconfig/rpcbind
[root@lamp01 ~]# less /etc/init.d/nfs #!/bin/sh # # nfs This shell script takes care of starting and stopping # the NFS services. # # chkconfig: - 30 60 # description: NFS is a popular protocol for file sharing across networks. # This service provides NFS server functionality, which is \ # configured via the /etc/exports file. # probe: true # config: /etc/sysconfig/nfs
rpcbind启动顺序为13 而nfs的启动顺序为30,所以rpcbind的启动过程要优先于nfs
查看服务的启动进程
[root@NFS ~]# ps -ef|grep -E 'rpc|nfs' root 2573 2 0 14:34 ? 00:00:00 [rpciod/0] rpc 2683 1 0 14:40 ? 00:00:00 rpcbind root 2803 1 0 14:49 ? 00:00:00 rpc.rquotad root 2808 1 0 14:49 ? 00:00:00 rpc.mountd root 2815 2 0 14:49 ? 00:00:00 [nfsd4] root 2816 2 0 14:49 ? 00:00:00 [nfsd4_callbacks] root 2817 2 0 14:49 ? 00:00:00 [nfsd] root 2818 2 0 14:49 ? 00:00:00 [nfsd] root 2819 2 0 14:49 ? 00:00:00 [nfsd] root 2820 2 0 14:49 ? 00:00:00 [nfsd] root 2821 2 0 14:49 ? 00:00:00 [nfsd] root 2822 2 0 14:49 ? 00:00:00 [nfsd] root 2823 2 0 14:49 ? 00:00:00 [nfsd] root 2824 2 0 14:49 ? 00:00:00 [nfsd] root 2851 1 0 14:49 ? 00:00:00 rpc.idmapd root 2994 2 0 15:31 ? 00:00:00 [nfsiod] root 2995 2 0 15:31 ? 00:00:00 [nfsv4.0-svc]
2、修改nfs的配置文件,发布挂载共享目录
[root@NFS ~]# cat /etc/exports /data 192.168.182.0/24(rw,sync,all_squash)
这里的all_squash表示客户端访问nfs服务的时候
然后再用exportfs -rv使nfs配置文件生效都要压缩成nfsnobody用户,这样才能保证挂载点的文件可修改。
这个命令相当于 /etc/init.d/nfs reload,这个可以从nfs的程序文件看出
[root@NFS ~]# grep 'reload' -A 2 /etc/init.d/nfs reload | force-reload) /usr/sbin/exportfs -r [ -f /var/lock/subsys/nfs ] && touch /var/lock/subsys/nfs
3、nfs配置文件设置好后就可以查看可挂载的nfs,用showmount(客户端必须安装nfs,才能使用这个命令)
[root@NFS ~]# showmount -e 127.0.0.1 Export list for 127.0.0.1: /data 192.168.182.0/24
查看到nfs挂载没问题了就可挂载了
mount -t nfs 192.168.182.141:/data /mnt
挂载好后进入挂载点操作提示没权限,这时候就要检查服务端的权限问题
如果nfs的exports配置文件的权限没问题,那么就是服务端的目录权限问题
[root@NFS ~]# cat /var/lib/nfs/etab /data 192.168.182.0/24(rw,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,no_subtree_check,secure_locks,acl,anonuid=65534,anongid=65534,sec=sys,rw,root_squash,no_all_squash)
进过cat /var/lib/nfs/etab查看可以看到服务端nfs服务挂载的参数,这里的anongid=65534,anonuid=65534就是访问nfs服务端所使用的身份
根据uid来查看用户名,而且这个uid在服务器及每台客户端上都要有才行。如果有的客户端没有这个uid的话,那就添加和nfs服务端一样就行了
[root@nfs-server ~]# grep '65534' /etc/passwd nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
根据uid查找到的用户名来修改目录权限
chown -R nfsnobody /data
这样客户端就可以向挂载点写入数据了
cat /proc/mounts 查看客户端挂载的参数
[root@lnmp01 ~]# cat /proc/mounts rootfs / rootfs rw 0 0 proc /proc proc rw,relatime 0 0 sysfs /sys sysfs rw,relatime 0 0 devtmpfs /dev devtmpfs rw,relatime,size=231936k,nr_inodes=57984,mode=755 0 0 devpts /dev/pts devpts rw,relatime,gid=5,mode=620,ptmxmode=000 0 0 tmpfs /dev/shm tmpfs rw,relatime 0 0 /dev/sda3 / ext4 rw,relatime,barrier=1,data=ordered 0 0 /proc/bus/usb /proc/bus/usb usbfs rw,relatime 0 0 /dev/sda1 /boot ext4 rw,relatime,barrier=1,data=ordered 0 0 none /proc/sys/fs/binfmt_misc binfmt_misc rw,relatime 0 0 sunrpc /var/lib/nfs/rpc_pipefs rpc_pipefs rw,relatime 0 0 192.168.1.101:/data/ /mnt nfs4 rw,relatime,vers=4,rsize=65536,wsize=65536,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.103,minorversion=0,local_lock=none,addr=192.168.1.101 0 0
同样查看挂载的参数还可以用mount
[root@lnmp01 ~]# mount /dev/sda3 on / type ext4 (rw) proc on /proc type proc (rw) sysfs on /sys type sysfs (rw) devpts on /dev/pts type devpts (rw,gid=5,mode=620) tmpfs on /dev/shm type tmpfs (rw) /dev/sda1 on /boot type ext4 (rw) none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw) sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw) 192.168.1.101:/data on /mnt type nfs (rw,vers=4,addr=192.168.1.101,clientaddr=192.168.1.103)
NFS服务内核优化相关建议
nfs服务端和客户端互连是通过socket服务的,这里优化就是提高服务端和客户端的读和写缓冲区,建议客户端和服务端都要加上这个优化。
cat >>/etc/sysctl.conf<<EOF net.core.wmem_default = 8388608 net.core.rmem_default = 8388608 net.core.wmem_max = 16777216 net.core.rmem_max = 16777216 EOF sysctl -p
安全加优化的客户端挂载参数为:[root@nfs-server ~]# mount -t nfs -o nosuid,noexec,nodev,noatime,nodiratime,rw 192.168.1.101:/data /mnt
这里的nosuid,noexec,nodev为安全参数
noatime,nodiratime为优化参数,这个优化是为了减少客户端和服务端的IO
当NFS SERVER宕机了或在挂载的目录中,需要强制卸载的话用 umount -lf /mnt