NFS 使用指南

简介: 今天来讲讲关于 NFS 的一些知识(主要是我学习的一些笔记,就当现学现卖了)

今天来讲讲关于 NFS 的一些知识(主要是我学习的一些笔记,就当现学现卖了!)

当然了,我的水平是有限的,可能会有一些理解错的的概念 or 知识点,还请大家不吝在评论区指正

本篇文章脑图如下:

image.png
相关文档:

http://www.tldp.org/HOWTO/NFS-HOWTO/index.html

http://cn.linux.vbird.org/linux_server/0330nfs.php#What_NFS_0

初识NFS

  • 什么是NFS?

NFS(Network File System)——网络文件系统

最大的功能就是可以通过网络,让不同的机器不同的操作系统可以共享彼此的文件或目录

所以可以简单的将其看作是一个文件服务器

NFS client 可以将 NFS server 共享的目录挂载到本地的文件系统中,从 client 来看,server 的目录就好像是自己的一个磁盘分区一样
image-20221009142532260.png

  • NFS优点

    • 节省本地存储空间,将常用的数据放在一台可以通过网络访问的服务器上
    • 部署简单快捷,容易上手
    • 维护简单
  • NFS缺点

    • 容易发生单点故障,一旦 server 宕机,那么所有 client 都不能访问到
    • 高并发情况下容易出现性能瓶颈(server 能力有限)
    • NFS 数据是明文传输,而且对数据完整性不做验证,所以安全性较差(一般建议在局域网内使用)

1.RPC远程调度

NFS 支持的功能非常多,且不同的功能都会去使用不同的程序来启动

每启动一个程序就会调用一个端口来进行数据传输,而且 NFS 功能调用的端口并不固定,是随机的

既然是随机端口,NFS client 又是如何知道 NFS server 到底是使用哪个端口进行文件共享的呢?

这时候就需要通过远程过程调用(Remote Procedure Call, RPC)协议来实现了!

  • 什么是RPC协议?

RPC(Remote Procedure Call)即远程过程调用。

RPC统一对外端口是111,主要的功能就是记录每个 NFS 功能所对应的端口 ,并且通知给客户端,让客户端可以连接到正确的端口上去

  • 那么RPC又是如何知道每个 NFS 功能的端口呢?

当 NFS 服务启动时会启用一些随机的端口,然后 NFS 就会向 RPC 去注册这些端口,RPC 就记录下这些端口

且 RPC 开启111端口去等待客户端请求,如果客户端有请求,那么 RPC 就会这些之前记录的 NFS 端口信息通知给客户端

此客户端就会获取 NFS 服务器端的端口信息,就会以实际端口进行数据的传输了

PS:

在启动 NFS server 之前首先要启动 RPC 服务(portmap 服务)否则 NFS server 就无法向 RPC 服务去注册

如果 RPC 服务重启,原来已经注册好的 NFS 端口数据会全部丢失,因此 NFS 服务也要重启以便重新向 RPC 注册

一般修改 NFS 配置文档后,是不需要重启 NFS 的,直接执行 exportfs -r -v 即可

  • NFS 启动的 RPC daemons

我们现在知道 NFS 服务器在启动的时候就得要向 RPC 注册,所以 NFS 服务器也被称为 RPC server 之一。 那么 NFS 服务器主要的任务是进行文件系统的分享,文件系统的分享则与权限有关。 所以 NFS 服务器启动时至少需要两个 daemons ,一个管理客户端是否能够登入的问题, 一个管理客户端能够取得的权限

rpc.nfsd

最主要的 NFS 服务器服务提供者,主要功能就是管理客户端是否能够使用服务器文件系统挂载信息

rpc.mountd

负责管理 NFS 的文件系统,当客户端通过 rpc.nfsd 登录到服务器后,在它可以使用 NFS server 的共享目录之前,还会经过共享目录的权限的认证

该进程会去读取 NFS 的配置文件( /etc/exports )来对比客户端的权限

rpc.lockd (非必要)

负责给共享目录加锁,当多个客户端同时尝试写入某个共享文件时,就会出现问题

rpc.lockd 可以解决这个问题,但 rpc.lockd 必须要同时在客户端与服务器端都开启才行。此外, rpc.lockd 也常与 rpc.statd 同时启用

rpc.statd (非必要)

负责检查共享文件的一致性,与 rpc.lockd 有关

若发生因为客户端同时使用同一档案造成档案可能有所损毁时, rpc.statd 可以用来检测并尝试回复该档案。与 rpc.lockd 同样的,这个功能必须要在服务器端与客户端都启动才会生效

2.NFS 工作过程

image-20221009143859373.png

  • 首先服务器端启动 RPC 服务,并开启 111 端口
  • 服务器端启动 NFS 服务,并向 RPC 注册端口信息
  • 客户端启动RPC(portmap服务),向服务端的 RPC (portmap) 服务请求服务端的NFS端口
  • 服务端的 RPC(portmap) 服务返回 NFS 端口信息给客户端。
  • 客户端通过获取的 NFS 端口来建立和服务端的 NFS 连接并进行数据的传输

3.NFS 权限

