1 什么是NFS?

NFS是Networ File System的缩写,即网络文件系统。一种使用于分散式文件系统的协定,由 Sun 公司开发,于1984年向外公布。功能是通过网络让不同的机器、不同的操作系统能够彼此分享个别的数据,让应用程序在客户端通过网络访问位于服务器磁盘中的数据,是在类Unix系统间实现磁盘文件共享的一种方法。

NFS 与Samba 的对比:

  • Samba 使用的 smb / cifs 协议,NFS 使用的 NFS协议。两者不能串联使用
  • Samba 和 NFS 均可以实现共享目录的挂载,Samba的挂载主要实现跨平台挂载,NFS的挂载主要在Linux 和 类Unix实现
  • NFS 比 Samba 拥有更加详细的访问控制

image.png
它的主要功能是通过网络让不同的机器系统之间可以彼此共享文件和目录。NFS服务器可以允许NPS客户端将远端NFS服务器端的共享目录挂载到本地的NFS客户端中。在本地的NFS客户端的机器看来,NFS 服务器端共享的目录就好像自己的磁盘分区和目录一样。一般客户端挂载到本地目录的名字可以随便,但为方便管理,我们要和服务器端一样比较好。
NFS 一般用来存储共享视频,图片等静态数据。不会对NFS服务器进行频繁的写操作
尽量不要存储动态类数据,例如:脚本,数据库文件等,其变化频率比较高,因为其高频次的数据交换,会导致NFS的传输效率的降低。
image.png

2 NFS挂载原理

NFS是通过网络来进行服务端和客户端(C/S)之间的数据传输。两者之间要传输数据就要有想对应的网络端口来进行传输。NFS服务器到底使用什么网络端口来传输数据的,NFS服务器端其实是随机选择端口来进行数据传输。那NFS客户端又是如何知道NFS服务器端到底使用的是哪个端口呢?其实NFS服务器时通过远程过程调用 ( remote procedure call 简称RPC )协议/服务来实现的。也就是说RPC服务会统一管理NFS的端口,客户端和服务端通过RPC来先沟通NFS便用了哪些端口,之后再利用这些端口(小于1024)来进行数据的传输。
也就是RPC管理服务端的NFS端口分配,客户端要传数据,那客户端的RPC会先跟服务端的RPC去要服务器的端口,要到端口后再建立连接,然后传输数据。

NFS服务器时通过远程过程调用 ( remote procedure call 简称RPC )协议/服务来实现的。NFS协议是通过 RPC 协议进行通信和会话的。 NFS客户端要与服务器端建立通信过程,客户端先通过RPC连接服务器,RPC询问服务器的NFS端口是多少,服务器将NFS端口通过RPC告知客户端其NFS端口号。 NFS客户端在通过NFS端口号访问NFS服务器进行通信,NFS服务器确认连接成功。才能进行NFS的通信过程。 两个过程:RPC的连接确认 - NFS的连接确认

那 RPC 和 NFS之间又是如何之间相互通讯的?
首先当NFS启动后,就会随机的使用一些端口,然后NFS就会向RPC去注册这些端口。RPC就会记录下这些端口。并且NFS服务器RPC 会开启111端口,等待客户端RPC的请求,如果客户端有请求,那服务端的RPC就会将记录的NFS端口信息告知客户端。
RPC和 NFS的启动顺序是怎样的?
在启动NPS SERVER之前,首先要启动RPC服务(即portmap服务,下同)否则NFS SERVER就无法向RPC服务区注册,另外,如果RPC 服务重新启动,原来已经注册好的NFS端口数据就会全部丢失。因此此时 RPC服务管理的NFS程序也要重新启动以重新向RPC注册。
特别注意:一般修改NFS配置文档后,是不需要重启NFS的,直接在命令执行 /etc/init.d/nfs reload
总结:客户端NFS和服务端NFS通讯过程
1)首先服务器端启动RPC服务,并开启111端口
2)启动NFS服务,并向RPC注册端口信息
3)客户端启动RPC ( portmap服务 ),向服务端的RPC( portmap服务 ) 服务请求服务端的NFS端口
4)服务端的RPC(portmap)服务反馈NFS端口信息给客户端。
5)客户端通过获取的NFS端口来建立和服务端的NFS 连接并进行数据的传输。

