整理:微信公众号【开源Linux】 文章作者: Escape 链接:http://33h.co/2jps9
一、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) 一些请求调整了参数和返回信息,毕竟
NFSv
3和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
转自文章《Linux 系统实战之 部署 NFS 服务器》