运维手册之 NFS 网络文件系统服务
后知后觉 暂无评论

NFSNetwork File System,网络文件系统)用于跨越文件系统,它允许网络中的计算机之间通过TCP/IP网络共享资源。

NFS 基本概述

NFS 主要功能是通过局域网络让不同的主机系统之间可以共享文件或目录。

NFS 系统和 Windows 网络共享、网络驱动器类似, 只不过windows用于局域网, NFS 用于企业集群架构中, 如果是大型网站, 会用到更复杂的分布式文件系统

为什么要NFS服务进行数据存储

NFS 应用场景

企业集群环境中,若用户上传的数据上传到某台服务器中,若不使用 NFS ,则其他服务器没办法访问及使用本资源,若使用 NFS ,则只需划分一个共享空间然后挂载到每台服务器即可。

NFS 实现原理

NFS工作原理(!AVIF)

rpc.nfsd:NFS 守护进程,控制客户端是否能够登录服务器;
rpc.mount:管理 NFS 文件系统,客户端成功登录并使用文件前,会对文件使用权限进行验证;
portmap:端口映射服务

本地操作方式

  1. 当用户进程发起本地文件访问或修改,该请求直接传递至内核,由内核驱动硬件完成操作。

远程操作方式

  1. 用户进程访问 NFS 客户端,使用不同的函数对数据进行处理。
  2. 请求会通过 TCP/IP 的方式传递给 NFS 服务端。
  3. NFS 服务端接收到请求后,会调用 portmap 进程进行端口映射。
  4. nfsd 进程用于判断客户端是否拥有权限连接 NFS 服务端。
  5. Rpc.mount 用于判断客户端是否有对应的权限进行验证。
  6. idmap 进程实现用户映射和压缩。
  7. 最后 NFS 服务端会将对应请求的函数转换为本地能识别的命令,传递至内核,由内核驱动硬件。

NFS 工具部署

环境准备

本文环境在未特殊声明时默认为 CentOS 7.5

服务器规划

| Hostname | 角色 | 外网IP | 内网IP |
| - | - | - | - | - |
| nfs0 | 服务端 | 10.0.0.31 | 172.16.1.31 |
| nfs1 | 客户端 | 10.0.0.41 | 172.16.1.41 |

禁用防火墙

sudo systemctl disable firewalld
sudo systemctl stop firewalld
注意: 需禁用防火墙或设置相应的规则, 以免默认的防火墙策略禁止正常的NFS共享服务,本文为方便操作,直接禁用。

禁用 SELinux

sudo sed -ri '#^SELINUX=#cSELINUX=Disabled' /etc/selinux/config
sudo setenforce 0

安装 NFS 组件

sudo yum -y install nfs-utils

修改 NFS 配置

服务的默认配置文件为/etc/exports(默认配置为空)。
我们可以按照共享目录的路径 允许访问的NFS客户端(共享权限参数)格式,定义要共享的目录与相应的权限。

exports 配置文件格式

NFS共享目录 NFS客户端地址0(参数1,参数2,...)
NFS共享目录 NFS客户端地址1(参数1,参数2,...) 客户端地址2(参数1,参数2,...)

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

挂载参数作用及解释频率
rw读写权限常用
ro只读权限/
root_squash当客户端以root身份访问时,映射为服务器的默认匿名用户/
no_root_squash当客户端以root身份访问时,映射为服务器的root管理员/
all_squash无论客户端以何种身份访问,均映射为服务器的匿名用户/
no_all_squash无论客户端以何种身份访问,均不进行映射/
sync同时将数据写入到内存与硬盘中,保证不丢失数据常用
async优先将数据保存到内存,然后再写入硬盘;这样效率更高,但可能会丢失数据/
anonuid配置all_squash使用,指定客户端的用户UID,确保用户存在常用
anongid配置all_squash使用,指定客户端的用户UID,确保用户存在常用

配置 NFS 服务

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

## 启动服务
sudo systemctl start rpcbind.service
sudo systemctl start nfs-server.service
## 配置服务自启动
sudo systemctl enable nfs-server.service

NFS 应用案例

需求

服务端

写入配置文件

echo "/data   172.16.1.0/24(rw,sync,all_squash)" | sudo tee /etc/exports

创建共享目录并授权

sudo mkdir /data
sudo chown -R nfsnobody:nfsnobody /data
注意:地址与权限之间无需空格!NFS 共享目录会记录至 /var/lib/nfs/etab,如果该目录不存在共享信息,请检查配置是否正确。

客户端

安装客户端工具,仅需要启动 rpcbind 服务

sudo yum -y install nfs-utils
sudo systemctl restart rpcbind
sudo systemctl enable rpcbind

查看远程提供的共享目录

