网络文件系统NFS

简介

  • 网络文件系统 NFSNetwork File System 的缩写, 他是一种分布式文件系统, 用来实现客户端主机可以
    访问服务端文件, 并且访问过程和本地存储时一样;
  • NFS 基于开放网络运算远程过程调用(ONC RPC)系统: 一个开放, 标准的RFC系统, 任何人或组织都可以依据标准实现它.
  • NFS 可用于热备服务器高可用数据库高可用以及负载均衡的文件服务器等.

安装

  1. 包管理器安装
    对于 Debian 来说, 安装NFS 很容易; 在 Debian Buster 下, 执行以下命令即可安装.
sudo apt install nfs*
  1. 编译安装
    // TODO

配置

nfs 的配置文件在 /etc/exports 配置项较少, 相对来说比较简单, 主要是在配置这部分比较困难.

注意: 不同的操作系统和安装方式, 在 /etc 下可能没有 exports 文件, 需要自行手工创建

cat /etc/exports
/home/web 192.168.123.0/24(rw, sync, fsid=0) 

/home/web 表示要共享的文件夹, 确保文件夹存在, 没有则创建
192.168.123.0/24 表示哪个网段可以挂载共享的文件夹
(rw, sync, fsid=0)表示分配该部分客户端连接后的权限

权限含义
roread-only 只读
rwread-write 读写
sync将数据同步写入内存和磁盘中, 适合实时性要求高的场合
async将数据同步先写入内存, 然后再写入磁盘, 效率高, 但有丢数据的风险
all_squash所有访问服务端的用户权限都将压缩为匿名用户, uid/gid会变为nobodynfsnobody
root_squashNFS客户端以root用户访问时, 映射为NFS服务器的匿名用户
no_root_squashNFS客户端以root管理员访问时, 映射为NFS服务器的root用户

配置 NFS 的重要技巧

  • 确保所有连接 NFS 服务端的服务器都具有相同的权限
    1. 使用 all_squash 将所有客户端的连接全部压缩为匿名用户.
    2. 设置 anonuidanongid 指定服务端的对应用户
  • 所有客户端和服务端需要具有相同的 uid/gid 用户, 即 nfsnobody (uid必须一样)

启动

启动nfs之前需要先启动rpcbind
启动rpcbind并将之设置为开机自启

sudo systemctl start rpcbind && sudo systemctl enable rpcbind

启动nfs并将至设置为开机自启

sudo systemctl start nfs-server && sudo systemctl enable nfs-server
sudo systemctl start nfs-kernel-server && sudo systemctl enable nfs-kernel-server
sudo systemctl start nfs-ganesha-lock && sudo systemctl enable nfs-ganesha-lock
sudo systemctl start nfs-ganesha && sudo systemctl enable nfs-ganesha

# nfs-utils nfs-blkmap nfs-idmapd nfs-mountd 这些服务将由 nfs-server 进行启动

注意:
nfs启动需要向rpc注册, 所以需要先启动rpc再启动nfs.
如果重启了rpc,之前注册的数据会丢失,所以nfs也需要跟着重启重新向rpc注册.

NFS 默认监听 2049 端口, RPC监听 111, 可以使用 rpcinfo 命令来查看nfs注册情况.

rpcinfo -p [ip|hostname] # 针对某IP(未写则预设为本机) 显示出所有的 port 与 porgram 的信息
rpcinfo -t/-u 检查某个主机的TCP/UDP封包, 如 rpcinfo -t localhost nfs 检查本机nfs的TCP封包

启动后可以使用 showmount -e [server_ip|hostname] 查看当前共享的文件夹, 如:

base@base3:~$ showmount -e localhost
Export list for localhost:
/etc       192.168.123.0/24
/home/base 192.168.123.0/24
/home/web  192.168.123.0/24
# 可以查看到当前本机(服务端)共享了3个文件夹, 允许 192.168.123.0/255.255.255.0 网段进行连接

# 使用showmount -a 可以查看当前的连接状态
base@base3:~$ showmount -a 
All mount points on base3:
192.168.123.152:/home/web
# 可以查看到客户端: 192.168.123.152 已经挂载了服务端共享的 /home/web 文件夹

showmount 命令在客户端更加有用, 例如:

base@base2:~$ sudo showmount -e 192.168.123.153
Export list for 192.168.123.153:
/etc       192.168.123.0/24
/home/base 192.168.123.0/24
/home/web  192.168.123.0/24
# 查看 192.168.123.153 这个服务端共享了哪些文件夹

