Ubuntu22.04 下 NFS 相关问题与完整配置(客户机 MacOS)


categories: [Linux-Shell]

tags: Linux NFS

写在前面

最近折腾一下 NFS, 先白嫖一顿华子云的 1 个月服务器, 2C4G 感觉不错了, 但NFS 配置起来还是有点难度, 主要还是随机分配的端口配置方面比较恶心.

server环境:

  • 华为云 2C4G Ubuntu22.04

client环境:

  • MacOS M1 with brew

  • Archlinux qemu-x86_64

背景

NFS 可以理解为网络主机上的一种服务, 支持多端的存储, 并且没有架构的限制, 底层通过 RPC 完成通信, 具体就是通过 RPC 寻找Server, 然后将找到的 Server 传到 Client,

server 端配置

安装基本包

首先需要安装一下nfs-Server:

bash 复制代码
sudo apt install rpcbind
sudo apt install nfs-server
sudo apt install nfs-kernel-server #这个好像在安装 nfs-server 之后就已经作为依赖安装过了

开启指定服务: (开机启动)

bash 复制代码
sudo systemctl enable rpcbind nfs-server
sudo systemctl start rpcbind nfs-server #这步可选, 因为安装之后默认是开启的

新建文件夹: (需要共享的文件夹)

bash 复制代码
mkdir /home/user/nfs_data
# 这里用 /nfs 也可以, 不过权限要注意. 

配置文件

bash 复制代码
sudo vi /etc/exports
# 下面的内容写入: (注意*之后左括号之前不要加任何空格!!!)
/home/user/nfs_data  *(rw,async,insecure,no_subtree_check,all_squash,anonuid=0,anongid=0)

端口配置

接下来遇到一个坑点了, 网上找到的关于 Ubuntu18 或者 20 的更改端口的方法都不起作用, 后来发现原来是 Ubuntu22.04 的一个更新点:

Bug #1971096 "Cannot Specify Fixed Ports for mountd and statd" : Bugs : nfs-utils package : Ubuntu;

Network File System (NFS) | Ubuntu;

参考的第二行给出了最新的配置文档, 也就是具体需要更改的配置文件: /etc/nfs.conf

这里主要是设置三个静态端口:

c 复制代码
[lockd]
port=40002

[mountd]
# debug=0
manage-gids=y
# descriptors=0
port=40001

[statd]
# debug=0
port=40000

其实主要就是搜索 port 对应的条目, 改之.

重启服务

然后划重点的来了!!! (当然事实就是重启解决一切问题, 不过作为服务器来说总重启对用户体验不太好)

这里又是一个坑.

需要明确的是重启的服务不只是 nfs 的, 还有 rpc 相关的, 这里文档也提到了, 只是我没注意...

For example, systemctl restart nfs-server.service will restart nfs-mountd, nfs-idmapd and rpc-svcgssd (if running). On the other hand, restarting nfs-utils.service will restart nfs-blkmap, rpc-gssd, rpc-statd and rpc-svcgssd.

Of course, each service can still be individually restarted with the usual systemctl restart <service>.

The nfs.systemd(7) manpage has more details on the several systemd units available with the NFS packages.

也就是说, status 改了之后需要重启的服务是rpc-utils!

bash 复制代码
sudo systemctl restart nfs-server
sudo systemctl restart rpc-utils

这样才算是完成了端口的指定了.

最后看一下设置的情况:

bash 复制代码
==> 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  40001  mountd
    100005    1   tcp  40001  mountd
    100005    2   udp  40001  mountd
    100005    2   tcp  40001  mountd
    100005    3   udp  40001  mountd
    100005    3   tcp  40001  mountd
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100227    3   tcp   2049
    100021    1   udp  40002  nlockmgr
    100021    3   udp  40002  nlockmgr
    100021    4   udp  40002  nlockmgr
    100021    1   tcp  40002  nlockmgr
    100021    3   tcp  40002  nlockmgr
    100021    4   tcp  40002  nlockmgr
    100024    1   udp  40000  status
    100024    1   tcp  40000  status

华为云服务器开放的端口:

控制台界面-> 安全组->配置规则->入方向规则->添加规则

优先级 1 即可, 端口都开放的是 TCP, 这里就不开放 UDP了, 如果网速比较慢需要开一下.

  • 2049(这里 UDP 可以开一下, 因为是实际走连接的端口)
  • 111
  • 40000
  • 40001
  • 40002

