每天学五分钟 Liunx 111 | 存储篇:NFS


NFS

NFS(Network File System,网络文件系统),它可以通过网络让不同操作系统,不同机器共享彼此的文件。
NFS 分为服务端和客户端。服务端提供共享的文件目录,客户端将该目录挂载到本地目录,从客户端上看,相当于是将磁盘分区挂载到目录,非常便利。

NFS 工作原理

 
 
NFS 工作原理如上图所示。其中,RPC 服务是 Remote Process Call 远程过程调用服务,它的出现主要是为了解决 NFS 端口无法固定的问题。由于文件系统非常复杂,NFS 中不同程序对应不同的功能,每个程序开启相应的功能会随机启用额外的端口。但是对于客户端来说,随机取用的端口,客户端无法获取到,所以就需要 RPC 服务作为“中介”,NFS 服务每次启用的端口信息,都会到 RPC 中注册(所以启动 NFS 服务之前要先确保 RPC 服务已经启动了)。同时,RPC 会提供一个固定的外部端口 111 供外部机器访问。这样客户端有 NFS 请求,服务端会通过 RPC 服务将 NFS 的端口信息告知客户端,从而实现客户端和服务端 NFS 的连接和数据传输。
 
 
NFS 的工作流程:
1. NFS 服务器端会启动 RPC 服务(portmap),并开启 111 端口。
2. NFS 服务器端再启动 NFS 服务,服务启动后向 RPC 服务注册端口信息。
3. 客户端启动 RPC 服务,向服务端的 RPC 服务请求服务端的 NFS 端口信息。
4. 服务端的 RPC 服务将端口信息发给客户端的 RPC 服务。
5. 客户端通过获取到的端口信息建议和服务端 NFS 的连接和数据的传输。
 
 

NFS 部署

NFS 程序

NFS 程序主要有 RPC 主程序 rpcbind 和 NFS 主程序 nfs-utils。
rpcbind: 如前所述,负责 port mapping 的工作。
nfs-utils: NFS 主程序,包含 rpc.nfsd / rpc.mount / rpc.locked / rpc.statd 等几个 damones 。
[root@test home]# ps -ef | egrep "rpc|nfs"
root         487       2  0 Mar21 ?        00:00:00 [rpciod]
rpc        65293       1  0 Mar21 ?        00:00:00 /sbin/rpcbind -w
rpcuser    76183       1  0 Mar21 ?        00:00:00 /usr/sbin/rpc.statd --no-notify
root      152992  567813  0 18:43 pts/0    00:00:00 grep -E --color=auto rpc|nfs
root      757265       1  0 17:08 ?        00:00:00 /usr/sbin/rpc.idmapd
root      757267       1  0 17:08 ?        00:00:00 /usr/sbin/rpc.mountd
root      757272       2  0 17:08 ?        00:00:00 [nfsd4_callbacks]
root      757278       2  0 17:08 ?        00:00:00 [nfsd]
root      757279       2  0 17:08 ?        00:00:00 [nfsd]
root      757280       2  0 17:08 ?        00:00:00 [nfsd]
root      757281       2  0 17:08 ?        00:00:00 [nfsd]
root      757282       2  0 17:08 ?        00:00:00 [nfsd]
root      757283       2  0 17:08 ?        00:00:00 [nfsd]
root      757284       2  0 17:08 ?        00:00:00 [nfsd]
root      757285       2  0 17:08 ?        00:00:00 [nfsd]
每个 damones 负责的功能如下:
rpc.nfsd:管理客户端是否能使用服务端文件系统。包括判断用户登录 ID 等。
rpc.mountd:管理 NFS 文件系统。当客户端通过 rpc.nfsd 登入主机之后,rpc.mountd 通过读取 NFS 配置文件 /etc/exports 对客户端进行权限认证。当权限认证通过后,客户端即可以访问服务端文件系统。
rpc.locked:管理文件锁定问题。当多个用户读写同一份文件时可能会对文件造成一些问题,rpc.locked 即对文件进行保护,从而避免出现这样的问题,它是可选的。
rpc.statd:管理文件一致性问题。当多个用户同时使用文件造成文件损坏时,rpc.statd 可以检测并且尝试恢复该文件。
 

