一、NFS的工作原理(Llinux)
1:什么是NFS服务
NFS是Network File System的缩写。最大的功能是可以通过网络来让不同的机器、不同的操作系统共享彼此的文件。
NFS服务可以让PC将网络中的NFS共享的目录挂载到本地端的文件系统中,在本地端的系统看来,远程挂载的目录就像本地的一个磁盘分区一样。使用时比较方便。
2:NFS挂载的原理
当在NFS服务器中设置好一个共享目录/home/public后,其他的有权访问NFS服务器的NFS客户端就可以将这个目录挂载到自己文件系统的某个挂载点,该挂载点路径客户端可以自定义。挂载完成后,如果服务器daunt配置的客户端为只读,那么客户端就只能读取文件。若为服务器端为读写,则客户端可以进行读写操作。
NFS服务通过网络来进行服务端和客户端之间的数据传输,那么两者之间要传输数据就需要有对应的网络端口。NFS服务器端的端口为2049,但由于文件系统的复杂性导致NFS还有其他程序去启动额外的端口,这些额外的用于传输数据的端口是随机选择的,一般是小于1024的端口。客户端通过远程调用(Remote Procedure Call,RPC)协议来得知NFS服务端使用的端口。(portmap或rpcbind服务)
3:什么是RPC服务
RPC(Remote Procedure Call),即远程过程调用。RPC最主要的功能是指定每个NFS功能所对应的端口号,并通知给客户端,让客户端可以连接到正确的端口上。
二、NFS通讯原理
1:RPC与NFS如何通讯
由于NFS支持的功能比较多,不同的功能都会使用不同的程序来启动,每启动一个功能就会启用一部分端口来传输数据。因此NFS的功能对应的端口并不固定。客户端需要知道NFS端口的相关信息才能建立连接并进行数据传输,而RPC就是用来统一管理NFS端口的服务,并且统一对外的端口号为111,RPC会记录NFS端口的信息。如此便能通过RPC来实现服务端和客户端沟通端口信息。
当NFS启动后会随机地使用一些端口,然后NFS主动向RPC去注册这些端口,RPC记录下这些NFS使用的端口并开启111端口。等待客户端RPC的请求,若客户端有请求,服务端的RPC就会将之前记录的NFS端口信息告知客户端。通过这种方式客户端就会获取到NFS服务器端的端口信息,然后以实际端口进行数据传输。
注:在启动NFS服务之前,首先要启动RPC服务(即portmap服务),否则NFS服务无法向RPC服务去注册端口。如果RPC服务重新启动,原来已经注册的NFS端口数据就会丢失。因此RPC管理的NFS程序也需要重启启动以重新向RPC注册。一般修改NFS配置文件后不需要重启NFS服务,直接在命令行执行/etc/init.d/nfs reload或exports -rv即可让修改的/etc/exports生效。
2:portmap
作用:把RPC程序号转化为Internet的端口号。
特点:只在第一次建立连接的时候帮助网络应用程序找到正确的端口。当双方正常连接后,端口就和应用绑定,portmap就没用了。
3:NFS客户端与NFS服务端的通讯过程
1>:服务端启动RPC服务,并开启111端口。
2>:服务端启动NFS服务,并向RPC注册端口信息。
3>:客户端启动RPC服务,向服务端的RPC服务请求NFS服务端口。
4>:服务端的RPC服务反馈NFS端口信息给客户端。
5>:客户端通过获取的NFS端口来建立和服务端的NFS链接并进行数据的传输。
即:
1(注册端口)–>2(达成协议)–>3(直接建立联系)–>4(达成协议)–>5(建立连接)
三、NFS服务的优缺点
优点:
1:节省本地存储空间,将常用的数据存放在可以通过网路访问的服务器上。
2:简单、容易上手。
3:方便部署,维护简单。
缺点:
1:局限性,容易发生单点故障以及server宕机导致所有客户端都不能访问。
2:在高并发下NFS的效率、性能有限。
3:客户端没有用户认证机制,且数据是通过明文传输,安全性一般(建议在局域网内使用)。
4:NFS的数据是明文的,没有对数据完整性做验证。
5:多台机器挂载NFS服务器时,连接管理维护比较麻烦。
四、部署NFS服务
在RHEL7.2版本中,默认已经安装了nfs-utils(nfs主程序)和rpcbind(rpc主程序)。
重启rpcbind服务:
[root@localhost ~]# systemctl restart rpcbind
[root@localhost ~]# systemctl status rpcbind
rpcinfo:通过rpcinfo工具显示使用portmap注册的程序信息,并向程序进行rpc调用,检查是否正常运行:
lsof(list open files):列出当前系统打开文件
netstat:该命令用于显示各种网络相关的信息,如网络连接、路由表、接口状态、masquerade连接、多播成员等等。
通过netstat查看nfs服务所开启的端口号:
进程:
nfsd最主要的NFS服务提供程序,该daemon主要的功能就是管理客户端是否能够使用服务器文件系统挂载信息,其中还包含判断这个登录用户的ID。
rpc.mountd:
该daemon主要功能是管理NFS的文件系统。当客户端顺利通过rpc.nfsd登录服务端后,在他可以使用NFS服务器提供规定文件之前,还会经过文件使用权限的认证程序。它回去读取NFS的配置文件/etc/exports来对比客户端的去哪先,当通过认证后就取得了NFS文件的权限。
rpc.statd(非必要):
该daemon可以用来检查文件的一致性。若发生因为客户端同时使用同一文件而造成的文件损坏时,rpc.statd可以用来检测并尝试恢复该文件 。
服务端设置访问权限选项:
参数命令 | 作用 |
---|---|
rw | 表示可读写 |
ro | Read-Only,表示只有读权限 |
sync | 请求或写入数据时,数据同步写入到nfs server的硬盘后才会返回 |
no_root_squash | 访问nfs server共享目录的用户如果是root的话,它对该目录有root权限。改配置一般为无盘用户准备。用户应避免使用 |
root_squash | 访问nfs server共享目录的用户是root用户。会被映射为其他用户,它对该目录并不具有root权限 |
all_squash | 无论访问nfs server共享目录的用户身份是什么(包括root用户),它的权限都会被映射为匿名用户,同时他们的uid、gid都会变为nobody或nfsnobody用户的uid、gid。在多个nfs客户端同时读写nfs server数据时,这个参数可以确保大家写入数据的权限是一样的 |
no_all_squash | 关闭所有用户映射,不同的客户端写入数据的权限可能不同。 |
anonuid | anonuid就是匿名用户的uid,说明客户端以什么权限来访问服务端。默认情况下为nfsnobody,uid为65534 |
anongid | anongid就是匿名用户的gid,作用同anonuid |
案例:
架设一台NFS服务器,并按照以下要求配置
1、开放/nfs/shared目录,供所有用户查询资料 ro
2、开放/nfs/upload目录,为172.16.80.0/24网段主机可以上传目录,rw o=rwx并将所有用户及所属的用户组映射为nfs-upload,其UID和GID均为210
3、将/home/tom目录仅共享给192.168.10.128这台主机,并只有用户tom可以完全访问该目录
注意:tom是一个用户目录,并且在客户端创建tom用户一定与服务端的tom用户的uid/gid保持一致。
服务端:
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# mount /dev/sr0 /mnt/
[root@localhost ~]# mkdir /nfs/{shared,upload} -p
[root@localhost ~]# systemctl restart nfs
[root@localhost ~]# systemctl status nfs
[root@localhost ~]# vim /etc/exports
[root@localhost ~]# groupadd -g 210 nfs-upload
[root@localhost ~]# useradd -u 210 -g 210 nfs-upload
[root@localhost ~]# chmod o+w /nfs/upload/
[root@localhost ~]# useradd tom
[root@localhost ~]# setfacl -m u:tom:rwx /home/tom/
[root@localhost ~]# exportfs -ra
客户端:
[root@localhost ~]# mkdir /{nfs1,nfs2,tom} -p
[root@localhost ~]# mount 192.168.199.128:/nfs/shared /nfs1/
[root@localhost ~]# mount 192.168.199.128:/nfs/upload /nfs2
[root@localhost ~]# mount 192.168.199.128:/home/tom /tom/
[root@localhost ~]# groupadd -g 1001 toms
[root@localhost ~]# useradd -u 1001 -g 1001 tom --客户端创建的tom用户应当与服务端的tom用户的uid、gid保持一致。否则权限认证会出现问题
测试:
1:
服务端:
[root@localhost ~]# touch /nfs/shared/{1,2,3}
客户端:
2:
服务端:
[root@localhost ~]# touch /nfs/upload/{1,2}
客户端:
在服务端上查看客户端上传的文件,所属用户和所属组被映射为nfs-upload。
3:
客户端:
在客户端上的root用户不能直接访问/tom目录,需要切换当前用户为tom用户。
在客户端上仅tom用户对/tom目录拥有全部的权限,其他用户不能访问该目录。
服务端: