首页 > 代码库 > NFS

NFS

什么是NFS

http://www.tldp.org/HOWTO/NFS-HOWTO/
NFS 是Network File System的缩写,即网络文件系统。 一种使用于分散式文件系统的协定,由Sun公司开发,于1984年向外公布。 功能是通过网络让不同的机器、不同的操作系统能够彼此分享个别的数据,让应用程序在客户端通过网络访问位于服务器磁盘中的数据,是在类Unix系统间实现磁盘文件共享的一种方法。 NFS 的基本原则是“容许不同的客户端及服务端通过一组RPC分享相同的文件系统”,它是独立于操作系统,容许不同硬件及操作系统的系统共同进行文件的分享。 NFS在文件传送或信息传送过程中依赖于RPC协议。RPC,远程过程调用 (Remote Procedure Call) 是能使客户端执行其他系统中程序的一种机制。 NFS本身是没有提供信息传输的协议和功能的,但NFS却能让我们通过网络进行资料的分享,这是因为NFS使用了一些其它的传输协议。 而这些传输协议用到这个RPC功能的。可以说NFS本身就是使用RPC的一个程序。或者说NFS也是一个RPC SERVER。所以只要用到NFS的地方都要启动RPC服务,不论是NFS SERVER或者NFS CLIENT。 这样SERVER和CLIENT才能通过RPC来实现PROGRAM PORT的对应。可以这么理解RPC和NFS的关系:NFS是一个文件系统,而RPC是负责负责信息的传输。

 

NFS安装与启动

[root@node85 ~]#  yum install nfs-utils rpcbind     (centos5 #yum install nfs-utils portmap)

NFS启动(rpcbind必须先于nfs启动)
[root@node85 ~]# service rpcbind start
Starting rpcbind: [  OK  ]
[root@node85 ~]# lsof -i:111    #rcpbind端口111
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
rpcbind 1886  rpc    6u  IPv4  12688      0t0  UDP *:sunrpc
rpcbind 1886  rpc    8u  IPv4  12691      0t0  TCP *:sunrpc (LISTEN)
rpcbind 1886  rpc    9u  IPv6  12693      0t0  UDP *:sunrpc
rpcbind 1886  rpc   11u  IPv6  12696      0t0  TCP *:sunrpc (LISTEN)
[root@node85 ~]# 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@node85 ~]# service nfs  start

Starting NFS services:  [  OK  ]
Starting NFS quotas: [  OK  ]
Starting NFS mountd: [  OK  ]
Starting NFS daemon: [  OK  ]
Starting RPC idmapd: [  OK  ]
[root@node85 ~]# netstat -tlnup | grep 2049  #nfs端口2049
tcp        0      0 0.0.0.0:2049                0.0.0.0:*                   LISTEN      -                   
tcp        0      0 :::2049                     :::*                        LISTEN      -                   
udp        0      0 0.0.0.0:2049                0.0.0.0:*                               -                   
udp        0      0 :::2049                     :::*                                    -    

[root@node85 ~]# 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
    100011    1   udp    875  rquotad
    100011    2   udp    875  rquotad
    100011    1   tcp    875  rquotad
    100011    2   tcp    875  rquotad
    100005    1   udp  40981  mountd
    100005    1   tcp  49698  mountd
    100005    2   udp  50593  mountd
    100005    2   tcp  54927  mountd
    100005    3   udp  57873  mountd
    100005    3   tcp  54151  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  50683  nlockmgr
    100021    3   udp  50683  nlockmgr
    100021    4   udp  50683  nlockmgr
    100021    1   tcp  37394  nlockmgr
    100021    3   tcp  37394  nlockmgr
    100021    4   tcp  37394  nlockmgr

[root@node85 ~]# chkconfig rpcbind on
[root@node85 ~]# chkconfig nfs on


nfs常用目录

/etc/exports                           NFS服务的主要配置文件
/usr/sbin/exportfs                     NFS服务的管理命令
/usr/sbin/showmount                    客户端的查看命令
/var/lib/nfs/etab                      记录NFS分享出来的目录的完整权限设定值
/var/lib/nfs/xtab                      记录曾经登录过的客户端信息

 

/etc/exports文件

/etc/exports文件内容格式:
<输出目录> [客户端1 选项(访问权限,用户映射,其他)] [客户端2 选项(访问权限,用户映射,其他)]

a. 输出目录:
输出目录是指NFS系统中需要共享给客户机使用的目录;