[kane@pxe1 ~]$ showmount -e 172.16.1.31
Export list for 172.16.1.31:
/data 172.16.1.0/24
参数作用
-e显示目标服务端的共享列表
-a显示本机挂载的文件资源的情况NFS资源的情况
-v显示版本号

在客户端创建挂载目录并挂载

## 创建挂载目录
sudo mkdir /nfsdir

## 挂载 NFS 分区
## 使用 -t 类型指定文件系统
sudo mount -t nfs 172.16.1.31:/data /nfsdir

## 亦可使用 . 类型指定文件系统
sudo mount.nfs4 172.16.1.31:/data /nfsdir

## 检查挂载情况
sudo df –h
Filesystem           Size  Used Avail Use% Mounted on
/dev/sda3             62G  845M   58G   2% /
tmpfs                244M     0  244M   0% /dev/shm
/dev/sda1            190M   26M  155M  14% /boot
172.16.1.31:/data     62G  880M   58G   2% /nfsdir
格式:mount.文件系统 远程地址:目录 本地挂载目录

开机自动挂载 NFS 分区

echo "172.16.1.31:/data /nfsdir nfs defaults,nofail 0 0" | sudo tee -a /etc/fstab

卸载 NFS 分区【扩展】

sudo umount /nfsdir 

注意:若卸载的时报错 umount: /nfsdir: device is busy

  • 切换至其他目录,然后再进行卸载;
  • 使用 sudo umount -lf /nfsdir 命令强制卸载。

参数优化【重点】

在企业工作场景下,通常情况 NFS 服务器共享的只是普通静态数据(如图片、附件、视频),不需要 suidexec 等权限,挂载的这个文件系统只能作为数据存取之用,禁用一些危险权限,对于客户端来讲增加了安全性。例如:很多木马篡改文件都是由上传入口上传的伪装程序然后执行。

通过指定挂载参数,禁止 suid(获取权限)、exec(可执行)权限,增加安全性。

sudo mount.nfs4 -o nosuid,noexec,nodev 172.16.1.31:/data /mnt

通过指定挂载参数,禁止 nodiratime(目录时间戳)、noatime(修改时间戳)权限,可提高文件系统性能。

sudo mount.nfs4 -o noatime,nodiratime 172.16.1.31:/data /mnt

NFS 共享存储总结

优点

局限

建议


AutoFS 自动挂载

无论是 Samba 服务还是 NFS 服务,都要把挂载信息写入到 /etc/fstab 中,这样远程共享资源就会自动随服务器开机而进行挂载。

短板:

  1. 虽然很方便,但挂载资源过多会造成网络带宽以及服务器硬件资源带来很大的负载
  2. 如果在资源挂载后长期不使用,也会造成服务器硬件资源的浪费。
  3. 每次使用之前执行 mount 进行手动挂载,这是个不错的选择,但每次都需要先挂载在使用,会非常的麻烦。

那么 autofs 自动挂载服务可以解决这一问题。autofs 程序是一种守护进程,当检测到用户试图访问一个尚未挂载的文件系统时,将自动挂载该文件系统,从而节约了网络资源和服务器的硬件资源。

客户端安装

先安装程序

sudo yum install -y autofs

然后配置自启动

sudo systemctl enable --now autofs.service

客户端配置

服务参数配置

默认服务配置项在 /etc/sysconfig/autofs 中,13 行是默认注释掉的可选参数,这个选项会在服务启动时自动加载

echo 'OPTIONS="--timeout=300"' | sudo tee -a /etc/sysconfig/autofs
## 比如上面的参数指定延时 5 分钟,超时会自动卸载,支持的参数可以用 man automount 命令查询

重启服务会看到加入的选项已经生效

## 修改前
$ systemctl status autofs
autofs.service - Automounts filesystems on demand
   [...]
   CGroup: /system.slice/autofs.service
           └─6459 /usr/sbin/automount --foreground --dont-check-daemon
   [...]
## 修改后
$ systemctl status autofs
autofs.service - Automounts filesystems on demand
   [...]
   CGroup: /system.slice/autofs.service
           └─6452 /usr/sbin/automount --timeout=300 --foreground --dont-check-daemon
   [...]

挂载配置

挂载相关的配置文件都在 /etc 中,以 auto 开头

$ ll /etc/auto*
-rw-r--r--. 1 root root 14622 Apr 13  2018 /etc/autofs.conf           # 程序配置
-rw-------. 1 root root   232 Apr 13  2018 /etc/autofs_ldap_auth.conf # LDAP 认证配置
-rw-r--r--. 1 root root   795 Apr 13  2018 /etc/auto.master           # 挂载主配置
-rw-r--r--. 1 root root   524 Apr 13  2018 /etc/auto.misc             # 光盘类挂载配置
-rwxr-xr-x. 1 root root  1260 Apr 13  2018 /etc/auto.net              # 网络类挂载工具
-rwxr-xr-x. 1 root root   687 Apr 13  2018 /etc/auto.smb              # SMB 挂载工具

