NFS(Network File System),网络文件系统,是一种比较常见的文件共享的方式,可以通过网络,让不通的机器,不通的操作系统之间实现文件共享。
NFS的基本原则是“容许不同的客户端及服务端通过一组RPC分享相同的文件系统”,它是独立于操作系统,允许不同硬件及操作系统的进行文件的共享。
NFS在文件传送或信息传送过程中依赖于RPC协议。RPC是什么呢,RPC是Remote Procedure Call的缩写,即远程过程调用,是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议,由于不是今天主要内容,用一张图看一下RPC原理
NFS本身是没有提供信息传输的协议和功能的,它就是用到RCP的传输协议,可以说NFS也是一个RPC SERVER。所以用到NFS的地方,无论是服务端还是客户端,都需要启动RPC服务。
NFS安装配置
NFS安装需要两个包,nfs-utils和rpcbind
# yum -y install nfs-utils
服务端和客户端,都需要安装这两个包,安装完成后,系统会自动创建nfsnobody用户和组,uid和gid都是65543
NFS除了主程序端口2049和rpcbind的端口111是固定端口以外,其他的还会有一些随机端口,这些端口是NFS向rpcbind注册产生的,先启动rpcbind,然后查看端口
接着启动NFS,之后再查看端口
由于端口都说是随机的,不方便防火墙管理,所以在nfs的配置文件中,可以绑定这些端口
# vim /etc/sysconfig/nfs
#追加端口配置
MOUNTD_PORT=40001
STATD_PORT=40002
LOCKD_TCPPORT=40003
LOCKD_UDPPORT=40003
RUEOTAD_PORT=40004
端口随便自己绑定,建议用后面一点的端口,前面的端口系统有定义服务,避免端口冲突,并将这些端口加入防火墙
启动服务和设置开机自启动
CentOS6:
# /etc/init.d/rpcbind start
# /etc/init.d/nfs start
# chkconfig rpcbind on
# chkconfig nfs on
CentOS7:
# systemctl start rpcbind.service
# systemctl enable rpcbind.service
# systemctl start nfs.service
# systemctl enable nfs.service
客户端也需要安装以上服务,但是只需要启动rpcbind服务
配置完成后,就可以开始在服务端创建共享目录,NFS的共享目录配置在/etc/exports文件中
配置完成后,不需要重启NFS服务,可以通过exportfs管理
export相关选项如下:
-a 全部挂载或卸载 /etc/exports中的内容
-r 重新读取/etc/exports 中的信息 ,并同步更新/etc/exports、/var/lib/nfs/xtab
-u 卸载单一目录(和-a一起使用为卸载所有/etc/exports文件中的目录)
-v 输出详细的共享参数
重新加载配置后,可以通过showmount命令查看nfs共享目录信息,相关选项如下:
-a 显示已经于客户端连接上的目录信息
-e IP或者hostname 显示此IP地址分享出来的目录
在客户端查看
客户端挂载
在服务端查看nfs状态
在服务端创建个文件,并查看文件权限
在客户端查看文件
貌似没有问题了,然后在客户端尝试修改文件权限
无法修改,在服务器端修改文件权限,并查看权限
同样,在客户端查看文件权限
发现权限有问题,502是什么呢,502是服务端test用户的id(uid和gid),下面针对nfs权限详细说一下
NFS文件权限
在服务端,查看nfs挂载所有配置参数
nfs配置参数详细说明如下:
ro:共享目录只读
rw:共享目录可读可写
all_squash:所有访问用户都映射为匿名用户或用户组
no_all_squash(默认):访问用户先与本机用户匹配,匹配失败后再映射为匿名用户或用户组
root_squash(默认):将来访的root用户映射为匿名用户或用户组
no_root_squash:来访的root用户保持root帐号权限
anonuid=:指定匿名访问用户的本地用户UID,默认为nfsnobody(65534)
anongid=:指定匿名访问用户的本地用户组GID,默认为nfsnobody(65534)
secure(默认):限制客户端只能从小于1024的tcp/ip端口连接服务器
insecure:允许客户端从大于1024的tcp/ip端口连接服务器
sync:将数据同步写入内存缓冲区与磁盘中,效率低,但可以保证数据的一致性
async:将数据先保存在内存缓冲区中,必要时才写入磁盘
wdelay(默认):检查是否有相关的写操作,如果有则将这些写操作一起执行,这样可以提高效率
no_wdelay:若有写操作则立即执行,应与sync配合使用
subtree_check(默认) :若输出目录是一个子目录,则nfs服务器将检查其父目录的权限
no_subtree_check :即使输出目录是一个子目录,nfs服务器也不检查其父目录的权限,这样可以提高效率
这里重点解释一下all_squash和no_all_squash这两个参数以及root_squash和no_root_squash的不同之处
这两组权限选项分别是对应普通用户和root用户的权限管理
普通用户
- 当设置all_squash时,客户端文件权限一律被映射为匿名用户(nfsnobody)
- 当设置no_all_squash时,客户端文件权限映射为服务端文件用户id相同的用户,因此,需要在客户端对应建立与服务端文件权限相同用户的一致id的用户,否则,映射过来之后,就会是nfsnobody或者是直接id显示权限
(这里说明一下,服务端是CentOS6的系统时,不会自动创建nfsnobody用户,所以映射到客户端的权限,一般都是服务端用户id,当服务端是CentOS7的系统时,一般都是nfsnobody用户)
root用户
- 当设置root_squash时,客户端以root用户访问服务端时,被映射为nfsnobody用户
- 当设置no_root_squash时,客户端以root用户访问服务端时,被映射为root用户
很多时候客户端挂载nfs的时候,用户是已经创建好的,大部分的情况是客户端与服务端相同用户的id不同,包括uid和gid,所以很多时候需要修改客户端用户的id
修改用户uid和gid的命令,分别是usermod和groupmod,所以,通过id命令查看服务端文件用户id,之后在客户端通过查看/etc/passwd和/etc/group确保该uid及gid未被占用之后,通过命令修改
服务端:
客户端:
客户端修改用户id时,需要将与该用户相关的进程全部停掉,才能修改,停掉某用户所有进程方法有以下几种:
- pkill -u test
- killall -u test
- ps -ef |grep test|awk '{print $2}'|xargs kill -9 (容易误杀)
- pgrep -u test|xargs kill -9
停掉所有该用户进程后,开始修改用户id
原先的test权限的文件,此时的权限会变成原来的uid和gid显示在权限的地方,所以还需要通过权限修改命令,将权限修改为现在用户的权限,用户和组的权限修改分别是
find / -user 1007 -exec chown -h test {} \;
find / -group 1007 -exec chgrp -h test {} \;
修改权限完成后,重新启动该用户的所有进程,可以查看nfs挂载目录的权限
由原来的502变为test,权限正常
NFS优化建议
NFS的优化,这里主要是从两个方面,一个是系统内核参数,一个是mount挂载
首先是内核参数的修改,主要是输入队列的内存限制,在nfs官网,建议将读写缓存[rw]mem_default和[rw]mem_max增加到256k
# echo 262144 > /proc/sys/net/core/rmem_default
# echo 262144 > /proc/sys/net/core/rmem_max
另外就是mount挂载参数优化
async 锁涉及到文件系统I/O的操作都是异步处理,即不会同步写到磁盘,此参数会提高性能,但是会降低数据安全
一般生产环境,不推荐使用,除非性能要求高,数据可靠性不高的场合
atime 在每一次数据访问是,同步更新每次的访问的inode的时间,默认是atime,在高并发的情况下,建议加上noatime来取消默认这个选项,以达到IO,优化目的
auto 能够被自动挂载
defaults 这是缺省值,rw,suid,dev,exec,auto,nouser,async
exec 运行可以执行二进制文件,取消这个参数会提升系统安全性nodiratime 不更新文件爱你系统上的directory inode访问时间,高并发时候建议使用此选型
noauto 不自动挂载
noexec 即使设置了noexec shell php 程序还是可以执行
nosuid 禁止已给普通用户挂载文件系统,
rsize wsize 如果内存足够大,可以将rsize wsize 设置大点
通过例子着重对比一下rsize,wsize参数对传输速度的影响
首先在客户端挂载,指定块大小为1024
用dd命令写入文件查看写入速度
修改rszie和wsize,重新挂载,并查看写入速度
可以看到有一个比较明显的提升,另外其他的影响nfs速度的因素还包括
- 网络包大小和网卡驱动、网络延迟、网络包分片等
- 传输采用TCP或UDP
- 传输超时等待和重传
- nfsd的进程个数
- 磁盘(阵列或SSD)
NFS常见故障
总结了以下埃及点NFS使用过程中常见的故障
- mount.nfs: access denied by server while mounting
该故障,通常是权限的问题,服务端防火墙未放行端口,或授权网段不对 - can't contactportmapper: RPC:Remotesystem error-Connection refused
该故障一般是服务端RPC的问题,没有启动PORTMAP,重启RPC服务 - mountclntudp_create: RPC: Programnotregistered
该故障一般是服务端nfs服务没有启动,通过showmount查看,启动服务端nfs服务 - 权限无论如何修改,都是nfsnobody或nobody
该故障一般是由于rpc的idmapd守护进程引起的,在nfs-v4版本中,rpc有一个rpc.idmapd的守护进程,该进程负责处理uid和gid的映射,它的配置文件是/etc/idmapd.conf,通常情况下,它会对映射关系进行缓存,所以首先在客户端重启rpcidmap服务,清除idmap的缓存,并重新挂载,大部分情况是可以解决问题的
若缓存清除后,问题仍然存在,可以在/etc/idmapd.conf配置文件中,给Domain指定一个值,然后重启rcpidmap服务,nfs的客户端同样修改/etc/idmapd.conf,指定Domain的值与服务端相同,重启rpcidmap服务,之后再重新挂载就没有问题
若在配置文件中Mapping配置段默认指定了Nobody-User=nobody,则需要注释掉之后重启rcpidmap服务,之后重新挂载,就没有问题了
完