avatar

3.NFS文件系统

NFS文件系统

第1章 NFS简介

NFS 是Network File System的缩写,中文称为网络文件系统,它的主要功能是通过网络(一个局域网)让不同的主机系统之间可以共享文件或目录,NFS的客户端(一般为应用服务器,例如web)可以通过挂载(mount)的方式将NFS服务器共享的数据目录挂载到NFS客户端本地系统中(就是某一个关在点下),从客户端本地看,NFS服务器端共享目录就好像是客户端自己的磁盘分区或者目录一样,而实际上却是远端的NFS服务器的目录。
NFS网络文件系统很像Windows系统的网络共享、安全功能、网络驱动器映射,这也和linux的samba服务类似,只不过一般情况下,Windows网络共享服务或samba服务用户办公局域网共享,而互联网中小型网站集群架构后端常用NFS进行数据共享,若是大型网站,那么有可能还会用到更复杂的分布式文件系统FastDFS,glusterfs,HDFS

缺点:

1:nfs属于本地文件系统,在高并发场景和大存储量下,需要使用分布式存储FastDFS,glusterfs,HDFS等。

2:客户端的数据都是通过明文传送。客户端没有用户认证机制,安全性能一般,所以建议一般在局域网内使用。

3:容易发生单点故障,即server服务器宕机所有的客户端都不能访问。

1.1 NFS应用场景

使用场景:web集群中NFS服务器主要用于存储用户上传的信息,方便集群中机器获取用户数据。如图片 附件 头像 视频 音频。

下面我将通过图解给大家展示集群需要共享存储服务的理由。

1.A 用户上传图片经过负载均衡,负载均衡将上传请求调度至 WEB1 服务器上。

2.B 用户访问 A 用户上传的图片,此时 B 用户被负载均衡调度至 WEB2 上,因为 WEB2 上没有这张图片,所以 B用户无法看到 A 用户传的图片

如果有共享存储的情况

1.A 用户上传图片无论被负载均衡调度至 WEB1 还是 WEB2, 最终数据都被写入至共享存储

2.B 用户访问 A 用户上传图片时,无论调度至 WEB1 还是 WEB2,最终都会上共享存储访问对应的文件,这样就可以访问到资源了

1.2 nfs存储工作原理实现

NFS工作原理

1.用户进程访问 NFS 客户端,使用不同的函数对数据进行处理

2.NFS 客户端通过 TCP/IP 的方式传递给 NFS 服务端

3.NFS 服务端接收到请求后,会先调用 portmap 进程进行端口映射。

4.nfsd 进程用于判断 NFS 客户端是否拥有权限连接 NFS 服务端。

5.Rpc.mount 进程判断客户端是否有对应的权限进行验证。

6.idmap 进程实现用户映射和压缩

7.最后 NFS 服务端会将对应请求的函数转换为本地能识别的命令,传递至内核,由内核驱动硬件。

注意: rpc 是一个远程过程调用,那么使用 nfs 必须有 rpc 服务

前提条件

1.nfs依赖于RPC服务来传递消息

2.NFS服务启动的端口号是随机的,启动之后会向本地的RCP注册

3.先启动RPC服务,再启动NFS服务

4.NFS和RPC之间的通讯是他们自己内部完成的,对于用户来说无感知

5.NFS客户端和服务端不会直接沟通,必须通过RPC服务传递消息

6.防火墙要开放RPC服务的端口

第2章 NFS服务的搭建

2.1部署前准备

操作系统 服务器角色 IP地址
CentOS 7.4 x86_64 NFS服务端(nfs-server) 内网:172.16.1.31/24
CentOS 7.4 x86_64 NFS客户端(nfs-client1) 内网:172.16.1.41/24

2.2 NFS服务端部署

2.2.1 服务端安装NFS

1
2
yum search nfs  #查看nfs服务的包名
yum -y install nfs-utils #安装nfs服务

2.2.2 配置参数