RPC 早期的服务名叫 portmap【在CentOS 5之前的版本】,CentOS 6之后统一改名为 RPC。本质是统一的服务。

4.3 NFS - 图3

3 NFS相关协议及软件安装管理

协议:

  • RPC (Remote Procedure Call Protocol)——远程过程调用协议【服务器端口号:111】
    • RPC协议是可以管理和控制NFS的连接,还可以管理其他的服务由于启动之后是随机端口,这些服务均可以被RPC协议进行管理。都需要客户端和服务器两个过程的协商通信(RPC通信,某个服务的通信)。
  • NFS 协议【服务器端口号:随机】

软件:

  • nfs-utils-* :包括NFS命令与监控程序
  • rpcbind-* :支持安全NFS RPC服务的连接

注意:通常情况下,是作为系统的默认包安装的
CentOS6.* 之前 rpcbind 叫 portmap
范例:

  1. #系统默认已经开启了RPC协议
  2. ~ netstat -antlp | grep 111
  3. tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1596/rpcbind
  4. tcp 0 0 :::111 :::* LISTEN 1596/rpcbind

4 NFS系统守护进程

nfs:它是基本的NFS守护进程,主要功能是管理客户端是否能够登录服务器
rpcbind:主要功能是进行端口映射工作。当客户端尝试连接并使用RPC服务器提供的服务(如NFS服务时),rpcbind会将所管理的与服务对应的端口提供给客户端,从而使客户可以通过该端口向服务器请求服务。

5 NFS服务器的配置

NFS服务器的配置相对比较简单,只需要在相应的配置文件中进行设置,然后启动NFS服务器即可。
NFS 服务的配置文件为/etc/exports,这个文件是NFS的主要配置文件,不过系统并没有默认值,所以这个文件不一定会存在,可能要使用vim手动建立,然后在文件里面写入配置内容。
/etc/exports文件内容格式:

共享目录 客户端1(访问权限,用户映射,其他) 客户端2(访问权限,用户映射,其他)

  1. 共享目录:共享目录是指NFS服务器共享给客户机使用的目录
  2. 客户端:客户端是指网络中可以访问这个NFS共享目录的计算机

客户端常用的指定方式:

  • 指定ip地址的主机:192.168.0.200
  • 指定子网中的所有主机:192.168.88.0/24 [CIDR模式,子网掩码一定不能少]
  • 指定域名的主机:www.atguigu.com
  • 指定域中的所有主机:*.atguigu.com
  • 所有主机:*
  1. 设置输出目录的访问权限、用户映射等。

访问权限选项:

  • 设置输出目录只读:ro
  • 设置输出目录读写:rw

用户映射选项:

  • root_squash:将root用户的访问映射为匿名(nfsnobody)用户 uid和 gid;(默认生效)
  • no_root_squash:保留管理员权限,以服务器管理员的权限管理;
  • all_squash:将远程访问的用户及所属组都映射为指定uid、gid的匿名用户;
    • anonuid=xxx:将远程访问的所有用户都映射为指定uid的匿名用户;
    • anongid=xxx:将远程访问的所有用户组都映射为指定gid匿名组账户;

      NFS客户端和NFS服务器,NFS客户端将NFS服务器端的目录映射到本地后,NFS客户端是使用客户端的用户进行创建 / 修改文件,那么实际是保存在NFS服务器的目录下。NFS客户端和NFS服务器的用户关系是完全不同。 用户映射关系:不管客户端使用什么用户进行创建,在服务器上显示的文件均是某一个指定用户创建