b. 客户端:
客户端是指网络中可以访问这个NFS输出目录的计算机

客户端常用的指定方式
        指定ip地址的主机:192.168.0.200
        指定子网中的所有主机:192.168.0.0/24 192.168.0.0/255.255.255.0
        指定域名的主机:david.bsmart.cn
        指定域中的所有主机:*.bsmart.cn
        所有主机:*

c. 选项:
选项用来设置输出目录的访问权限、用户映射等。
NFS主要有3类选项:
访问权限选项
        设置输出目录只读:ro
        设置输出目录读写:rw

用户映射选项
        all_squash:    将远程访问的所有普通用户及所属组都映射为匿名用户或用户组(nfsnobody);
        no_all_squash:  与all_squash取反(默认设置);
        root_squash:   将root用户及所属组都映射为匿名用户或用户组(默认设置);
        no_root_squash:  与rootsquash取反;
        anonuid=xxx:    将远程访问的所有用户都映射为匿名用户,并指定该用户为本地用户(UID=xxx);
        anongid=xxx:    将远程访问的所有用户组都映射为匿名用户组账户,并指定该匿名用户组账户为本地用户组账户(GID=xxx);

其它选项
        secure:    限制客户端只能从小于1024的tcp/ip端口连接nfs服务器(默认设置);
        insecure:   允许客户端从大于1024的tcp/ip端口连接服务器;
        sync:     将数据同步写入内存缓冲区与磁盘中,效率低,但可以保证数据的一致性;
        async:    将数据先保存在内存缓冲区中,必要时才写入磁盘;
        wdelay:    检查是否有相关的写操作,如果有则将这些写操作一起执行,这样可以提高效率(默认设置);
        no_wdelay:  若有写操作则立即执行,应与sync配合使用;
        subtree:     若输出目录是一个子目录,则nfs服务器将检查其父目录的权限(默认设置);
        no_subtree:  即使输出目录是一个子目录,nfs服务器也不检查其父目录的权限,这样可以提高效率;

 

NFS配置实例

[root@node85 ~]# mkdir /data
[root@node85 ~]# cat /etc/exports   #将/data目录export
/data  192.168.0.0/24(rw)
[root@node85 ~]# /etc/init.d/nfs reload  #重新加载

[root@node85 ~]# showmount -e localhost  #查看共享的服务
Export list for localhost:
/data 192.168.0.0/24


在客户端进行测试
[root@node84 ~]# yum install nfs-utils rpcbind    一般来说,客户端无需安装nfs-utils,但是测试中发现问题,可能有依赖,而且showmount命令在nfs包中,但是服务可以不起。
[root@node84 ~]# /etc/init.d/rpcbind start
Starting rpcbind: [  OK  ]
[root@node84 ~]# chkconfig rpcbind on
[root@node84 ~]# /etc/init.d/rpcbind start
Starting rpcbind: [  OK  ]
[root@node84 ~]# chkconfig rpcbind on
[root@node84 ~]# showmount -e 192.168.0.85
Export list for 192.168.0.85:
/data 192.168.0.0/24

