NFS

《鸟哥Linux私房菜》
《老男孩Linux运维》



NFS介绍

NFS维基百科:网络文件系统(英语:Network File System,缩写为NFS)是一种分布式文件系统协议,最初由Sun Microsystems公司开发,并于1984年发布。
其功能旨在允许客户端主机可以像访问本地存储一样通过网络访问服务器端文件。从客户端看,NFS服务器端共享的目录就好像是客户端自己的磁盘分区或目录一样,而实际确是远端的NFS服务器的目录。
NFS和其他许多协议一样,是基于开放网络运算远程过程调用(ONC RPC)协议之上的。它是一个开放、标准的RFC协议,任何人或组织都可以依据标准实现它。

NFS的目的就是想让不同的机器、不同的操作系统可以彼此共享数据文件方案。基本上,Unix-like主机连接到Unix-like主机来共享彼此的文件时,使用NFS要比Samba服务器快速且方便得多。

在Linux集群方面,NFS服务器也经常使用。

NFS是第一个构建于IP协议之上的现代网络文件系统,NFS协议归属于RFC标准。

它代表了一个非常稳定的,可移植的网络文件系统,具备可扩展、高性能等特性,并达到了企业级应用质量标准。由于网络速度的增加和延迟的降低,NFS系统一直是通过网络提供文件系统服务的有竞争力的选择 ,特别是在中小型互联网企业中。

NFS网络文件系统与Samba服务类似。只不过一般情况下,Windows网络共享服务或Samba服务用语办公局域网共享;而互联网中小型网站集群架构后端常用NFS进行数据共享;如果是大型网站,那么有可能还会用到更复杂的分布式文件系统,如Moosefs,FastDFS等。


NFS在企业中的应用场景

在企业集群架构的工作场景中,NFS网络文件系统一般被用来存储图片、视频等静态资源,通常网站用户上传的文件都会放到NFS共享里。NFS是当前互联网系统架构中最常用的数据存储服务之一。

NFS_第1张图片
NFS服务在企业生产集群架构中的位置
NFS_第2张图片
示意图




NFS系统原理介绍

NFS系统挂载结构图解与介绍

NFS_第3张图片
NFS服务器共享与客户端挂载结构图
mount source destnation
mount ip:/path /nfstest

NFS会使用一些端口来传输数据。而NFS在传输数据时使用的端口会随机选择。通过 RPC(Remote Procedure Call)远程过程调用 协议/服务使得NFS客户端知道了NFS服务器使用的是那些端口。

什么是RPC

因为NFS支持的功能相当多,而不同的功能都会使用不同的程序来启动,没启动一个功能就会启用一些端口来传输数据。因此,NFS的功能所对应的端口无法固定,它会随机取用一些未使用的端口。
因为端口不固定,这样就造成NFS客户端与NFS服务端的通信障碍。因为客户端必须要知道NFS服务器端的数据传输端口才能进行通信,才能交互数据。

要解决上面的为题,就需要通过远程调用 RPC 服务来实现。
NFS的RPC服务最主要的功能就是记录每个NFS 功能所对应的端口号,并且在NFS客户端请求时将端口和功能对应的信息传递给请求数据的NFS客户端,从而确保客户端可以连接到正确的NFS端口上去,达到实现数据传输交互数据目的。
RPC服务使用固定的111端口来监听NFS客户端提交的请求,并且将正确的NFS端口信息回复给请求的NFS客户端。

在启动NFS-Server之前,首先要启动RPC服务(centos7下为rpcbind),否则NFS-Server就无法向RPC服务注册。另外,如果RPC服务重新启动,原来已经注册好的NFS端口数据就会丢失,因此,此时RPC服务管理的NFS程序也需要重新启动以重新向RPC注册。
还有,修改NFS配置文件后,是不需要重启NFS的,直接reload就可以了。


NFS的文件访问权限

因为NFS本身的服务并没有进行用户身份验证,所以当客户端想要访问服务器端的文件系统时,服务器端会以客户端的用户 UID和GID 等身份来尝试读取服务器端的文件系统。

文件系统的 inode 所记录的属性为 UID、GID,而非账号与属性名。一般Linux主机会主动以自己的 /etc/passwd,/etc/group来查询对应的用户名和组名。

