之前接到一个电话面试其中一个问题是如何搭建一个NFS服务器,他说他看过我的博客了,忽然我的第一反应是联想到博客里面可能是缺少了一篇关于NFS的文章了^_^~ 开玩笑啦!~ 

     下面说点正经的,如果大家是在生产环境上建议使用成熟封装后产品,国产和国外的很多固定存储产品都能满足并且价格也不算太贵。如果实在是囊中羞涩可以使用free nasopenfiler等软件。这样是提供服务更加纯粹,从而减少不必要的麻烦。以前在建行工作的时候提供nfs服务的主机经常要重启服务甚至主机才行,因急于恢复生产所以也没详细测试过(估计是软件或协议版本问题)。现在工作的地方从去年开始使用NetApp的Nas(跑oracle和ap),目前来看使用的生产系统运行还是比较稳定的。

好了废话说多了,下面开始

##################################################################################

实验环境:Red Hat Enterprise Linux Server release 6.8 (Santiago)

Vmware Workstation 12.5

NTP Client Name:ocbsap01  IP:192.168.10.128

NTP Server Name: ocbsdb01   IP:192.168.10.131

实验目的:ap01 为NFS client ,db01 为NFS server

###################################################################################

简介:

   NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源。在NFS的应用中,NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件,就像访问本地文件一样。

(另外多在说一句:使用NFS的clent都为Linux或Unix,如果client是Windows 要搭建Samba服务才行)

#####################Server 端操作#####################################

1、安装NFS服务器软件包,检查如下安装包,如果没有安装就rpm或者yum安装一下

[root@ocbsdb01 ~]# rpm -qa | grep nfs

nfs-utils-lib-1.1.5-11.el6.x86_64

nfs-utils-1.2.3-70.el6.x86_64

[root@ocbsdb01 /]# rpm -qa | grep rpcbind

rpcbind-0.2.0-12.el6.x86_64


2、创建nfs共享文件系统/nfs和测试文件hello.py ,记得加入到/etc/fstab中实现开机自启动

[root@ocbsdb01 ~]# lvcreate  -L 1G -n lv_nfs system

[root@ocbsdb01 ~]# mkfs.ext4  /dev/system/lv_nfs

[root@ocbsdb01 /]# mkdir /nfs

[root@ocbsdb01 /]# mount /dev/system/lv_nfs  /nfs

[root@ocbsdb01 nfs]# touch hellp.py

[root@ocbsdb01 nfs]# cat hello.py 

print('hello world!')


3、NFS服务配置实例

修改/etc/exports文件(文件默认为空)

/nfs      192.168.10.128(rw,sync,no_root_squash)  
#只允许192.168.10.128主机以读写权限在来挂载/nfs目录

或/nfs  192.168.10.*(rw) #指定192.168.10.0网段的客户进行访问  *号表示所有用户