其它选项:

  • sync:将数据同步写入内存缓冲区与磁盘中,效率低,但可以保证数据的一致性(同步),使用较多
  • async:将数据先保存在内存缓冲区中,必要时才写入磁盘(异步)

    6 NFS服务器的启动与停止

    1、启动NFS服务器
    为了使NFS服务器能正常工作,需要启动rpcbind和 nfs两个服务,并且 rpcbind一定要先于 nfs 启动。
    1. service rpcbind start
    2. service nfs start
    2、查询NFS服务器状态
    1. service rpcbind status
    2. service nfs status
    3、停止NFS服务器
    要停止NFS运行时,需要先停止 nfs 服务再停止 rpcbind服务,对于系统中有其他服务(如NIS)需要使用时,不需要停止 rpcbind 服务
    1. service nfs stop
    2. service rpcbind stop
    4、设置NFS服务器的自动启动状态
    设置rpcbind和 nfs服务在系统运行级别2345自动启动。
    1. # chkconfig --level 2345 rpcbind on
    2. # chkconfig --level 2345 nfs on
    3. 或者
    4. chkconfig rpcbind on
    5. chkconfig nfs on
    5、查看RPC服务器开启了哪些端口
    1. rpcinfo -p localhost
    范例: ```bash ~ service nfs start #RPC默认启动 ~ mkdir -p /nfs && chmod o+w /nfs/ #修改权限 ~ vim /etc/exports /nfs 10.0.0.41(rw,sync)

~ service nfs reload #重新加载NFS配置文件,不需要修改端口 ~ service nfs status #查看NFS服务状态 ~ service nfs stop #停止NFS服务 ~ chkconfig nfs on #设置NFS开机自启动

~ rpcinfo -p localhost

  1. <a name="u0OqU"></a>
  2. # 7 实验相关案例
  3. 1. 将NFS服务器的 /home/zhangsan共享给10.0.0.0网段,rw权限
  4. ```bash
  5. vim /etc/exports
  6. /home/zhangsan 10.0.0.0/24(rw,insecure,sync)
  1. 重启rpcbind和nfs服务 ```bash service rpcbind restart service nfs restart

查看NFS的配置信息

~ exportfs /nfs 10.0.0.41 /home/zhangsan 10.0.0.0/24

  1. 3. 服务器端查看nfs共享状态
  2. ```bash
  3. showmount -e 本机ip
  4. #查看自己共享的服务 和 exportf命令效果本质上一样
  1. 客户端查看nfs共享状态 ```bash showmount -e NFS服务器IP地址

~ showmount -e 10.0.0.40 Export list for 10.0.0.40: /home/zhangsan 10.0.0.0/24 /nfs 10.0.0.41


5. 客户端挂载nfs服务器共享目录

命令格式:mount NFS服务器IP:共享目录本地挂载点目录
```bash
mount -o vers=3 10.0.0.40:/home/zhangsan/ /mnt/zhangsan/
mount | grep nfs

#客户端操作
~ mkdir /mnt/nfs
~ mount -o vers=3 10.0.0.40:/nfs /mnt/nfs
~ echo "Hello NFS" >> /mnt/nfs/nfs.txt
#查看文件列表,默认采用root_squash
~ ls -l /mnt/nfs/
total 4
-rw-r--r-- 1 nfsnobody nfsnobody 10 Jun 29 04:39 nfs.txt

#服务器端操作
~ ls -l
total 4
-rw-r--r-- 1 nfsnobody nfsnobody 10 Jun 29 04:39 nfs.txt

mount -o vers=3共享本地 #指定挂载使用NFS v3版本(避免同步延迟)
验证客户端和 NFS 服务器端文件是否一致:
image.png
修改服务器端相应权限,不然客户端无法正常访问和使用

~ cat /var/log/message #查看NFS日志信息
  1. nfs共享权限和访问控制

a、客户端root用户
使用客户端的root身份在nfs服务器上创建文件,文件的所有者和所属组是nfsnobody。
b、客户端普通用户
使用客户端的普通用户身份在nfs服务器上创建文件,所有者和所属组是nobody或普通用户。如果明确设定了普通用户的映射用户身份,那么此时客户端用户的身份转换为指定映射用户;
如果NFS server上面有同名用户,那么此时客户端登录账户的身份转换为NFS server上面的同名用户;
范例:NFS共享权限和访问控制

###服务器端
#添加参数 no_root_squash
~ vim /etc/exports
/nfs 10.0.0.41(rw,sync,no_root_squash)
~ service nfs reload

#客户端建议需要重新挂载
#umount /mnt/nfs
#mount -o vers=3 10.0.0.40:/nfs /mnt/nfs
~ echo "Hello NFS-FS" >> /mnt/nfs/nfs.log
~ ls -l /mnt/nfs/
total 8
-rw-r--r-- 1 root      root      13 Jun 29  2022 nfs.log
-rw-r--r-- 1 nfsnobody nfsnobody 10 Jun 29 04:39 nfs.txt