查看状态

除了上面提到的rpcinfo, 还可以通过下面的一些命令查看连接状态

端口

1024 以下的端口号需要 sudo

bash 复制代码
 ==> sudo lsof -i:111
COMMAND PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
systemd   1 root   91u  IPv4   1847      0t0  TCP *:sunrpc (LISTEN)
systemd   1 root   93u  IPv4   1848      0t0  UDP *:sunrpc
systemd   1 root   96u  IPv6   1849      0t0  TCP *:sunrpc (LISTEN)
systemd   1 root   97u  IPv6   1850      0t0  UDP *:sunrpc
rpcbind 485 _rpc    4u  IPv4   1847      0t0  TCP *:sunrpc (LISTEN)
rpcbind 485 _rpc    5u  IPv4   1848      0t0  UDP *:sunrpc
rpcbind 485 _rpc    6u  IPv6   1849      0t0  TCP *:sunrpc (LISTEN)
rpcbind 485 _rpc    7u  IPv6   1850      0t0  UDP *:sunrpc

查看连接情况

bash 复制代码
 ==> showmount -a
All mount points on hecs:
ip:/home/user/nfs_data
 [Ubuntu] √  ~
 ==> showmount -e
Export list for hecs:
/home/user/nfs_data *
 [Ubuntu] √  ~
 ==> showmount -d
Directories on hecs:
/home/user/nfs_data
 [Ubuntu] √  ~
 ==> showmount -d
--all          -a  -- list both hostname and mounted dir in host:dir format
--directories  -d  -- list only the directories mounted by some client
--exports      -e  -- show server export list
--help         -h  -- help
--no-headers       -- suppress descriptive headers from output
--version      -v  -- version

查看 rpc 连接情况

bash 复制代码
 ==> rpcinfo -m
PORTMAP (version 2) statistics
NULL    SET     UNSET   GETPORT DUMP    CALLIT
19      0/0     0/0     18/22   21      0/0

PMAP_GETPORT call statistics
prog		vers	netid	  success	failure
status          1	tcp	  3           	0
mountd          3	tcp	  7           	0
nfs             3	tcp	  8           	0
status          1	udp	  0           	4

RPCBIND (version 3) statistics
NULL    SET     UNSET   GETADDR DUMP    CALLIT  TIME    U2T     T2U
0       148/148 73/73   0/0     0       0/0     0       0       0

RPCBIND (version 4) statistics
NULL    SET     UNSET   GETADDR DUMP    CALLIT  TIME    U2T     T2U
11      198/198 168/168 10/10   0       0/0     0       0       0
VERADDR INDRECT GETLIST GETSTAT
0       0       0       1

RPCB_GETADDR (version 4) call statistics
prog		vers	netid	  success	failure
mountd          3	tcp	  10          	0

nfsstat

bash 复制代码
 ==> nfsstat -m #在 Client 端执行
/Volumes/nfs_data from ip:/home/user/nfs_data
  -- Original mount options:
     General mount flags: 0x0
     NFS parameters: deadtimeout=45
     File system locations:
       /home/user/nfs_data @ ip (ip)
  -- Current mount parameters:
     General mount flags: 0x4000018 nodev,nosuid,multilabel
     NFS parameters: vers=3,tcp,port=2049,nomntudp,hard,nointr,noresvport,negnamecache,callumnt,locks,quota,rsize=32768,wsize=32768,readahead=16,dsize=32768,rdirplus,nodumbtimer,timeo=10,maxgroups=16,acregmin=5,acregmax=60,acdirmin=5,acdirmax=60,deadtimeout=45,nomutejukebox,nonfc,sec=sys
     File system locations:
       /home/user/nfs_data @ ip (ip)
     Status flags: 0x0

Server 端的一些选项:

bash 复制代码
==> nfsstat -l
nfs v3 server        total:      180
------------- ------------- --------
nfs v3 server         null:        8
nfs v3 server      getattr:       81
nfs v3 server       lookup:       22
nfs v3 server       access:       33
nfs v3 server         read:        1
nfs v3 server  readdirplus:        3
nfs v3 server       fsstat:       24
nfs v3 server       fsinfo:        4
nfs v3 server     pathconf:        4