NFS 配置文件

NFS 的主要配置文件是 /etc/exports 文件。它的格式是   #共享目录 [客户端地址1(权限)] [客户端地址2(权限)] ...   其中,共享目录是服务端要共享给客户端的目录。客户端地址是可以建立 NFS 连接的客户端地址,可以是 ip ,可以是 cidr ,也可以是主机名 (前提是在 /etc/hosts 或者通过 DNS 可以查询到)。权限是客户端用户访问服务端文件系统所具有的权限,它包含以下几个参数:
参数命令
参数作用
rw
可读写
ro
只读权限
sync
请求或写入数据时,数据会同步写入到服务端硬盘,再返回
no_root_squas
对于客户端用户 root 不压缩。即客户端 root 可以以 root 身份来访问文件
root_squash
对客户端用户 root 压缩,将 root 身份压缩为 nobody
all_squash
对客户端所用用户压缩,默认将用户身份压缩为用户 nobody 和用户组 nobody。
可指定压缩用户的身份,但是需要客户端和服务端都有该用户,否则无法访问
anonuid
匿名的 uid,说明客户端以什么用户来访问服务端文件系统
anongid
匿名的 gid,说明客户端以什么用户组来访问服务端文件系统
 
举例:
/home/test 10.57.0.0/24(rw,sync,all_squash,anonuid=4300,anongid=4300),指 在 cidr 10.57.0.0/24 内的客户端主机,能够以 uid/gid 4300 的用户身份通过读写方式访问服务端 /home/test 目录。
 
NFS 还有两个文件是 /var/lib/nfs/etab 和 /var/lib/nfs/rmtab 。 etab 文件记录了 NFS 共享的文件目录的完整权限设定值。 rmtab 文件记录了共享目录被挂载情况。
 

NFS 命令

rpcinfo: 输出 RPC 记录的信息。
exportfs: 维护 NFS 文件系统表。通过 exportfs 命令可重新分享 /etc/exports 文件的目录,该命令用在服务端。
showmount:查看 NFS server 共享的目录资源,该命令主要用在客户端。
 

NFS 配置实例

配置 NFS 使得 cidr 10.57.0.0/24 内的客户端主机,能够以 uid/gid 4300 的用户身份通过读写方式访问服务端 /home/test 目录。
 
配置步骤如下:
1. 服务端,客户端安装 rpcbind 和 nfs-utils。
2. 启动 rpcbind 服务,启动 nfs 服务。
3. 服务端配置 /etc/exports 文件:/home/test 10.57.0.0/24(rw,sync,all_squash,anonuid=4300,anongid=4300)
4. 服务端关闭 iptables。关闭 iptables 是因为 NFS 随机开启的端口信息并不会写入到 iptables 中,所以需要手动写入(关于 iptables 可看这里),这里暴力一点直接将 iptables 关掉。SELiunx 有开的,可以将 SELiunx 关闭。
5. 客户端挂载服务端共享目录。
6. 新建文件测试是否配置是否生效。
 
1. 服务端,客户端安装 rpcbind 和 nfs-utils:
[root@test home]# rpm -qa | egrep "rpc|nfs"
libnfsidmap-0.25-15.el7.x86_64
rpcbind-0.2.0-38.el7.x86_64
libtirpc-0.2.4-0.8.el7.x86_64
nfs-utils-1.3.0-0.33.el7.x86_64
xmlrpc-c-1.32.5-1905.svn2451.el7.x86_64
xmlrpc-c-client-1.32.5-1905.svn2451.el7.x86_64
已经安装好了,没安装的可通过 yum install rpcbind nfs-utils 命令安装。
 
2. 启动 rpcbind 服务,启动 nfs 服务:
[root@test home]# systemctl start rpcbind
[root@test home]# systemctl start nfs
 
