之前接到一个电话面试其中一个问题是如何搭建一个NFS服务器,他说他看过我的博客了,忽然我的第一反应是联想到博客里面可能是缺少了一篇关于NFS的文章了^_^~ 开玩笑啦!~
下面说点正经的,如果大家是在生产环境上建议使用成熟封装后产品,国产和国外的很多固定存储产品都能满足并且价格也不算太贵。如果实在是囊中羞涩可以使用free nas或openfiler等软件。这样是提供服务更加纯粹,从而减少不必要的麻烦。以前在建行工作的时候提供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