不知道你有没有想过这个问题,假如 client 以 user1 这个身份去对 NFS server 提供的共享目录进行操作时,NFS server 提供的共享目录会让 client 以什么身份去操作,user1还是其他?

这是因为 NFS 服务是没有身份识别的,所以说当 client 以 user1 的身份对共享目录进行操作时, server 会以 client 当前用户(即 user1)的 UID 和 GID 等身份来尝试操作 server 的共享目录(即系统不识别用户名字,只识别用户对应的 UID 和 GID)

这时就会有一个问题产生:如果 client 与 server 的使用者身份并不一致怎么办?

当 client 以 user1 这个一般身份去操作来自 server 的共享目录时,首先要注意到的是——文件系统的 innode 所记录的属性为 UID、GID 而非账号名和群组命

一般 Linux 系统会主动的以自己的 /etc/passwd, /etc/group 来查询对应的账号名、组名。

所以当 user1 首先会参照 client 的账号名和组名(假设 user1 的 UID 是666),但是由于该共享目录来自 server端,所以就可能会发生以下情况:

  • NFS server/NFS client 刚好有相同的账号与群组(即 server 端 UID 为 666 的用户为 user1)

    • 此时 client 可以直接以 user1 的身份对共享目录进行操作
  • NFS server 的 666 这个 UID 账号对应为 test

    • 如果 NFS server 上 UID 为 666 的用户为 test 时,则 client 的 user1 用户可以直接操作 test 用户的共享目录
    • 因为这两个用户具有相同的 UID
    • 这就造成很大的问题了!因为没有人可以保证 client 的 UID 所对应的账号会与 server 相同, 那 server 所提供的数据不就可能会被错误的用户乱改
    • NFS server 没有 666 这个 UID

      • 在 server 端并没有666这个 UID,那么 user1在该共享目录下会被压缩成匿名用户
      • 一般 NFS 的匿名用户会以 UID 为 65534 为其使用者
      • 但有时也会有特殊的情况,例如在服务器端分享 /tmp 的情况下, user1 的身份还是会保持 666 但创建的数据在服务端来看,就会属于 nobody
  • root 用户

    • 想一想,如果 client 用 root 的身份去操作服务器端的文件系统时,那 server 的数据还有什么保护性? 所以在预设的情况下, root 的身份会被主动的压缩成为匿名者

总的来讲,client 的权限是与 UID 和 GID 相关的,当 client 与 server 的 UID 对应的用户不一致时,就有可能造成一些问题

NFS配置权限设置,即/etc/exports文件配置格式中小括号()里的参数集

参数 说明
ro 只读访问
rw 读写访问
sync 同步传输数据,读写数据时,数据同步到 NFS server硬盘后才返回
async 异步传输数据,写入数据时会先写到内存缓存区
secure nfs 通过 1024 以下的安全 TCP/IP 端口发送
insecure nfs 通过 1024 以上的端口发送
wdelay 如果多个用户要写入 nfs 目录,则归组写入(默认)
no_wdelay 如果多个用户要写入 nfs 目录,则立即写入,当使用 async 时,无需此设置
hide 在 nfs 共享目录中不共享其子目录
no_hide 共享 nfs 目录的子目录
subtree_check 如果共享 /usr/bin 之类的子目录时,强制 nfs 检查父目录的权限(默认)
no_subtree_check 不检查父目录权限
all_squash 共享文件的 UID 和 GID 映射匿名用户 anonymous,适合公用目录
no_all_squash 保留共享文件的 UID 和 GID(默认)
root_squash root 用户的所有请求映射成如 anonymous 用户一样的权限(默认)
no_root_squash root 用户具有根目录的完全管理访问权限
anonuid=xxx 指定 nfs 服务器 /etc/passwd 文件中匿名用户的 UID
anongid=xxx 指定 nfs 服务器 /etc/passwd 文件中匿名用户的 GID

4.NFS 相关文件

主要配置文件:/etc/exports

NFS的配置文件,可能必须要使用 vim 主动的建立起这个文件

NFS 文件系统维护指令:/usr/sbin/exportfs

维护 NFS 共享资源的命令,可以对共享资源进行更新、卸载等

