完全解读NFS

2021-02-23 11:41:32 浏览数 (1)

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>:指定匿名访问用户的本地用户UID,默认为nfsnobody(65534) anongid=<GID>:指定匿名访问用户的本地用户组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时,需要将与该用户相关的进程全部停掉,才能修改,停掉某用户所有进程方法有以下几种:

  1. pkill -u test
  2. killall -u test
  3. ps -ef |grep test|awk '{print $2}'|xargs kill -9 (容易误杀)
  4. 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速度的因素还包括

  1. 网络包大小和网卡驱动、网络延迟、网络包分片等
  2. 传输采用TCP或UDP
  3. 传输超时等待和重传
  4. nfsd的进程个数
  5. 磁盘(阵列或SSD)

NFS常见故障

总结了以下埃及点NFS使用过程中常见的故障

  1. mount.nfs: access denied by server while mounting 该故障,通常是权限的问题,服务端防火墙未放行端口,或授权网段不对
  2. can't contactportmapper: RPC:Remotesystem error-Connection refused 该故障一般是服务端RPC的问题,没有启动PORTMAP,重启RPC服务
  3. mountclntudp_create: RPC: Programnotregistered 该故障一般是服务端nfs服务没有启动,通过showmount查看,启动服务端nfs服务
  4. 权限无论如何修改,都是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服务,之后重新挂载,就没有问题了

0 人点赞