NFS设置的权限非常多, 在exports中配置的仅仅只是一部分设置, 还有非常的预设值, 这些预设值可以查看/var/lib/nfs/etab

base@base3:~$ cat /var/lib/nfs/etab
# ...... 前面两个省略
/home/web 192.168.123.0/24(rw,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,no_subtree_check,secure_locks,acl,no_pnfs,fsid=0,anonuid=65534,anongid=65534,sec=sys,rw,secure,root_squash,no_all_squash)

如果有其他客户端挂载了服务端的NFS文件系统时, 可以通过/var/lib/nfs/xtab查看详情

重载配置

通常会有需要新增, 删除共享的文件夹或者修改某些设置, 将会涉及到修改exports文件. 这样需要重启NFS来使配置生效, 一旦重启则需要再次向rpc注册, 此时可以使用exportfs命令来重载配置文件, 使修改的配置生效而不需要重启nfs服务.

选项与参数:

-a :全部挂载(或卸载)/etc/exports档案内的设定.
-r :重新挂载/etc/exports里面的设定,此外,亦同步更新/etc/exports/var/lib/nfs/xtab的内容.
-u :卸除某一目录.
-v :在export的时候,将分享的目录显示到屏幕上.

# 在服务器exports文件中添加一行: 
# /usr 192.168.123.0/24(rw,sync,fsid=0,no_subtree_check)

########## Server ##########
base@base3:~$ sudo exportfs -arv
exporting 192.168.123.0/24:/usr
exporting 192.168.123.0/24:/etc
exporting 192.168.123.0/24:/home/base
exporting 192.168.123.0/24:/home/web

########## Client ##########
base@base2:~$ sudo showmount -e 192.168.123.153
Export list for 192.168.123.153:
/usr       192.168.123.0/24 # 可以看到新增的共享文件夹
/etc       192.168.123.0/24
/home/base 192.168.123.0/24
/home/web  192.168.123.0/24

实践

拟定文件服务器: 192.168.123.153
拟定web服务器1: 192.168.123.151
拟定web服务器2: 192.168.123.152

  1. 文件服务器共享/home/web1指定web服务器1所有用户连接, 压缩权限为用户web1test只读;
# 首先需要为文件服务器新建 web1test 用户
base@base3:~$ sudo useradd -u 1010 -s /sbin/nologin web1test
base@base3:~$ id web1test 
uid=1010(web1test) gid=1010(web1test) groups=1010(web1test)

# 创建 /home/web1 文件夹并修改用户和组为 web1test
base@base3:~$ sudo mkdir -p /home/web1
base@base3:~$ sudo chown -R web1test:web1test /home/web1
base@base3:~$ ls -al /home/web1/
total 8
drwxr-xr-x 2 web1test web1test 4096 Jun 18 22:05 .
drwxr-xr-x 5 root     root     4096 Jun 18 22:05 ..

# 共享该文件夹
base@base3:~$ cat /etc/exports 
/home/web1 192.168.123.151(ro,sync,no_subtree_check,all_squash,anonuid=1010,anongid=1010)
base@base3:~$ sudo exportfs -arv
exporting 192.168.123.151:/home/web1

# 在web1服务器扫描一下文件服务器共享的文件夹
base@base1:~$ sudo showmount -e 192.168.123.153
Export list for 192.168.123.153:
/home/web1 192.168.123.151

# web1服务器也需要新建uid为1010的web1test用户
base@base1:~$ sudo useradd -u 1010 -s /sbin/nologin web1test
base@base1:~$ id web1test
uid=1010(web1test) gid=1010(web1test) groups=1010(web1test)

# 将共享文件夹挂载到web1服务器/mnt/nfs/web1下
base@base1:~$ sudo mkdir -p /mnt/nfs/web1
base@base1:~$ sudo mount -t nfs 192.168.123.153:/home/web1 /mnt/nfs/web1
base@base1:~$ ls -al /mnt/nfs/web1
total 8
drwxr-xr-x 2 web1test web1test 4096 Jun 18 22:05 .
drwxr-xr-x 3 root     root     4096 Jun 18 22:13 ..

# 尝试在/mnt/nfs/web1下创建1.txt
base@base1:~$ touch /mnt/nfs/web1/1.txt
touch: cannot touch '/mnt/nfs/web1/1.txt': Read-only file system