exports文件(NFS权限设置最终的权限是NFS和文件的权限结合起来的这一点一定要记得!


用户映射选项:

    ro:                        只读访问

    rw :                      读写访问

    all_squash:          将远程访问的所有普通用户及所属组都映射为匿名用户或用户组(nfsnobody);

    no_all_squash:    与all_squash取反(默认设置);

    root_squash:       将root用户及所属组都映射为匿名用户或用户组(默认设置);

    no_root_squash: 客户端把共享目录挂载后,操作共享目录,就像是用自己的目录一样的权限;

    客户端使用 NFS  文件系统的账号若为 root 时,系统该如何判断这个账号的身份?

    预设的情况下,客户端 root 的身份会由 root_squash 的设定压缩成 nfsnobody,

    如此对服务器的系统会较有保障。但如果你想要开放客户端使用 root 身份来操作服务器的文件系统,

    那么这里就得要开 no_root_squash 才行!

    anonuid=xxx:    将远程访问的所有用户都映射为匿名用户,并指定该用户为本地用户(UID=xxx);

    anongid=xxx:    将远程访问的所有用户组都映射为匿名用户组账户,并指定该匿名用户组账户为本地用户组账户(GID=xxx);


其它选项:

    secure :         限制客户端只能从小于1024的TCP/IP端口连接nfs服务器(默认设置);

    insecure:      允许客户端从大于1024的TCP/IP端口连接服务器;

    sync(同步):    将数据同步写入内存缓冲区与磁盘中,效率低,但可以保证数据的一致性;

    async(异步):  将数据先保存在内存缓冲区中,必要时才写入磁盘;

    wdelay :        检查是否有相关的写操作,如果有则将这些写操作一起执行,这样可以提高效率(默认设置)

    no_wdelay :  若有写操作则立即执行,应与sync配合使用;

    subtree:       若输出目录是一个子目录,则nfs服务器将检查其父目录的权限(默认设置);

    no_subtree:  即使输出目录是一个子目录,nfs服务器也不检查其父目录的权限,这样可以提高效率;

    subtree_check:    如果共享/usr/bin之类的子目录时,强制NFS检查父目录的权限

    no_subtree_check: 和上面相对,不检查父目录权限(默认)

    hide::             在NFS共享目录中不共享其子目录

    no_hide :       共享NFS目录的子目录

    

4、NFS服务管理

4.1、启动NFS服务

[root@ocbsdb01 /]# service nfs start

启动 NFS 服务:                                              [确定]

关掉 NFS 配额:                                              [确定]

启动 NFS mountd:                                        [确定]

启动 NFS 守护进程:                                       [确定]

正在启动 RPC idmapd:                                 [确定]


4.2、在服务器端查看NFS共享目录信息

[root@ocbsdb01 /]# exportfs -v

/nfs    192.168.10.128(rw,wdelay,no_root_squash,no_subtree_check,sec=sys,rw,no_root_squash,no_all_squash)


exportfs
         -a 输出在/etc/exports文件中所定义的所有目录;
         -r 重新读取/etc/exports文件,不需要重起服务;
         -u 停止输出某一目录;
         -v 在屏幕上显示过程;
         
exportfs  -auv 停止共享
exportfs  -rv  重新共享



[root@ocbsdb01 /]# showmount -e 192.168.10.131
Export list for 192.168.10.131:
/nfs 192.168.10.128


5、使用rpcinfo –p 检查rpc注册信息,查看服务端口,除111/875/2049外其余为随机端口

通过如下操作能验证上面信息

[root@ocbsdb01 /]# service  nfs stop

关闭 NFS 守护进程:                                        [确定]

关闭 NFS mountd:                                         [确定]

关闭 NFS quotas:                                           [确定]

关闭 NFS 服务:                                               [确定]

Shutting down RPC idmapd:                           [确定]


rpcinfo 选项与参数:
-p :针对某 IP (未写则预设为本机) 显示出所有的 port 与 porgram 的信息;
-t :针对某主机的某支程序检查其 TCP 封包所在的软件版本;
-u :针对某主机的某支程序检查其 UDP 封包所在的软件版本;

[root@ocbsdb01 /]# rpcinfo  -p localhost

   program vers proto   port  service

    100000    4   tcp    111  portmapper

    100000    3   tcp    111  portmapper

    100000    2   tcp    111  portmapper

    100000    4   udp    111  portmapper

    100000    3   udp    111  portmapper

    100000    2   udp    111  portmapper

    100024    1   udp  52029  status

    100024    1   tcp  60903  status


[root@ocbsdb01 /]# rpcinfo  -p localhost

   program vers proto   port  service

    100000    4   tcp    111  portmapper

    100000    3   tcp    111  portmapper

    100000    2   tcp    111  portmapper

    100000    4   udp    111  portmapper

    100000    3   udp    111  portmapper

    100000    2   udp    111  portmapper

    100024    1   udp    52029  status

    100024    1   tcp      60903  status

    100011    1   udp    875  rquotad

    100011    2   udp    875  rquotad

    100011    1   tcp    875  rquotad

    100011    2   tcp    875  rquotad

    100005    1   udp  44037  mountd

    100005    1   tcp  60499  mountd

    100005    2   udp  49190  mountd

    100005    2   tcp  54931  mountd

    100005    3   udp  43762  mountd

    100005    3   tcp  51304  mountd

    100003    2   tcp   2049  nfs

    100003    3   tcp   2049  nfs

    100003    4   tcp   2049  nfs

    100227    2   tcp   2049  nfs_acl

    100227    3   tcp   2049  nfs_acl

    100003    2   udp   2049  nfs

    100003    3   udp   2049  nfs

    100003    4   udp   2049  nfs

    100227    2   udp   2049  nfs_acl

    100227    3   udp   2049  nfs_acl

    100021    1   udp  54852  nlockmgr

    100021    3   udp  54852  nlockmgr

    100021    4   udp  54852  nlockmgr

    100021    1   tcp  35706  nlockmgr

    100021    3   tcp  35706  nlockmgr

    100021    4   tcp  35706  nlockmgr


6、自定义nfs固定端口

vim /etc/sysconfig/nfs

自定义以下端口,但不能和其它端口冲突

默认如下:

#RQUOTAD_PORT=875

#LOCKD_TCPPORT=32803

#LOCKD_UDPPORT=32769

#MOUNTD_PORT=892

#STATD_PORT=662


可以修改为

RQUOTAD_PORT=60001 

LOCKD_TCPPORT=60002 

LOCKD_UDPPORT=60002 

MOUNTD_PORT=60003 

STATD_PORT=60004


[root@ocbsdb01 sysconfig]# rpcinfo -p

   program vers proto   port  service

    100000    4   tcp    111  portmapper

    100000    3   tcp    111  portmapper

    100000    2   tcp    111  portmapper

    100000    4   udp    111  portmapper

    100000    3   udp    111  portmapper

    100000    2   udp    111  portmapper

    100011    1   udp  60001  rquotad

    100011    2   udp  60001  rquotad

    100011    1   tcp  60001  rquotad

    100011    2   tcp  60001  rquotad

    100005    1   udp  60004  mountd

    100005    1   tcp  60004  mountd

    100005    2   udp  60004  mountd

    100005    2   tcp  60004  mountd

    100005    3   udp  60004  mountd

    100005    3   tcp  60004  mountd

    100003    2   tcp   2049  nfs

    100003    3   tcp   2049  nfs

    100003    4   tcp   2049  nfs

    100227    2   tcp   2049  nfs_acl

    100227    3   tcp   2049  nfs_acl

    100003    2   udp   2049  nfs

    100003    3   udp   2049  nfs

    100003    4   udp   2049  nfs

    100227    2   udp   2049  nfs_acl

    100227    3   udp   2049  nfs_acl

    100021    1   udp  60003  nlockmgr

    100021    3   udp  60003  nlockmgr

    100021    4   udp  60003  nlockmgr

    100021    1   tcp  60002  nlockmgr

    100021    3   tcp  60002  nlockmgr

    100021    4   tcp  60002  nlockmgr


7、使用iptables策略

iptables -P INPUT   DROP 

iptables -A INPUT -i lo -j ACCEPT 

iptables -A INPUT -p tcp -m multiport --dport 111,2049 -j ACCEPT 

iptables -A INPUT -p udp -m multiport --dport 111,2049 -j ACCEPT 

iptables -A INPUT -p tcp --dport 60001:60004 -j ACCEPT 

iptables -A INPUT -p udp --dport 60001:60004 -j ACCEPT 

service iptables save


8、实际应用举例

 需求:

1、/media目录

共享/media目录,允许所有客户端访问该目录并只有只读权限。


2、/nfs/public目录

共享/nfs/public目录,允许192.168.146.0/24网段的客户端访问,并且对此目录只有只读权限。


3、/nfs/team1、/nfs/team2、/nfs/team3目录

共享/nfs/team1、/nfs/team2、/nfs/team3目录,并/nfs/team1只有team1.michael.com域成员可以访问并有读写权限,/nfs/team2、/nfs/team3目录同理哈~


4、/nfs/works目录

共享/nfs/works目录,192.168.8.0/24网段的客户端具有只读权限,并且将root用户映射成匿名用户。


5、/nfs/test目录

共享/nfs/test目录,所有人都具有读写权限,但当用户使用该共享目录时都将帐号映射成匿名用户,并且指定匿名用户的UID和GID都为65534。


6、/nfs/security目录

共享/nfs/security目录,仅允许192.168.146.129客户端访问并具有读写权限


操作:

1、创建需要的目录

[root@www /]# mkdir /nfs

[root@www /]# mkdir /nfs/public

[root@www /]# mkdir /nfs/team1  /nfs/team2

[root@www /]# mkdir /nfs/team3

[root@www /]# mkdir /nfs/works

[root@www /]# mkdir /nfs/test

[root@www /]# mkdir /nfs/security


2、编辑/etc/exports配置文件

/etc/exports:nfs服务的主配置文件

vim /etc/exports 输入如下内容

/media           *(ro)

/nfs/public      192.168.10.0/24(ro)

/nfs/team1       *.team1.michael.com(rw)

/nfs/team2       *.team2.michael.com(rw)

/nfs/team3       *.team3.michael.com(rw)

/nfs/works       192.168.10.0/24(ro,root_squash)

/nfs/test        *(rw,all_squash,anonuid=65534,anongid=65534)

/nfs/security    192.168.10.128/24(rw,no_root_squash)


备注:

在发布共享目录的格式中除了共享目录是必跟参数外,其他参数都是可选的。

并且共享目录与客户端之间、客户端与客户端之间需要使用空格符号,但是客户端与参数之间是不能有空格的~

 

#########################Client端验证操作#############################

1、在client检查软件是否安装,这里已经安装好了,如果没有rpm或者yum安装

[root@ocbsap01 /]# rpm -qa | grep rpcbind
rpcbind-0.2.0-12.el6.x86_64


2、在client端查看NFS共享目录信息

[root@ocbsap01 ~]# showmount -e 192.168.10.131

Export list for 192.168.10.131:

/nfs 192.168.10.128


showmount [选项]  nfs服务器ip
           -a  显示指定的nfs服务器的所有客户端主机及其所连接的目录;
           -d  显示指定的nfs服务器中已被客户端连接的目录;
           -e  显示指定nfs服务器上所有输出的目录;


3、挂载和卸载NFS服务器上的共享目录

[root@ocbsap01 /]# mount -t nfs 192.168.10.131:/nfs /nfs
[root@ocbsap01 /]# df -h  /nfs
Filesystem           Size  Used Avail Use% Mounted on
192.168.10.131:/nfs  976M  1.3M  924M   1% /nfs


[root@ocbsap01 /]# umount /nfs

[root@ocbsap01 /]# df -h

Filesystem                                        Size    Used Avail   Use%  Mounted on

/dev/mapper/system-lv_root          12G    5.2G  6.0G   47%      /

tmpfs                                               238M     0  238M    0%       /dev/shm

/dev/sda1                                        190M   34M  147M  19%   /boot

/dev/mapper/system-lv_home        2.0G   3.1M  1.9G   1%       /home

/dev/mapper/system-lv_ocbs          976M   11M  915M   2%     /home/ocbs

/dev/mapper/system-lv_anaconda  5.8G   2.8G  2.8G     50%    /anaconda3

/dev/sr0                                             3.7G  3.7G     0     100%     /mnt


查看权限为rw状态

[root@ocbsap01 nfs]# mount 

/dev/mapper/system-lv_root on / type ext4 (rw)

proc on /proc type proc (rw)

sysfs on /sys type sysfs (rw)

devpts on /dev/pts type devpts (rw,gid=5,mode=620)

tmpfs on /dev/shm type tmpfs (rw,rootcontext="system_u:object_r:tmpfs_t:s0")

/dev/sda1 on /boot type ext4 (rw)

/dev/mapper/system-lv_home on /home type ext4 (rw)

/dev/mapper/system-lv_ocbs on /home/ocbs type ext4 (rw)

/dev/mapper/system-lv_anaconda on /anaconda3 type ext4 (rw)

/dev/sr0 on /mnt type iso9660 (ro)

none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)

sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)

192.168.10.131:/nfs on /nfs type nfs (rw,vers=4,addr=192.168.10.131,clientaddr=192.168.10.128)


4、设置client 开机自启动挂载NFS文件系统。当然nfs挂载也有很多参数这里就使用default了

在/etc/fstab文件中添加一行内容

192.168.10.131:/nfs                       /nfs              nfs     defaults        0 0

备注:

但是一般生产系统不建议自动挂载,因为一旦NFS有问题会导致client端服务器可能启动不起来


5、测试文件写入和读取

[root@ocbsap01 nfs]# cat hello.py 

print('hello world!')


[root@ocbsap01 nfs]# touch 111

[root@ocbsap01 nfs]# ls -l

总用量 20

-rw-r--r--. 1 root root     0 3月  10 2018 111

-rw-r--r--. 1 root root    28 3月  10 2018 hello.py

drwx------. 2 root root 16384 3月  10 2018 lost+found


####################################常见问题################################################

a、在RHEL 6 操作系统中挂载 NAS文件系统,并将其设置为开机自启动,则需提前配置以下内容:

1.开启必须的系统服务:rpcbind,nfslock,netfs

2.将NAS挂载信息写入 /etc/fstab中,需要将文件系统类型设置为“nfs”,增加“_netdev”参数,同时将dump和fsck字段设置为“0”。


