环境:
OS:CentOS 6.5 x86_64
Kernel Ver:2.6.32-431.20.3.el6.x86_64
Server IP:192.168.100.248(已关闭SELinux)
ClientA IP:192.168.100.208(已关闭SELinux)
ClientB IP:192.168.100.209(已关闭SELinux)
在每台机器上都运行如下命令安装nfs-utils和rpcbind
1
|
[root@Server ~]
# yum -y install nfs-utils rpcbind
|
ps:在CentOS 6以后使用rpcbind替换portmap
在每台机器上查看用户及组的id
1
2
3
4
5
6
|
[root@Server ~]
# id nfsnobody
uid=65534(nfsnobody) gid=65534(nfsnobody)
groups
=65534(nfsnobody)
[root@ClientA ~]
# id nfsnobody
uid=65534(nfsnobody) gid=65534(nfsnobody)
groups
=65534(nfsnobody)
[root@clientB ~]
# id nfsnobody
uid=65534(nfsnobody) gid=65534(nfsnobody)
groups
=65534(nfsnobody)
|
说明每台机器nfsnobody的uid及gid与其他机器的必须相同,否则可能出现权限问题。
如果不一样的话,可以使用
1
2
|
groupmod -g 65534 nfsnobody
usermod
-u 65534 nfsnobody
|
这种情况一般出现在centos 5.*的64位版本中。
在Server上运行
1
2
3
4
5
6
7
|
[root@Server ~]
# service rpcbind start ;chkconfig rpcbind on
Starting rpcbind: [ OK ]
[root@Server ~]
# service nfs start ;chkconfig nfs on
Starting NFS services: [ OK ]
Starting NFS mountd: [ OK ]
Starting NFS daemon: [ OK ]
Starting RPC idmapd: [ OK ]
|
在机器开机时,一定是先启动rpcbind服务,再启动nfs服务。否则可能出现
1
2
3
4
5
6
7
8
9
10
11
|
[root@Server ~]
# service rpcbind stop
Stopping rpcbind: [ OK ]
[root@Server ~]
# service nfs restart
Shutting down NFS daemon: [ OK ]
Shutting down NFS mountd: [ OK ]
Shutting down RPC idmapd: [ OK ]
Starting NFS services: [ OK ]
Starting NFS mountd: [FAILED]
Starting NFS daemon: rpc.nfsd: writing fd to kernel failed: errno 111 (Connectio n refused)
rpc.nfsd: unable to
set
any sockets
for
nfsd
[FAILED]
|
现在查看/etc/init.d/rpcbind文件及/etc/init.d/nfs
从上面可以看出chkconfig后面的数字(30 60 )(13 87)说明rpcbind比nfs先启动,关闭时nfs比rpcbind先关闭。
现在我们创建一个/data目录,并共享出去,192.168.100.0段的用户可以访问并读写。
1
2
3
4
5
|
[root@Server ~]
# mkdir /data
[root@Server ~]
# chown -R nfsnobody /data
[root@Server ~]
# chmod 750 /data
[root@Server ~]
# vim /etc/exports
/data
192.168.100.0
/24
(rw,
sync
,all_squash,anonuid=65534,anongid=65534)
|
参数说明:
选项 说明
ro 该主机对该共享目录有只读权限
rw 该主机对该共享目录有读写权限
root_squash 客户机用root用户访问该共享文件夹时,将root用户映射成匿名用户
no_root_squash 客户机用root访问该共享文件夹时,不映射root用户,NFS客户端连接服务端时如果使用的是root的话,那么对服务端分享的目录来说,也拥有root权限。显然开启这项是不安全的
all_squash 客户机上的任何用户访问该共享目录时都映射成匿名用户
anonuid 将客户机上的用户映射成指定的本地用户ID的用户
anongid 将客户机上的用户映射成属于指定的本地用户组ID
sync 资料同步写入到内存与硬盘中
async 资料会先暂存于内存中,而非直接写入硬盘
secure 限制客户端只能从小于1024的tcp/ip端口连接nfs服务器(默认设置);
insecure 允许客户端从大于1024的tcp/ip端口连接服务器
wdelay 检查是否有相关的写操作,如果有则将这些写操作 一起执行,这样可以提高效率(默认设置);
no_wdelay 若有写操作则立即执行,应与sync配合使用;
subtree 若输出目录是一个子目录,则nfs服务器将检查其父目录的权限(默认设置);
no_subtree 即使输出目录是一个子目录,nfs服务器也不检查其父目录的权限,这样可以提高效率;
重新加载nfs配置文件
1
2
3
|
[root@Server ~]
# exportfs -rv
或者
/etc/init
.d
/nfs
reload
exporting 192.168.100.0
/24
:
/data
|
查看是否正常
1
2
3
|
[root@Server ~]
# showmount -e 127.0.0.1
Export list
for
127.0.0.1:
/data
192.168.100.0
/24
|
可以看到共享目录,说明正常,当然你也可以到ClientA和ClientB上去尝试。如果服务器上开启了防火墙或者网络不通,则可能出现
1
2
|
[root@ClientA ~]
# showmount -e 192.168.100.248
clnt_create: RPC: Port mapper failure - Timed out
|
因为NFS服务器一般是内网,不对外提供服务,为了保持良好的网络性能,一般关闭防火墙
1
2
3
4
|
[root@Server ~]
# service iptables stop ;chkconfig iptables off
iptables: Setting chains to policy ACCEPT: filter [ OK ]
iptables: Flushing firewall rules: [ OK ]
iptables: Unloading modules: [ OK ]
|
现在在服务器上挂载
1
2
3
4
5
6
7
8
9
10
|
[root@ClientA ~]
# mkdir /data
[root@ClientA ~]
# mount -t nfs 192.168.100.248:/data /data
[root@ClientA ~]
# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root
28G 1.4G 25G 6% /
tmpfs 497M 0 497M 0%
/dev/shm
/dev/xvda1
485M 119M 341M 26%
/boot
192.168.100.248:
/data
28G 1.4G 25G 6%
/data
|
可以看到现在nfs正常挂载了。
一般NFS服务器存储的只是普通数据(图片、附件、HTML、CSS、JS、视频),应该是不需要执行suid,exec等权限,因此生产环境中在挂载的时候可以执行如下命令挂载。
1
|
[root@clientB ~]
# mount -t nfs -o nosuid,noexec,nodev,hard,intr,rw 192.168.100.248:/data /data
|
挂载选项说明:
-t nfs是说明挂载类型
设置了nosuid、noexec、nodev选项,意味着不允许任何suid程序,从这个分区不能执行任何内容,并且不存在设备文件
soft:使用软挂载的方式挂载系统,若Client的请求得不到回应,则重新请求并传回错误信息。
hard:使用硬挂载的方式挂载系统,该值是默认值,重复请求直到NFS服务器回应。
intr:允许NFS中断文件操作和向调用它的程序返回值,默认不允许文件操作被中断。
atime 每次存取都更新inode的存取时间,默认设置,取消选项为noatime。
noatime 每次存取时不更新inode的存取时间
rsize=n:在NFS服务器读取文件时NFS使用的字节数,默认值是1 024个字节
wsize=n:向NFS服务器写文件时NFS使用的字节数,默认值是1 024个字节
在默认情况下,NFS 的配置不适合大容量磁盘。 每个客户机应该用 rsize=32768,wsize=32768,intr,noatime 挂装远程文件系统,从而确保:
使用大的读/写块(数字指定最大块大小,在这个示例中是 32KB)
我在ClientA服务器没有使用noexec选项,在ClientB上使用了noexec选项,现在进行测试
1
2
3
4
5
6
7
8
9
10
|
[root@ClientA ~]
# echo "echo OK" >/data/ok.sh
[root@ClientA ~]
# cat /data/ok.sh
echo
OK
[root@ClientA ~]
# chmod +x /data/ok.sh
[root@ClientA ~]
# /data/ok.sh
OK
#ClientA服务器正常执行
[root@clientB ~]
# /data/ok.sh
-
bash
:
/data/ok
.sh: Permission denied
#ClientB服务器执行错误,被拒绝
|
通过使用noexec及nosuid,NFS只能存取文件,没有执行权限,相对于来说更安全。
现在我们需要开机自动挂载则需要在clientA和ClientB上都执行
1
2
3
|
[root@ClientA data]
# echo "mount -t nfs -o nosuid,noexec,nodev,hard,intr,rw 192.168.100.248:/data /data >/dev/null 2>&1" >> /etc/rc.local
[root@ClientA data]
# tail -l /etc/rc.local
mount
-t nfs -o nosuid,noexec,nodev,hard,intr,rw 192.168.100.248:
/data
/data
>
/dev/null
2>&1
|
缺省的情况下系统在启动时启动8个nfsd进程。
1
2
3
4
5
6
7
8
9
10
11
|
[root@Server ~]
# ps -ef |grep nfsd |grep -v grep
root 2175 2 0 15:06 ? 00:00:00 [nfsd4]
root 2176 2 0 15:06 ? 00:00:00 [nfsd4_callbacks]
root 2177 2 0 15:06 ? 00:00:00 [nfsd]
root 2178 2 0 15:06 ? 00:00:00 [nfsd]
root 2179 2 0 15:06 ? 00:00:00 [nfsd]
root 2180 2 0 15:06 ? 00:00:00 [nfsd]
root 2181 2 0 15:06 ? 00:00:00 [nfsd]
root 2182 2 0 15:06 ? 00:00:00 [nfsd]
root 2183 2 0 15:06 ? 00:00:00 [nfsd]
root 2184 2 0 15:06 ? 00:00:00 [nfsd]
|
通过查看/proc/net/rpc/nfsd文件的th行,第一个是nfsd的个数,后十个是线程是用的时间数,第二个到第四个值如果很大,那么就需要增加nfsd的个数。
具体如下:
1
2
|
[root@Server ~]
# vim /etc/init.d/nfs
[ -z
"$RPCNFSDCOUNT"
] && RPCNFSDCOUNT=8
|
找到RPCNFSDCOUNT,修改该值,一般和client端数目一致,然后重启nfs服务
nfsd的队列长度
对于8个nfsd进程,系统的nfsd队列长度是64k大小,如果是多于8个,就要相应的增加相应的队列大小
查看默认及最大队列大小
1
2
3
4
|
[root@Server ~]
# cat /proc/sys/net/core/rmem_default
124928
[root@Server ~]
# cat /proc/sys/net/core/rmem_max
124928
|
修改
#vi /etc/sysctl.conf
加入
net.core.mem_max=数目
net.core.mem_default=数目
执行sysctl -p生效
注意:
NFS服务器关机时要确保NFS没有客户端连接,否则无法正常关机 。可以先强制停止或杀死nfs服务。
如果出现问题,需要强制umount的话,需要使用umount -lf参数