[root@node84 ~]# mkdir /nfs84
[root@node84 ~]# mount 192.168.0.85:/data /nfs84/
[root@node84 ~]# df
Filesystem         1K-blocks    Used Available Use% Mounted on
/dev/sda2            5916420 1450480   4158740  26% /
tmpfs                 502384       0    502384   0% /dev/shm
/dev/sda1             194241   35987    148014  20% /boot
192.168.0.85:/data   5916544 1450496   4158848  26% /nfs84
[root@node84 /]# cd nfs84/
[root@node84 nfs84]# touch nfstest
touch: cannot touch `nfstest‘: Permission denied

[root@node85 ~]#  cat /var/lib/nfs/etab
/data   192.168.0.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)
=>这些参数会把客户端用户压缩成nfsnobody用户,所以无法写入,因此将/data/目录属主改为nfsnobody
[root@node85 ~]# chown   nfsnobody  /data

[root@node84 nfs84]# touch nfstest  #客户端可以写入了
[root@node84 nfs84]# ls -l
total 0
-rw-r--r-- 1 nfsnobody nfsnobody 0 Jan 30 04:29 nfstest
[root@node84 nfs84]# cat /proc/mounts | grep nfs84  #查看到挂载参数
192.168.0.85:/data/ /nfs84 nfs4 rw,relatime,vers=4,rsize=131072,wsize=131072,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.0.84,minorversion=0,local_lock=none,addr=192.168.0.85 0 0


关于权限的分析
  1. 客户端连接时候,对普通用户的检查
    a. 如果明确设定了普通用户被压缩的身份,那么此时客户端用户的身份转换为指定用户;
    b. 如果NFS server上面有同名用户,那么此时客户端登录账户的身份转换为NFS server上面的同名用户;
    c. 如果没有明确指定,也没有同名用户,那么此时 用户身份被压缩成nfsnobody;
  2. 客户端连接的时候,对root的检查
    a. 如果设置no_root_squash,那么此时root用户的身份被压缩为NFS server上面的root;
    b. 如果设置了all_squash、anonuid、anongid,此时root 身份被压缩为指定用户;
    c. 如果没有明确指定,此时root用户被压缩为nfsnobody;
    d. 如果同时指定no_root_squash与all_squash 用户将被压缩为 nfsnobody,如果设置了anonuid、anongid将被压缩到所指定的用户与组;

将nfs加入开机自动挂载
[root@node84 ~]# cat /etc/fstab | grep nfs
192.168.0.85:/data      /nfs84                  nfs     defaults        0 0

 小结

使得NFS客户端可写的服务端配置条件
1、nfs服务器/ext/exports设置需要开放可写入的条件
2、nfs服务器实际要共享的目录需要有写权限
3、每台机器对应存在和nfs默认配置uid的相同的uid65534用户


NFS客户端mount挂载深入(man nfs)
在nfs服务器端可以通过var/lib/nfs/etab 有服务器端的export参数
在nfs客户端可以通过cat /proc/mounts查看(更多参数,mann  nfs)
1、fg和 bg  默认前台执行
2、soft 和hard  软挂载在出现问题后,客户端尝试到timeout后显示错误并停止尝试,而hard一致会尝试下去,此时无法umount或kill,所以常常会配合intr参数使用,默认为硬
3、rsize和wsize  读写的块大小,决定列cs端传输数据的缓冲存储量,一般在LAN内,cs端内存足够,可以设置的大些,提升传输能录,但是也不能太大,要考虑网络情况(centos6默认131072,已经足够大了)
4、proto udp或tcp  默认tcp
带参数挂载实例,一般默认即可
mount -t nfs  -o  bg,hard,intr,rsize=131072,wsize=131072   192.168.0.81:/data  /mnt(有问题?)


企业场景优化
1、NFS服务内核优化建议
/proc/sys/net/core/rmem_default    接收socket的缺省缓存大小(字节)
/proc/sys/net/core/rmem_max        接收socket的最大缓存大小(字节)
/proc/sys/net/core/wmem_default    发送的socket缺省缓存大小(字节)
/proc/sys/net/core/wmem_max        发送的socket最大缓存大小(字节)
cat >> sysctl.conf<<EOF   (官方资料建议)
net.core.rmem_default=8388608
net.core.rmem_max=16777216 
net.core.wmem_default=8388608
net.core.wmem_max=16777216
EOF
#sysctl -p生效
2、硬件优化
使用sas/ssd硬盘,raid0或raid10,千兆级网卡(多块bond)
3、NFS服务器端export参数rw,sync,all_squash
4、客户端挂载参数
加安全挂载  mount -t nfs -o nosuid,noexec,nodev,rw   nfsip:/data  /mnt
加性能挂载  noatime ,nodiratime ,intr
mount -t nfs  -o  bg,hard,intr,rsize=131072,wsize=131072   nfsip:/data  /mnt(有问题)
5、如果卸载时提示device is busy.强制卸载命令#umount -lf /mnt
6、超大型网站,可选择更复杂的分布式文件系统。例如Moosefs,glusterfs,FastDFS

NFS系统应用优缺点
1、简单,易掌握
2、NFS文件系统内数据是在文件系统上的,即数据能看得见
3、部署快,维护简单,可控且能满足需求
4、软件层面上看,数据可靠性高
5、非常稳定

局限性
1、局限性是存在单点故障。可通过负载均衡及高可用弥补
2、大数据高并发的场合,NFS效率\性能有限,但是2千万以下pv可以支撑,但是架构不能太差
3、客户端认证基于ip和主机名,权限根据ID识别,安全性一般
4、NFS数据是明文,NFS本身对数据完整性不做验证
5、多台客户端挂载一个NFS时,连接管理维护麻烦(耦合度较高)

 

NFS