NFS(Network File System)即网络文件系统,它允许网络中的计算机之间通过网络共享资源。将NFS主机分享的目录,挂载到本地客户端当中,本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件,在客户端端看起来,就像访问本地文件。NFS系统和Windows网络共享、网络驱动器类似, 只不过windows用于局域网, NFS用于企业集群架构中, 如果是大型网站, 会用到更复杂的分布式文件系统FastDFS、glusterfs、HDFS。实现多台服务器之间数据的一致。NFS文件系统简单易用、方便部署、数据可靠、服务稳定、满足中小企业需求。NFS文件系统内存放的数据都在文件系统之上,所有数据都是能看得见。存在单点故障, 如果构建高可用维护麻烦。(web-》nfs()-》backup)。NFS数据明文, 并不对数据做任何校验。客户端挂载无需账户密码, 安全性一般(内网使用)。
Linux而言,文件系统是在内核空间实现的,即文件系统比如ext3、ext4等是在Kernel启动时,以内核模块的身份加载运行的。外部用户不能直接通过网络操控内核(除了ssh)。 RPC,基于C/S模型。程序可以使用这个协议请求网络中另一台计算机上某程序的服务而不需知道网络细节,甚至可以请求对方的系统调用。NFS本身的服务并没有提供数据传递的协议,而是通过使用RPC(远程过程调用 Remote Procedure Call)来实现。当NFS启动后,会随机的使用一些端口,NFS就会向RPC去注册这些端口。RPC就会记录下这些端口,RPC会开启111端口。通过client端和sever端端口的连接来进行数据的传输。在启动nfs之前,首先要确保rpc服务启动。
用户进程访问NFS客户端,NFS客户端通过TCP/IP的方式传递给NFS服务端。在连接之前,NFS服务除了启动nfsd本身监听的端口2049/tcp和2049/udp,还会启动其它进程(如mountd,statd,rquotad等)以完成文件共享,这些进程的端口是不固定的;是每次NFS服务启动时向RPC服务注册的,RPC服务会随机分配未使用的端口 。NFS服务端接收到请求后,会先调用portmap进程进行端口映射。nfsd进程用于判断NFS客户端是否拥有权限连接NFS服务端。Rpc.mount进程判断客户端是否有对应的权限进行验证。idmap进程实现用户映射和压缩。最后NFS服务端会将对应请求的函数转换为本地能识别的命令,传递至内核,由内核驱动硬件。
rpc:远程过程调用协议,是实现本地调用远程主机实现系统调用的协议。
portmapper:负责分配rpc server的端口,并在client端请求时,负责响应目的rpc server端口返回给client端,工作在tcp与udp的111端口上。
mountd:是nfs服务的认证服务的守护进程,client在收到返回的真正端口时,就会去连接mountd,认证取得令牌。
nfsd:nfs的守护进程,负责接收到用户的调用请求后与内核发出请求并得到调用结果响应给用户,工作在tcp和udp的2049端口。
idmapd:是NFS的一个程序,用来负责远程client端创建文件后的权限问题。
quotad:用用于实现磁盘配额,当client端挂载nfs后可以限制磁盘空间的大小。
优点
节省本地存储空间将常用的数据存放在一台服务器可以通过网络访问
方快速便部署,维护十分简单
缺点
局限性容易发生单点故障,及server机宕机了所有客户端都不能访问
在高并发下NFS效率/性能有限
客户端没用用户认证机制,且数据是通过明文传送,安全性一般(一般建议在局域网内使用)
NFS的数据是明文的,对数据完整性不做验证
多台机器挂载NFS服务器时,连接管理维护麻烦
[root@resource ~]# yum -y install nfs-utils lsof net-tools
[root@resource ~]# echo '/data 192.168.1.0/24(rw,sync,all_squash)' > /etc/exports
[root@resource ~]# systemctl enable rpcbind nfs-server
[root@resource ~]# systemctl start rpcbind nfs-server
检查端口
[root@resource ~]# netstat -lntp
检查共享的内容
[root@resource ~]# cat /var/lib/nfs/etab
查看rpcbind监听状态(主端口为111)
[root@resource ~]# lsof -i:111
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root 79u IPv4 37768 0t0 TCP *:sunrpc (LISTEN)
systemd 1 root 80u IPv4 37769 0t0 UDP *:sunrpc
systemd 1 root 81u IPv6 37770 0t0 TCP *:sunrpc (LISTEN)
systemd 1 root 82u IPv6 37771 0t0 UDP *:sunrpc
rpcbind 7482 rpc 4u IPv4 37768 0t0 TCP *:sunrpc (LISTEN)
rpcbind 7482 rpc 5u IPv4 37769 0t0 UDP *:sunrpc
rpcbind 7482 rpc 6u IPv6 37770 0t0 TCP *:sunrpc (LISTEN)
rpcbind 7482 rpc 7u IPv6 37771 0t0 UDP *:sunrpc
[root@resource ~]# netstat -tlunp | grep rpcbind
udp 0 0 0.0.0.0:873 0.0.0.0:* 7482/rpcbind
udp6 0 0 :::873 :::* 7482/rpcbind
nfs服务所开启的端口号
[root@resource ~]# netstat -tlunp | grep -E 'nfs|rpc'
tcp 0 0 0.0.0.0:59851 0.0.0.0:* LISTEN 7493/rpc.statd
tcp 0 0 0.0.0.0:20048 0.0.0.0:* LISTEN 7540/rpc.mountd
tcp6 0 0 :::20048 :::* LISTEN 7540/rpc.mountd
tcp6 0 0 :::60093 :::* LISTEN 7493/rpc.statd
udp 0 0 0.0.0.0:58836 0.0.0.0:* 7493/rpc.statd
udp 0 0 0.0.0.0:20048 0.0.0.0:* 7540/rpc.mountd
udp 0 0 0.0.0.0:873 0.0.0.0:* 7482/rpcbind
udp 0 0 127.0.0.1:885 0.0.0.0:* 7493/rpc.statd
udp6 0 0 :::38444 :::* 7493/rpc.statd
udp6 0 0 :::20048 :::* 7540/rpc.mountd
udp6 0 0 :::873 :::* 7482/rpcbind
[root@master ~]# yum install nfs-utils -y
[root@master ~]# systemctl enable rpcbind
[root@master ~]# systemctl start rpcbind
[root@master ~]# showmount -e resource
Export list for resource:
/data/yum 192.168.1.0/24
[root@master ~]# echo '192.168.1.77:/data/yum /data/yum nfs defaults 0 0' >> /etc/fstab
客户端挂载共享目录后,不管是root用户还是普通用户,创建新文件时属主、属组为nobody。
Notice:★★★★
rpcbind在nfs-utils中。
序号 | 参数 | 作用 |
---|---|---|
1 | rw* | 读写权限 |
2 | ro | 只读权限 |
3 | root_squash | 当NFS客户端以root管理员访问时,映射为NFS服务器的匿名用户(不常用) |
4 | no_root_squash | 当NFS客户端以root管理员访问时,映射为NFS服务器的root管理员(不常用) |
5 | all_squash | 无论NFS客户端使用什么账户访问,均映射为NFS服务器的匿名用户(常用) |
6 | no_all_squash | 无论NFS客户端使用什么账户访问,都不进行压缩 |
7 | sync* | 同时将数据写入到内存与硬盘中,保证不丢失数据 |
8 | async | 优先将数据保存到内存,然后再写入硬盘;这样效率更高,但可能会丢失数据 |
9 | anonuid* | 配置all_squash使用,指定NFS的用户UID,必须存在系统 |
10 | anongid* | 配置all_squash使用,指定NFS的用户UID,必须存在系统 |
示例1
只读
echo ‘/data 172.16.1.0/24(ro,sync,all_squash)’ > /etc/export
示例2
映射为gid为666的账户,只有gid为666的才能访问
echo ‘/data 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)’ > /etc/exports
exportfs命令和nfs-utils这个包一起安装的
假设在第一次配置nfs的共享目录,之后需要新增、更改某些机器或共享的目录; 首先需要更改配置文件,然后重启NFS服务,但如果远程客户端正在使用NFS服务,正在挂载着,如果你需要先停止nfs服务,那远程的客户端就会挂起,就会很大的影响,造成服务异常,进程异常,有很大可能导致系统坏掉。
nfs服务不能随便重启,要重启,就需要先去服务器上,把挂载的目录卸载下来。在卸载目录的时候,若是在当前目录下去卸载会提示umount.nfs4: /mnt: device is busy
方法一:退出该目录后,再去卸载
方法二:在目录下卸载的时候,加 -l 选项,表示 lazy 懒惰的意思
在卸载目录后,在重启nfs服务
若是挂载了很多台机器,那么每台机器都需要去卸载,就会很麻烦,降低了工作效率。
方法:使用exportfs命令,重新加载。
/usr/sbin/exportfs [-avi] [-o options,…] [client:/path …]
-a:跟-r或-u选项同时使用,表示重新挂载所有文件系统或取消导出所有文件系统;
-r: 重新导出
-u: 取消导出
-v: 显示详细信息
exportfs -arv
exportfs -u 192.168.119.134/32:/data
-a或-all:以host:dir这样的格式来显示客户主机名和挂载点目录。
-d或-directories:仅显示被客户挂载的目录名。
-e或-exports:显示NFS服务器的输出清单。
–no-headers:禁止输出描述头部的信息。
-p hostname(orIP):显示所有的 port 与 program 的信息。
如果要让mountd和quotad等进程监听在固定端口,编辑配置文件/etc/sysconfig/nfs
prognum 参数是一个数值,用以表示一个 RPC 程序号。如果指定了 versnum (版本号),rpcinfo 会试图调用该指定程序号的对应版本。否则,rpcinfo 会通过调用版本号0,这样会试图找到所有指定程序号程序的所有版本号。
-p 选项,使用 rpcbind 协议的第 2 版本样式来探测 rpcbind ,第 2 版本的 rpcbind 在早些时也称为 portmapper 协议。
-t 选项,使用 TCP 协议向指定 host 上的 prognum 的 过程0 发出 RPC 调用,并报告是否能收到一个响应。该选项建议使用上述的 -T 来代替。
-u 选项,使用 UDP 协议向指定 host 上的 prognum 的 过程0 发出 RPC 调用,并报告是否能收到一个响应。该选项建议使用上述的 -T 来代替。
-a 选项,指定主机的完整 IP 地址和端口号。使用该选项时注意地址的格式,可以先单独运行 。
# rpcinfo
program version netid address service owner
100000 4 tcp6 ::.0.111 portmapper superuser
100000 4 tcp 0.0.0.0.0.111 portmapper superuser
100000 3 local /var/run/rpcbind.sock portmapper superuser
100024 1 udp 0.0.0.0.162.19 status 29
100024 1 tcp 0.0.0.0.136.165 status 29
100024 1 udp6 ::.235.140 status 29
100024 1 tcp6 ::.200.18 status 29
# rpcinfo -a 192.168.1.102.176.112 -T tcp 100005 2
program 100005 version 2 ready and waiting
-b 选项,将 RPC 广播到指定的“程序号/版本号"对的 过程0 ,并报告响应的所有主机。如果指定了 transport 参数,它仅广播它的指定 transport 上的请求。如果任何 transport 不支持广播,那么打印错误信息。由于广播行为可能会对别的系统产生不利影响,应该限制使用广播。
-m 选项,显示指定主机上的端口映射操作统计信息表。该表包含了对每个版本的端口映射(版本2,3 和4)的统计信息、每个过程请求和成功服务的次数,所做的远程调用请求的类型和数目,以及关于已处理的 RPC 地址查询信息。本信息用来监视在主机上的 RPC 活动,比如:
-l 选项,显示在指定主机上的”程序号/版本号"对 的条目的列表。返回所有使用与用于联系远程 portmap 守护进程的协议在同一个协议系列内的传输的条目,比如:
#rpcinfo -l localhost 100000 3
program vers tp_family/name/class address service
100000 3 inet6/tcp/cots_ord ::1.0.111 portmapper
100000 3 inet6/udp/clts ::1.0.111 portmapper
-n portnum 选项,使用 portnum 参数作为 -t 和 -u 选项的端口号来代替 rpcbind 给出的端口号。使用该选项避免了调用远程 rpcbind 来查找服务的地址。不建议用该选项,而是使用 -a 选项。
-d 选项,删除给定“程序号/版本号”对上的 RPC 服务上的注册。如果使用 transport,那么只注销那个 transport 上的服务;否则注销掉所有 transport 上的服务。只有服务的拥有者可以删除相应的注册,root 用户可以删除任一个服务上的注册。
mount -t nfs NFS_SERVER:/PATH/TO/SOME_EXPORT /PATH/TO/SOMEWHRERE
NFS 4版本会有该问题,客户端挂载共享目录后,不管是root用户还是普通用户,创建新文件时属主、属组为nobody。
客户端挂载时加上 -o nfsvers=3
mount -t nfs -oremount,nfsvers=3 192.168.1.77:/data /mnt/data
客户端和服务端都需要修改
vim /etc/idmapd.conf
把“#Domain = local.domain.edu” 改为 “Domain = xxx.com” (这里的xxx.com,随意定义吧),然后再重启rpcidmapd服务。
————Blueicex 2020/2/3 23:56 [email protected]