总之,客户端用户能做的事情与UID和GID有关,而当客户端与服务端的uid及账号对不上时,可能会造成文件系统使用上的混乱,这是NFS文件系统在使用上的一个重要弊端。而NFS默认是使用 匿名用户(anonymity)。


NFS的工作流程原理

NFS_第4张图片
NFS工作原理流程简略图

因为NFS的各项功能都需要向RPC服务注册,所以只有RPC服务才能获取到NFS服务的各项功能对应的端口号、PID、监听地址等信息,而NFS客户端也只能通过向RPC服务询问才能找到正确的端口。
也就是说,NFS需要有RPC服务的协助才能成功对外提供服务。




NFS服务器端

任何情况下都需要注意当前系统环境!

NFS软件列表

nfs-utils:NFS服务的主程序;
rpcbind:RPC程序;

CentOS7里面默认是已经安装好此软件的。

yum install -y nfs-utils rpcbind
rpm -ra nfs-utils rpcbind

NFS软件结构

  • 主要配置文件:/etc/exports;
  • NFS文件系统维护命令:/usr/bin/exportfs;
  • 共享资源的日志文件: /var/lib/nfs/*tab;
  • 客户端查询共享资源命令: /usr/sbin/showmount;

启动NFS相关服务

因为NFS及其辅助程序都是基于RPC协议的,所以首先要确保系统中运行了rpcbind服务。
111端口为rpcbind服务对外提供服务的主端口。

service rpcbind start
service nfs start

rpcinfo -p localhost
#查看NFS服务向RPC服务注册的端口信息

NFS服务常见进程

NFS服务主要任务是共享文件系统数据,而文件系统数据的共享离不开权限问题。所以NFS服务器启动时最少需要两个不同的进程:

一个是管理NFS客户端是否能够登录的 rpc.nfsd 主进程;
另一个是用于管理NFS客户端是否能够取得对应权限的 rpc.mountd 进程;
如果还需磁盘配额,则NFS还要再加载 rpc.rquotad 进程。

nfsd               #NFS daemon,管理登录,ID身份判别等
rpc.mounted        #权限管理认证等
rpc.idmapd         #名字映射后台进程
rpc.locked         #用来锁定文件,用于多客户端同时写入
rpc.statd          #检查文件一致性,与.locked有关

#man 进程名 ,查看有关进程说明 

开机启动

将 NFS 和 rpcbind 服务加入开机启动的命令:

chkconfig rpcbind on
chkconfig nfs on
#注意顺序

要说明的是,在一些企业里,都是统一按照运维规范将服务的启动命令放到 /etc/rc.local 文件里,而不是用 chkconfig
/etc/rc.local 文件作为本机的重要服务档案文件,所有服务的开机自启动都必须放入 /etc/rc.local 。这样规范的好处是,一旦管理服务器的人员离职,或者业务迁移,都可以通过 /etc/rc.local 很容易地查看到服务器对应的相关服务,方便运维管理。

vi /etc/rc.local

service rpcbind start
service nfs start


配置NFS服务器端

NFS服务的默认配置文件为: /etc/exports,默认是存在的,并且没有内容,需要用户自行配置。

exports配置文件格式

exports配置文件格式为:

/share 192.168.1.11(rw,sync) 192.168.2.0/24(rw) localhost(ro) *.zhang21.com(rw,sync)
#NFS共享目录 NFS客户端地址(参数1,参数2,··) 客户端地址2(参数)
#使用的主机名得存在与 /etc/hosts 中

#共享目录用绝对路径,注意目录权限
#NFS客户端地址,可为单独IP、主机名、域名或网段
#权限参数集

NFS配置参数权限

可以通过 man exports 查看更多参数说明。

参数 参数用途
rw 可读写权限
ro 只读权限
sync 请求或写入数据时,数据同步写入NFS Server的硬盘后才返回
async 写入数据会先写到内存缓冲区,直到硬盘有空档才会再写入磁盘,这样可以提升效率!
anonuid anon*开头指匿名用户,这个用户的UID设置值通常为 nfsnobody 的UID值,当然也可以自行设置这个 UID值。但是,UID必须存在与/etc/passwd中。
anongid GID
no_root_squash 如果访问NFS Server的用户是root的话,它对该目录具有root权限。 应避免使用。
root_squash 如果访问NFS Server的用户是root,则它的权限将被压缩成匿名用户,同时UID和GID会变成nfsnobody账号身份
all_squash 不管访问NFS Server共享目录的用户身份如何,它的权限将被压缩成匿名用户,同时它的UID和GID都会变成nfsnobody账号身份。这个参数很有用

创建共享的目录并授权

mkdir  /nfs
chown -R nfsnobody:nfsnobody /nfs
chmod xxx

挂载NFS

修改了 /etc/exports 后记得重新加载NFS配置

exportfs -rv    #r重新共享所有目录,v显示详细信息
或 service nfs reload

客户端挂载

mount -t nfs Server_Ip:/nfs /mnt

showmount -e ip
或mount
或df
NFS_第5张图片
df -h

设置客户端自动挂载

1. 将挂载命令放在/etc/rc.local 里
缺点:偶尔开机挂在不上,除了开机自启动配置,还要对是否挂载做监控;

echo "/bin/mount -t nfs Server_Ip:/nfs /mnt" >> /etc/rc.local

2. 将挂载命令放在 /etc/fstab 里
注意一下开机流程,网络启动是在本机挂在志候,因此当利用 /etc/fstab 挂载NFS时,系统由于网络尚未启动,所以肯定无法挂载成功。


NFS客户端挂载深入

在NFS_Server端可通过 cat /var/lib/nfs/etab 查看NFS服务器端配置参数的细节;

NFS_第6张图片
NFS_Server

在NFS_Client端可通过 mount | grep /mnt 查看挂载参数细节。

NFS_第7张图片
NFS_Client

NFS客户端挂载参数

可通过 man nfs查看下列参数

参数 参数功能 默认
fg
bg
当客户端在挂载时,可选择是 前台(fg) 还是 后台(bg) fg
soft
hard
当NFS_Client以 soft 挂载 Server时,若网络或Server出现问题,造成Client和Server无法传输数据,Client会一直尝试,直到 timeout。可能会在 timeout 出现时造成资料丢失,故一般不建议使用
若用 hard 模式挂载硬盘时,Client会一直尝试连接到Server,Server有响应就继续刚才的操作,无响应就一直尝试,此时无法 umount ,kill ,所以常常会配合 intr使用
hard
intr 这个参数在timeout后中断 hard,避免出问题时整个系统被NFS锁死,建议使用
rsize
wsize
读出(rsize) 和 写入(wsize)区块大小(block size)
proto= 指定使用 UDP 还是 TCP proto=tcp

栗子:

mount -f nfs 192.168.1.7:/nfs /mnt

mount -t nfs -o fg,hard,intr,rsize=102400,wsize=102400 192.168.1.7:/nfs /mnt


mount -o参数对应选项

一般情况下,安全的参数与性能的参数是对立的!

参数 参数含义 默认值
defaults 这里是 fstab 里的默认值,包括 rw, suid, dev, exec, auto, nouser, async
suid
nosuid
当挂载的文件系统上有任何 SUID 的程序时,使用 nosuid 就能够取消SUID的功能 suid
rw
ro
可读写(rw) 或 只读(ro) rw
sync
async
文件系统I/O是 同步处理 还是 异步处理。异步提高性能但降低数据安全,而同步保障数据安全但会牺牲I/O性能 sync
dev
nodev
是否保留装置文件的权限 dev
exec
noexec
是否具有执行文件的权限 exec
user
nouser
是否允许用户拥有文件的挂载与写在功能 nouser
auto
noauto
mount -a 时会不会被挂载的项目,如果不需要这个 partition 随时被挂载,可以设置为 noauto auto
atime
noatime
是否更新时间戳 atime
dirsync 目录更新时同步写入磁盘


自动挂载 autofs 的使用

我们知道,NFS服务器与客户端的连接或许不会永远存在,而RPC这个服务也要在。如果挂载了NFS服务器后,任何一方脱机(如,网络中断)都可能造成另一方总是在等待超时;
而且,挂载的NFS文件系统可能又不是常常被使用,但若不挂载的话,要使用的时候还是得挂载!

autofs服务 就是让客户端在有使用NFS文件系统的需求时才让系统自动挂载,当NFS文件系统使用完毕后让NFS自动卸载,以避免可能的RPC错误。

autofs 的主要配置文件为: /etc/autofs.master,这个文件只要有持续检测的目录及数据对应文件即可,数据对应文件的文件名是可以自定义的,下面定义为 auto.nfs;
autofs的主要服务为: autofs;
数据对应文件:/etc/auto.nfs,这个文件其实不存在,是我们自行设置的;

配置 autofs.master

vim /etc/autofs.master

/nfs /etc/auto.nfs    # /nfs目录不需要事先存在,因为auto.nfs会自动建立该目录

配置 auto.nfs

image -rw,bg,soft 192.168.1.7:/nfs/image
video -ro,bg,hard,intr,rsize=xxxx,wsize=xxxx 192.168.1.7:/nfs/video
tmp -rw 192.168.1.7:/tmp

# 本地子目录  挂载参数 服务器提供的目录
#本地目录,/etc/auto.master 内指定的目录的子目录,不需要事先创建

启动 autofs 服务
service autofs start


NFS客户端挂载优化

在企业生产环境中,NFS客户端挂载有没有必要加某些参数呢? 这就属于 mount 挂载优化内容,一般来说要适当挂载参数,但是,最好事先做好测试。用数据来说话,才能更好地确定到底是挂载还是不挂载。

rsize 和 wsize 的大小最好是 1024的倍数;
非性能的参数越多,性能就越慢;

NFS内核优化

优化选项说明:

/proc/sys/net/core/rmem_default,接收套接字缓冲区大小默认值(byte);
/proc/sys/net/core/rmem_max, 接收套接字缓冲区大小的最大值;
/proc/sys/net/core/wmem_default, 发送套接字缓冲区大小的默认值;
/proc/sys/net/core/wmem_max, 发送套接字缓冲区大小的最大值;

内核优化:

cat >> /etc/sysctl.conf <
  • 如果卸载的时候提示 “umount: /mnt :device is busy”,需要退出挂载目录再卸载;
  • 如果是NFS_Server宕机了,则需要强制卸载,执行 umount -fl /mnt
  • 大型网站NFS网络文件系统的替代软件为分布式文件系统 Moosefs,FastDFS,GlusterFS;




NFS安全性

防火墙的设置与解决

一般来说,NFS的服务仅会对内网开放,不会对外网开放。
因为NFS的端口不固定,所以防火墙很难搞。但CentOS提供了一个固定特定NFS服务的端口配置文件 --- /etc/sysconfig/nfs ,这里面能够指定特定的端口。这样每次启动NFS时,相关服务启动的端口就是固定的,对于设置防火墙来说就容易些了。

使用/etc/exports 设置更安全的权限

root_squash
all_squash
anonuid 等参数

更安全的 partition 规划

规划单独的一个分区给NFS共享使用;
由于共享的 partition 可能较容易被入侵,最好在 /etc/fstab 文件中对该分区设置比较严格的权限参数;

更安全的 mount 挂载选项

mount -o xxx




NFS应用优缺点说明

NFS服务可以让不同的客户端使用同一个共享目录,也就是将其作为共享存储使用,这样可以保证不同节点客户端数据的一致性,在集群架构环境中常用;
如果是Windows和Linux混合环境的集群,可以用Samba来实现;

优点:

  • 简单,容易上手和掌握;
  • NFS文件系统内数据是在文件系统之上的,即数据是能看得见的;
  • 部署快速,可控,满足需求;
  • 数据可靠性高,经久耐用;
  • 服务稳定;

缺点:

  • 存在单点故障,如果NFS_Server宕机了,所有客户端都无法访问共享目录; 这在后期会通过 负载均衡及高可用 方案弥补;
  • 在大数据高并发的场合,NFS效率、性能有限;
  • 客户端认证是基于 IP和主机名,权限根据ID识别,安全性一般(用于内网则问题不大);
  • NFS数据是明文,NFS本身不对数据完整行进行验证;
  • 多台Client挂载一个Server时,连接管理维护麻烦。尤其在Server出问题后,所有Client都处于挂掉状态;
  • 涉及了同步(实时等待)和异步(解耦)的概念,NFS服务器和客户端相对来说就是耦合度有些高;

建议:
对于大中小型网站(20 millon/day PV)线上应用,门户网站应用,生产场景应该多将数据的访问量往前推。即尽量将静态文件通过CDN或缓存服务器提供服务,如果没有缓存服务或架构不好,存储服务器数量再多也是扛不住压力的,而且用户体验很差。

你可能感兴趣的:(NFS)