本地硬盘挂载

接下来简单演示一下本地硬盘如何实现自动挂载和卸载,新硬盘为 sdb 容量 8 TiB。

  1. 先将硬盘创建文件系统并分区

    sudo fdisk /dev/sdb
    ## 按 g 创建 GPT 文件系统,按 n 一路回车创建分区,按 w 写入磁盘。
    sudo mkfs.ext4 /dev/sdb1
    ## 格式化分区为 ext4
  2. 测试挂载分区

    sudo mkdir /auto
    sudo mount /dev/sdb1 /mnt/
    sudo umount /mnt/
  3. 写入配置并重启服务

    echo '/auto /etc/auto.sdb1' | sudo tee /etc/auto.master.d/sdb1.autofs
    echo 'sdb1 -fstype=ext4 :/dev/sdb1' | sudo tee /etc/auto.sdb1
    sudo systemctl restart autofs.service
  4. 测试自动挂载

    ## 先查看目录是否挂载
    [kane@pxe1 ~]$ df -Th
    Filesystem          Type      Size  Used Avail Use% Mounted on
    /dev/mapper/cl-root xfs        14G  1.6G   12G  12% /
    devtmpfs            devtmpfs  990M     0  990M   0% /dev
    tmpfs               tmpfs    1001M     0 1001M   0% /dev/shm
    tmpfs               tmpfs    1001M   13M  988M   2% /run
    tmpfs               tmpfs    1001M     0 1001M   0% /sys/fs/cgroup
    /dev/sda2           xfs      1014M  144M  871M  15% /boot
    /dev/sda1           vfat      200M   12M  189M   6% /boot/efi
    tmpfs               tmpfs     201M     0  201M   0% /run/user/1000
    ## 并没有挂载,然后进入挂载点,虽然没有挂载但是可以发现可以进入
    cd /auto/sdb1
    ## 进入后再查看挂载信息,可以看到已经自动将其挂载
    [kane@pxe1 sdb1]$ df -Th
    Filesystem          Type      Size  Used Avail Use% Mounted on
    /dev/mapper/cl-root xfs        14G  1.6G   12G  12% /
    devtmpfs            devtmpfs  990M     0  990M   0% /dev
    tmpfs               tmpfs    1001M     0 1001M   0% /dev/shm
    tmpfs               tmpfs    1001M   13M  988M   2% /run
    tmpfs               tmpfs    1001M     0 1001M   0% /sys/fs/cgroup
    /dev/sda2           xfs      1014M  144M  871M  15% /boot
    /dev/sda1           vfat      200M   12M  189M   6% /boot/efi
    tmpfs               tmpfs     201M     0  201M   0% /run/user/1000
    /dev/sdb1           ext4      7.8T   20M  7.8T   0% /auto/sdb1

挂载方式

autofs 允许两种挂载方式:

直接挂载方式

本地的挂载点是绝对路径

## 配置文件后缀必须是 .autofs,/- 代表这是一个直接挂载定义,根据 /etc/auto.nfs_direct 进行挂载
echo '/-      /etc/auto.nfs_direct' | sudo tee /etc/auto.master.d/nfs.autofs
## 子配置中,按 “挂载目录 挂载文件类型及权限 :设备名称” 的格式进行填写
echo '/nfsdir  -fstype=nfs,rw,sync,soft,nosuid,nodev  172.16.1.31:/data' | sudo tee /etc/auto.nfs_direct
## 重启服务
sudo systemctl restart autofs.service

间接挂载

本地路径和服务端的路径都没有直接写绝对路径

## 配置文件后缀必须是 .autofs,访问本地目录对应的远端 NFS 目录
echo '/nfsdir /etc/auth.nfs_share' | sudo tee /etc/auto.master.d/nfs.autofs
## 子配置中,按 “* 参数 挂载目录” 的格式进行填写(& 表示目录下访问哪个挂载哪个)
echo '*       -rw,sync,soft,nosuid,nodev,'sec=krb5p' 172.16.1.31:/data/&' | sudo tee /etc/auth.nfs_share
## 重启服务
sudo systemctl restart autofs.service
注意:如果有 kerberos 验证则需要启动 nfs-secure 并加入开机自启动。若使用 df 命令无法查看具体挂载内容,则使用 mount 命令。

附录

参考链接

本文撰写于一年前,如出现图片失效或有任何问题,请在下方留言。博主看到后将及时修正,谢谢!
禁用 / 当前已拒绝评论,仅可查看「历史评论」。