nfs v4 server        total:      130
------------- ------------- --------
nfs v4 server         null:        2
nfs v4 server     compound:      128

nfs v4 servop        total:      401
------------- ------------- --------
nfs v4 servop       access:        9
nfs v4 servop        close:        1
nfs v4 servop      getattr:      104
nfs v4 servop        getfh:       15
nfs v4 servop       lookup:       14
nfs v4 servop         open:        1
nfs v4 servop        putfh:      113
nfs v4 servop    putrootfh:        4
nfs v4 servop      readdir:        4
nfs v4 servop       rename:        1
nfs v4 servop       savefh:        1
nfs v4 servop      setattr:        1
nfs v4 servop        write:        1
nfs v4 servop  exchange_id:        4
nfs v4 servop   create_ses:        2
nfs v4 servop  destroy_ses:        2
nfs v4 servop secinfononam:        2
nfs v4 servop     sequence:      118
nfs v4 servop destroy_clid:        2
nfs v4 servop reclaim_comp:        2

查看配置文件信息

bash 复制代码
 ==> sudo exportfs -v
/home/user/nfs_data
		<world>(async,wdelay,hide,no_subtree_check,anonuid=0,anongid=0,sec=sys,rw,insecure,root_squash,all_squash)

client 端配置

这里比较有讲究, MacOS需要开放全部的端口, 否则连接会失败, 但是 archLinux 不需要, 仅通过 2049 完成连接, 这也是 Linux 的魅力所在吧.

MacOS

不需要安装额外的软件, 甚至通过访达也能连接, 只需要通过⌘+K, 键入:

bash 复制代码
nfs://<公网IP>/home/user/nfs_data

或者终端:

bash 复制代码
sudo mount_nfs -o rw <公网IP>:/home/user/nfs_data ~/code/nfs
sudo umount ~/code/nfs #取消挂载, 取消挂载之前记得先返回上级目录

都是比较方便的, 通过:

bash 复制代码
rpcinfo -p <公网IP>

查看连接情况, 一般来说应该与 Server 端的端口开放情况保持一致的, 例如:

bash 复制代码
   program vers proto   port
    100000    4   tcp    111  rpcbind
    100000    3   tcp    111  rpcbind
    100000    2   tcp    111  rpcbind
    100000    4   udp    111  rpcbind
    100000    3   udp    111  rpcbind
    100000    2   udp    111  rpcbind
    100005    1   udp  40001  mountd
    100005    1   tcp  40001  mountd
    100005    2   udp  40001  mountd
    100005    2   tcp  40001  mountd
    100005    3   udp  40001  mountd
    100005    3   tcp  40001  mountd
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100227    3   tcp   2049  nfs_acl
    100021    1   udp  40002  nlockmgr
    100021    3   udp  40002  nlockmgr
    100021    4   udp  40002  nlockmgr
    100021    1   tcp  40002  nlockmgr
    100021    3   tcp  40002  nlockmgr
    100021    4   tcp  40002  nlockmgr
    100024    1   udp  40000  status
    100024    1   tcp  40000  status

archlinux

直接一行:

bash 复制代码
sudo mount -t nfs -o rw <公网IP>:/home/user/nfs_data ~/nfs
# 因为没读取系统级端口, 所以 sudo 不是必须的. 
相关推荐
轩辰~2 分钟前
网络协议入门
linux·服务器·开发语言·网络·arm开发·c++·网络协议
雨中rain1 小时前
Linux -- 从抢票逻辑理解线程互斥
linux·运维·c++
Bessssss1 小时前
centos日志管理,xiao整理
linux·运维·centos
s_yellowfish1 小时前
Linux服务器pm2 运行chatgpt-on-wechat,搭建微信群ai机器人
linux·服务器·chatgpt
豆是浪个1 小时前
Linux(Centos 7.6)yum源配置
linux·运维·centos
vvw&1 小时前
如何在 Ubuntu 22.04 上安装 Ansible 教程
linux·运维·服务器·ubuntu·开源·ansible·devops
我一定会有钱1 小时前
【linux】NFS实验
linux·服务器
Ven%1 小时前
如何在防火墙上指定ip访问服务器上任何端口呢
linux·服务器·网络·深度学习·tcp/ip
是阿建吖!2 小时前
【Linux】基础IO(磁盘文件)
linux·服务器·数据库
张暮笛2 小时前
蓝牙协议——音量控制
linux