NFS架构搭建详解
欢迎来到 来到大浪涛天的博客 !
NFS架构
1. NFS简述
NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源。在NFS的应用中,本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件,就像访问本地文件一样。注意,如果企业的业务量比较小的时候,单台机器(不使用nfs)的性能是优于集群性能的,但是当业务量大的时候,单台机器支撑不住的时候,集群的优势就体现出来了。
2.为什么要使用NFS
NFS是一种简单方便的,在linux和unix系统中进行共享的网络文件系统,它在linux和unix系统中挂载就像用本地硬盘挂载一样,可以实现,多个用户共同读取,而且把各个用户读写的文件权限都压缩成一个普通用户权限,这样各个主机一起读取写入就不会造成权限问题,非常适合中小型互联网企业应用,而且在读写速度上,如果带宽足够的话,不会有延迟的现象。
在企业集群架构的工作场景中,NFS网络文件系统一般用来存储共享视频、图片、附件等静态资源文件,一般是网站用户上传的文件都放在NFS共享里,例如播客产品的图片、附件、头像、注意网站程序不要放在NFS共享里,然后前端所有的节点访问这些静态资源时都会读取NFS存储上的资源,所以NFS是当前中小型互联网架构中最常用的数据存储服务之一,大的公司可能会使用比较复杂的分布式文件系统Moosefs,glusterfs,FastDFS等。
如下图:
3 NFS架构流程
1 .服务端RPC服务起来,NFS服务再起来
2 待NFS服务起来后将所用的端口后向RPC上注册
3 NFS服务端将端口注册成功后等待连接进来
4 客户端不用起NFS服务,只需要起RPC服务,客户端的RPC服务向服务端的RPC daemon请求访问端口
5 服务端RPC daemon 向客户端RPC反馈NFS端口号
6 NFS客户端携带端口号向NFS服务端请求数据连接
4 NFS服务配置
4.1 NFS 的配置文件为:/etc/exports
配置文件格式为:NFS 共享目录 NFS客户端地址1(参数1,参数2... )NFS客户端地址2(参数1,参数2... )
[root@server www]# cat /etc/exports
/data 192.168.50.0/24(rw,sync,all_squash)
4.2 NFS和RPC安装,注意先启动rpcbind,再启动nfs服务
[root@server www]# mkdir /data
[root@server www]# chown 65536:65536 /data
[root@server mnt]# ls -ld /data
drwxr-xr-x. 2 nfsnobody nfsnobody 98304 May 18 17:28 /data
[root@server www]# yum install nfs-utils rpcbind -y
Loaded plugins: fastestmirror
Setting up Install Process
Loading mirror speeds from cached hostfile
* base: mirrors.aliyun.com
* extras: mirrors.aliyun.com
[root@server www]# /etc/init.d/rpcbind restart
Stopping rpcbind: [ OK ]
Starting rpcbind: [ OK ]
[root@server www]#
[root@server www]# /etc/init.d/nfs restart
Shutting down NFS daemon: [ OK ]
Shutting down NFS mountd: [ OK ]
Shutting down NFS services: [ OK ]
Shutting down RPC idmapd: [ OK ]
Starting NFS services: [ OK ]
Starting NFS mountd: [ OK ]
Starting NFS daemon: [ OK ]
Starting RPC idmapd: [ OK ]
4.3 nfs服务端确定nfs端口已向rpcbind注册,并在服务端尝试挂载
[root@server www]# /etc/init.d/prcbind restart
-bash: /etc/init.d/prcbind: No such file or directory
[root@server www]# /etc/init.d/rpcbind restart
Stopping rpcbind: [ OK ]
Starting rpcbind: [ OK ]
[root@server www]#
[root@server www]# /etc/init.d/nfs restart
Shutting down NFS daemon: [ OK ]
Shutting down NFS mountd: [ OK ]
Shutting down NFS services: [ OK ]
Shutting down RPC idmapd: [ OK ]
Starting NFS services: [ OK ]
Starting NFS mountd: [ OK ]
Starting NFS daemon: [ OK ]
Starting RPC idmapd: [ OK ]
[root@server www]#
[root@server www]# exportfs -av
exporting 192.168.50.0/24:/data
[root@server www]# showmount -e localhost
Export list for localhost:
/data 192.168.50.0/24
[root@server www]# rpcinfo -p localhost
program vers proto port service
100000 4 tcp 111 portmapper
100000 3 tcp 111 portmapper
100000 2 tcp 111 portmapper
100000 4 udp 111 portmapper
100000 3 udp 111 portmapper
100000 2 udp 111 portmapper
100005 1 udp 45209 mountd
100005 1 tcp 58457 mountd
100005 2 udp 54966 mountd
100005 2 tcp 37880 mountd
100005 3 udp 40224 mountd
100005 3 tcp 49630 mountd
100003 2 tcp 2049 nfs
100003 3 tcp 2049 nfs
100003 4 tcp 2049 nfs
100227 2 tcp 2049 nfs_acl
100227 3 tcp 2049 nfs_acl
100003 2 udp 2049 nfs
100003 3 udp 2049 nfs
100003 4 udp 2049 nfs
100227 2 udp 2049 nfs_acl
100227 3 udp 2049 nfs_acl
100021 1 udp 50773 nlockmgr
100021 3 udp 50773 nlockmgr
100021 4 udp 50773 nlockmgr
100021 1 tcp 46835 nlockmgr
100021 3 tcp 46835 nlockmgr
100021 4 tcp 46835 nlockmgr
[root@server www]# ifconfig eth0 |awk -F '[ :]+' 'NR==2 {print $4}'
192.168.50.1
[root@server www]# mount -t nfs 192.168.50.1:/data /mnt
[root@server www]# df -k |grep "mnt"
192.168.50.1:/data 18241408 2077888 15230240 13% /mnt
[root@server www]# cd /mnt
[root@server mnt]# touch file{1..100}
[root@server mnt]# ls |wc -l
4.4 NFS客户端安装nfs和rpcbind套件
一般来说客户端只需要安装rpcbind,但是因为nfs-utils里含有一些工具,如showmount等,因此最好在客户端也安装nfs但是不启动服务,如:
[root@lamp01 ~]# yum install nfs-utils rpcbind -y
Loaded plugins: fastestmirror
Setting up Install Process
Determining fastest mirrors
* base: mirrors.aliyun.com
[root@lamp01 ~]# /etc/init.d/rpcbind restart
Stopping rpcbind: [ OK ]
Starting rpcbind: [ OK ]
[root@lamp01 ~]# rpcinfo -p localhost
program vers proto port service
100000 4 tcp 111 portmapper
100000 3 tcp 111 portmapper
100000 2 tcp 111 portmapper
100000 4 udp 111 portmapper
100000 3 udp 111 portmapper
100000 2 udp 111 portmapper
[root@lamp01 ~]# /etc/init.d/rpcbind restart
Stopping rpcbind: [ OK ]
Starting rpcbind: [ OK ]
[root@lamp01 ~]# rpcinfo -p localhost
program vers proto port service
100000 4 tcp 111 portmapper
100000 3 tcp 111 portmapper
100000 2 tcp 111 portmapper
100000 4 udp 111 portmapper
100000 3 udp 111 portmapper
100000 2 udp 111 portmapper
[root@lamp01 ~]# showmount -e 192.168.50.1
Export list for 192.168.50.1:
/data 192.168.50.0/24
[root@lamp01 ~]# mkdir nfs
[root@lamp01 ~]# mount -t nfs 192.168.50.1:/data ~/nfs
[root@lamp01 ~]# df -hk |grep "nfs"
192.168.50.1:/data 18241408 2077920 15230208 13% /nfspool
192.168.50.1:/data 18241408 2077920 15230208 13% /root/nfs
4.5 配置完成后在客户端查看挂载参数,确认所需权限是不是对的,然后换成普通用户看可不可正常读写,服务端用root写数据,客户端用普通用户看可不可以修改删除。
[root@server mnt]# touch file
[root@server mnt]# ls -l
total 0
-rw-r--r--. 1 nfsnobody nfsnobody 0 May 18 18:12 file
[root@lamp01 nfs]# ls -l
total 0
-rw-r--r--. 1 nfsnobody nfsnobody 0 May 18 2018 file
[root@lamp01 nfs]# echo "hello" >>file
[root@lamp01 nfs]# cat file
hello
[root@lamp01 nfs]# cat /proc/mounts |grep "root/nfs"
192.168.50.1:/data/ /root/nfs nfs4 rw,relatime,vers=4,rsize=32768,wsize=32768,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.50.3,minorversion=0,local_lock=none,addr=192.168.50.1 0 0
[root@server mnt]# cat /var/lib/nfs/etab
/data 192.168.50.0/24(rw,sync,wdelay,hide,nocrossmnt,secure,root_squash,all_squash,no_subtree_check,secure_locks,acl,anonuid=65534,anongid=65534,sec=sys,rw,root_squash,all_squash)
5 配置参数详解及注意事项
5.1 服务端要注意,一定要先启动rpcbind再启动nfs,因为nfs需要向rpcbind注册端口。
5.2 常用命令解释
showmount -e 127.0.0.1 显示可以挂载的文件系统
rpcinfo -p localhost 查看nfs注册的端口号
mount -t nfs 192.168.50.1:/data /mnt 挂载nfs文件系统
/etc/init.d/nfs reload 平滑重启服务
cat /proc/mounts |grep "root/nfs" 客户端查看挂载参数
cat /var/lib/nfs/etab 服务端查看nfs配置参数
5.3 如果nfs客户端查不到挂载项,排错思路,首先确认ping服务端是否通,然后telnet服务端ip看端口是否可以连接
5.4 服务一般我们用rc.local来管理,把rc.local 文件作为本机的重要文件,所有服务的开机自动启动项都放入/etc/rc.local内,这样规范的好处是,一旦服务器的运维人员离职或者业务迁移时都可以通过/etc/rc.local很容易查到服务器的相关服务,方便运维管理。例如:
[root@server ~]# tail -5 /etc/rc.local
/etc/init.d/rpcbind start
/etc/init.d/nfs start
sh /service/scripts/inotify.sh &
rsync --daemon
Starting SMB services:
[root@server ~]#
5.5 服务端配置文件中的yu允许客户端访问的ip可以设置为单个ip也可以整个网段,如
10.0.0.0/24
6 NFS 服务端设置参数详解
- rw,ro:读写与只读
- sync:同步客户端往服务端写数据,写成功后才返回OK,安全不会丢数据,但是性能没async那么好。
- async: 异步请求写入数据时,先返回请求,再将数据写入到内存,如果服务器中途断电,可hui能内存内的数据来不及向硬中写入,所以可能会丢数据,但是效率高,因为是往对方内中写数据,电商秒杀是异步,短时间内数据会稍微延迟。
- no_root_squash:如果对于访问NFS server共享目录用户是root的话,那这个客户端对这个共享目录具有root权限
- root_squash:如果对于访问NFS server共享目录用户是root的话,那被写入的数据的权限会被压缩成匿名用户,UID和GID通常会变成nfsnobody,这个用户是可以改的,只是通常默认是这个。
- all_squash:不管访问NFS server共享目录用户是root还是普通用户都会被压缩成匿名用户,UID和GID通常会变成nfsnobody,这个用户是可以改的,只是通常默认是这个。
7 NFS客户端挂载参数
- 挂载时最好选择hard +intr :为了防止整个系统被NFS锁死,因为hard连接的时候,即使服务端NFS没起来,客户端也是一直在尝试进行连接,导致df -h无输出,如果添加了intr,可以按ctrl+c中断
- rsize和wsize:性能优化参数,这个设置可以影响客户端和服务端传输数据的缓冲存储量,一般来说在局域网内,并且客户端和服务端都足够大内存可以设置大一点,比如65535或者131072,提升缓冲区可提升NFS文件系统传输能力,但是也不要太大了,最好是在网络能传输的最大值,一般默认是:32768。
- 客户端挂载加参数命令格式为:
mount -t nfs -o bg,hard,intr,rsize=131072,wsize=131072 10.0.0.7:/data /mnt
- async:异步
- sync:同步
- ro:只读
- rw:读写
- auto:可以通过mount -a 自动挂载,但是前提要写入/etc/fstab文件
- defaults:fstab的缺省值包括:rw,suid,dev,exec,auto,nouser,async
- exec:允许文件系统执行二进制文件,取消这个参数可以提升安全,因为***即使被上传也不能被执行,适用于那种仓库存储
- noatime:不更新文件系统上的inode访问时间,高并发环境推荐,可以显著提高性能
- nodiratime:不更新文件系统上的目录节点访问时间,高并发环境推荐,可以显著提高性能
- nosuid:不允许权限位生效,可以提高安全
- noexec:不允许文件系统执行二进制文件
- remount:mount -o remount,rw(当系统出错进入救援模式时无法写系统,可利用remount参数
- 客户端的安全挂载命令:
mount -t nfs -o nosuid,noexec,nodev,rw 192.168.50.1:/data /mnt
- 客户端的性能挂载命令:
mount -t nfs -o noatime,nodiratime,rw 192.168.50.1:/data /mnt
- 客户端的安全加性能参数为:
mount -t nfs -o noatime,nodiratime,nosuid,noexec,nodev,rw,hard,intr,rsize=131072,wsize=131072 192.168.50.1:/data /mnt
- 本地文件系统挂载:
mount /dev/sdb1 /mnt -o defaults,async,noatime,data=writeback,barrier=0
- 如果卸载文件系统时,有用户或者进程在访问,导致卸载的时候提示设备忙,则可以使用
umount -lf /mnt
8 NFS内核优化
- /proc/sys/net/core/rmem-default :指定接收套接字缓冲区大小的缺省值,缺省值为124928,对应优化是将值设置为最大8388608
[root@server ~]# cat /proc/sys/net/core/rmem_default
124928
[root@server ~]# echo "8388608" > /proc/sys/net/core/rmem_default
[root@server ~]# cat /proc/sys/net/core/rmem_default
8388608
- /proc/sys/net/core/rmem_max:指定接收套接字缓冲区大小的最大值,缺省值为124928,对应优化是将值设置为最大16777216
[root@server ~]# cat /proc/sys/net/core/rmem_max
124928
[root@server ~]# echo "16777216" > /proc/sys/net/core/rmem_max
[root@server ~]# cat /proc/sys/net/core/rmem_max
16777216
3 . /proc/sys/net/core/wmem_default :指定发送套接字缓冲区大小的缺省值,缺省值为124928,对应优化是将值设置为最大8388608
[root@server ~]# cat /proc/sys/net/core/wmem_default
124928
[root@server ~]# echo "8388608" > /proc/sys/net/core/wmem_default
[root@server ~]# cat /proc/sys/net/core/wmem_default
8388608
- /proc/sys/net/core/wmem_max: 指定发送套接字缓冲区大小的最大值,缺省值为124928,对应优化是将值设置为最大16777216
[root@server ~]# cat /proc/sys/net/core/wmem_max
124928
[root@server ~]# echo "16777216" > /proc/sys/net/core/w
warnings wmem_default wmem_max
[root@server ~]# echo "16777216" > /proc/sys/net/core/wmem_max
[root@server ~]# cat /proc/sys/net/core/wmem_max
16777216
以上是临时修改,如果需要永久修改则必须写入配置文件,依次追加以上4条到/etc/sysctl.conf,然后执行,sysctl -p 使之生效,如:
[root@server ~]# echo "net.core.rmem_max = 16777216" >>/etc/sysctl.conf
[root@server ~]# echo "net.core.wmem_max = 16777216" >>/etc/sysctl.conf [root@server ~]# echo "net.core.wmem_default = 8388608" >>/etc/sysctl.conf [root@server ~]# echo "net.core.rmem_default = 8388608" >>/etc/sysctl.conf [root@server ~]# tail -4 /etc/sysctl.conf
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
[root@server ~]# sysctl -p
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608