Linux学习笔记:NFS
NFS的生产场景
NFS可以让多个客户端挂载,轻松实现文件共享,在集群中经常用到。
NFS与SAMBA比较
同样是文件共享服务软件,NFS能提供的功能,SAMBA都能提供,但SAMBA主要应用于与Windows实现文件共享并带有认证机制,而Linux之间的文件共享应优先考虑NFS,性能更优,也能实现简单的安全措施(指定来访者的IP)。
NFS的优点与缺点
优点 | 缺点 |
|
|
NFS客户端的autofs功能
该功能可让客户端在需要用到nfs时才进行自动挂载,空闲时自动卸载,但生产环境中不宜使用,原因是对于突然的高并发会有延迟(挂载需时)
NFS服务器的安装及配置
NFS依赖的组件:
Centos5.x上是portmap
Centos6.x上是rpcbind
必须先安装好依赖组件并运行。RPC(Remote Procedure Call)远程过程调用,它的作用就是别的程序运行时监听一个随机端口并向外界提供服务,可能每次监听的端口都不一样,所以客户端无法得知每次的服务器端口号,这时就要用到RPC,服务器程序打算监听某一个端口时先向RPC进行注册,客户端透过RPC先访问服务器的RPC(TCP/UDP 111)询问指定程序的端口号,并得到RPC的回应后,再去连接那端口。也正因此,服务器RPC必须先启动,然后才可以接受程序注册。而如果服务器RPC重启后,原本已注册的程序必须重新注册。
NFS服务器的配置文件
[root@NFSSERVER ~]# rpm -qc nfs-utils /etc/nfsmount.conf #服务器配置文件 /etc/rc.d/init.d/nfs /etc/rc.d/init.d/nfslock /etc/rc.d/init.d/rpcgssd /etc/rc.d/init.d/rpcidmapd /etc/rc.d/init.d/rpcsvcgssd /etc/request-key.d/id_resolver.conf /etc/sysconfig/nfs /var/lib/nfs/etab #服务器共享文件夹的明细配置 /var/lib/nfs/rmtab /var/lib/nfs/state /var/lib/nfs/xtab 除了以上文件外,对于nfs服务器来说/etc/exports文件是最重要的共享目录的配置文件,默认是不存在的或者存在但为空。
NFS的组件:nfs-utils (服务器、客户端都需要安装)
[root@Lab2 ~]# /etc/init.d/nfs start Starting NFS services: [ OK ] Starting NFS quotas: [ OK ] Starting NFS mountd: rpc.mountd:svc_tli_create: could not open connection for udp6 rpc.mountd: svc_tli_create: could not openconnection for tcp6 rpc.mountd: svc_tli_create: could not openconnection for udp6 rpc.mountd: svc_tli_create: could not openconnection for tcp6 rpc.mountd: svc_tli_create: could not openconnection for udp6 rpc.mountd: svc_tli_create: could not openconnection for tcp6 [ OK ] Starting NFS daemon: rpc.nfsd: addressfamily inet6 not supported by protocol TCP [ OK ] Starting RPC idmapd: [ OK ]
由于关闭了Ipv6,所以rpc关联不到,可忽略这些错误提示。
NFS服务一般会监听2049端口
而NFS还有其他的功能,每一个功能就是一个daemon进程且监听一个端口,并且向RPC注册。
[root@Lab2 ~]# 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 100024 1 udp 52067 status 100024 1 tcp 34097 status 100011 1 udp 875 rquotad 100011 2 udp 875 rquotad 100011 1 tcp 875 rquotad 100011 2 tcp 875 rquotad 100005 1 udp 39148 mountd 100005 1 tcp 54013 mountd 100005 2 udp 57878 mountd 100005 2 tcp 45483 mountd 100005 3 udp 34825 mountd 100005 3 tcp 36880 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 45411 nlockmgr 100021 3 udp 45411 nlockmgr 100021 4 udp 45411 nlockmgr 100021 1 tcp 37701 nlockmgr 100021 3 tcp 37701 nlockmgr 100021 4 tcp 37701 nlockmgr
服务器上共享目录的实际配置参数可参考,但不要编辑它,它是自动生成的。
[root@NFSSERVER ~]# cat /var/lib/nfs/etab /data/test 192.168.5.0/24(rw,async,wdelay,hide,nocrossmnt,insecure,root_squash,all_squash,no_subtree_check,secure_locks,acl,anonuid=65534,anongid=65534)
上面etab文件一大堆的参数,是根据NFS服务器端的配置文件/etc/exports 来生成的,这个文件默认是空的,需要我们自己去定义,详细的写法可参考man exports
写法大致上这样
[root@Lab2 ~]# cat /etc/exports /data/test 192.168.5.0/24(rw,async)
第一列是服务器上的本地文件夹的绝对路径
第二列是允许访问的主机,括号里是选项。rw是读写、async是异步,选项之间用逗号隔开
主机的写法有4种
single host 单一ip、Ipv6或域名 netgroups wildcards 通配符,* IP network 网段,子网掩码可写255.255.255.0,或/24
参数如下
secure 默认参数,要求客户端的端口必须小于1024。关闭该参数可使用insecure。 rw 允许读写 async 默认参数,异步写入,可提高性能,但碰到非法关机的话,有丢失数据的危险 sync 同步写入,与async相反 no_wdelay 该参数与async同用时没有效果。通常NFS服务器会延迟写入到磁盘,因它预计会有关联的写入请求到达。但如果NFS服务器收到许多不关联的写入请求,则应打开no_wdelay禁止延迟写入。 wdelay 与上相反
角色转换
来自客户端的读写权限默认情况下会发生转换,这是因为服务器端默认情况下,是不信任客户端的root,会自动转换成uid=65534,gid=65534(默认);而客户端上的其他用户(非root)的uid、gid得以保留,不会发生转换。
root_squash 仅转换uid、gid为0的请求到65534,可使用anonuid和anongid修改转换后的id。 no_root_squash 保留uid、gid为0 all_squash 转换所有请求的uid、gid anonuid和anongid 显式指定转换成哪个id 服务器端测试 [root@Lab2data]# ls -ln test/ total 0 -rwxrwxrwx 1 0 0 0 Mar 4 13:04 nfs.test #该文件是本地生成的 -rw-r--r-- 1 503 801 0 Mar 4 15:48 pannyfile #客户端上用panny用户生成的 -rw-r--r-- 1 65534 65534 0Mar 4 15:48 rootfile #客户端上用root生成的 -rw-r--r-- 1 27 27 0 Mar 4 15:50 sqlfile #客户端上用mysql用户生成的
一些例子
# sample /etc/exports file / master(rw)trusty(rw,no_root_squash) 把根目录分享给master主机(可读写)和trusty主机(可读写,不转换root) /projects proj*.local.domain(rw) /usr *.local.domain(ro) @trusted(rw) 通配符例子 /home/joe pc001(rw,all_squash,anonuid=150,anongid=100) 可读写,转换所有来访者,uid改为150,gid改为100 /pub *(ro,insecure,all_squash) 只读,允许客户端的端口大于等于1024,全部转换角色 /srv/www -sync,rw server @trusted @external(ro) sync、rw配到后面三个主机,但第三个@external只读覆盖rw /foo 2001:db8:9:e54::/64(rw) 192.0.2.0/24(rw) Ipv6于4的写法 /build buildhost[0-9].local.domain(rw) 另一种通配符的写法
NFS客户端
客户端也需要安装nfs-utils
当装好后,就可以查看服务器上的共享目录,如下,在服务器192.168.5.138上有个共享目录/data/test
[root@Lab3 ~]# showmount -e 192.168.5.138 Export list for 192.168.5.138: /data/test 192.168.5.0/24 在客户端上进行挂载 [root@Lab3 ~]# mount -t nfs 192.168.5.138:/data/test /mnt 在客户端上查看挂载状态,有两个方法: 1.直接mount命令; [root@Lab3 ~]# mount|grep nfs 192.168.5.138:/data/test on /mnt type nfs (rw,vers=4,addr=192.168.5.138,clientaddr=192.168.5.142) 2.查看/proc/mounts,可以更清晰地看到所有参数; [root@Lab3 ~]# cat /proc/mounts | grep mnt 192.168.5.138:/data/test /mnt 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.5.142,minorversion=0,local_lock=none,addr=192.168.5.138 0 0
以上是最简单的挂载方法和查看状态的方法
透过方法2,可以看到nfs的挂载参数有很多(具体可参考man 5 nfs),部分如下
rw 读写 vers 版本 rsize 读缓存(非常重要)范围在1024到1048576(即1M),如小于1024,会自动用4096代替,如大于1048576,则自动用1048576代替;生效的数值必须是1024的n倍数。最终数值还需要客户端和服务器端协商。 wsize 写缓存(非常重要)同上; hard 默认hard,当nfs请求失败会不断重试;可以修改为soft,在超过重传次数后返回错误 proto 使用TCP还是UDP timeo 超时时间,数值是秒数x10,默认600(即60秒) retrans 重传次数 intr 允许用户中断尝试中的挂载 nointr 默认值,表示用户不能中断尝试中的挂载
另外还有一些mount命令自身支持的参数,比较重要的如下
noatime 访问文件时不修改相关文件的Access Time nodiratime 不修改目录的Access Time noexec 不允许直接运行文件,即使该文件有x权限 nodev 屏蔽字符设备或块设备的属性 nosuid 屏蔽suid
如果我们在客户端上,想挂载nfs目录,并且希望得到最佳性能和安全性,则应
[root@Lab3 ~]# mount -t nfs -o rsize=1048576,wsize=1048576,soft,timeo=30,noatime,nodiratime,noexec,nodev,nosuid 192.168.5.138:/data/test /mnt
在该测试中,尽管rsize和wsize都用了最大值1048576,但查看/proc/mounts的wsize和rsize只有131072,但查看mount命令则是1048576,不知是否bug。
[root@Lab3 ~]# cat /proc/mounts | grep /mnt 192.168.5.138:/data/test /mnt nfs4 rw,nosuid,nodev,noexec,noatime,nodiratime,vers=4,rsize=131072,wsize=131072,namlen=255,soft,proto=tcp,port=0,timeo=30,retrans=2,sec=sys,clientaddr=192.168.5.142,minorversion=0,local_lock=none,addr=192.168.5.138 0 0 [root@Lab3 ~]# mount|grep mnt 192.168.5.138:/data/test on /mnt type nfs (rw,noexec,nosuid,nodev,noatime,nodiratime,rsize=1048576,wsize=1048576,soft,timeo=30,vers=4,addr=192.168.5.138,clientaddr=192.168.5.142)