NFS网络文件系统
NFS简介
NFS就是Network File System的缩写,它最大的功能就是可以通过网络,让不同的机器、不同的操作系统可以共享彼此的文件(share files)。这个NFS服务器可以让PC将网络中的NFS服务器共享的目录挂载到本地端的文件系统中,而在本地端的系统中来看,那个远程主机的目录就好像是自己的一个磁盘分区一样,在使用上相当便利。
NFS一般用来存储共享视频,图片等静态数据
1. NFS特点
- NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源
- 在NFS的应用中,本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件,就像访问本地文件一样
- nfs适用于Linux与Unix之间实现文件共享,不能实现Linux与Windows间的文件共享功能
- nfs是运行在应用层的协议,其监听于2049/tcp和2049/udp套接字上
- nfs服务只能基于IP进行认证
2. NFS的应用场景
NFS有很多实际应用场景,以下是一些常用的场景:
- 多个机器共享一台CDROM或其他设备。这对于在多台机器中安装软件来说更加便宜与方便
- 在大型网络中,配置一台中心NFS服务器用来放置所有用户的home目录可能会带来便利。这些目录能被输出到网络以便用户不管在哪台工作站上登录,总能得到相同的home目录
- 不同客户端可在NFS上观看影视文件,节省本地空间
- 在客户端完成的工作数据,可以备份保存到NFS服务器上用户自己的路径下
3. NFS的体系组成
NFS体系至少有两个主要部分:
- 一台nfs服务器
- 若干台客户机
nfs体系的架构图如下:
客户机通过TCP/IP网络远程访问存放在NFS服务器上的数据
在NFS服务器正式启用前,需要根据实际环境和需求,配置一些NFS参数
NFS工作机制
nfs是基于rpc来实现网络文件系统共享的。所以我们先来说说rpc
1. RPC
RPC(Remote Procedure Call Protocol),远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。
RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。
RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。
rpc工作机制如上图所示,下面来描述一下它:
- 客户端程序发起一个RPC系统调用基于TCP协议发送给另一台主机(服务端)
- 服务端监听在某个套接字上,当收到客户端的系统调用请求以后,将收到的请求和其所传递的参数通过本地的系统调用执行一遍,并将结果返回给本地的服务进程
- 服务端的服务进程收到返回的执行结果后将其封装成响应报文,再通过rpc协议返回给客户端
- 客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行
2. NFS工作机制
//NFS服务器端运行着四个进程:
nfsd
mountd
idmapd
portmapper
idmapd //实现用户帐号的集中映射,把所有的帐号都映射为NFSNOBODY,但是在访问时却能以本地用户的身份去访问
mountd //用于验证客户端是否在允许访问此NFS文件系统的客户端列表中,在则允许访问(发放一个令牌,持令牌去找nfsd),否则拒绝访问
//mountd的服务端口是随机的,由rpc服务(portmapper)提供随机端口号
nfsd //nfs的守护进程,监听在2049/tcp和2049/udp端口上
//不负责文件存储(由NFS服务器本地内核负责调度存储),用于理解客户端发起的rpc请求,并将其转交给本地内核,而后存储在指定的文件系统上
portmapper //NFS服务器的rpc服务,其监听于111/TCP和111/UDP套接字上,用于管理远程过程调用(RPC)
下面通过一个例子来说明NFS的简单工作流程:
需求:查看file文件的信息,此file存储在远程NFS服务端主机上(挂载在本地目录/shared/nfs中)
- 客户端发起查看file信息的指令(ls file)给内核,内核通过NFS模块得知此文件并不是本地文件系统中的文件,而是在远程NFS主机上的一个文件
- 客户端主机的内核通过RPC协议把查看file信息的指令(系统调用)封装成rpc请求通过TCP的111端口发送给NFS服务端主机的portmapper
- NFS服务端主机的portmapper(RPC服务进程)告诉客户端说NFS服务端的mountd服务在某某端口上,你去找它验证
因为mountd在提供服务时必须要向portmapper注册一个端口号,所以portmapper是知道其工作于哪个端口的
- 客户端得知服务端的mountd进程端口号后,通过已知的服务端mountd端口号请求验证
- mountd收到验证请求后验证发起请求的客户端是否在允许访问此NFS文件系统的客户端列表中,在则允许访问(发放一个令牌,持令牌去找nfsd),否则拒绝访问
- 验证通过后客户端持mountd发放的令牌去找服务端的nfsd进程,请求查看某文件
- 服务端的nfsd进程发起本地系统调用,向内核请求查看客户端要查看的文件的信息
- 服务端的内核执行nfsd请求的系统调用,并将结果返回给nfsd服务
- nfsd进程收到内核返回的结果后将其封装成rpc请求报文并通过tcp/ip协议返回给客户端
3. exports文件的格式
nfs的主配置文件是/etc/exports,在此文件中,可以定义NFS系统的输出目录(即共享目录)、访问权限和允许访问的主机等参数。该文件默认为空,没有配置输出任何共享目录,这是基于安全性的考虑,如此即使系统启动了NFS服务也不会输出任何共享资源。
exports文件中每一行提供了一个共享目录的设置,其命令格式为:
<输出目录> [客户端1(选项1,选项2,...)] [客户端2(选项1,选项2,...)]
其中,除输出目录是必选参数外,其他参数均是可选项。另外,格式中的输出目录和客户端之间、客户端与客户端之间都使用空格分隔,但客户端与选项之间不能有空格。
客户端是指网络中可以访问这个NFS共享目录的计算机。客户端的指定非常灵活,可为单个主机的IP或域名,亦可为某个子网或域中的主机等。
客户端常用的指定方式:
客户端 | 说明 |
---|---|
192.168.110.10 | 指定IP地址的主机 |
192.168.110.0/24(或192.168.110.*) | 指定子网中的所有主机 |
www.leidazhuang.com | 指定域名的主机 |
*.leidazhuang.com | 指定leidazhuang.com域中的所有主机 |
*(或缺省) | 所有主机 |
选项用来设置共享目录的访问权限、用户映射等。exports文件中的选项比较多,一般可分为三类:
- 访问权限选项(用于控制共享目录的访问权限)
- 用户映射选项
- 默认情况下,当客户端访问NFS服务器时,若远程访问的用户是root用户,则NFS服务器会将其映射成一个本地的匿名用户(该用户为nfsnobody),并将其所属的用户组也映射成匿名用户组(该用户组也为nfsnobody),如此有助于提高系统的安全性。
- 其他选项
访问权限选项:
访问权限选项 | 说明 |
---|---|
ro | 设置输出目录只读 |
rw | 设置输出目录可读写 |
用户映射选项:
用户映射选项 | 说明 |
---|---|
all_squash | 将远程访问的所有普通用户及所属组都映射为匿名用户或用户组(nfsnobody) |
no_all_squash | 不将远程访问的所有普通用户及所属用户组都映射为匿名用户或用户组(默认设置) |
root_squash | 将root用户及所属用户组都映射为匿名用户或用户组(默认设置) |
no_root_squash | 不将root用户及所属用户组都映射为匿名用户或用户组 |
anonuid=xxx | 将远程访问的所有用户都映射为匿名用户,并指定该匿名用户为本地用户帐户(UID=xxx) |
anongid=xxx | 将远程访问的所有用户组都映射为匿名用户组,并指定该匿名用户组为本地用户组(GID=xxx) |
常用的其他选项:
其他选项 | 说明 |
---|---|
secure | 限制客户端只能从小于1024的TCP/IP端口连接NFS服务器(默认设置) |
insecure | 允许客户端从大于1024的TCP/IP端口连接NFS服务器 |
sync | 将数据同步写入内存缓冲区或磁盘中,效率较低,但可保证数据一致性 |
async | 将数据先保存在内存缓冲区中,必要时才写入磁盘 |
wdelay | 检查是否有相关的写操作,如果有则这些写操作一起执行,可提高效率(默认设置) |
no_wdelay | 若有写操作则立即执行,应与sync配置使用 |
subtree_check | 若输出目录是一个子目录,则NFS服务器将检查其父目录的权限(默认设置) |
no_subtree_check | 即使输出目录是一个子目录,NFS服务亦不检查其父目录的权限,可提高效率 |
nohide | 若将一个目录挂载到另一个目录之上,则原来的目录通常就被隐藏起来或看起来像空的一样。要禁用这种行为,需启用hide选项 |
4. NFS管理
nfs安装:
//安装
yum -y install nfs-utils
//启动
systemctl start rpcbind nfs-server
使用shoumount命令测试NFS服务器的输出目录状态:
//语法:showmount [选项] [NFS服务器名称或地址]
//常用的选项有:
-a //显示指定NFS服务器的所有客户端主机及其所连接的目录
-d //显示指定的NFS服务器中已被客户端连接的所有输出目录
-e //显示指定的NFS服务器上所有输出的共享目录
在客户端挂载NFS文件系统:
mount -t nfs SERVER:/path/to/sharedfs /path/to/mount_point
在客户端设置开机自动挂载nfs:编辑/etc/fstab文件,添加如下格式的内容
SERVER:/PATH/TO/EXPORTED_FS /mnt_point nfs defaults,_netdev 0 0
客户端挂载时可以使用的特殊选项:
- rsize:其值是从服务器读取的字节数(缓冲)。默认为1024。若使用比较高的值,如8192,可以提高传输速度
- wsize:其值是写入到服务器的字节数(缓冲)。默认为1024。若使用比较高的值,如8192,可以提高传输速度
exportfs //维护exports文件导出的文件系统表的专用工具
-a //输出在/etc/exports文件中所设置的所有目录
-r //重新读取/etc/exports文件中的设置,并使其立即生效,无需重启服务
-u //停止输出某一目录
-v //在输出目录时将目录显示到屏幕上
检查输出目录所使用的选项:
在配置文件/etc/exports中,即使在命令行中只设置了一两个选项,但在真正输出目录时,实际上还带有很多默认的选项。通过查看/var/lib/nfs/etab文件,可以看到具体使用了何选项
[root@localhost ~]# cat /var/lib/nfs/etab
....此处省略
NFS工作原理
在传输时使用的端口是随机的未被使用<1024的端口,他是通过RPC(远程过程调用)服务来实现的。
RPC的主要功能就是记录每个NFS功能所对应的端口号,并且将该信息传到NFS客户端,来实现连接。
启动NFS server之前,首先要启动RPC服务(即portmap服务),否则nfs server就无法向RPC服务注册。
注意:如果RPC服务重新启动,原来已注册好的NFS端口数据就会丢失,因此,此时RPC服务管理的NFS程序也需要重新启动以重新向RPC注册。
NFS权限设置
NFS配置权限设置,即/etc/exports文件配置格式中小括号()里的参数集。
参数命令 | 参数用途 |
---|---|
rw | Read-write表示可读写 |
ro | Read-only表示只能读权限 |
Sync | 同步模式,请求或写入数据时,数据同步写入到NFS Server的硬盘后才返回。优点:数据安全不会丢;缺点:性能比不启用该参数要差 |
no_root_squash | 访问NFS Server共享目录的用户是root的话,它对该共享目录具有root权限。这个配置原本是为无盘客户端准备的。用户应避免使用。 |
root_squash | 如果访问NFS Server共享目录的用户是root,则它的权限将被压缩成匿名用户,同时它的UID和GID通常会变成nfsnobody账号身份 |
all_squash | 不管访问NFS Server共享目录的用户身份如何,它的权限都将被压缩成匿名用户,同时它的UID和GID都会变成nfsnobody账号身份。在早期多个NFS客户端同时读写NFS Server数据时,这个参数很有用 |
anonuid | 参数以anon开头即指anonymous匿名用户,这个用户的UID设置值通常为nfsnobody的UID值,当然也可以自行设置这个UID值。但是,UID必须存在于/etc/passwd中。在多NFS Clients时,如多台Web Server共享一个NFS目录,通过这个参数可以使得不同的NFS Clients写入的数据对所有NFS Clients保持同样的用户权限,即为配置的匿名UID对应用户权限,这个参数很有用,一般默认即可 |
anongid | 同anongid,就是把uid换成gid而已 |
配置文件
NFS 配置文件是 /etc/exports,内容如下:
[root@localhost ~]# cat /etc/exports
/data 192.168.100.10/32(rw,sync,all_squash,anonuid=1000,anongid=1000)
/home 192.168.100.20/24(rw,sync,all_squash,anonuid=1000,anongid=1000)
# /data:指定要共享的目录
# 192.168.100.10/32:指定要共享给哪些客户端
# rw,sync,all_squash,.....:指定客户端的挂载选项
命令使用
客户端使用mount命令挂载
mount -t nfs NFS_SERVER:/PATH/TO/SOME_EXPORT /PATH/TO/SOMEWHRERE
exportfs
-
-a:跟-r或-u选项同时使用,表示重新挂载所有文件系统或取消导出所有文件系统;
-
-r: 重新导出
-
-u: 取消导出
-
-v: 显示详细信息
showmount
-
-e NFS_SERVER: 查看NFS服务器"导出"的各文件系统
-
-a NFS_SERVER: 查看NFS服务器所有被挂载的文件系统及其挂载的客户端对应关系列表
-
-d NFS_SERVER: 显示NFS服务器所有导出的文件系统中被客户端挂载了文件系统列表
rpcinfo
- -p :显示所有的 port 与 program 的信息
练习
环境说明
主机名称 | IP地址 | 系统版本 |
---|---|---|
客户端client | 192.168.153.10 | RHEl-8.2 |
服务端service | 192.168.153.11 | RHEL-8.2 |
准备工作
#在两台机器上进行操作,关闭selinx和防火墙
[root@client ~]# setenforce 0
[root@client ~]# systemctl stop firewalld
[root@service ~]# setenforce 0
[root@service ~]# systemctl stop firewalld
#在服务端操作
//安装nfs rpcbind
[root@service ~]# yum -y install nfs-utils rpcbind
//创建需要共享的abc文件
[root@service ~]# mkdir -p /leidazhuang/file
[root@service ~]# cd /leidazhuang/file/
[root@service file]# touch abc
//配置NFS服务端配置文件,此文件用于定义共享的目录及权限
[root@service ~]# vim /etc/exports
/leidazhuang/file 192.168.153.10 *(rw)
//启动服务
[root@service ~]# systemctl start nfs-server
[root@service ~]# systemctl start rpcbind
#在客户端操作
//安装showmount命令
[root@client ~]# yum -y install showmount
//显示NFS服务器列表
[root@client ~]# showmount -e 192.168.153.11
Export list for 192.168.153.11:
/leidazhuang/file (everyone)
//在本地创建一个挂载目录
[root@client ~]# mkdir /leidazhuang
手动挂载
//把192.168.153.11主机上的leidazhuang目录挂载在本机的leidazhuang目录上
[root@client ~]# mount 192.168.153.11:/leidazhuang /leidazhuang/
//查看目录,挂载完成,共享文件成功
[root@client ~]# cd /leidazhuang/
[root@client leidazhuang]# ls
file
[root@client leidazhuang]# cd file/
[root@client file]# ls
abc
//取消挂载,方便下面演示
[root@client ~]# umount /leidazhuang/
使用autofs自动挂载
#在客户端进行操作
//定义主配置文件
[root@client ~]# vim /etc/auto.master
#
# Sample auto.master file
# This is a 'master' automounter map and it has the following format:
# mount-point [map-type[,format]:]map [options]
# For details of the format look at auto.master(5).
#
/misc /etc/auto.misc
/media /etc/cdrom.misc
/leidazhuang /etc/ldaz.misc
//定义子配置文件
[root@client ~]# vim /etc/ldaz.misc
ldaz -rw 192.168.153.11:/leidazhuang
//重启autofs服务
[root@client ~]# systemctl restart autofs
//查看当前挂载情况
[root@client ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 883M 0 883M 0% /dev
tmpfs 901M 0 901M 0% /dev/shm
tmpfs 901M 17M 884M 2% /run
tmpfs 901M 0 901M 0% /sys/fs/cgroup
/dev/mapper/rhel-root 47G 1.9G 46G 4% /
/dev/sda1 1014M 179M 836M 18% /boot
tmpfs 181M 0 181M 0% /run/user/0
//进入目录触发挂载
[root@client ~]# cd /leidazhuang/ldaz
[root@client ldaz]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 883M 0 883M 0% /dev
tmpfs 901M 0 901M 0% /dev/shm
tmpfs 901M 17M 884M 2% /run
tmpfs 901M 0 901M 0% /sys/fs/cgroup
/dev/mapper/rhel-root 47G 1.9G 46G 4% /
/dev/sda1 1014M 179M 836M 18% /boot
tmpfs 181M 0 181M 0% /run/user/0
192.168.153.11:/leidazhuang 47G 1.7G 46G 4% /leidazhuang/ldaz
//查看abc文件,成功自动挂载
[root@client ldaz]# ls
file
[root@client ldaz]# cd file/
[root@client file]# ls
abc