nfs 服务程序的配置文件为/etc/exports,需要严格按照共享目录的路径 允许访问的 NFS 客户端(共享权限参数)格式书写,定义要共享的目录与相应的权限,具体书写方式如下图所示

配置文件参数解释:
执行 man exports 命令,然后切换到文件结尾,可以快速查看如下样例格式:

1
2
3
4
5
6
7
8
9
10
11
nfs共享参数 参数作用
rw #读写权限
ro #只读权限
root_squash #当 NFS 客户端以 root 管理员访问时,映射为 NFS 服务器的匿名用户(不常用)
no_root_squash #当 NFS 客户端以 root 管理员访问时,映射为 NFS 服务器的 root 管理员(不常用)
all_squash #无论 NFS 客户端使用什么账户访问,均映射为 NFS 服务器的匿名用户(常用)
no_all_squash #无论 NFS 客户端使用什么账户访问,都不进行压缩
sync #同时将数据写入到内存与硬盘中,保证不丢失数据
async #优先将数据保存到内存,然后再写入硬盘;这样效率更高,但可能会丢失数据
anonuid #配置 all_squash 使用,指定 NFS 的用户 UID,必须存在系统
anongid #配置 all_squash 使用,指定 NFS 的用户 UID,必须存在系统

2.2.3 配置NFS服务端

写入配置文件:注意!IP地址和后面的小括号没有空格

1
2
3
cat > /etc/exports <<EOF
/data 172.16.1.0/24(rw,sync,all_squash) #这里是172.16.1.0网段
EOF

创建要共享的数据目录,并授权

1
2
mkdir /data
chown -R nfsnobody:nfsnobody /data/

2.2.4 启动NFS服务

1
2
systemctl start rpcbind nfs-server #注意先启动rpc服务
systemctl status rpcbind nfs-server #查看服务

2.2.5 检查nfs命令

1
2
3
# showmount -e 172.16.1.31
Export list for 172.16.1.31:
/data 172.16.1.0/24

2.2.6 加入开机自启动

​ 在使用 NFS 服务进行文件共享之前,需要使用 RPC(Remote Procedure Call 远程过程调用服务将 NFS 服务器的IP 地址和端口号信息发送给客户端。因此,在启动 NFS 服务之前,需要先重启并启用 rpcbind 服务程序,同时都加入开机自启动

1
2
systemctl enable rpcbind nfs-server
systemctl restart rpcbind nfs-server

2.3 客户端挂载

客户端安装nfs服务十分简单,只需要安装nfs软件包即可

1
yum -y install nfs-utils rpcbind

客户端安装完成后只需要启动rpcbind,不需要启动nfs

1
2
systemctl restart rpcbind
systemctl enable rpcbind

客户端使用命令查看nfs共享信息

1
2
3
# showmount -e 172.16.1.31
Export list for 172.16.1.31:
/data 172.16.1.0/24

客户端挂载 : 创建挂载目录
在 NFS 客户端创建一个挂载目录, 使用 mount 命令并结合-t 参数, 指定要挂载的文件系统的类型, 并在命令后面写上服务器的 IP 地址, 以及服务器上的共享目录, 最后需要写上要挂载到本地系统(客户端)的目录

1
2
mkdir /data
mount -t nfs 172.16.1.31:/data /data/

挂载完成后查看是否挂载成功?

1
2
# df -h
172.16.1.31:/data 39G 2.8G 37G 8% /data

卸载命令:注意!卸载的时候如果提示”umount.nfs: /nfsdir: device is busy”先切换到其他目录再卸载

1
2
# umount /data/
# umount -rl /data/ #强制卸载

2.4 测试NFS

客户端41在挂载目录创建文件

1
2
3
# touch oldboy.txt && echo 123 >oldboy.txt 
# cat oldboy.txt
123

NFS服务器端查看

1
2
3
[root@nfs /data]# ls -l
total 4
-rw-r--r-- 1 nfsnobody nfsnobody 4 Jul 18 16:56 oldboy.txt

客户端41写入开机自动挂载

1
2
3
4
# vim /etc/fstab
# tail -1 /etc/fstab
172.16.1.31:/data /data nfs defaults 0 0
# mount -a

2.5 NFS 权限验证

2.5.1 验证ro权限

服务器端配置

1
2
3
4
5
6
# cat /etc/exports
/data 172.16.1.0/24(ro,sync,all_squash)
# systemctl restart rpcbind nfs-server
# showmount -e 172.16.1.31
Export list for 172.16.1.31:
/data 172.16.1.0/24

客户端挂载

1
2
3
# mount -t nfs 172.16.1.31:/data /data
# df -h
172.16.1.31:/data 39G 2.8G 37G 8% /data

客户端测试读取权限:

1
2
# cat /data/oldboy.txt 
123

客户端测试写入权限:(没有权限)

1
2
# echo 456 >> /data/oldboy.txt 
-bash: /data/oldboy.txt: Read-only file system

2.5.2 验证all_squash、 anonuid、 anongid 权限

服务器端配置

1
2
# cat /etc/exports
/data 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)