示例如下:

192.168.0.1:/vol/nas_fs  /home/ap/nas_mount  nfs  defaults,_netdev  0  0

Redhat 6 在自动挂载的时候要在/etc/fstab 里面加入_netdev


b、关于客户端目录属组更改问题,需要在server端更改后客户端才能改变 ,切记!!


c、showmount 命令报错

[root@ocbsdb01 /]# showmount -e

clnt_create: RPC: Unknown host

解决方法:

在/etc/hosts下面写上主机名和IP对应关系如:

192.168.10.131 ocbsdb01

或者检查iptables是否关闭


d、NFS服务启动失败,

[root@ocbsdb01 sysconfig]# service  nfs start

启动 NFS 服务:                                            [确定]

关掉 NFS 配额:无法注册服务: RPC:无法接收; errno = 拒绝连接

rpc.rquotad: unable to register (RQUOTAPROG, RQUOTAVERS, udp).

                                                           [失败]

启动 NFS mountd:                                          [失败]

启动 NFS 守护进程:rpc.nfsd: writing fd to kernel failed: errno 111 (Connection refused)


解决方法:

检查rpcbind服务是否启动,rpcbind一定要先启动

[root@ocbsdb01 sysconfig]# service  rpcbind start

正在启动 rpcbind:                                         [确定]

[root@ocbsdb01 sysconfig]# service  nfs start

启动 NFS 服务:                                               [确定]

关掉 NFS 配额:                                                [确定]

启动 NFS mountd:                                          [确定]

启动 NFS 守护进程:                                          [确定]

正在启动 RPC idmapd:                                    [确定]


e、关掉 NFS 配额:rpc.rquotad: Cannot bind to given address: 权限不够

解决方法:

重启rpcbind

修改/etc/sysconfig/nfs 配置文件端口是否自定义了,如果自定义修改端口


f、showmount -a 不显示信息

查阅资料后说是版本4的nfs,运行showmount是不返回客户端信息的,

/var/lib/nfs/rmtab | xtab里面也没有记录,

于是我在客户端挂载nfs时运行命令:mount -t nfs -o vers=3 192.168.10.131:/nfs /nfs,

它会成功挂载nfs。再在服务端运行showmount -a|-d就会有返回了。也就是说这是版本问题。

命令例子:

mount -t nfs -o nfsvers=3 host:/exportdir /client_dir