一、NFS服务
网络文件系统(Network File System,NFS),由SUN公司开发,目前被广泛应用于UNIX和Linux操作系统中。NFS在异构系统和设备之间提供文件和资源共享服务,类似于Windows的磁盘映射,将NFS服务器中的共享目录挂载到本地后,就像访问本地文件一样访问和操作远程文件,从而方便了多台计算机之间的文件共享和协作。
如下图所示,NFS服务器通过网络共享目录/mnt/public,NFS客户端将服务器共享目录挂载到本地目录/mnt/nfsdata上,对客户端来说,访问网络共享目录就如同访问本地目录一样。
借助NFS服务,协同工作的NFS客户端可以将数据存储在NFS服务器上,比如多个WEB服务器集群可以利用NFS服务器共享数据,既可以实现数据的共享,还可以保证数据一致。
二、NFS工作原理
2.1 NFS和RPC的关系
NFS服务器工作时需要通过远程过程调用(Remote Procedure Call 简称RPC)服务来实现,RPC服务本身使用的是TCP和UDP的111端口。
NFS协议功能复杂,涉及到文件传输、身份验证、权限验证等多个方面,每个功能都需要占用一个端口,然而NFS大都的功能都没有固定的端口,而是由NFS服务器随机选择的。当NFS启动后,会向RPC去注册登记这些端口,RPC服务记录每个NFS功能对应的端口,并开启自身的111端口,等待客户端的请求。
当客户端请求NFS服务时,请求会转发给服务器上RPC的111端口,RPC服务会将记录的NFS的端口返回给客户端,客户端获取到NFS服务器的端口信息后,就可以与NFS服务器建立连接传输数据了。
如下图所示,说明了NFS和RPC合作为客户端提供NFS服务的过程。
(1)服务器启动NFS服务后,向RPC服务注册工作端口,RPC负责登记,并在111端口侦听请求;
(2)NFS客户端请求NFS服务时,内核调用RCP Client,并向服务器请求NFS的端口信息;
(3)服务器查询NFS端口信息,并返回给客户端;
(4)客户端内核调用NFS模块;
(5)NFS客户端根据获取到的端口信息与服务器端NFS服务建立连接;
(6)NFS处理连接请求、权限认证,建立连接。
2.2 NFS服务的主要进程
1、rpc.nfsd
nfs的主要进程,用于响应客户端的连接请求,决定客户端是否具备登录主机的权限。
2、rpc.mountd
NFS服务端会维护一张可被NFS客户端访问的文件系统表。表中的每个文件都有单独的访问控制列表(acl),rpc.mountd使用这些acl来决定NFS客户端是否允许访问对应的文件。
3、rpcbind
rpcbind进程主要是进行端口映射工作,当客户端尝试连接并使用RPC管理的服务时,rpcbind会将该服务对应的端口提供给客户端,从而使客户端可以通过该端口向服务器请求服务。
rpcbind进程应该在所有RPC管理的服务启动之前启动,如果rpcbind重启了,所有RPC管理的服务都必须重启。
4、rpc.locked
本进行处理服务器上共享文件的锁定问题,以保持数据的一致性。
5、rpc.statd
文件锁并不是持久的,当主机重启时锁的状态会丢失。该守护进程用于监听其他主机的重启消息,并管理本地主机重启时需要通知的主机列表,配合rpc.locked进程,确定文件的一致性。
三、NFS服务器配置(以CentOS 7为例)
3.1 安装NFS服务
几乎所有的Linux发行版都默认安装了NFS,运行NFS服务,至少需要两个套件,一是rpcbind,二是nfs-utils。
安装之前,可以先检查是否安装了这两个套件。
[root@server ~]# rpm -qa | grep rpcbind[root@server ~]# rpm -qa | grep nfs-utils
如果没有安装,可以使用yum命令安装这两个套件。
[root@server ~]# yum install rpcbind nfs-utils -y
3.2 启动NFS服务
使用rpcinfo -p 命令检查nfs是否运行,如果没有看到nfs和mountd,表示nfs没有启动。
[root@server ~]# rpcinfo -p
使用systemctl命令管理nfs服务,并在启动nfs服务之前,确保rpcbind服务已启动。
[root@server ~]# systemctl start rpcbind #启动rpcbind服务[root@server ~]# systemctl start nfs #启动nfs服务[root@server ~]# systemctl enable rpcbind #设置开机自动启动rpcbind服务[root@server ~]# systemctl enable nfs #设置开机自动启动nfs服务
3.3 配置NFS服务
NFS服务的配置文件是/etc/exports,但是这个文件并没有随nfs服务安装而创建,需要管理员手工创建它。
1、exports文件的格式
/etc/exports文件的格式如下,例如 “/mnt/share 192.168.1.0/24(rw) *(ro,all_squash)”。
共享目录 [客户端1 (权限,用户映射,其他)] [客户端2 (权限,用户映射,其他)]
2、文件格式说明
(1)共享目录
NFS服务器需共享目录的实际路径,使用绝对路径。如“/mnt/share”。
(2)客户端
指可以访问NFS服务器共享目录的计算机。可以是IP地址、网段、域名等形式,还可以使用通配符。例如:
客户端 | 说明 |
---|---|
192.168.200.100 | 指定IP地址的主机 |
192.168.200.0/24 | 指定子网的所有主机 |
192.168.200.* | IP地址前缀为192.168.200的所有主机 |
www.example.com | 指定域名的主机 |
*.example.com | 指定域内的所有主机 |
* | 任意主机 |
(3)权限
访问权限参数用于控制共享目录的访问权限,有rw和ro两种,rw表示共享目录可读写,ro表示共享目录只读。
(4)用户映射
客户端访问NFS服务器上的共享目录时,不需要提供用户账号和密码。默认情况下,客户端若以root用户访问NFS服务器时,NFS服务器会将其映射成一个本地的匿名用户nfsnobody,并将其所属的组也映射成匿名用户组nfsnobody,从而提高系统的安全性。客户端若以普通用户访问NFS服务器,则映射成服务器上UID相同的用户和GID相同的组,若不存在,则映射成匿名用户和组。具体映射参数如下表所示:
参数值 | 内容说明 |
---|---|
all_squash | 将远程访问的所有普通用户及所属用户组都映射成匿名用户或匿名组。 |
no_all_squash | 不将远程访问的所有普通用户及所属用户组都映射成匿名用户或匿名组。(默认配置) |
root_squash | 将root用户及所属组都映射为匿名用户或匿名组。(默认配置) |
no_root_squash | 不将root用户及所属组都映射为匿名用户或匿名组。 |
anonuid=XXX | 将远程访问的所有用户都映射为指定用户,该用户的UID=XXX |
anongid=XXX | 将远程访问的所有用户组都映射为指定组,该组的GID=XXX |
(5)其他
其他参数可以用于对共享目录更全面的控制。
参数值 | 内容说明 |
---|---|
secure | 限制客户端只能从小于1024的端口连接NFS服务器 |
insecure | 允许客户端从大于1024的端口连接NFS服务器 |
sync | 将数据同步写入内存缓冲区与磁盘中 |
async | 将数据先保存在内存缓冲区中,必要时才写入磁盘 |
wdelay | 检查是否有相关的写操作,如果有则将这些写操作一起执行,提高效率 |
no_wdelay | 若有写操作则立即执行,应与sync配合 |
subtree_check | 若输出目录时一个子目录,则NFS服务器将检查其父目录的权限 |
no_subtree_check | 即使输出目录时一个子目录,则NFS服务器也不检查其父目录的权限 |
四、NFS客户端访问NFS共享
4.1 showmount命令查看共享
NFS客户端安装nfs-utils软件包后,可以使用showmount命令查看NFS服务器上的共享目录。
showmount的使用语法如下:
showmount [-adehv] [NFS服务器名或IP地址]
选项 | 说明 |
---|---|
a | 显示客户端主机名和挂载目录 |
d | 仅显示已被NFS客户端加载的目录 |
e | 显示NFS服务器上所有的共享目录 |
v | 显示版本信息 |
h | 显示帮助信息 |
4.2 mount命令挂载共享
可以使用mount命令将NFS共享挂载到本地目录,格式如下:
mount -t nfs NFS服务器IP:共享资源目录 挂载目录
例如:下面命令可以将服务器192.168.200.100上的共享目录/mnt/share挂载到本地目录/mnt/nfs
mount -t nfs 192.168.200.100:/mnt/share /mnt/nfs
4.3 修改/etc/fstab实现开机自动挂载
若需系统启动自动挂载到NFS服务器上的共享目录,可以修改/etc/fstab,在文件最后一行添加如下格式代码:
NFS服务器IP:共享资源目录 挂载目录 nfs defaults 0 0
五、企业NFS服务器配置案例
5.1 案例描述
某公司因门户网站并发量增加,采用Web集群技术提供Web访问,为保证Web数据共享且保持一致,将网站数据使用NFS服务器存储,经研讨,决定按如下需求搭建NFS服务器。
1、共享/public目录,允许所有客户端访问该目录并只有读取权限。
2、共享/website/code目录,允许192.168.100.0/24和192.168.200.0/24网段的客户端访问,并且对此目录只有读取权限。
3、共享/website/images目录和/website/videos目录,所有人都具有读写权限,但是当用户使用该共享目录时,都将账号映射成用户webuser(UID=9999)和组webgroup(GID=9999)。
4、共享/website/security目录,仅允许192.168.200.138客户端访问并具有读写权限。
5.2 实验环境
主机名称 | 操作系统 | IP地址 | 备注 |
---|---|---|---|
Server | CentOS 7.5 | 192.168.200.100 | 防火墙关闭、Selinux关闭、YUM源配置完成 |
Client | CentOS 7.5 | 192.168.200.138 | 防火墙关闭、Selinux关闭、YUM源配置完成 |
5.3 配置NFS服务器
1、安装NFS服务
[root@server ~]# yum install rpcbind -y #安装rpcbind,一般默认已安装[root@server ~]# yum install nfs-utils -y #安装nfs-utisl,一般默认已安装
2、启动NFS服务,并设置开机自启动
[root@server ~]# systemctl start rpcbind #启动rpcbind,要先于nfs前启动[root@server ~]# systemctl start nfs #启动nfs服务[root@server ~]# systemctl enable rpcbind [root@server ~]# systemctl enable nfs
3、查看NFS端口注册信息
[root@server ~]# rpcinfo -p #查看NFS服务端口注册信息 program vers proto port service 100000 4 tcp 111 portmapper #rpc端口映射portmap使用111端口 100000 3 tcp 111 portmapper 100000 2 tcp 111 portmapper 100000 4 udp 111 portmapper 100000 3 udp 111 portmapper 100000 2 udp 111 portmapper 100005 1 udp 20048 mountd #rpc.mountd使用了端口20048 100005 1 tcp 20048 mountd 100005 2 udp 20048 mountd 100005 2 tcp 20048 mountd 100005 3 udp 20048 mountd 100005 3 tcp 20048 mountd 100003 3 tcp 2049 nfs #rpc.nfsd使用了端口2049 100003 4 tcp 2049 nfs 100227 3 tcp 2049 nfs_acl 100003 3 udp 2049 nfs 100003 4 udp 2049 nfs 100227 3 udp 2049 nfs_acl 100021 1 udp 50120 nlockmgr 100021 3 udp 50120 nlockmgr 100021 4 udp 50120 nlockmgr 100021 1 tcp 39126 nlockmgr 100021 3 tcp 39126 nlockmgr 100021 4 tcp 39126 nlockmgr
4、添加用户、创建共享目录并设置权限
[root@server ~]# groupadd -g 9999 webgroup[root@server ~]# useradd -g webgroup -u 9999 webuser
[root@server ~]# mkdir /public[root@server ~]# mkdir -p /website/code[root@server ~]# mkdir -p /website/images[root@server ~]# mkdir -p /website/videos[root@server ~]# mkdir -p /website/security
[root@server ~]# chmod -R 777 /website/images[root@server ~]# chmod -R 777 /website/videos[root@server ~]# chown -R webuser:webgroup /website/security[root@server ~]# chmod -R 700 /website/security
5、编辑配置文件
[root@server ~]# touch /etc/exports[root@server ~]# vim /etc/exports
##/etc/exports文件内容如下:/public *(ro)/website/code 192.168.100.0/24(ro) 192.168.200.0/24(ro)/website/images *(rw,all_squash,anonuid=9999,anongid=9999)/website/videos *(rw,all_squash,anonuid=9999,anongid=9999)/website/security 192.168.200.138(rw)
6、重新启动rpcbind和NFS服务
[root@server ~]# systemctl restart rpcbind[root@server ~]# systemctl restart nfs
5.4 配置NFS客户端
1、安装NFS服务
[root@client ~]# yum install nfs-utils -y
2、查询服务器共享目录
[root@client ~]# showmount -e 192.168.200.100Export list for 192.168.200.100:/website/videos */website/images */public */website/code 192.168.200.0/24,192.168.100.0/24/website/security 192.168.200.138
3、挂载目录
[root@client ~]# mkdir -p /nfs/{public,code,images,videos,security}
[root@client ~]# mount -t nfs 192.168.200.100:/public /nfs/public/[root@client ~]# mount -t nfs 192.168.200.100:/website/code /nfs/code[root@client ~]# mount -t nfs 192.168.200.100:/website/images /nfs/images/[root@client ~]# mount -t nfs 192.168.200.100:/website/videos /nfs/videos/[root@client ~]# mount -t nfs 192.168.200.100:/website/security /nfs/security/
[root@client ~]# df -Th文件系统 类型 容量 已用 可用 已用% 挂载点/dev/mapper/centos-root xfs 17G 5.8G 12G 34% /devtmpfs devtmpfs 2.0G 0 2.0G 0% /devtmpfs tmpfs 2.0G 0 2.0G 0% /dev/shmtmpfs tmpfs 2.0G 21M 2.0G 2% /runtmpfs tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup/dev/sda1 xfs 1014M 157M 858M 16% /boottmpfs tmpfs 394M 4.0K 394M 1% /run/user/42tmpfs tmpfs 394M 60K 394M 1% /run/user/0192.168.200.100:/public nfs4 17G 1.2G 16G 7% /nfs/public192.168.200.100:/website/code nfs4 17G 1.2G 16G 7% /nfs/code192.168.200.100:/website/images nfs4 17G 1.2G 16G 7% /nfs/images192.168.200.100:/website/videos nfs4 17G 1.2G 16G 7% /nfs/videos192.168.200.100:/website/security nfs4 17G 1.2G 16G 7% /nfs/security
4、测试权限
[root@client ~]# cd /nfs/public/ #public目录可以访问,不可写[root@client public]# touch atouch: 无法创建"a": 只读文件系统
[root@client code]# touch a #code目录可以访问,不可写,换个别网段(非192.168.100.0/24和192.168.200.0/24)将不可读touch: 无法创建"a": 只读文件系统
[root@client ~]# cd /nfs/images/ #image目录可读写,且用户映射成9999[root@client images]# touch pl.jpg[root@client images]# ll总用量 0-rw-r--r--. 1 9999 9999 0 3月 24 18:48 pl.jpg
[root@client ~]# cd /nfs/security/ #无法访问security目录,因为root用户被映射成nfsbody,-bash: cd: /nfs/security/: 权限不够
在客户端添加一个UID=9999的用户,可以对security目录读写。
[root@client ~]# groupadd -g 9999 webgroup[root@client ~]# useradd -g webgroup -u 9999 webuser[root@client ~]# passwd webuser更改用户 webuser 的密码 。新的 密码:无效的密码: 密码少于 8 个字符重新输入新的 密码:passwd:所有的身份验证令牌已经成功更新。[root@client ~]# su - webuser[webuser@client ~]$ cd /nfs/security/[webuser@client security]$ touch web.sec[webuser@client security]$ ll总用量 0-rw-r--r--. 1 webuser webgroup 0 3月 24 18:56 web.sec