功能强大的网络文件系统------NFS

1.什么是NFS?
NFS(Network File System):即网络文件系统,是FreeBSD支持的文件系统中的一种,它最早是由sun 公司开发出来的。NFS最大的功能就是允许网络中的计算机之间通过TCP/IP网络共享资源,在NFS的应用中,本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件,就像访问本地文件一样。也就是可以透过网络,让不同的机器、不同的操作系统、可以彼此分享相应的资源。所以,我们也可以简单的将它看做是一个文件服务器。NFS 服务可以让PC将网络中的NFS服务器共享的目录挂载到本地端的文件系统中,而在本地端的系统来看,那个远程主机的目录就好像是自己的一个磁盘分区一样,在使用上相当便利。
2. NFS有什么样的优缺点呢?
优点:

1)节省本地存储空间,将常用的数据存放在一台NFS服务器上且可以通过网络访问,那么本地终端将可以减少自身存储空间的使用;
2)用户不需要在网络中的每个机器上都建有Home目录,Home目录可以放在NFS服务器上且可以在网络上被访问使用;
3)一些存储设备如软驱、CDROM和Zip(一种高储存密度的磁盘驱动器与磁盘)等都可以在网络上被别的机器使用,这可以减少整个网络上可移动介质设备的数量。

功能强大的网络文件系统------NFS
缺点:

1)局限性容易发生单点故障,及server机宕机了所有客户端都不能访问;
2)在高并发(多台客户端同时访问)下NFS效率/性能有限;
3)客户端没用用户认证机制,且数据是通过明文传送,安全性一般(一般建议在局域网内使用);
4)NFS的数据是明文的,且对数据完整性不做验证;
5)多台机器挂载NFS服务器时,连接管理维护会比较麻烦。

3.NFS的挂载原理,如下图所示是NFS的挂载结构图:
功能强大的网络文件系统------NFS
如图所示,当我们在NFS服务器设置好一个共享目录/home/public后,其他的有权访问NFS服务器的NFS客户端就可以将这个目录挂载到自己文件系统的某个挂载点,这个挂载点可以自己定义,如上图客户端A与客户端B挂载的目录就不相同。并且挂载好后我们在本地能够看到服务端/home/public的所有数据。如果服务器端配置的客户端为只读权限,那么客户端就只能够读去/home/public目录下的内容。如果配置的是读写权限,那么客户端就能够进行读写操作。
挂载完成之后,NFS客户端查看磁盘信息命令#df –h
既然NFS是通过网络来进行服务器端和客户端之间的数据传输,那么两者之间要传输数据就要有相对应的网络端口,NFS服务器到底使用哪个端口来进行数据传输呢?基本上NFS这个服务器的端口是2049(随机端口),但由于文件系统非常复杂。因此NFS还有其他的程序去启动额外的端口,这些额外的用来传输数据的端口是随机选择的,是小于1024的端口(固定端口);既然是随机的那么客户端又是如何知道NFS服务器端到底使用的是哪个端口呢?这时就需要通过远程过程调用RPC(Remote Procedure Call)协议来实现了.RPC服务(portmap 服务)。
注意:

同一挂载点可以连接多个设备;
一个设备可以连接多个挂载点。

4.了解RPC远程过程调用:
RPC(Remote Procedure Call)即远程过程调用。RPC 最主要的功能就是在指定每个NFS功能所对应的port number ,并且回报给客户端,让客户端可以连接到正确的port上去。 那 RPC 又是如何知道每个NFS程序所对应的端口呢?首先当NFS启动后,就会随机的使用一些端口,然后NFS就会向RPC去注册这些端口,RPC就会记录下这些端口,并且RPC会开启111端口,等待客户端RPC的请求,如果客户端有请求,那么服务器端的RPC就会将之前记录的NFS端口信息告知客户端。如此客户端就会获取NFS服务器端的端口信息,就会以实际端口进行数据的传输了。
所以这里我们需要注意,在启动NFS服务之前,RPC 服务(即portmap)就要先启动了,否则 NFS 会无法向 RPC 注册。另外,RPC 若重新启动,原本注册的数据就会全部丢失,因此 RPC 重新启动后,它管理的所有服务都需要重新启动来重新向RPC注册。
特别注意:一般修改NFS配置文档后,是不需要重启NFS服务的,直接在命令行执行/etc/init.d/nfs reload或exportfs –rv命令即可使修改的/etc/exports生效。
了解Portmap:

功能:主要是把RPC程序号转化为Internet的端口号;
特点:只在第一次建立连接时帮助网络应用程序找到正确的port,当双方正确连接时,端 口就和应用绑定,portmap就无用。相当于媒婆的作用。

5.NFS客户端与NFS服务器端通讯过程:
功能强大的网络文件系统------NFS

1)首先服务器端启动RPC服务,并且开启111端口;
2)服务器端启动NFS服务,并向RPC注册端口信息;
3)客户端启动RPC(portmap服务),向服务端的RPC(portmap)服务请求服务端的NFS端口;
4)服务端的RPC(portmap)服务反馈NFS端口信息给客户端;
5)客户端通过获取的NFS端口来建立和服务端的NFS连接并进行数据的传输。