服务端创建用户及授权:

1
2
3
4
# groupadd -g 666 www
# useradd -u 666 -g 666 -s /sbin/nologin -M www
# id www
uid=666(www) gid=666(www) groups=666(www)

重启NFS服务

1
# systemctl restart rpcbind nfs-server

服务器端更改目录属主、属组

1
2
3
# chown -R www.www /data
# ll -d /data/
drwxr-xr-x 2 www www 24 Jul 18 11:52 /data/

客户端创建用户www

1
2
3
4
# groupadd -g 666 www
# useradd -u 666 -g 666 -s /sbin/nologin -M www
# id www
uid=666(www) gid=666(www) groups=666(www)

客户端挂载测试

1
2
3
# mount -t nfs 172.16.1.31:/data /data
# ll -d /data
drwxr-xr-x 2 www www 24 Jul 18 11:52 /data

注意:创建用户前,先创建组(666),然后再创建用户www(666),否则会出现属主、属组不同的情况

第3章查看nfs端口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 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
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 37349 nlockmgr
100021 3 udp 37349 nlockmgr
100021 4 udp 37349 nlockmgr
100021 1 tcp 39255 nlockmgr
100021 3 tcp 39255 nlockmgr
100021 4 tcp 39255 nlockmgr

工作中防火墙配置

1
2
3
4
firewall-cmd --add-service=nfs --permanent
firewall-cmd --add-service=mountd --permanent
firewall-cmd --add-service=rpc-bind --permanent
firewall-cmd --reload

NFS故障案例

​ 在生产环境中,对于共享的NFS目录,一般不会配置到/etc/fstab里。因为在客户端主机重启时如果由于网络等原因连接不上nfs server时,就会导致客户机无法启动的厄运发生。一般是通过把mount -t nfs 172.16.1.31:/data /data命令放到rc.local中来实现开机自动挂载NFS。

如果设置了开机自启动,但是系统启动的时候NFS并没有提供服务,就会导致开机自检的时候卡在挂在那一步

1
2
3
4
开机启动时添加rd.break
ctrl+x
mount -o remount,rw /sysroot/
chroot /sysroot/

第4章 NFS小结

NFS 存储优点
1.NFS 文件系统简单易用、方便部署、数据可靠、服务稳定、满足中小企业需求。
2.NFS 文件系统内存放的数据都在文件系统之上,所有数据都是能看得见
NFS 存储局限
1.存在单点故障, 如果构建高可用维护麻烦 web->nfs()->backup
2.NFS 数据明文, 并不对数据做任何校验。
3.客户端挂载 NFS 服务没有密码验证, 安全性一般(内网使用)
NFS 应用建议
1.生产场景应将静态数据尽可能往前端推, 减少后端存储压力
2.必须将存储里的静态资源通过 CDN 缓存 jpg\png\mp4\avi\css\js
3.如果没有缓存或架构本身历史遗留问题太大, 在多存储也无用

