NFSs是那层协议 nfs基于什么协议_nfs客户端

NFS(Network File System),网络文件系统,是一种比较常见的文件共享的方式,可以通过网络,让不通的机器,不通的操作系统之间实现文件共享。

NFS的基本原则是“容许不同的客户端及服务端通过一组RPC分享相同的文件系统”,它是独立于操作系统,允许不同硬件及操作系统的进行文件的共享。

NFS在文件传送或信息传送过程中依赖于RPC协议。RPC是什么呢,RPC是Remote Procedure Call的缩写,即远程过程调用,是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议,由于不是今天主要内容,用一张图看一下RPC原理

NFSs是那层协议 nfs基于什么协议_nfs 端口_02

NFS本身是没有提供信息传输的协议和功能的,它就是用到RCP的传输协议,可以说NFS也是一个RPC SERVER。所以用到NFS的地方,无论是服务端还是客户端,都需要启动RPC服务。



NFSs是那层协议 nfs基于什么协议_客户端_03

NFS安装配置


NFS安装需要两个包,nfs-utils和rpcbind

# yum -y install nfs-utils                                                           

服务端和客户端,都需要安装这两个包,安装完成后,系统会自动创建nfsnobody用户和组,uid和gid都是65543

NFSs是那层协议 nfs基于什么协议_NFSs是那层协议_04

NFS除了主程序端口2049和rpcbind的端口111是固定端口以外,其他的还会有一些随机端口,这些端口是NFS向rpcbind注册产生的,先启动rpcbind,然后查看端口

NFSs是那层协议 nfs基于什么协议_nfs 端口_05

接着启动NFS,之后再查看端口

NFSs是那层协议 nfs基于什么协议_NFSs是那层协议_06

由于端口都说是随机的,不方便防火墙管理,所以在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文件中

NFSs是那层协议 nfs基于什么协议_nfs客户端_07

配置完成后,不需要重启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地址分享出来的目录


NFSs是那层协议 nfs基于什么协议_客户端_08

在客户端查看

NFSs是那层协议 nfs基于什么协议_nfs 端口_09

客户端挂载

NFSs是那层协议 nfs基于什么协议_NFSs是那层协议_10

NFSs是那层协议 nfs基于什么协议_nfs客户端_11

在服务端查看nfs状态

NFSs是那层协议 nfs基于什么协议_nfs客户端_12

在服务端创建个文件,并查看文件权限

NFSs是那层协议 nfs基于什么协议_nfs客户端_13

在客户端查看文件

NFSs是那层协议 nfs基于什么协议_nfs客户端_14

貌似没有问题了,然后在客户端尝试修改文件权限

NFSs是那层协议 nfs基于什么协议_客户端_15

无法修改,在服务器端修改文件权限,并查看权限

NFSs是那层协议 nfs基于什么协议_nfs客户端_16

同样,在客户端查看文件权限

NFSs是那层协议 nfs基于什么协议_nfs客户端_17

发现权限有问题,502是什么呢,502是服务端test用户的id(uid和gid),下面针对nfs权限详细说一下



NFSs是那层协议 nfs基于什么协议_客户端_03

NFS文件权限


在服务端,查看nfs挂载所有配置参数

NFSs是那层协议 nfs基于什么协议_客户端_19

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用户

NFSs是那层协议 nfs基于什么协议_win挂载nfs后打开很慢_20

很多时候客户端挂载nfs的时候,用户是已经创建好的,大部分的情况是客户端与服务端相同用户的id不同,包括uid和gid,所以很多时候需要修改客户端用户的id

修改用户uid和gid的命令,分别是usermod和groupmod,所以,通过id命令查看服务端文件用户id,之后在客户端通过查看/etc/passwd和/etc/group确保该uid及gid未被占用之后,通过命令修改

服务端:

NFSs是那层协议 nfs基于什么协议_客户端_21

客户端:

NFSs是那层协议 nfs基于什么协议_nfs客户端_22

客户端修改用户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

NFSs是那层协议 nfs基于什么协议_客户端_23

原先的test权限的文件,此时的权限会变成原来的uid和gid显示在权限的地方,所以还需要通过权限修改命令,将权限修改为现在用户的权限,用户和组的权限修改分别是

find / -user 1007 -exec chown -h test {} \;

find / -group 1007 -exec chgrp -h test {} \;

修改权限完成后,重新启动该用户的所有进程,可以查看nfs挂载目录的权限

NFSs是那层协议 nfs基于什么协议_客户端_24

由原来的502变为test,权限正常



NFSs是那层协议 nfs基于什么协议_客户端_03

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

NFSs是那层协议 nfs基于什么协议_NFSs是那层协议_26

用dd命令写入文件查看写入速度

NFSs是那层协议 nfs基于什么协议_nfs客户端_27

修改rszie和wsize,重新挂载,并查看写入速度

NFSs是那层协议 nfs基于什么协议_win挂载nfs后打开很慢_28

NFSs是那层协议 nfs基于什么协议_NFSs是那层协议_29

可以看到有一个比较明显的提升,另外其他的影响nfs速度的因素还包括

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

NFSs是那层协议 nfs基于什么协议_客户端_03

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服务,之后重新挂载,就没有问题了