共享资源的登录文件:/var/lib/nfs/*tab

在 NFS server的登录文件都放置到 /var/lib/nfs/ 目录里面,在该目录下有两个比较重要的登录文件

一个是 etab ,主要记录了 NFS 所共享出来的目录的完整权限设定值;

另一个 xtab 则记录曾经连接到此 NFS 服务器的相关客户端数据

客户端查询服务器分享资源的指令:/usr/sbin/showmount

showmount 则主要用在 Client 端, 可以用来查看 NFS server 共享出来的目录资源

NFS 案例

有两台 web 服务器通过 NFS 将后端存储服务器的数据挂载到本地

用户去访问 web 服务器上的资源,其实访问的是后端存储服务器的资源

架构图如下:

image-20221009144613306.png

  • web1:192.168.149.130
  • web2:192.168.149.131
  • NFS server:192.168.149.129

1.NFS server

安装 NFS、RPC 服务

[root@server ~]# yum install -y nfs-utils rpcbind

创建共享目录作为客户端挂载的远端入口

[root@server ~]# mkdir /data/{web1,web2} -pv 

修改 NFS 配置文件

[root@server ~]# vim /etc/exports
/data/web1  192.168.149.130(rw,sync,insecure,no_subtree_check,no_root_squash)
/data/web2  192.168.149.131(rw,sync,insecure,no_subtree_check,no_root_squash)
一般修改 NFS 配置文档后,是不需要重启 NFS 的,直接执行 exportfs -r -v 即可

启动 rpc 服务

[root@server ~]# systemctl start rpcbind.service

注意:此时我们还没有启动 NFS 服务,只监听了 111 端口,接着我们来启动 NFS 服务

[root@server ~]# systemctl start nfs.service

启动了 NFS 服务后,rpc 注册的端口列表明显增多。现在服务端都启动起来了,在服务端看下是否正确加载了设置的 /etc/exports 配置

[root@server ~]# showmount -e localhost
Export list for localhost:
/data/web2 192.168.149.131
/data/web1 192.168.149.130

接着我们在共享目录下存放web资源

[root@server ~]# cat /data/web1/test.html 
<h1> I am NFS server</h1>
<h2> This is web1 </h2>
[root@server ~]# cat /data/web2/test.html 
<h1> I am NFS server</h1>
<h2> This is web2 </h2>

2.NFS client

安装nginx提供web服务

yum install epel-release -y
yum install -y nginx

安装 nfs 服务

yum install -y nfs-utils

nginx配置

#web1
vim /etc/nginx/conf.d/web.conf
server{
        listen 8080;
        root         /mnt/html/;
        index test.html;
}

#web2
vim /etc/nginx/conf.d/web.conf
server{
        listen 8080;
        root         /mnt/html/;
        index test.html;
}

web1、web2 分别创建挂载目录

mkdir /mnt/html/

我们可以在客户端查看下 NFS server ( IP 为:192.168.149.129 ) 设置可共享的目录信息

[root@web1 ~]# showmount -e 192.168.149.129
Export list for 192.168.149.129:
/data/web2 192.168.149.131
/data/web1 192.168.149.130
[root@web2 ~]# showmount -e 192.168.149.129
Export list for 192.168.149.129:
/data/web2 192.168.149.131
/data/web1 192.168.149.130

web1挂载 NFS server 的 /data/web1 共享目录

[root@web1 ~]# mount -t nfs 192.168.149.129:/data/web1 /mnt/html

[root@web1 ~]# df -Th
文件系统                   类型      容量  已用  可用 已用% 挂载点
192.168.149.129:/data/web1 nfs4       17G  2.1G   15G   12% /mnt/html

web2挂载 NFS server 的 /data/web2 共享目录

[root@web2 ~]# mount -t nfs 192.168.149.129:/data/web2 /mnt/html

[root@web2 ~]# df -Th
文件系统                   类型      容量  已用  可用 已用% 挂载点
192.168.149.129:/data/web2 nfs4       17G  2.1G   15G   12% /mnt/html

3.验证

我们分别访问web1、web2,看下是否能够正确读取并修改

[root@server ~]# curl 192.168.149.131:8080
<h1> I am NFS server</h1>
<h2> This is web2 </h2>


[root@server ~]# curl 192.168.149.130:8080
<h1> I am NFS server</h1>
<h2> This is web1 </h2>
[root@web1 ~]# echo "hello" >> /mnt/html/test.html

#在 NFS server 上查看,可以看到成功修改了
[root@server ~]# cat /data/web1/test.html 
<h1> I am NFS server</h1>
<h2> This is web1 </h2>
hello

最后,如果客户端要卸载 NFS 挂载的话,使用如下命令即可

umount /mnt/html

[鸟哥的 Linux 私房菜 -- NFS 服务器 (vbird.org)](

相关文章
|
存储 数据安全/隐私保护
|
3月前
|
存储 安全 API
NFS 的版本
【10月更文挑战第13天】
231 62
|
4月前
cephFS客户端使用指南
关于如何手动和自动挂载cephFS客户端的详细指南,包括移除认证文件、创建用户、导出钥匙环和key文件、挂载cephFS、验证用户权限以及设置开机自动挂载的三种方法。
213 7
|
8月前
|
运维 Linux
NFS配置实战
NFS配置实战
185 2
|
存储 弹性计算 文件存储
阿里云文件系统SMB访问协议服务及使用指南
阿里云于2016年发布了支持NFS网络文件系统访问协议的阿里云文件系统。2017年3月,又增加了SMB文件系统访问协议的支持,正式对外公测。2018年1月,阿里云NAS SMB支持正式提供商业化服务。本文简单描述了SMB文件系统访问协议以及阿里云NAS支持的SMB协议功能,并简单介绍了该服务的使用场景以及使用流程。
6480 0
|
开发工具
NFS搭建
NFS环境搭建
200 0
|
Linux 网络安全 数据安全/隐私保护
Linux环境下NFS服务的安装与配置
一、几个概念 NFS 就是 Network File System 的缩写,最早是由 Sun 这家公司所发展出来的。
2104 0