第5章 项目实战

5.1 项目需求

准备 3 台虚拟机服务器,并且请按照要求搭建配置 NFS 服务。
NFS 服务端(A nfs-31)
NFS 客户端(B backup-41)
NFS 客户端(C nfs-42)
1.在 NFS 服务端(A)上共享/data/rw(读写)给客户端B及/data/r(只读)给客户端C
2.在 NFS 客户端(B/C)上进行挂载测试

环境准备

操作系统 服务器角色 IP地址
CentOS 7.4 x86_64 NFS服务端(nfs-server) 内网:172.16.1.31/24
CentOS 7.4 x86_64 NFS客户端(nfs-client1) 内网:172.16.1.41/24
CentOS 7.4 x86_64 NFS客户端(nfs-client2) 内网:172.16.1.42/24

5.2 服务端配置

服务器端创建www用户和组,并指定/data目录的属性

1
2
3
4
5
6
7
# groupadd -g 666 www
# useradd -u 666 -g 666 -s /sbin/nologin -M www
# id www
uid=666(www) gid=666(www) groups=666(www)
# chown -R www.www /data
# ll -d /data/
drwxr-xr-x 2 www www 24 Jul 18 11:52 /data/

修改配置文件

1
2
3
4
# cat /etc/exports
/data 172.16.1.0/24(rw,sync,all_squash) #注意:这里不指定用户uid和gid,否则权限会失效
/data 172.16.1.41/24(rw,sync,all_squash,anonuid=666,anongid=666)
/data 172.16.1.42/24(ro,sync,all_squash,anonuid=666,anongid=666)

重启服务及查看nfs信息

1
2
3
4
# systemctl restart rpcbind nfs-server  #重启服务
# showmount -e 172.16.1.31 #查看nfs共享信息
Export list for 172.16.1.31:
/data 172.16.1.42/24,172.16.1.41/24,172.16.1.0/24

5.3 客户端挂载测试

5.3.1 客户端B (backup-41)

重启rpc服务,并写入开机自启

1
2
systemctl restart rpcbind
systemctl enable rpcbind

创建挂载目录,并挂载

1
2
3
4
# mkdir /data
# mount -t nfs 172.16.1.31:/data /data
# df -h
172.16.1.31:/data 39G 2.8G 37G 8% /data

测试读写权限

1
2
3
4
5
6
7
# echo 123456 >test.txt   #客户端B写入文件,并读取
# cat test.txt
123456
# ll /data/ #服务器端可以看到文件
total 8
-rw-r--r-- 1 www www 4 Jul 18 16:56 oldboy.txt
-rw-r--r-- 1 www www 7 Jul 18 18:29 test.txt

5.3.2 客户端B(nfs-42)

安装nfs服务

1
# yum -y install nfs-utils

重启rpc命令

1
2
# systemctl restart rpcbind
# systemctl enable rpcbind #写入开机自启

创建用户www和组

1
2
3
4
# groupadd -g 666 www
# useradd -u 666 -g 666 -s /sbin/nologin -M www
# id www
uid=666(www) gid=666(www) groups=666(www)

创建挂载目录,并授权

1
2
3
4
# mkdir /data
# chown -R www.www /data
# ll -d /data/
drwxr-xr-x 2 www www 6 Jul 19 02:41 /data/

挂载目录

1
2
3
# mount -t nfs 172.16.1.31:/data /data
# df -h
172.16.1.31:/data 39G 2.8G 37G 8% /data

测试只读权限

1
2
3
4
5
6
# cat test.txt  #可以查看文件内容
123456
# echo abc >>test.txt #不能写入内容到文件
-bash: test.txt: Permission denied
# touch nfs.txt #不能创建文件
touch: cannot touch ‘nfs.txt’: Permission denied
文章作者: Wu Fei
文章链接: http://linuxwf.com/2020/04/13/3-NFS%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 WF's Blog
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论