<服务>NFS

时间:Feb. 6, 2017 分类:

目录:

NFS

NFS的主要功能是通过网络让不同的主机系统之间可以彼此共享文件或目录。NFS客户端可以通过挂载的方式将NFS客户端共享的数据文件目录挂载到NFS客户端本地系统中。另外还有MFS,GFS,FASTFS和TFS等。

RPC

由于NFS的端口调用是随机不固定的,所以需要通过RPC通信来实现,RPC服务的最主要功能是记录每个NFS功能所对应的端口号,并且在NFS客户端请求的时候将该端口和功能对应的信息传递给请求数据的NFS客户端,从而可以确保客户端可以连接到正确的NFS端口上,实现数据传输交互的目的。

安装NFS

server端安装

[root@why-1 ~]# cat /etc/redhat-release 
Red Hat Enterprise Linux Server release 6.5 (Santiago)
[root@why-1 ~]# uname -r
2.6.32-431.el6.x86_64
[root@why-1 ~]# rpm -qa  nfs-utils rpcbind
[root@why-1 ~]# yum grouplist | grep NFS
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
   NFS file server
[root@why-1 ~]# yum groupinstall -y 'NFS file server'
[root@why-1 ~]# service rpcbind start
Starting rpcbind:                                          [  OK  ]
[root@why-1 ~]# ps -ef | grep rpc
rpc      29323     1  0 21:50 ?        00:00:00 rpcbind
root     29327 29123  0 21:51 pts/2    00:00:00 grep rpc
[root@why-1 ~]# 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
[root@why-1 ~]# service rpcbind stop
Stopping rpcbind:                                          [  OK  ]
[root@why-1 ~]# rpcinfo -p localhost
rpcinfo: can't contact portmapper: RPC: Remote system error - Connection refused
[root@why-1 ~]# service rpcbind start
Starting rpcbind:                                          [  OK  ]
[root@why-1 ~]# service nfs start
Starting NFS services:                                     [  OK  ]
Starting NFS quotas:                                       [  OK  ]
Starting NFS mountd:                                       [  OK  ]
Starting NFS daemon:                                       [  OK  ]
Starting RPC idmapd:                                       [  OK  ]
[root@why-1 ~]# 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
    100011    1   udp    875  rquotad
    100011    2   udp    875  rquotad
    100011    1   tcp    875  rquotad
    100011    2   tcp    875  rquotad
    100005    1   udp  59547  mountd
    100005    1   tcp  38748  mountd
    100005    2   udp  34468  mountd
    100005    2   tcp  52384  mountd
    100005    3   udp  46558  mountd
    100005    3   tcp  34046  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  51765  nlockmgr
    100021    3   udp  51765  nlockmgr
    100021    4   udp  51765  nlockmgr
    100021    1   tcp  53125  nlockmgr
    100021    3   tcp  53125  nlockmgr
    100021    4   tcp  53125  nlockmgr
[root@why-1 ~]# chkconfig rpcbind on 
[root@why-1 ~]# chkconfig nfs on 
[root@why-1 ~]# chkconfig --list nfs
nfs             0:off   1:off   2:on    3:on    4:on    5:on    6:off
[root@why-1 ~]# chkconfig --list rpcbind
rpcbind         0:off   1:off   2:on    3:on    4:on    5:on    6:off

client端安装

[root@why-2 ~]# yum install -y nfs-utils portmap rpcbind
[root@why-2 ~]# service rpcbind start
Starting rpcbind:                                          [  OK  ]
[root@why-2 ~]# chkconfig rpcbind on
[root@why-2 ~]# chkconfig --list rpcbind 
rpcbind         0:off   1:off   2:on    3:on    4:on    5:on    6:off

到此NFS服务安装完成

配置NFS服务

