简介
- 网络文件系统
NFS
是Network File System
的缩写, 他是一种分布式文件系统, 用来实现客户端主机可以
访问服务端文件, 并且访问过程和本地存储时一样; NFS
基于开放网络运算远程过程调用(ONC RPC
)系统: 一个开放, 标准的RFC系统, 任何人或组织都可以依据标准实现它.NFS
可用于热备服务器高可用
和数据库高可用
以及负载均衡
的文件服务器等.
安装
- 包管理器安装
对于Debian
来说, 安装NFS
很容易; 在Debian Buster
下, 执行以下命令即可安装.
sudo apt install nfs*
- 编译安装
// 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)
表示分配该部分客户端连接后的权限
权限 | 含义 |
---|---|
ro | read-only 只读 |
rw | read-write 读写 |
sync | 将数据同步写入内存和磁盘中, 适合实时性要求高的场合 |
async | 将数据同步先写入内存, 然后再写入磁盘, 效率高, 但有丢数据的风险 |
all_squash | 所有访问服务端的用户权限都将压缩为匿名用户, uid/gid 会变为nobody 或nfsnobody |
root_squash | NFS客户端以root用户访问时, 映射为NFS服务器的匿名用户 |
no_root_squash | NFS客户端以root管理员访问时, 映射为NFS服务器的root用户 |
配置
NFS
的重要技巧
- 确保所有连接
NFS
服务端的服务器都具有相同的权限- 使用
all_squash
将所有客户端的连接全部压缩为匿名用户. - 设置
anonuid
和anongid
指定服务端的对应用户
- 使用
- 所有客户端和服务端需要具有相同的
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
- 文件服务器共享
/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
- 尝试使用
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
- 文件服务器共享
/home/web
给192.168.123.0/24
网段, 压缩权限给uid
为1005
的web
用户, 赋予读写权限.
# 创建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 | 挂载行为为前台还是后台,前台会持续尝试挂载,直到成功或者超时,如果网络不稳定或者需要经常关机重启建议设置为bg | fg |
soft/hard | hard : 一方脱机rpc 会持续呼叫直到恢复;soft : 会在超时后重复呼叫,并非持续,系统的延迟不会这么明显, 如果经常关机或者网络不好, 建议设置soft | hard |
intr | 当上面设置为hard 时附带该参数表示在持续呼叫时可以被中断 | none |
rsize | 读取的区块大小,局域网内客户端和服务端具有足够的内存,可以设置大点但不能超过带宽上限,以此可以提升nfs 的传输能力 | rsize=1024 |
wsize | 写入的区块大小,局域网内客户端和服务端具有足够的内存,可以设置大点但不能超过带宽上限,以此可以提升nfs 的传输能力 | wsize=1024 |
更加详细的说明和设置可以参看鸟哥的这文章