NFS技术
NFS可以通过网络让不同的主机系统之间彼此共享文件或者目录。
在服务器的使用过程中,通常会有专门的数据存放机器和应用服务机器。我们所要做的就是如何让应用服务机访问到数据机的数据。这里使用NFS(network file system)技术。
NFS使用的方式也是基于C/S架构,就是说,数据机可以充当S端,而访问者充当C端。通过挂载的方式,可以使数据端的目录如同本地目录一样访问。
由于数据和应用程序是在不同的机器上的,那么可以知道NFS是通过网络来进行数据传输的,那么也就会使用一些端口来传输数据,在端口选择的时候,通常是随机选择的。而为了NFS的客户端能够知道服务端到底使用了哪个端口,通常会用RPC(远程过程调用,Remote Procedure Call)协议/服务来实现。
RPC技术
NFS功能非常多,而不同的功能涉及到网络传输时,都会启用一些端口来传输数据,因此,NFS功能所对应的端口才无法固定,而是随机选用一些未使用的端口来传输。这些端口必须要进行记录,这样才能够保证不同的客户端在访问服务器时,能够通过不同的端口,找到正确的数据。
RPC的主要功能就是记录每个NFS功能所对应的端口号,并在NFS客户端请求时将该端口和功能对应的信息传递给客户端,保证客户端可以正确的连接到NFS端口上。相当于中介的功能。
大致如以下几点:
1、首先用户访问网站程序,由程序在NFS客户端上发出NFS文件存取功能的询问请求,这时NFS客户端(即执行程序的服务器)RPC服务(portmap或rpcbind服务)就会通过网络向NFS服务端的RPC服务(portmap或rpcbind)的某个端口发出NFS文件存取功能的询问请求。
2、NFS服务器端的RPC服务(即portmap或rpcbind)找到对应的已注册的NFS daemon端口后,通知NFS客户端的RPC服务(即portmap或rpcbind服务)
3、此时NFS客户端就可以获取到正确的端口,然后就直接与NFS daemon联机存取数据了。
4、NFS客户端把数据存取成功后,返回给当前访问程序,告知用户存取结果,作为网站用户,我们就完成了一次存取操作。 由于NFS的各项功能都需要向RPC服务注册,所以RPC服务才能获取到NFS服务的各项功能对应的端口、PID、NFS在主机所监听的IP等,NFS客户端才能够通过向RPC服务询问才找到正确的端口。也就是说,NFS需要有RPC服务的协助才能成功对外提供服务。由上面的描述,我们不难推出:无论是NFS客户端还是NFS服务器端,当要使用NFS时,都需要首先启动RPC服务,然后在启动NFS服务,客户端可以不启动NFS服务。
部署实例
服务端
sudo apt-get update
sudo apt install nfs-kernel-server
sudo apt install rpcbind
检查各项服务的状态
ps -ef | grep rpcbind/nfs
# 或
/etc/init.d/rpcbind status
启动rpcbind服务:
/etc/init.d/rpcbind start/restart
查看rpc信息 rpcinfo
rpcinfo -p localhost
#program vers proto port service
#1000004 tcp111 portmapper
#1000003 tcp111 portmapper
#1000002 tcp111 portmapper
#1000004 udp111 portmapper
#1000003 udp111 portmapper
#1000002 udp111 portmapper
如果没有开启,则上述指令会报错:
rpcinfo: can't contact portmapper: RPC: Remote system error - Connection refused
启动nfs服务
/etc/init.d/nfs-kernel-server start/restart
再次查看rpc信息 rpcinfo
rpcinfo -p localhost
#program vers proto port service
#1000004 tcp111 portmapper
#1000003 tcp111 portmapper
#1000002 tcp111 portmapper
#1000004 udp111 portmapper
#1000003 udp111 portmapper
#1000002 udp111 portmapper
#1000052 udp 50921 mountd
#1000052 tcp 36843 mountd
#1000053 udp 55650 mountd
#1000053 tcp 45212 mountd
上面可以看出,多了一些端口,说明NFS已经向RPC服务进行了端口注册
客户端
和服务端一样,客户端只需要启动RPC服务就可以了,具体使用方式和上面一样。
配置服务端
后面假设服务端的ip地址为:1, 2, 3, 4,客户端的ip地址为5,6, 7, 8
- 创建共享目录
mkdir /data
chmod 777 data
- 配置/etc/exports
vim /etc/exports
在最下面添加一行
/data 5.6.7.8(rw, sync, no_root_squash, no_subtree_check)
其中,5.6.7.8这个网址就是客户端的ip地址,表示该客户端可以对/data文件夹进行操作,操作的权限在括号中的参数中指定。如果将这个地址设为*,那么表示允许任意客户端来访问该文件夹。
后面的参数意思如下:
参数 | 说明 |
---|---|
rw | read-write,读写权限 |
ro | read-only,只读权限 |
sync | 同步,请求或写入数据时,数据同步写入到NFS Server的硬盘后才返回 |
async | 异步,请求或写入数据时,先返回请求,再将数据写入到内存缓存和硬盘中,即异步写入数据。此参数可以提升NFS性能,但是会降低数据的安全性。因此,一般情况下建议不用,如果NFS处于瓶颈状态,并且允许数据丢失的话可以打开此参数提升性能。写入时会先放到内存缓冲区,等硬盘有空档再写入磁盘,这样可以提升写入效率,风险:服务器宕机或不正常关机,会损失缓冲区中未写入磁盘的数据。 |
no_root_squash | 访问NFS Server共享目录的用户,如果是root,它对该共享目录具有root权限,这个配置原本为无盘客户端准备的,用户应避免使用。 |
root_squash | 对于访问NFS Server共享目录的用户,如果是root,则它的权限将被压缩成匿名用户,同时它的UID和GID通常会变成nobody或nfsnobody账号身份。 |
all_squash | 不管访问NFS Server共享目录的用户身份如何,它的权限都将被压缩成匿名用户,同时他的UID和GID都会变成nobody或nfsnobody账号身份,在多个NFS客户端同时读写NFS Server数据时,这个参数很有用。 |
anonuid | 参数以anon*开头是指anonymous匿名用户,这个用户的UID设置值通常为nobody和nfsnobody的UID值,当然我们也可以自行设置这个UID值。但是UID必须存在于/etc/passwd中。在多个NFS Client时,如多台web server共享一个NFS目录时,通过这个参数可以使得不同的NFS Client写入的数据对所有的NFS Client保持同样的用户权限,即为配置的匿名UID对应用户权限,这个参数很有用。 |
anongid | 同上,区别就在于uid和gid |
secure | 不允许Client使用大于1024的端口号,也就是从Server传递的资料到Client端的目标port要小于1024,此时,Client端一定要使用root账号才能mount远端NFS Server,建议使用insecure |
insecure | 允许Client端自行决定个你自己机器使用的port,通常都会设置这个,如此非root账号的client端才能 mount NFS Server |
nohide | 当export出两个目录,而其中一个目录是另外一个目录的子目录,例如:我们使用虚拟目录的例子,此时我们mount跟目录时,会自动把所有子目录mount起来。建议使用这个选项比较方便,尤其是在NFSv4有虚拟目录的情形。 |
hide | 当mount跟目录时,export出的子目录需要自己明确的再挂载 |
subtree_check | 当分享的目录是某个档案系统的子目录,选用这个可以确定父目录的权限让NFS Server分享使用。 |
no_subtree_check | 刚好和上面的相反,因为不做权限测试,效能比较好 |
fsid=0 | 定义NFSv4中的目录,只能有一个 |
- 检查配置结果
cat /etc/exports
可能在修改exports之后没有立即生效,这时可以通过重启rpc和nfs服务,这样再执行上面的命令,就可以看到修改之后的结果。上面的结果表明允许任何客户端访问,开放状态。
- 服务端自身检查
showmount -e localhost
表示这个路径是开放的。
配置客户端
- 客户端检查
查看服务端的情况
showmount -e 1,2,3,4
- 客户端挂载目录
在客户端上执行下面的命令
sudo mount -t nfs 1.2.3.4:/data /本地目录
- 检查磁盘情况
df -h
可以看到,出现了服务端的地址和对应的目录,包括容量大小,最后还有本地挂载的目录的绝对路径
出错情况
- 出现permissiong deny的情况一般都是权限问题,所以检查文件的权限。
- 偶尔会出现服务器重启或者因为各种不明原因,导致服务器的路径/data出现了问题,这时如果在客户端在进行访问的时候,就会发现访问挂载在本地的目录时会出现:"mount.nfs: stale file handle"的报错
通过指令进行查看文件属性,挂载的目录结果可能是下面这样的:
ls -al
无法通过rm等命令进行删除,并且提示这是个句柄。
解决这个问题,可以通过在宿主机目录中,将该目录卸载来进行处理:
umount -rf /本地目录绝对路径
然后再次查看的话,可以发现目录已经还原到本地文件夹正常形式,这时候可以进行删除等其他操作。
对于服务端也是这样。
之后再按照前面的方式进行再次配置就可以了。
后续问题
可以通过参考NFS讲解来继续了解