一、NFS 协议
NFS服务工作在TCP的2049端口,UDP的2049端口。
NFS是Network File System的缩写,即网络文件系统,是一种使用于分散式文件系统的协定。功能是通过网络让不同的机器、不同的操作系统能够彼此分享个别的数据,让应用程序在客户端通过网络访问位于服务器磁盘中的数据,是在类Unix系统间实现磁盘文件共享的一种方法。
这个NFS服务器可以让你的PC来将网络远程的NFS服务器分享的目录,挂载到本地端的机器当中, 在本地端的机器看起来,那个远程主机的目录就好像是自己的一个磁盘分区槽一样。
1.1 工作原理
因为 NFS 支持的功能相当的多,而不同的功能都会使用不同的程序来启动, 每启动一个功能就会启用一些端口来传输数据,因此, NFS 的功能所对应的端口才没有固定住, 而是随机取用一些未被使用的小于 1024 的端口来作为传输之用。但如此一来又造成客户端想要连上服务器时的困扰, 因为客户端得要知道服务器端的相关端口才能够联机吧!
NFS在文件传送或信息传送过程中依赖于RPC协议。RPC,即远程过程调用的缩写,是能使客户端执行其他系统中程序的一种机制。RPC 最主要的功能就是在指定每个 NFS 功能所对应的端口号,并且回报给客户端,让客户端可以连接到正确的端口上去。
NFS本身是没有提供信息传输的协议和功能的,但NFS却能让我们通过网络进行资料的分享,这是因为NFS使用了一些其它的传输协议。而这些传输协议用到这个RPC功能的。可以说NFS本身就是使用RPC的一个程序,或者说NFS也是一个RPC SERVER。所以只要用到NFS的地方都要启动RPC服务,不论是NFS SERVER或者NFS CLIENT。这样SERVER和CLIENT才能通过RPC来实现PROGRAM PORT的对应。可以这么理解RPC和NFS的关系:NFS是一个文件系统,而RPC是负责负责信息的传输。
事实上,有很多这样的服务器都是向 RPC 注册的,举例来说,NIS (Network Information Service) 也是 RPC server 的一种。
那RPC又是如何知道每个NFS的端口呢?
- 这是因为当服务器在启动 NFS 时会随机取用数个端口,并主动的向 RPC 注册,因此 RPC 可以知道每个埠口对应的 NFS 功能,然后 RPC 又是固定使用 111 端口来监听客户端的需求并报客户端正确的埠口, 所以当然可以让 NFS 的启动更为轻松愉快了。
- 所以你要注意,要启动 NFS 之前,RPC 就要先启动了,否则 NFS 会无法向 RPC 注册。另外,RPC 若重新启动时,原本注册的数据会不见,因此 RPC 重新启动后,它管理的所有服务都要重新启动来重新向 RPC 注册。
那客户端如何向NFS服务端交换数据数据呢?
- (1) 客户端会向服务器端的 RPC 的111端口发出 NFS 档案存取功能的询问要求
- (2) 服务器端找到对应的已注册的 NFS 守护进程端口后,会回报给客户端
- (3) 客户端了解正确的端口后,就可以直接与 NFS 守护进程来联机
1.2 激活 NFS 服务
NFS 服务需要激活几个重要的 RPC 守护进程
工作流程
nfs—client => portmapper => mountd => nfs-server(nfsd)
(1) rpc.nfsd
- 这个守护进程主要的功能,则是在管理客户端是否能够登入主机的权限,其中还包含这个登入者的 ID 的判别。
(2) rpc.mountd
主要功能
- 这个守护进程主要的功能,则是在管理 NFS 的档案系统,用于给用户提供访问令牌。
- 访问的令牌,由本地的RPC提供随机端口。本地的RPC叫做portmapper,可以使用rpcinfo -P查看。
- RPC的portmapper服务工作在1111端口。
请求过程
- 当客户端顺利的通过 rpc.nfsd 而登入主机之后,在它可以使用 NFS server 提供的档案之前,还会经过档案使用权限 的认证程序,就是那个-rwxrwxrwx、owner、group那几个权限啦。
- 然后它会去读 NFS 的设定档 /etc/exports 来比对客户端的权限,当通过这一关之后,客户端就可以取得使用 NFS 档案的权限啦。
注释:NFS需要有两个套件
- nfs-utils
NFS服务的主要套件
提供rpc.nfsd和rpc.mountd两个NFS守护进程和与其它相关文档与说明文件、执行档等的套件
- portmap
主要负责RPC端口和守护进程的映射关系,即portmapper
在激活任何一个RPC server之前,我们都需要激活portmapper才行
1.3 各个版本之间的比较
NFS是一种网络文件系统,从1985年推出至今,共发布了3个版本:NFSv2、NFSv3、NFSv4,NFSv4包含两个次版本NFSv4.0和NFSv4.1。经过20多年发展,NFS发生了非常大的变化,最大的变化就是推动者从Sun变成了NetApp,NFSv2和NFSv3基本上是Sun起草的,NetApp从NFSv4.0参与进来,并且主导了NFSv4.1标准的制定过程,而Sun已经被Oracle收购了。
1. NFSv2
- NFSv2·是第一个以RFC形式发布的版本,实现了基本的功能。
2. NFSv3
协议特点
- NFSv3修正了NFSv2的一些bug,两者有如下一些差别,但是感觉没有本质的差别。
区别差别
- (1) NFSv2只支持同步写,如果客户端向服务器端写入数据,服务器必须将数据写入磁盘中才能发送应答消息。NFSv3支持异步写操作,服务器只需要将数据写入缓存中就可以发送应答信息了。
- (2) NFSv3增加了ACCESS请求,ACCESS用来检查用户的访问权限。因为服务器端可能进行uid映射,因此客户端的uid和gid不能正确反映用户的访问权限。
- (3) 一些请求调整了参数和返回信息,毕竟NFSv3和NFSv2发布的间隔有6年,经过长期运行可能觉得NFSv2某些请求参数和返回信息需要改进。
3. NFSv4.0
协议特点
- 相比NFSv3,NFSv4发生了比较大的变化,最大的变化是NFSv4有状态了。NFSv2和NFSv3都是无状态协议,服务区端不需要维护客户端的状态信息。
- 无状态协议的一个优点在于灾难恢复,当服务器出现问题后,客户端只需要重复发送失败请求就可以了,直到收到服务器的响应信息。
区别差别
(1) NFSv4增加了安全性,支持RPCSEC-GSS身份认证。
(2) NFSv4设计成了一种有状态的协议,自身实现了文件锁功能和获取文件系统根节点功能。
(3) NFSv4只提供了两个请求NULL和COMPOUND,所有的操作都整合进了COMPOUND中,客户端可以根据实际请求将多个操作封装到一个COMPOUND请求中,增加了灵活性。
(4) NFSv4文件系统的命令空间发生了变化,服务器端必须设置一个根文件系统(fsid=0),其他文件系统挂载在根文件系统上导出。
(5) NFSv4支持delegation。由于多个客户端可以挂载同一个文件系统,为了保持文件同步,NFSv3中客户端需要经常向服务器发起请求,请求文件属性信息,判断其他客户端是否修改了文件。如果文件系统是只读的,或者客户端对文件的修改不频繁,频繁向服务器请求文件属性信息会降低系统性能。NFSv4可以依靠delegation实现文件同步。
(6) NFSv4修改了文件属性的表示方法。由于NFS是Sun开发的一套文件系统,设计之出NFS文件属性参考了UNIX中的文件属性,可能Windows中不具备某些属性,因此NFS对操作系统的兼容性不太好。
4. NFSv4.1
- 与NFSv4.0相比,NFSv4.1最大的变化是支持并行存储了。在以前的协议中,客户端直接与服务器连接,客户端直接将数据传输到服务器中。
- 当客户端数量较少时这种方式没有问题,但是如果大量的客户端要访问数据时,NFS服务器很快就会成为一个瓶颈,抑制了系统的性能。NFSv4.1支持并行存储,服务器由一台元数据服务器(MDS)和多台数据服务器(DS)构成,元数据服务器只管理文件在磁盘中的布局,数据传输在客户端和数据服务器之间直接进行。由于系统中包含多台数据服务器,因此数据可以以并行方式访问,系统吞吐量迅速提升。
二、NFS 服务
CentOS7以NFSv4作为默认版本,NFSv4使用TCP协议(端口号是2049)和NFS服务器建立连接。
- # 系统环境
- 系统平台:CentOS release 7.0 (Final)
- NFS Server IP:192.168.10.10
- 防火墙已关闭/iptables: Firewall is not running.
- SELINUX=disabled
2.1 安装 NFS 服务
服务端
- 服务端,程序包名nfs-utils、rpcbind,默认都已经安装了
- 可以通过rpm -ql nfs-utils查看帮助文档等信息
客户端
- 客户端,需要安装程序包名nfs-utils,提供基本的客户端命令工具
- [root@localhost ~]# yum install nfs-utils
- Loaded plugins: langpacks, product-id, subscription-manager
- ......
- Package 1:nfs-utils-1.3.0-0.el7.x86_64 already installed and latest version
- Nothing to do
查看NFS服务端口
- NFS启动时会随机启动多个端口并向RPC注册,为了方便配置防火墙,需要固定NFS服务端口。
- 这样如果使用iptables对NFS端口进行限制就会有点麻烦,可以更改配置文件固定NFS服务相关端口
- 分配端口,编辑配置文件/etc/sysconfig/nfs
- # 使用rpcinfo -P会发现rpc启动了很多监听端口
- [root@localhost ~]# rpcinfo -p localhost
- program vers proto port service
- 100000 4 tcp 111 portmapper
- 100000 2 udp 111 portmapper
- 100005 1 udp 49979 mountd
- 100005 1 tcp 58393 mountd
- 100003 2 tcp 2049 nfs
- 100227 2 tcp 2049 nfs_acl
- ......
- # 添加如下
- [root@localhost ~]# vim /etc/sysconfig/nfs
- RQUOTAD_PORT=30001
- LOCKD_TCPPORT=30002
- LOCKD_UDPPORT=30002
- MOUNTD_PORT=30003
- STATD_PORT=30004
启动服务
- [root@localhost ~]# service nfs start
- Starting NFS services: [OK]
- Starting NFS quotas: [OK]
- Starting NFS mountd: [OK]
- Starting NFS daemon: [OK]
- Starting NFS idmapd: [OK]
2.2 服务文件配置
- 相关文件和命令
- 配置文件/etc/exports
我们可以按照“共享目录的路径 允许访问的 NFS 客户端(共享权限参数)”的格式,定义要共享的目录与相应的权限
- [root@localhost ~]# cat /etc/exports
- /nfsfile 192.168.10.*(rw,sync,root_squash)
- /tmp/serverdir 192.168.174.132(rw,sync,no_root_squash) 192.168.174.133(ro,sync,no_root_squash)
三、实战演示
如果有兴趣,可以尝试:两台 web 服务器,共享关系型数据库,共享 NFS 服务器,利用 DNS 记录轮询提供负载均衡。
第 1 步:机器设置
- 创建服务端和客户端
- 关闭iptables和selinux服务
主机名称 | 操作系统 | IP地址 |
---|---|---|
NFS服务端 | RHEL 7 | 192.168.10.10 |
NFS客户端 | RHEL 7 | 192.168.10.20 |
# 清空NFS服务器上面iptables防火墙的默认策略,以免默认的防火墙策略禁止正常的NFS共享服务- [root@localhost ~]# iptables -F
- [root@localhost ~]# service iptables save
- iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
第 2 步:创建共享目录
- 在NFS服务器上,建立用于NFS文件共享的目录
- 在NFS服务器上,设置足够的权限确保其他人也有写入权限
- [root@localhost ~]# mkdir /nfsfile
- [root@localhost ~]# chmod -Rf 777 /nfsfile
- [root@localhost ~]# echo "welcome to localhost.com" > /nfsfile/readme
第 3 步:编辑配置文件/etc/exports
- 定义要共享的目录与相应的权限
- 请注意,NFS 客户端地址与权限之间没有空格
- # 把/nfsfile目录共享给192.168.10.0/24网段内的所有主机,让这些主机都拥有读写权限
- [root@localhost ~]# vim /etc/exports
- /nfsfile 192.168.10.*(rw,sync,root_squash)
第 4 步:启动和启用 NFS 服务程序
- 在启动NFS服务之前,还需要顺带重启并启用rpcbind服务程序,并将这两个服务一并加入开机启动项中
- [root@localhost ~]# systemctl restart rpcbind
- [root@localhost ~]# systemctl enable rpcbind
- [root@localhost ~]# systemctl start nfs-server
- [root@localhost ~]# systemctl enable nfs-server
- ln -s '/usr/lib/systemd/system/nfs-server.service' '/etc/systemd/system/nfs.target.wants/nfs-server.service'
第 5 步:NFS 客户端的配置
- 使用showmount命令查询NFS服务器的远程共享信息
- showmount命令输出格式为“共享的目录名称 允许使用客户端地址”
showmount命令
参数 | 作用 |
---|---|
-e | 显示NFS服务器的共享列表 |
-a | 显示本机挂载的文件资源的情况NFS资源的情况 |
-v | 显示版本号 |
exportfs命令
- 维护exports文件导出的文件系统表的专用工具,可以修改配置之后不重启NFS服务
- export -ar:重新导出所有的文件系统
- export -au:关闭导出的所有文件系统
- export -u FS: 关闭指定的导出的文件系统
- # 查看NFS服务器端共享的文件系统
- # showmount -e NFSSERVER_IP
- [root@localhost ~]# showmount -e 192.168.10.10
- Export list for 192.168.10.10:
- /nfsfile 192.168.10.*
- # NFS客户端创建一个挂载目录,挂载服务端NFS文件系统到本地
- # mount -t nfs SERVER:/path/to/sharedfs /path/to/mount_point
- [root@localhost ~]# mkdir /nfsfile
- [root@localhost ~]# mount -t nfs 192.168.10.10:/nfsfile /nfsfile
- # 挂载成功后就应该能够顺利地看到在执行前面的操作时写入的文件内容了
- [root@localhost ~]# cat /nfsfile/readme
- welcome to linuxprobe.com
- # 如果希望NFS文件共享服务能一直有效,则需要将其写入到fstab文件中
- # SERVER:/PATH/TO/EXPORTED_FS /mount_point nfs defaults,_netdev 0 0
- [root@localhost ~]# vim /etc/fstab
- /dev/mapper/rhel-root / xfs defaults 1 1
- UUID=812b1f7c-8b5b-43da-8c06-b9999e0fe48b /boot xfs defaults 1 2
- /dev/mapper/rhel-swap swap swap defaults 0 0
- /dev/cdrom /media/cdrom iso9660 defaults 0 0
- 192.168.10.10:/nfsfile /nfsfile nfs defaults 0 0