[root@why-1 ~]# mkdir /data
mkdir: cannot create directory `/data': File exists
[root@why-1 ~]# ll /etc/exports 
-rw-r--r--. 1 root root 0 Jan 12  2010 /etc/exports
[root@why-1 ~]# vi !$
vi /etc/exports
[root@why-1 ~]# cat !$
cat /etc/exports
#shared /data for 1.202 by why
/data 192.168.1.0/24(rw,sync) 
[root@why-1 ~]# service nfs reload
[root@why-1 ~]# showmount -e localhost
Export list for localhost:
/data 192.168.1.0/24

配置解释

  • /data 共享目录
  • 192.168.1.0/24 共享网段
  • rw 读写权限
  • sync 同步到磁盘

    client端挂载

[root@why-2 ~]# showmount -e 192.168.1.201
Export list for 192.168.1.201:
/data 192.168.1.0/24

故障排除

[root@why-2 ~]# ping 192.168.1.201
PING 192.168.1.201 (192.168.1.201) 56(84) bytes of data.
64 bytes from 192.168.1.201: icmp_seq=1 ttl=64 time=0.657 ms
^C
--- 192.168.1.201 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 992ms
rtt min/avg/max/mdev = 0.657/0.657/0.657/0.000 ms
[root@why-2 ~]# telnet 192.168.1.201 111
Trying 192.168.1.201...
Connected to 192.168.1.201.
Escape character is '^]'.
^]
Connection closed by foreign host.
[root@why-2 ~]# mount -t nfs 192.168.1.201:/data /mnt
[root@why-2 ~]# df -h
df: `/mnt/os': No such file or directory
Filesystem                      Size  Used Avail Use% Mounted on
/dev/mapper/vg_redoop-LogVol01   39G   15G   22G  41% /
tmpfs                           242M     0  242M   0% /dev/shm
/dev/sda1                       194M   35M  150M  19% /boot
/dev/mapper/vg_redoop-LogVol02   57G  180M   54G   1% /data
192.168.1.201:/data              57G  180M   54G   1% /mnt
[root@why-2 ~# ll /mnt/
total 16
drwx------ 2 root root 16384 Oct 13 20:37 lost+found

防火墙开启报错

[root@why-2 ~]# telnet 192.168.1.201 111
Trying 192.168.1.201...
telnet: connect to address 192.168.1.201: No route to host

检验

server端创建文件

[root@why-1 ~]# touch /data/text

client端检查

[root@why-2 ~]# ll /mnt/
total 16
drwx------ 2 root root 16384 Oct 13 20:37 lost+found
-rw-r--r-- 1 root root     0 Jan 26  2017 text

client端创建文件

[root@why-2 ~]# touch /mnt/text2
touch: cannot touch `/mnt/text2': Permission denied

可以看到,是权限拒绝,但是已经配置了nfs权限,那就是文件系统/data的权限问题,确定nfs的用户 我想到了两种情况,查看是否新添加了用户,给/data目录777权限后创建文件并查看文件用户

查看是否新添加了用户

[root@why-1 ~]# tail -n 1 /etc/passwd
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin

给/data目录777权限后创建文件并查看文件用户

修改权限
[root@why-1 ~]# chmod 777 /data
client端创建文件
[root@why-2 ~]# touch /mnt/text2
[root@why-2 ~]# ll !$
ll /mnt/text2
-rw-r--r-- 1 nfsnobody nfsnobody 0 Jan 27  2017 /mnt/text2

配置文件

[root@why-1 ~]# cat /var/lib/nfs/etab 
/data   192.168.1.0/24(rw,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,no_subtree_check,secure_locks,acl,anonuid=65534,anongid=65534)
[root@why-1 ~]# grep 65534 /etc/passwd
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin

可以看到了,在配置文件中指向了65534的用户和组

修改用户权限

[root@why-1 ~]# chmod 755 /data
[root@why-1 ~]# chown -R nfsnobody.nfsnobody /data
客户端可以创建文件
[root@why-2 ~]# touch /mnt/text3

开机挂载

如果想配置开始启动,添加到/etc/rc.local中,不要配到/etc/fstab中。因为linux开机的时候先加载磁盘,后加载网络,网络文件系统放在fstab中基本都挂载不上。不过记得要在开启启动的时候先启动rpcbind

nfs流程

  1. rpc服务启动
  2. nfs服务向rpc服务同步端口
  3. nfs客户端向rpc服务请求nfs端口
  4. rpc服务向nfs客户端返回端口
  5. nfs客户端向nfs服务端口请求文件

nfs和rpc进程

[root@why-1 yum.repos.d]# ps -ef | egrep 'nfs|rpc'
rpc      29367     1  0 Jan26 ?        00:00:00 rpcbind             #rpc服务,5.x版本为portmap
root     29401     2  0 Jan26 ?        00:00:00 [rpciod/0]          #磁盘配额
root     29409     1  0 Jan26 ?        00:00:00 rpc.rquotad
root     29413     1  0 Jan26 ?        00:00:00 rpc.mountd          #通过权限访问控制列表,对客户端权限和本地文件系统权限比对,然后获取文件
root     29419     2  0 Jan26 ?        00:00:00 [nfsd4]
root     29420     2  0 Jan26 ?        00:00:00 [nfsd4_callbacks]
root     29421     2  0 Jan26 ?        00:00:00 [nfsd]              #主进程,管理nfs客户端登入
root     29422     2  0 Jan26 ?        00:00:00 [nfsd]
root     29423     2  0 Jan26 ?        00:00:00 [nfsd]
root     29424     2  0 Jan26 ?        00:00:00 [nfsd]
root     29425     2  0 Jan26 ?        00:00:00 [nfsd]
root     29426     2  0 Jan26 ?        00:00:00 [nfsd]
root     29427     2  0 Jan26 ?        00:00:00 [nfsd]
root     29428     2  0 Jan26 ?        00:00:00 [nfsd]
root     29451     1  0 Jan26 ?        00:00:00 rpc.idmapd          #权限管理
root     29583 29123  0 00:43 pts/2    00:00:00 egrep nfs|rpc

以上进程功能都可以通过man 进程名获取。另外提供锁的功能,防止多客户端写入。

配置文件

/etc/export NFS主配置文件,默认为空,以行为单位 /usr/sbin/exportfs NFS服务管理命令,exportfs -rv加载配置文件,在/etc/init.d/nfs的reload选项定义,临时挂载export -o rw,sync 192.168.1.0/24:/data,更多的使用可以man exportfs /usr/sbin/showmount 用于查看NFS配置及挂载结果 /var/lib/nfs/etab 补全的配置文件,比/etc/export配置详细

主配置文件详解

/data 192.168.1.0/24(rw,sync) 第一列为共享目录,必须写绝对路径,同时也要主机本地目录的本地读写权限 第二列为客户端地址,地址后括号内为参数,可以写单独的IP地址,主机名或域名,也可以写整个网段,也可以用'*'来匹配所有客户端服务器,例如*.why.com,可以添加多个客户端地址和参数,例如/data 192.168.1.0/24(rw,sync) 192.168.2.0/24(ro,assync) 更多的配置方式可以通过man export获得,EXAMPLE

EXAMPLE
       # sample /etc/exports file
       /               master(rw) trusty(rw,no_root_squash)
       /projects       proj*.local.domain(rw)
       /usr            *.local.domain(ro) @trusted(rw)
       /home/joe       pc001(rw,all_squash,anonuid=150,anongid=100)
       /pub            *(ro,insecure,all_squash)
       /srv/www        -sync,rw server @trusted @external(ro)
       /foo            2001:db8:9:e54::/64(rw) 192.0.2.0/24(rw)
       /build          buildhost[0-9].local.domain(rw)

rw read-write,读写权限 ro read-only,只读权限 sync 同步写入,数据写入到NFSserver端磁盘才返回 async 异步写入,特点是写入到内存就返回为写入完成,等之后定期写入到磁盘,这样速度快,但是稳定性差,容易丢数据,必须在性能和稳定性之间选着一个 no_root_squash 如果是root用户访问NFS server共享目录,它对该共享目录具有root权限,这个配置为无盘客户端准备 root_squash 如果是root用户访问NFS server共享目录,它的权限会被压缩成匿名用户,nobody或nfsnobody all_squash 不论任何用户访问NFS server共享目录,它的权限都会被压缩成匿名用户,nobody或nfsnobody(用于多台主机共同对同一NFS目录进行读写) anonuid 指定匿名用户的UID anongid 指定匿名用户的GID secure 不允许Client使用大于1024的端口,不建议 insecure 允许Client自行决定使用端口 nohide 当配置中存在目录下存在多个目录,我们挂载父目录时,会自动把所有子目录挂载 hide 与上述相反,需要我们自行挂载子目录 更多的配置可以通过man exports查看

确保多个服务器对NFS共享目录具有相同的权限

  1. all_squash把所有客户端都压缩成匿名用户
  2. anonuid,anongid指定的UID和GID的用户
  3. 所有的客户端和服务端都有一个相同的UID和GID的用户,即nfsnobody(UID必须相同) 一般默认的即可,当然如果出现64位和32位混合的,默认也会出问题,当然,现在32位的系统我就见过一次。

配置多台机器使用其他用户

[root@why-1 ~]# useradd why -u 567 [root@why-1 ~]# id why uid=567(why) gid=567(why) groups=567(why) [root@why-1 ~]# vi /etc/exports [root@why-1 ~]# cat !$ cat /etc/exports /data 192.168.1.0/24(rw,sync,all_squash,anonuid=567,anongid=567) [root@why-1 ~]# exportfs -rv exporting 192.168.1.0/24:/data [root@why-1 ~]# chown -R why.why /data [root@why-1 ~]# ll -ld /data/ drwxr-xr-x. 3 why why 4096 Jan 27 00:05 /data/

[root@why-2 ~]# useradd why -u 567 [root@why-2 ~]# id why uid=567(why) gid=567(why) groups=567(why) [root@why-2 ~]# touch /mnt/test4 [root@why-2 ~]# ll /mnt/ total 16 drwx------ 2 why why 16384 Oct 13 20:37 lost+found -rw-r--r-- 1 why why 0 Jan 27 2017 test4 -rw-r--r-- 1 why why 0 Jan 26 2017 text -rw-r--r-- 1 why why 0 Jan 27 2017 text2 -rw-r--r-- 1 why why 0 Jan 27 2017 text3 可以看到以前的也跟着改变

可选择mount -o 参数

async All I/O to the filesystem should be done asynchronously. (See also the sync option.) 所以涉及到的文件系统的I/O都是异步处理,即不会写入到磁盘,此参数会提高性能,但是会降低安全系数,一般生产环境下不推荐使用,除非对性能要求特别高并且对数据可靠性不要求的情况下 atime Do not use noatime feature, then the inode access time is controlled by kernel defaults. See also the description for strictatime and relatime mount options. 在每一次数据访问的时候,同步更新每次访问inode的时间,是默认的选项,在高并发的情况下,建议使用noatime来取消这个选项,以此来达到提高IO性能的目的 noatime Do not update inode access times on this filesystem (e.g, for faster access on the news spool to speed up news servers). 被推荐与atime相反 auto Can be mounted with the -a option. 可以被mount -a挂载 noauto Can only be mounted explicitly (i.e., the -a option will not cause the filesystem to be mounted). 与auto相反 defaults Use default options: rw, suid, dev, exec, auto, nouser, async, and relatime. 默认省缺值,包括rw, suid, dev, exec, auto, nouser, async, and relatime diratime Update directory inode access times on this filesystem. This is the default. 更新访问文件夹的inode时间 nodiratime Do not update directory inode access times on this filesystem. 不更新访问文件夹的inode时间,这个也是推荐的 exec Permit execution of binaries. 允许执行程序 noexec Do not allow direct execution of any binaries on the mounted filesystem. (Until recently it was possible to run binaries anyway using a command like /lib/ld*.so /mnt/binary. This trick fails since Linux 2.4.25 / 2.6.0.) 不允许执行程序 suid Allow set-user-identifier or set-group-identifier bits to take effect. 在其上的程序允许设置uid nosuid Do not allow set-user-identifier or set-group-identifier bits to take effect. (This seems safe, but is in fact rather unsafe if you have suidperl(1) installed.) 在其上的程序不允许设置uid nouser Forbid an ordinary (i.e., non-root) user to mount the filesystem. This is the default. 禁止普通用户挂载该文件系统,默认选项 remount Attempt to remount an already-mounted filesystem. This is commonly used to change the mount flags for a filesystem, especially to make a readonly filesystem writeable. It does not change device or mount point. 允许重新挂载该文件系统 当然参数还有好多,这边只是举例了常用的一些,更多的可以man mount获得。

特别说一下remount,一般盘会出现只读盘,可选项有好多

  1. 重启系统
  2. fsck -y /dev/sdb1这个修复的时候会把文件进行转移,有点麻烦
  3. umount文件系统,如果出现device is busy,可以通过fuser -m /dev/sdb1显示占用磁盘的进程pid,fuser -mk /dev/sdb1直接kill那个pid或者umount -lf /dev/sdb1强制卸载,然后重新mount
  4. mount -o rw,remount /dev/sdb1 推荐用第四种,不论是系统重启时或者其他时候造成的文件系统只读,修改文件wq!都不能进行强制保存的时候,可以mount -o rw,remount /

nfs df -h卡住

当nfs服务关闭的情况下,客户端会出现df -h卡住的情况,这是因为挂载的时候会通过rpc呼叫导致,nfs服务关闭,rpc会持续进行呼叫,直到对方回复为止,只是默认参数hard导致的,可以使用相对的参数soft,在rpc超时后再重复呼叫,也可以在hard方式挂载,额外指定inir参数使rpc持续呼叫可以中断,可以通过-o指定soft或者inir

[root@why-2 ~]# cat /proc/mounts 
rootfs / rootfs rw 0 0
proc /proc proc rw,relatime 0 0
sysfs /sys sysfs rw,relatime 0 0
devtmpfs /dev devtmpfs rw,relatime,size=236904k,nr_inodes=59226,mode=755 0 0
devpts /dev/pts devpts rw,relatime,gid=5,mode=620,ptmxmode=000 0 0
tmpfs /dev/shm tmpfs rw,relatime 0 0
/dev/mapper/vg_redoop-LogVol01 / ext4 rw,relatime,barrier=1,data=ordered 0 0
/proc/bus/usb /proc/bus/usb usbfs rw,relatime 0 0
/dev/sda1 /boot ext4 rw,relatime,barrier=1,data=ordered 0 0
/dev/mapper/vg_redoop-LogVol02 /data ext4 rw,relatime,barrier=1,data=ordered 0 0
none /proc/sys/fs/binfmt_misc binfmt_misc rw,relatime 0 0
/dev/sr0 /mnt/os iso9660 ro,relatime 0 0
sunrpc /var/lib/nfs/rpc_pipefs rpc_pipefs rw,relatime 0 0
192.168.1.201:/data/ /mnt nfs4 rw,relatime,vers=4,rsize=65536,wsize=65536,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.202,minorversion=0,local_lock=none,addr=192.168.1.201 0 0

查看一下默认的挂载参数,另外rsize和wsize是读写的块大小,可以根据业务进行调整,不光是nfs,其他服务的挂载参数也可以通过这个调整

禁止执行权限测试

[root@why-2 ~]# mount -t nfs -o noexec,nosuid,nodev,rw 192.168.1.201:/data /nfs
[root@why-2 ~]# echo 'pwd' > /nfs/test.sh
[root@why-2 ~]# chmod +x !$
chmod +x /nfs/test.sh
[root@why-2 ~]# !$
/nfs/test.sh
-bash: /nfs/test.sh: Permission denied
[root@why-2 ~]# sh !$
sh /nfs/test.sh
/root

可以看到

挂载配置参数

mount -t nfs -o noexec,nosuid,nodev,noatime,nodiratime,rw,bg,hard,intr,rsize=131072,wsize=131072 192.168.1.201:/data /nfs 当然,每多加一个参数,性能就会有损耗,可以自行通过dd测试,简单点配置就是mount -t nfs -o noatime,rsize=131072,wsize=131072 192.168.1.201:/data /nfs

性能优化

[root@why-2 ~]# cat /proc/sys/net/core/rmem_default 接收套接字缓存区大小的缺省值
124928
[root@why-2 ~]# cat /proc/sys/net/core/rmem_max 接收套接字缓冲区大小的最大值
124928

官方建议值分别为8388608和16777216, 如果有写入的要求,可以同时修改wmem_defaultwmem_max

常见报错

rpcbind未启动

[root@why-2 ~]# showmount -e 192.168.1.201 clnt_create: RPC: Port mapper failure - Unable to receive: errno 111 (Connection refused)

rpcbind在nfs后启动

[root@why-2 ~]# showmount -e 192.168.1.201 clnt_create: RPC: Program not registered

nfs server端开启防火墙

[root@why-2 ~]# showmount -e 192.168.1.201 clnt_create: RPC: Port mapper failure - Unable to receive: errno 113 (No route to host)