###服务器端
#服务器端创建用户的UID和GID尽量要大于60000。要避免其服务器端的UID和客户端的UID重复
~ groupadd -g 1000 nfstest ; useradd -c "NFS User" -u 1000 -g 1000 nfstest
~ id nfstest
uid=1000(nfstest) gid=1000(nfstest) groups=1000(nfstest)
#使用参数all_squash
#all_squash ; anonuid ; anongid
~ vim /etc/exports
/nfs 10.0.0.41(rw,sync,all_squash,anonuid=1000,anongid=1000)
~ service nfs reload

#客户端建议需要重新挂载
#umount /mnt/nfs
#mount -o vers=3 10.0.0.40:/nfs /mnt/nfs
~ echo "NFS all_squash" >> /mnt/nfs/nfs.conf
~ ls -l /mnt/nfs/
total 12
-rw-r--r-- 1      1000      1000 15 Jun 29  2022 nfs.conf
-rw-r--r-- 1 root      root      13 Jun 29 05:08 nfs.log
-rw-r--r-- 1 nfsnobody nfsnobody 10 Jun 29 04:39 nfs.txt
#客户端显示的所有者和所属组为1000,服务器端显示则为nfstest用户
~ ls -l /nfs/
total 12
-rw-r--r-- 1 nfstest   nfstest   15 Jun 29 05:14 nfs.conf
-rw-r--r-- 1 root      root      13 Jun 29 05:08 nfs.log
-rw-r--r-- 1 nfsnobody nfsnobody 10 Jun 29 04:39 nfs.txt
  1. 卸载和自动挂载,

卸载:
1、卸载客户端的挂载目录
umount 挂载点
2、停止服务器端的共享
exportfs - au
自动挂载:/etc/fstab

格式:: nfs 0 0 192.168.115.10:/home/zhangsan /media/zhangsan nfs defaults 0 0 mount - a

#NFS客户端挂载
~ vim /etc/fstab
10.0.0.40:/nfs          /mnt/nfs                nfs     defaults,vers=3 0 0
~ mount -a 
~ df -Th

8 相关命令

8.1 exportfs 命令

如果我们在启动了NFS之后又修改了/etc/exports,是不是还要重新启动nfs呢?这个时候我们就可以用exportfs命令来使改动立刻生效,该命令格式如下:
格式:exportfs [-aruv]

  • -a 全部挂载或卸载/etc/exports中的内容,
  • -r 重新读取/etc/exports中的信息,并同步更新/etc/exports、/var/lib/nfs/xtab
  • -u 卸载单一目录(和-a一起使用为卸载所有/etc/exports文件中的目录)
  • -v 在export的时候,将详细的信息输出到屏幕上。

具体例子:

exportfs -au卸载所有共享目录 exportfs -ra重新共享所有目录并输出详细信息

范例:exportfs 命令

~ exportfs -av
exporting 10.0.0.41:/nfs
exporting 10.0.0.0/24:/data/nfs
exporting 10.0.0.0/24:/home/zhangsan
~ exportfs -v
/nfs            10.0.0.41(rw,wdelay,root_squash,all_squash,no_subtree_check,anonuid=1000,anongid=1000,sec=sys,rw,root_squash,all_squash)
/home/zhangsan  10.0.0.0/24(rw,wdelay,insecure,root_squash,no_subtree_check,sec=sys,rw,root_squash,no_all_squash)
/data/nfs       10.0.0.0/24(rw,wdelay,root_squash,no_subtree_check,sec=sys,rw,root_squash,no_all_squash)

8.2 rpcinfo 命令

利用rpcinfo -p 可以查看出RPC开启的端口所提供的程序有哪些,
其中nfs开启的是2049,portmapper(rpcbind)开启的是111,其余则是rpc开启的:

~ rpcinfo -p

~ service rpcbind status #rpcbind不要停止,该服务需要给其他服务提供服务

8.3 showmount 命令

showmount命令查询“mount”守护进程,以显示NFS服务器的加载信息。

Usage: showmount [-adehv]
       [--all] [--directories] [--exports]
       [--no-headers] [--help] [--version] [host]
-d 仅显示已被NFS客户端加载的目录
-e 显示NFS服务器上所有的共享目录