nfs 服务部署使用

NFS(Network File System 的缩写),它的主要功能是:通过网络、让不同的机器、不同的 OS 可以共享彼此的文件

NFS 服务器可以允许 NFS 客户端将远端 NFS 服务器的共享目录挂载到自己的系统上,当作本地磁盘一样使用

环境信息

  • Centos 7

服务安装

服务端安装

安装需要的软件包

yum -y install nfs-utils rpcbind

创建数据目录

mkdir /data/NFSDataHome
chmod 666 /data/NFSDataHome

修改配置文件 /etc/exports:

/etc/exports
/data/NFSDataHome 192.168.1.0/24(rw,sync,insecure,no_subtree_check,no_root_squash) 
/data/NFSDataHome *(ro)

相关选项说明:

参数 说明
ro 只读访问
rw 读写访问
sync 所有数据在请求时写入共享
async nfs 在写入数据前可以响应请求
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 无论 NFS 客户端以哪种用户身份访问,均映射为 NFS 服务器的 nfsnobody 用户
no_all_squash 保留共享文件的 UID 和 GID(默认)
root_squash 当 NFS 客户端以 root 用户身份访问时,映射为 NFS 服务器的 nfsnobody 用户
no_root_squash 当 NFS 客户端以 root 身份访问时,映射为 NFS 服务器的 root 用户,也就是要为超级用户保留权限。这个选项会留下严重的安全隐患,一般不建议采用。
anonuid=xxx 指定 nfs 服务器 /etc/passwd 文件中匿名用户的 UID
anongid=xxx 指定 nfs 服务器 /etc/passwd 文件中匿名用户的 GID

启动 rpcbind 服务

systemctl enable rpcbind.service --now

启动 nfs 服务

systemctl enable nfs.service --now

检查 expose 的资源

$ showmount -e localhost
Export list for localhost:
/data/NFSDataHome *

默认情况下,NFS server 启动时会随机启动多个端口并向 RPC 注册,有防火墙的场景下,不利于防火墙配置确切的端口。所以建议配置 NFS 使用固定的端口,配置方式如下

  1. 编辑配置文件 /etc/sysconfig/nfs,添加以下内容

    RQUOTAD_PORT=30001

    LOCKD_TCPPORT=30002

    LOCKD_UDPPORT=30002

    MOUNTD_PORT=30003

    STATD_PORT=30004
  2. 重启服务

    systemctl restart rpcbind
    systemctl restart nfs

  3. 查看 NFS 使用的 RPC 端口

    $ 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 30003 mountd
    100005 1 tcp 30003 mountd
    100005 2 udp 30003 mountd
    100005 2 tcp 30003 mountd
    100005 3 udp 30003 mountd
    100005 3 tcp 30003 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 30002 nlockmgr
    100021 3 udp 30002 nlockmgr
    100021 4 udp 30002 nlockmgr
    100021 1 tcp 30002 nlockmgr
    100021 3 tcp 30002 nlockmgr
    100021 4 tcp 30002 nlockmgr

  4. 添加防火墙规则

    iptables -I INPUT 6 -p udp -m multiport --dports 111,2049,30001:30004 -j ACCEPT -m comment --comment "nfs"
    iptables -I INPUT 6 -p tcp -m multiport --dports 111,2049,30001:30004 -j ACCEPT -m comment --comment "nfs"

客户端安装

linux 客户端安装

yum -y install nfs-utils

测试 NFS 服务端 expose 的资源

$ showmount -e ${NFS_SERVER_IP}
Export list for ${NFS_SERVER_IP}:
/data/NFSDataHome *

客户端挂载

mount.nfs ${NFS_SERVER_IP}:/data/NFSDataHome /mnt/

配置开机自动挂载,在 /etc/fstab 文件中添加以下内容

/etc/fstab
${NFS_SERVER_IP}:/data/NFSDataHome /mnt nfs defaults        0 0

Windows 客户端安装

  • windows os: Win 10

打开控制面板 -> 程序 -> 打开或关闭windows功能 -> NFS客户端 ,启用 NFS。

cmd 执行以下命令挂载:

mount IP:/nfsroot X:

其中,IP 为 NFS 服务器得 IP,/nfsroot 为你挂载得 NFS 目录路径,执行成功后 NFS 路径会被挂载到 X:

常见问题

windows 挂载 NFS 后访问速度慢

在 cmd 中通过命令 mount 查看挂载信息

$ mount

Local Remote Properties
-------------------------------------------------------------------------------
x: \\nfsserver\NFSDataHome UID=-2, GID=-2
rsize=1048576, wsize=1048576
mount=soft, timeout=0.8
retry=1, locking=yes
fileaccess=755, lang=ANSI
casesensitive=no
sec=sys

输出中可以看到读写大小(rsize=1048576, wsize=1048576,1M),NFS 服务默认的读写大小在配置文件 /etc/nfsmount.conf,默认大小为 8k

/etc/nfsmount.conf
# Maximum Read Size (in Bytes)
# Rsize=8k
#
# Maximum Write Size (in Bytes)
# Wsize=8k

将此配置修改为和 windows nfs 客户端的读写大小一样,重启 nfs 服务,window 重新挂载。

Mysql 数据目录使用 NFS 文件系统

Mysql 数据目录使用 NFS 文件系统,只用来测试

当 NFS 服务使用选项 all_squash 时,因为所有的客户端操作时,用户身份都会映射为 NFS 服务器上面的 nfsnobody 用户,Mysql 默认的用户 mysql 对此 NFS 目录权限受到限制,会导致初始化失败,报以下错误

$ mysql_install_db --defaults-file=/etc/my.cnf -u mysql --basedir=/var/lib/mysql --datadir=/var/lib/mysql/data/
2023-02-10 14:53:22 [WARNING] mysql_install_db is deprecated. Please consider switching to mysqld --initialize
2023-02-10 14:53:22 [ERROR] Failed to set file ownership for /var/lib/mysql/data/ to (999, 1002)


2023-02-10 14:53:59 [ERROR] Child process: /bin/mysqldterminated prematurely with errno= 32

针对此情况,可以修改 Mysql 服务运行的用户为 nfsnobody,并且此 nfsnobody 用户需要和 NFS 服务器上面的 nfsnobody 用户具有相同的 UID 和 GID

查看 NFS 服务器上面的 nfsnobody 的 ID 信息,默认为 65534

$ id nfsnobody
uid=65534(nfsnobody) gid=65534(nfsnobody) groups=65534(nfsnobody)

在 Mysql 服务器上面创建具有相同 UID 和 GID 的 nfsnobody 用户和组信息

groupadd --gid 65534 nfsnobody

useradd --uid 65534 --gid 65534 -M -s /sbin/nologin

使用 nfsnobody 用户初始化数据库

mysql_install_db --defaults-file=/etc/my.cnf -u nfsnobody --basedir=/var/lib/mysql --datadir=/var/lib/mysql/data/

修改 mysql 服务配置文件,配置以下内容,指定运行时使用的用户

/etc/my.cnf
user = mysql