[root@test test]# 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  55860  status
    100024    1   tcp  49019  status
    100005    1   udp  20048  mountd
    100005    1   tcp  20048  mountd
    100005    2   udp  20048  mountd
    100005    2   tcp  20048  mountd
    100005    3   udp  20048  mountd
    100005    3   tcp  20048  mountd
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100227    3   tcp   2049  nfs_acl
    100003    3   udp   2049  nfs
    100003    4   udp   2049  nfs
    100227    3   udp   2049  nfs_acl
    100021    1   udp  36125  nlockmgr
    100021    3   udp  36125  nlockmgr
    100021    4   udp  36125  nlockmgr
    100021    1   tcp  42363  nlockmgr
    100021    3   tcp  42363  nlockmgr
    100021    4   tcp  42363  nlockmgr
 
3. 服务端配置 /etc/exports 文件:
服务端:
[root@test test]# cat /etc/passwd | grep 4300
[root@test test]# cat /etc/group | grep 4300
[root@test test]# groupadd -g 4300 lianhuasheng
[root@test test]# useradd -u 4300 -g 4300 lianhuasheng
[root@test test]# cat /etc/passwd | grep lianhuasheng
lianhuasheng:x:4300:4300::/home/lianhuasheng:/bin/bash
 
[root@test home]# cat /etc/exports | grep 4300
/home/test 10.57.0.0/24(rw,sync,all_squash,anonuid=4300,anongid=4300)
 
[root@test home]# systemctl restart nfs
 
客户端:
[root@test test]# cat /etc/passwd | grep 4300
[root@test test]# cat /etc/group | grep 4300
[root@test test]# groupadd -g 4300 lianhuasheng
[root@test test]# useradd -u 4300 -g 4300 lianhuasheng
[root@test test]# cat /etc/passwd | grep lianhuasheng
lianhuasheng:x:4300:4300::/home/lianhuasheng:/bin/bash
 
如参数一节所述,服务端和客户端都需要配置相同的 uid 和 gid。同时,在重新写 exports 文件后,需要重启 nfs 服务使配置生效。
 
4. 关闭 iptables:
[root@test test]# systemctl stop iptables
 
5. 客户端挂载服务端共享目录:
[root@test lianhuasheng]# showmount -e 10.57.0.1
Export list for 10.57.0.1:
/home/test 10.57.0.0/24
[root@test test]# mount -t nfs 10.57.0.1:/home/test  /home/test/lianhuasheng/
[root@test home]# df -hT | grep lianhuasheng
10.57.0.1:/home/test nfs4      895G  849G   46G  95% /home/test/lianhuasheng
 
6. 新建文件测试是否配置是否生效:
客户端:
[root@test lianhuasheng]# touch nfs.log
[root@test lianhuasheng]# ll
total 0
-rw-r--r--. 1 lianhuasheng lianhuasheng 0 Mar 22 17:10 nfs.log
 
服务端:
[root@test test]# ll -h
total 0
-rw-r--r--. 1 lianhuasheng lianhuasheng 0 Mar 22 17:10 nfs.log
 
客户端以 root 身份创建文件 nfs.log,文件所属用户和用户组被修改为 4300 对应的用户 lianhuasheng。服务端查看该文件所属用户和用户组为 lianhuasheng。
 

NFS Troubleshooting

1. 挂载出现 error:clnt_create: RPC: Port mapper failure - Unable to receive: errno 113 (No route to host)
出现这种 error 是由于客户端无法访问到服务端。可通过两种方式解决:
  • 暴力一点直接将 iptables 服务关闭。
  • 固定 NFS 端口,将端口信息写入 iptables 中,重启 iptables 服务。
参考连接见这里:  
 
2. umount 文件时出现 error:umount:/mnt:target is busy
出现这个 error 时当前磁盘正在使用。可通过 lsof 命令 show 出使用该挂载目录的 PID:
[root@test lianhuasheng]# lsof /home/test/lianhuasheng/
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF       NODE NAME
lsof    407987 root  cwd    DIR  0,549       21 1325440613 /home/test/lianhuasheng (10.57.0.1:/home/test)
lsof    407988 root  cwd    DIR  0,549       21 1325440613 /home/test/lianhuasheng (10.57.0.1:/home/test)
bash    682732 root  cwd    DIR  0,549       21 1325440613 /home/test/lianhuasheng (10.57.0.1:/home/test)
然后将此 PID kill 掉,重新 umount。
 
 
 (完)

猜你喜欢

转载自www.cnblogs.com/xingzheanan/p/12549537.html
111