执行的顺序是:注册端口->达成协议->直接建立联系->达成协议->建立连接;
功能强大的网络文件系统------NFS
6.Linux操作系统下NFS服务的部署:
要部署NFS服务,必须安装两个软件包:nfs-utils(NFS主程序)和rpcbind(RPC主程序),默认系统已经安装了这两个软件包。
6.1查看NFS服务相关的软件包:

[[email protected] ~]# rpm -qa | egrep "nfs|rpcbind"          //egrep相当于grep –E扩展过滤即对多个参数进行过滤
libnfsidmap-0.25-12.el7.x86_64
rpcbind-0.2.0-32.el7.x86_64
nfs-utils-1.3.0-0.21.el7.x86_64

6.2NFS服务的默认状态是没有启动的,可以通过下列命令查看nfs服务的状态:

[[email protected] ~]# systemctl status nfs

6.3注意两个相关的进程:

rpc.nfsd //NFS守护进程,即就是用来实现端口注册端口应答的进程
rpc.mountd //管理文件系统和权限,管理挂载的进程

6.4查看RPC在本地对应的详细信息(默认也是未开启状态):

[[email protected] ~]# rpcinfo -p localhost

6.5启动NFS服务,默认也就启动了RPC服务:

[[email protected] ~]# systemctl restart nfs

6.6再次查看RPC在本地对应的详细信息:

[[email protected] ~]# rpcinfo -p localhost

功能强大的网络文件系统------NFS
6.6通过lsof –i:***查看指定的端口对应的应用程序是什么:
例如:
功能强大的网络文件系统------NFS
6.7查看NFS默认的随机端口:

Netstat(linux,windows下网络监听工具)是一个监控TCP/IP网络非常有利的工具,它可以显示路由表、实际的网络连接以及网络接口设备的状态信息。

[[email protected] ~]# netstat -tlunp | grep -E '(rpc|nfs)'      // -t(tcp)l(显示监控中的服务对应的端口信息)u(udp)n(直接通过ip地址而不通过域名服务器)p(识别Socket的程序码和程序名称)

功能强大的网络文件系统------NFS
6.8了解NFS常见的一些进程:

[[email protected] ~]# ps -ef | grep -E 'rpc|nfs'               //ps查看进程信息

功能强大的网络文件系统------NFS

Nfsd是最主要的NFS服务提供程序,这个daemon主要的功能就是管理客户端是否能够使用服务器文件系统挂载信息,其中还包含判断这个登录用户的ID。
rpc.mountd这个daemon主要功能则是管理NFS的文件系统。当client端顺利通过rpc.nfsd登入主机后,在它可以使用NFS服务器提供规定文件之前,还会经过文件使用权限的认证程序。它会去读取NFS的配置文件/etc/exports来对比客户端的权限,当通过这一关之后,client端也就取得使用NFS文件的权限。
rpc.statd(非必要的进程)这个daemon可以用来检查文件的一致性,若发生因为客户端同时使用同一个文件造成文件损坏时,rpc.statd可以用来检测并尝试恢复该文件。

6.9NFS服务的常用目录和文件:

/etc/exports
/usr/sbin/exportfs
/usr/sbin/showmount
/var/lib/nfs/*tab
             etab      //记录NFS分享出来的目录的完整权限设定值
             xtab      //记录曾经链接到此NFS主机的相关客户端数据

6.10NFS服务的配置文件:

/etc/exports

配置格式: 输出目录 客户端 选项
[访问权限,用户映射(防止我服务端与客户端有相同的用户无法区分,注意映射必须我当前系统上存在这个用户,才能映射成他),其他]
输出目录: 需要共享的目录路径; 客户端: 服务的用户对象;
选项:共享的权限,紧跟客户端列。

例如:

cat  /etc/exports
/test *(ro)                  //共享/test目录,*代表客户端允许所有用户,(ro)权限为只读权限
访问权限选项:
rw	                         //表示可读写权限
ro	                         //Read-only表示只读权限

了解访问权限选项:

参数命令 参数用途
rw 表示可读写权限
ro Read-only表示只读权限
Sync 请求或者写入数据时,数据同步写入到NFS server的硬盘中后才会返回
async 不同步请求,客户端上传后就结束了
no_root_squas 访问nfs server共享目录的用户如果是root的话,它对该目录具有root权限。这个配置原本为无盘用户准备的。用户应避免使用!对root用户不做映射
root_squash 对于访问NFS server共享目录的用户,如果是root的话会被压缩,成为nobody用户身份
all_squash 不管访问nfs server共享目录的用户身份是谁,如果是root,它的权限都将被压缩成为匿名用户,同时他们的udi和gid都会变成nobody或nfsnobody账户的uid,gid。在多个nfs客户端同时读写nfs server数据时,这个参数很有用可以确保大家写入的数据的权限是一样的。但不同系统有可能匿名用户的uid,gid不同。因为此处我们需要服务端和客户端之间的用户是一样的。比如说:服务端指定匿名用户的UID为2000,那么客户端也一定要存在2000这个账号才可以,对所有普通用户添加用户映射
No_all_squash 对普通用户不添加用户映射
anonuid anonuid就是匿名的uid和gid。说明客户端以什么权限来访问服务端,在默认情况下是nfsnobody。Uid65534
anongid 同anongid,就是把uid换成gid而已

举个例子来了解用户映射选项:
张三用了李四家的nfs服务,但是张三用root的身份在李四家的nfs服务器上面创建了一个文件,这个文件默认的所属用户所属组都是root,但是对于李四来说他可能将这个文件认为是自己服务端上的root用户创建的文件所以张三创建的这个root用户的文件在nfs服务器上会默认映射为匿名用户和组。还有如果张三用redhat用户在李四家的nfs服务器上创建但是李四端就没有redhat用户,默认创建就不会显示为redhat了。
了解其他选项:

Async所涉及到文件系统i/O的操作都是异步处理,即不会同步写到磁盘,此参数会提高性能,但是会降低数据安全,一般生产环境,不推荐使用,除非性能要求高,数据可靠性不高的场合;
atime在每一次数据访问时,同步更新每次的访问的inode的时间,默认是atime,在高并发的情况下,建议加上noatime来取消默认这个选项,以达到IO,优化目的;
auto 能够被自动挂载;
defaults 这是缺省值,rw,suid,dev,exec,auto,nouser,async;
exec运行可以执行二进制文件,取消这个参数会提升系统安全性;
nodiratime 不更新文件系统上的directory inode访问时间,高并发时候建议使用此选型;
noauto 不自动挂载;
noexec 即使设置了noexec shell php程序还是可以执行;
nosuid 禁止给普通用户挂载文件系统;
secure限制客户端只能从小于1024的tcp/ip端口连接nfs服务器(默认设置);
insecure允许客户端从大于1024的tcp/ip端口连接服务器;
sync将数据同步写入内存缓冲区与磁盘中,效率低,但可以保证数据的一致性;
async将数据先保存在内存缓冲区中,必要时才写入磁盘;
wdelay检查是否有相关的写操作,如果有则将这些写操作一起执行,这样可以提高效率(默认设置);
no_wdelay若有写操作则立即执行,应与sync配合使用;
subtree若输出目录是一个子目录,则nfs服务器将检查其父目录的权限(默认设置);
no_subtree即使输出目录是一个子目录,nfs服务器也不检查其父目录的权限,这样可以提高效率。

6.11案例演练:

架设一台NFS服务器,并根据要求完成配置。要求:1)开放/nfs/shared目录,供所有用户查询资料;2)开放/nfs/upload目录作为192.168.10.0/24网段的数据上传目录,并将所有用户及所属的用户组映射为nfs-upload,其UID和GID均为210;3)将/home/tom目录仅共享给192.168.10.66这台主机,并只有用户tom可以完全访问该目录。

服务器端配置:

[[email protected] ~]# mkdir /nfs/shared -pv
[[email protected] ~]# mkdir /nfs/upload 
[[email protected] ~]# useradd tom
[[email protected] ~]# cd /nfs/shared/
[[email protected] shared]# touch {a,b,c}
[[email protected] ~]# vim /etc/exports
/nfs/shared             *(ro)
/nfs/upload             192.168.10.0/24(rw,all_squash,anonuid=210,anongid=210)
/home/tom               192.168.10.66(rw)
配置完成后重启服务:
[[email protected] ~]# systemctl restart nfs
服务端查看共享的NFS:
[[email protected] ~]# showmount -e 192.168.10.206
Export list for 192.168.10.206:
/nfs/shared *
/nfs/upload 192.168.10.0/24
/home/tom   192.168.10.66
[[email protected] ~]# exportfs –r         //添加新的内容之后通过此命令重新读取一下配置文件
服务端关闭防火墙服务:
 [[email protected] ~]# systemctl stop firewalld.service

客户端配置:

客户端查看共享的NFS:
[[email protected] ~]# showmount -e 192.168.10.206
Export list for 192.168.10.206:
/nfs/shared *
/nfs/upload 192.168.10.0/24
/home/tom   192.168.10.66
客户端创建相应的挂载点:
[[email protected] ~]# mkdir /mnt/nfs
客户端进行挂载测试:
[[email protected] ~]# mount 192.168.10.206:/nfs/shared /mnt/nfs
[[email protected] ~]# mount 192.168.10.206:/nfs/upload /mnt/nfs
注意测试第三条要求的时候客户端要通过tom用户来进行测试,所以客户端必须有一个tom用户,并且客户端tom用户的uid与gid要与服务端的tom用户一致:
[[email protected] ~]# mount 192.168.10.206:/home/tom /mnt/nfs  
切换到指定挂载点目录下查看:
[[email protected] ~]# cd /mnt/nfs/
[[email protected] nfs]# ll
总用量 0
-rw-r--r--. 1 root root 0 2月  27 22:47 a
-rw-r--r--. 1 root root 0 2月  27 22:47 b
-rw-r--r--. 1 root root 0 2月  27 22:47 c