# 在文件服务器/home/web1创建1.txt, 查看web1服务器/mnt/nfs/web1是否存在1.txt
base@base3:~$ sudo touch /home/web1/1.txt
base@base1:~$ ls /mnt/nfs/web1/
1.txt
  1. 尝试使用web2服务器挂载文件服务器/home/web1
base@base2:~$ sudo mount -t nfs -o fg 192.168.123.153:/home/web1 /mnt
mount.nfs: access denied by server while mounting 192.168.123.153:/home/web1
  1. 文件服务器共享/home/web192.168.123.0/24网段, 压缩权限给uid1005web用户, 赋予读写权限.
# 创建uid为1005的web用户
base@base3:~$ sudo useradd -u 1005 -s /sbin/nologin web
base@base3:~$ id web
uid=1005(web) gid=1005(web) groups=1005(web)
base@base3:~$ sudo chown -R web:web /home/web
base@base3:~$ sudo chmod -R 755 /home/web
base@base3:~$ cat /etc/exports 
/home/web1 192.168.123.151(ro,sync,no_subtree_check,all_squash,anonuid=1010,anongid=1010)
/home/web 192.168.123.150/24(rw,sync,no_subtree_check,all_squash,anonuid=1005,anongid=1005)
base@base3:~$ mkdir -p /home/web
base@base3:~$ sudo exportfs -arv
exporting 192.168.123.151:/home/web1
exporting 192.168.123.150/24:/home/web

# 分别为web1和web2创建uid为1005的web用户, 并创建用于挂载的/www 文件夹
base@base1:~$ sudo useradd -u 1005 -s /sbin/nologin web
base@base1:~$ sudo mkdir -p /www
base@base2:~$ sudo useradd -u 1005 -s /sbin/nologin web
base@base2:~$ sudo mkdir -p /www

# 将文件服务器/home/web分别挂载在web1和web2上
base@base1:~$ sudo mount -t nfs -o fg 192.168.123.153:/home/web /www
base@base2:~$ sudo mount -t nfs -o fg 192.168.123.153:/home/web /www

# 在web1的/www下创建1.txt并写入 Hello Web2, 然后在web2下查看该文件
base@base1:~$ echo "Hello Web2" | sudo tee /www/1.txt
base@base2:~$ cat /www/1.txt 
Hello Web2

# 在web2下为1.txt追加 Hello Web1 然后在web1下查看该文件
base@base2:~$ echo "Hello Web1" | sudo tee -a /www/1.txt
base@base1:~$ cat /www/1.txt 
Hello Web2
Hello Web1

# 在web1下使用root用户在/www文件夹下创建2.txt并分别在web2和文件服务器下查看该文件权限
base@base1:~$ sudo touch /www/2.txt
base@base2:~$ ls -al /www/2.txt 
-rw-r--r-- 1 web web 0 Jun 18 22:45 /www/2.txt
base@base3:~$ ls -al /home/web/2.txt 
-rw-r--r-- 1 web web 0 Jun 18 22:45 /home/web/2.txt

NFS常用挂载参数说明

此项设置表示在执行 mount -t nfs -o-o选项可以设置参数

参数说明默认值
suid/nosuid(取消)程序在执行时具备的属主权限(设置了SUID/SGID后同组其他用户执行时)suid
rw/ro读写和只读,即使在exports中设置了rw,在挂载时仍然可以限制为只读rw
dev/nodev一般来说只有/dev这个目录才会需要,可以在挂载时取消dev
exec/noexec是否具有执行二进制文件的权限exec
user/nouser是否允许使用者具有配置文件的挂载和卸载权限nouser
auto/noauto如果将挂载命令写入了fstab, 那么在触发mount -a时是否会被挂载auto
fg/bg挂载行为为前台还是后台,前台会持续尝试挂载,直到成功或者超时,如果网络不稳定或者需要经常关机重启建议设置为bgfg
soft/hardhard: 一方脱机rpc会持续呼叫直到恢复;soft: 会在超时后重复呼叫,并非持续,系统的延迟不会这么明显, 如果经常关机或者网络不好, 建议设置softhard
intr当上面设置为hard时附带该参数表示在持续呼叫时可以被中断none
rsize读取的区块大小,局域网内客户端和服务端具有足够的内存,可以设置大点但不能超过带宽上限,以此可以提升nfs的传输能力rsize=1024
wsize写入的区块大小,局域网内客户端和服务端具有足够的内存,可以设置大点但不能超过带宽上限,以此可以提升nfs的传输能力wsize=1024

更加详细的说明和设置可以参看鸟哥的这文章

# Debian   Linux  

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×