什么是NFS服务器
NFS(Network File System)即网络文件系统,它允许网络中的计算机之间共享资源。在NFS的应用中,本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件,就像访问本地文件一样。简单来说就是一个共享服务。不同于ftp协议,ftp需要将文件通通下载到本地之后才能修改,占用了本地空间。而nsf可以直接在服务器上进行对文件的修改。
工作原理
VFS简单介绍
linux的文件系统高达几十个,如果ext4,ext2,nfs等等。 我们在用ls命令时,不能每个文件系统都专门设计一个ls命令。而vfs就是将所有的文件系统接口汇总成一个接口(API)。在访问文件系统时通过vfs抽象层来访问到真正的文件系统。
NFS工作逻辑
针对上图来进行说明:
-
用户在访问本地文件时,通过本地磁盘访问即可。本地磁盘上的文件通过vfs功能抽象出来统一的系统接口供用户使用。
-
对于NFS来说,它基于网络,用户在访问NFS文件系统时,通过套接字TCP/UDP IP协议(
NFS很早以前都是UDP协议,而现在基本上都是用TCP协议
)来访问NFS服务器。服务器在接收到报文协议之后,服务器经过相关操作将结果返回给用户。而这些都是通过RPC
实现的。`(服务器上的磁盘里可以装有各种各样的文件系统,只不过它通过VFS将客户想要访问的文件通通转化为NFS系统返回给客户而已。) -
NFS提供众多的功能,每个功能就得提供一个端口,导致NFS的端口永远是不固定的。那么客户端怎么知道NFS的端口呢。RPC提供了统一对外的端口111。如果NFS需要提供什么功能,它会向RPC进行注册端口,RPC会记录NFS注册的端口。并且告诉客户端,让客户端连接上去。也是
rpc.bind
的功能 -
注意:用户在访问NFS时是以用户自己的身份访问。同样服务器端也是如此。问题就出现了,假如客户端的用户ID1001,用户名centos 。服务器上的用户ID也是1001,用户却是kun。这两个名字不一样,却是同一个用户。因为用户是以ID号存在的。我们看到的用户名称都是经过反解析才看到。这样服务器端看自己的文件是kun,而客户端看到的文件是centos,又假如centos拥有一切能力,那就可以在nfs服务器上肆无忌惮。为避免这种错误,我们就要专门建立存放用户名的地方。如ldap,nis等…
NFS辅助功能
RPC:简单来说就是客户机远程调用服务器上函数以实现系统调用。
mountd:提供NFS服务认证功能。
解释:内核中的nfs模块监听套接字,需要用户空间内的进程向内核注册进行代为监听套接字,但是为了数据安全性,不是所有人都可以随便访问的。这时就需要一个认证功能mountd,当用户去访问nfs时,它通过mountd的认证,就可以进行访问。反之拒绝。这里mountd的端口是半随机的,也就是不确定。客户怎么mountd的端口?客户的nfs在连接服务器时,需要先跟rpc-server进行连接。由rpc-server来告知mountd的端口,然后进行连接。
rpc.lockd:加锁;
解释:用户在访问文件时,会对文件进行一个暂时加锁的状态,别的用户想访问同一个文件时,会访问不了,这样为防止数据在修改时出现混乱的状态。
rpc.statd:状态;
解释:用户修改文件时出现不可抗力因素,导致nfs出现故障,nfs重新启动之后,故障前访问的文件会有状态通知。
NFS使用
使用NFS之前,先查看内核中是否含有NFS模块。
[root@bogon mysql]# lsmod | grep nfs
nfsd 302418 13
auth_rpcgss 59343 2 nfsd,rpcsec_gss_krb5
nfs_acl 12837 1 nfsd
lockd 93600 1 nfsd
grace 13295 2 nfsd,lockd
sunrpc 300464 23 nfsd,rpcsec_gss_krb5,auth_rpcgss,lockd,nfs_acl
安装nfs-utils
由于nfs模块处于内核,无法监听套接字,所以需要nfs-utils来代为监听。
[root@bogon mysql]# yum info nfs-utils
已加载插件:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
* base: mirrors.huaweicloud.com
* epel: mirror01.idc.hinet.net
* extras: mirrors.huaweicloud.com
* updates: mirrors.huaweicloud.com
已安装的软件包
名称 :nfs-utils
架构 :x86_64
时期 :1
版本 :1.3.0
发布 :0.61.el7
大小 :1.0 M
源 :installed
配置文件/etc/exports
既然是共享,就需要定义你想给谁共享以及共享哪些文件。可以使用man exports
格式: /PATH/TO/SOME_DIR clients1(export_options, ...) clients2(export_options, ...)
-
/PATH/TO/SOME_DIR
:要共享的目录,最好是一个单独的分区 -
client
: singalhost:ipv4, ipv6, FQDN;
network:address/netmask, 支持长短格式的掩码;
wildcards:主机名通配,例如:*.magedu.com;
netgroups:NIS域内的主机组;@group_name;
anonymous:使用*通配所有主机;
两个客户端直接要使用空格隔开,客户端后面的括号不要有空格! -
export_options
:- General Options:
ro:只读
rw:读写
sync:同步
async:异步;一般都用异步,同步会影响性能
secure:客户端端口小于1024,否则就要使用insecure选项
- User ID Mapping:
root_squash:压缩root用户,一般指将其映射为nfsnobody; 就是来宾用户
no_root_squash:不压缩root用户;
危险!!
all_squash:压缩所有用户;
anonuid and anongid:将压缩的用户映射为此处指定的用户;
- General Options:
NFS Client的常用命令:
NFS属于文件系统,所以需要挂载之后使用
mount -t nfs servername:/path/to/share /path/to/mount_point [-rvVwfnsh ] [-o options]
查看NFS服务器上的挂载相关信息
showmount -e NFS_SERVER_IP: 查看指定的nfs server上导出的所有文件系统;
修改NFS配置文件后,重载NFS
exportfs:
-r:重新导出;
-a:所有文件系统;
-v:详细信息;
-u:取消导出文件系统;
示例
客户端在挂载nfs服务时,默认情况下客户端上的root用户权限将会被压榨,被当做nfsnobody用户来进行访问。普通用户则仍然是普通用户。
1)将/data/share目录分享出去
[root@localhost ~]# cat /etc/exports
/data/share/ *(rw)
2)在客户端上对share下的文件进行修改
[root@localhost ~]# mount 11.2.1.205:/data/share /mnt/share1
3)发现无法写入文件
5 dshadskajidsnkjada
6 dsjakljdslka
"/mnt/share1/f1"
"/mnt/share1/f1" E212: 无法打开并写入文件
请按 ENTER 或其它命令继续
4)将服务器上的文件夹权限设置成777,使其它用户也有写权限
[root@localhost ~]# chmod 777 /data/share
5)在客户端上再次对f1进行编辑
[root@localhost ~]# cat /mnt/share1/f1
a
b
c
6)查看服务器端f1文件的属主和属组,发现变成来nfsnobody权限。
[root@localhost ~]# ll /data/share
总用量 4
-rw-r--r-- 1 nfsnobody nfsnobody 6 3月 21 15:24 f1
7)客户端切换到ydong用户,重新在/mnt/share1下创建我呢间
[ydong@localhost ~]$ echo "ydong" > /mnt/share1/f2
8)查看服务器端上f2的文件,发现属主和属组都是ydong
[root@localhost ~]# ll /data/share
总用量 8
-rw-r--r-- 1 nfsnobody nfsnobody 6 3月 21 15:24 f1
-rw-rw-r-- 1 ydong ydong 6 3月 21 15:26 f2
这就是因为root的权限太大导致root权限被压榨,而普通用户权限相对来说比较小,所以并未压缩。
如果nfs客户端上的用户在nfs服务器端上没有,那么nfs客户端上普通用户创建的文件将会映射成服务器端上相同id号的属组和属主。
如果nfs客户端和nfs服务器上拥有同一个id号的情况,nfs客户端和服务器端会出现两个不同属组和属主的文件。
NFS自动挂载
开机自动挂载
1)nfs共享目录
[root@localhost ~]# cat /etc/exports
/data/share/ *(rw)
2)在客户端fstab文件中写入挂载选项
[root@localhost ~]# cat /etc/fstab
11.2.1.205:/data/share /mnt/share1 nfs defaults 0 0
3)查看挂载效果
[root@localhost ~]# mount -a
[root@localhost ~]# mount | grep 11
11.2.1.205:/data/share on /mnt/share1 type nfs4 (rw,relatime,vers=4.1,rsize=262144,wsize=262144,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=11.2.3.46,local_lock=none,addr=11.2.1.205)
autofs自动挂载
不需要开机就启动挂载的那些文件,可以使用autofs实现。直接进入某目录而实现自动挂载
比如我们正常挂载磁盘的时候,我们需要将/dev/cdrom挂载到某个挂载点上。
[root@localhost ~]# mount /dev/cdrom /media/cdrom/
mount: /dev/sr0 写保护,将以只读方式挂载
有了autofs,我们可以直接进入目录实现自动挂载,而不用手动挂载
[root@localhost ~]# df
文件系统 1K-块 已用 可用 已用% 挂载点
devtmpfs 1001816 0 1001816 0% /dev
tmpfs 1018848 0 1018848 0% /dev/shm
tmpfs 1018848 9984 1008864 1% /run
tmpfs 1018848 0 1018848 0% /sys/fs/cgroup
/dev/mapper/centos_bogon-root 20961280 4062668 16898612 20% /
/dev/sda1 508580 167020 341560 33% /boot
/dev/mapper/centos_bogon-data 20961280 65760 20895520 1% /data
/dev/mapper/centos_bogon-home 10475520 70212 10405308 1% /home
/dev/mapper/centos_bogon-var 20961280 711844 20249436 4% /var
tmpfs 203772 0 203772 0% /run/user/0
11.2.1.205:/data/share 20961280 65792 20895488 1% /mnt/share1
1)启动autofs功能
[root@localhost ~]# systemctl start autofs
2)进入到/misc/cd目录,实现自动挂载
[root@localhost ~]# cd /misc/cd
[root@localhost cd]# df
/dev/sr0 10767514 10767514 0 100% /misc/cd
实现这些功能是autofs的配置文件实现的。
[root@localhost ~]# cat /etc/auto.master
/misc /etc/auto.misc # 定义了挂载点父目录以及挂载配置文件
[root@localhost ~]# cat /etc/auto.misc
cd -fstype=iso9660,ro,nosuid,nodev :/dev/cdrom # 挂载点子目录,以及挂载选项及挂载的磁盘
实现nfs自动挂载
1)将需要共享的目录写入到/etc/exports中
[root@server ~]# cat /etc/exports
/data/share/ *(rw)
2)在客户端中auto/misc定义父目录以及挂载选项,如果文件夹为d1/d2/d3,那么它的父目录就是d1/d2。就是相对路径的父目录
[root@client ~]# cat /etc/auto.master
/mnt /etc/nfs.misc
3)写nfs.misc的配置文件
[root@client share1]# cat /etc/nfs.misc
share1 -fstype=nfs,rw,nosuid,vers=3 11.2.1.205:/data/share
4)重新启动nfs
[root@client ~]# systemctl restart autofs
[root@client ~]# df
文件系统 1K-块 已用 可用 已用% 挂载点
devtmpfs 1001816 0 1001816 0% /dev
tmpfs 1018848 0 1018848 0% /dev/shm
tmpfs 1018848 9988 1008860 1% /run
tmpfs 1018848 0 1018848 0% /sys/fs/cgroup
/dev/mapper/centos_bogon-root 20961280 4062696 16898584 20% /
/dev/sda1 508580 167020 341560 33% /boot
/dev/mapper/centos_bogon-data 20961280 65760 20895520 1% /data
/dev/mapper/centos_bogon-home 10475520 70212 10405308 1% /home
/dev/mapper/centos_bogon-var 20961280 710996 20250284 4% /var
tmpfs 203772 0 203772 0% /run/user/0
5)进入到客户端的/mnt/share下
[root@client ~]# cd /mnt/share1
[root@client share1]# df
11.2.1.205:/data/share 20961280 65792 20895488 1% /mnt/share1
绝对路径挂载
两个用户希望看到到的共享内容不一样,我们就需要使用绝对路径法来实现
1)提供两个共享文件
[root@server ~]# cat /etc/exports
/data/wang *(rw)
/data/ydong *(ro)
2)在客户端设置auto配置文件
[root@client ~]# cat /etc/auto.master
/- /etc/nfs.misc #表示使用绝对路径
3)编写/etc/nfs.misc
[root@client ~]# cat /etc/nfs.misc
/home/ydong -fstype=nfs,ro,nosuid,vers=3 11.2.1.205:/data/ydong
/home/wang -fstype=nfs,rw,nosuid,vers=3 11.2.1.205:/data/wang
4)测试
[root@client ~]# su - ydong
上一次登录:六 3月 21 15:25:41 CST 2020pts/0 上
-bash-4.2$ ls
ydong.home
-bash-4.2$ exit
登出
[root@client ~]# su - wang
-bash-4.2$ ls
wang.home
-bash-4.2$
出现上述情况是因为nfs服务器直接把ydong和wang的家目录完全霸占了,所以才不会有主机名称。