之前接到一个电话面试其中一个问题是如何搭建一个 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 或 Uinx, 如果 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!')
3NFS 服务配置实例
修改 / 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 目录的子目录
4NFS 服务管理
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 nfs-utils
- nfs-utils-lib-1.1.5-11.el6.x86_64
- nfs-utils-1.2.3-70.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 端更改后客户端才能改变 , 切记!!
cshowmount 命令报错
- [root@ocbsdb01 /]# showmount -e
- clnt_create: RPC: Unknown host
解决方法:
在 / etc/hosts 下面写上主机名和 IP 对应关系如:
192.168.10.131 ocbsdb01
或者检查 iptables 是否关闭
dNFS 服务启动失败,
[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 配置文件端口是否自定义了, 如果自定义修改端口
fshowmount -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
来源: http://www.bubuko.com/infodetail-2522075.html