14.1 NFS介绍
NFS介绍
-
NFS是Network File System的缩写;这个文件系统是基于网路层面,通过网络层面实现数据同步
-
NFS最早由Sun公司开发,分2,3,4三个版本,2和3由Sun起草开发,4.0开始Netapp公司参与并主导开发,目前最新为4.1版本——>4.1版本是2010年出来还没更新过
-
NFS数据传输基于RPC协议,RPC为Remote Procedure Call的简写,意思为 远程过程调用
-
例子:
-
服务端和客户端通信,A机器和B机器之间不能直接通信,需要借助RPC协议来实现
-
NFS应用场景是:A,B,C三台机器上需要保证被访问到的文件是一样的,A共享数据出来,B和C分别去挂载A共享的数据目录,从而B和C访问到的数据和A上的一致
-
NFS架构
- 例子:
- 跑了一个网站,上面传输了很多图片,用户访问一个图片时,需要从A机器上去请求,但A机器负载高,为了分担负载,就多弄了两台机器,B机器C机器同时提供服务;正常的话,需要到A机器上才能拿到数据,但是B机器和C机器做了负载均衡,分担了相同的服务器,那么用户也有可能到B机器或者C机器上;那么用户请求到B机器上的时候,如何才能获取到A机器上的数据呢;要么把A机器的数据传输到B机器上,同时传输到C机器上,但是这个不能时时更新,(用户上传的数据是存放在A机器上,但用户请求的时候数据是请求到B机器上)这样A上的数据还没到B上面去,就会导致用户请求获取的数据访问不到,访问为空,为404;那么NFS服务就可以解决这个问题,将A机器的数据共享到B机器、C机器,通过NFS来实现。有NFS服务以后,上传到A机器上的数据,B机器或C机器上就能马上看到和调用
- 总结,NFS就是实时同步
NFS原理图
- 服务端需要启动一个NFS服务,服务端要想给客户端提供服务,需要借助RPC协议,RPC协议是由rpcbind服务所实现的;在centos 5或者之前的版本叫portmap服务,centos6及之后的版本叫rpcbind服务,这两个都是一个服务,最终实现了RPC协议的通信,NFS服务默认不会监听任何端口(启动服务,但不会监听端口),最终监听端口,实现RPC通信的过程是由rpcbind服务产生的RPC协议实现的,RPC协议 默认监听 的 端口是111 端口;
- 整个流程为:服务端的NFS服务监听一个端口通过RPC协议监听的端口,再去告诉客户端RPC协议,然后NFS客户端通过本机的RPC端口回传数据信息到服务端NFS监听的端口,最终实现通信
- NFS服务需要借助RPC协议实现通信
14.2 NFS服务端安装配置
NFS服务端安装配置目录概要
- yum install -y nfs-utils rpcbind
- vim /etc/exports //加入如下内容
/home/nfstestdir 192.168.133.0/24(rw,sync,all_squash,anonuid=1000,anongid=1000)
- 保存配置文件后,执行如下准备操作
- mkdir /home/nfstestdir
- chmod 777 /home/nfstestdir
- systemctl start rpcbind
- systemctl start nfs
- systemctl enable rpcbind
- systemctl enable nfs
NFS服务端安装配置
1.首先准备两台机器,我这里准备两台虚拟机,A机器IP分别为192.168.5.130,B机器IP为192.168.5.133
A机器,查看IP:192.168.5.130
[root@xuexi-001 ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.5.130 netmask 255.255.255.0 broadcast 192.168.5.255
inet6 fe80::9625:3e1d:12c7:4fe6 prefixlen 64 scopeid 0x2
B机器,查看IP: 192.168.5.133
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.5.133 netmask 255.255.255.0 broadcast 192.168.5.255
inet6 fe80::cf14:5db2:1b49:f0c2 prefixlen 64 scopeid 0x2
2.将A机器作为服务端,并安装两个包,分别为 nfs-utils 和 rpcbind
- yum install -y nfs-utils rpcbind
[root@xuexi-001 ~]# yum install -y nfs-utils rpcbind
3.将B机器作为客户端,安装 nfs-utils 包
- 每次刚开机运行yum的时候都会很慢,因为需要重新生成一个缓存文件
- 有时yum安装的时候很慢,我们可以先禁掉,进入到/etc/yum.repos.d/目录下,将目录下的epel.repo文件改个名字,重新安装即可
- yum install -y nfs-utils
[root@localhost ~]# yum install -y nfs-utils
4.在安装完成后,需要去A机器中 /etc/exports 编辑配置文件
vim /etc/exports //加入如下内容
[root@xuexi-001 ~]# vi /etc/exports
/home/nfstestdir
要分享出去的目录是哪一个目录,这个目录是不存在的,后期还需要创建的
192.168.5.0/24(rw,sync,all_squash,anonuid=1000,anongid=1000)
指定你要给哪个机器去分享这个目录,首先定义IP或IP段
保存退出
5.下面就可以启动服务了,启动服务前需要先创建目录,并设置权限
6.在A机器上创建分享的目录
[root@xuexi-001 ~]# mkdir /home/nfstestdir
7.并设置成777的权限,这里设置777权限是为了方便接下里的实验
[root@xuexi-001 ~]# chmod 777 /home/nfstestdir
8.启动 rpcbind ,再启动前查看A机器上监听的端口,就会看到启动了1/systemd,这是centos7系统的一个特性——>111端口是rpcbind服务监听的
查看A机器:
用ps可以查看服务已经启动,因为有这个服务,所以监听了111端口
[root@xuexi-001 ~]# netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 2605/rpcbind
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1038/nginx: master
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 911/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1262/master
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 1038/nginx: master
tcp6 0 0 :::111 :::* LISTEN 2605/rpcbind
tcp6 0 0 :::22 :::* LISTEN 911/sshd
tcp6 0 0 ::1:25 :::* LISTEN 1262/master
tcp6 0 0 :::3306 :::* LISTEN 1223/mysqld
9.再到B机器上查看下端口,会看到也启动了rpcbind
[root@localhost ~]# netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 2577/rpcbind
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 852/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1029/master
tcp6 0 0 :::111 :::* LISTEN 2577/rpcbind
tcp6 0 0 :::22 :::* LISTEN 852/sshd
tcp6 0 0 ::1:25 :::* LISTEN 1029/master
注:如果rpcbind没有启动的话可以使用 systemctl start rpcbind启动服务
10.在A机器启动了rpcbind,下面就可以启动nfs服务,在使用ps查看
[root@xuexi-001 ~]# systemctl start nfs
[root@xuexi-001 ~]# ps aux | grep nfs
root 2713 0.0 0.0 0 0 ? S< 00:10 0:00 [nfsd4_callbacks]
root 2719 0.0 0.0 0 0 ? S 00:10 0:00 [nfsd]
root 2720 0.0 0.0 0 0 ? S 00:10 0:00 [nfsd]
root 2721 0.0 0.0 0 0 ? S 00:10 0:00 [nfsd]
root 2722 0.0 0.0 0 0 ? S 00:10 0:00 [nfsd]
root 2723 0.0 0.0 0 0 ? S 00:10 0:00 [nfsd]
root 2724 0.0 0.0 0 0 ? S 00:10 0:00 [nfsd]
root 2725 0.0 0.0 0 0 ? S 00:10 0:00 [nfsd]
root 2726 0.0 0.0 0 0 ? S 00:10 0:00 [nfsd]
root 2730 0.0 0.0 112720 968 pts/0 R+ 00:11 0:00 grep --color=auto nfs
11.同时也可以在A机器上ps aux |grep rpc查询,在启动nfs服务的时候,它会自动帮你启动rpc相关的一些服务
[root@xuexi-001 ~]# ps aux | grep rpc
rpc 2605 0.0 0.0 65000 1416 ? Ss 00:01 0:00 /sbin/rpcbind -w
rpcuser 2683 0.0 0.0 42420 1756 ? Ss 00:10 0:00 /usr/sbin/rpc.statd
root 2685 0.0 0.0 0 0 ? S< 00:10 0:00 [rpciod]
root 2695 0.0 0.0 43860 540 ? Ss 00:10 0:00 /usr/sbin/rpc.idmapd
root 2703 0.0 0.0 42608 944 ? Ss 00:10 0:00 /usr/sbin/rpc.mountd
root 2732 0.0 0.0 112720 968 pts/0 R+ 00:12 0:00 grep --color=auto rpc
12.而在客户端B机器上是没有的这些服务的
[root@localhost ~]# ps aux |grep rpc
rpc 2577 0.0 0.1 64956 1048 ? Ss 00:01 0:00 /sbin/rpcbind -w
root 2585 0.0 0.0 112676 980 pts/0 R+ 00:13 0:00 grep --color=auto
13.如果想让nfs开机启动,还需要执行systemctl enable nfs 命令,在服务端A机器上调用
- systemctl enable nfs 开机启动nfs
- systemctl disable nfs 关闭开机启动
[root@xuexi-001 ~]# systemctl enable nfs
Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to /usr/lib/systemd/system/nfs-server.service.
14.3 NFS配置选项
NFS配置选项
- rw 读写
- ro 只读
- sync 同步模式,内存数据实时写入磁盘,相应的就会降低磁盘效率
- async 非同步模式,它会每隔一段时间才会将数据刷新到磁盘
- 优势:能够保证磁盘的效率
- 劣势:万一断电,就会有可能丢失一部门数据
- no_root_squash 客户端挂载NFS共享目录后,root用户不受约束,权限很大
- NFS,要想在客户端上去使用服务端上共享的目录,需要去把它挂载到客户端上的一个挂载点,那就跟本地上的目录是一样的,在操作本地的目录时候,肯定会有一些权限设置,如果加上no_root_squash,这样root用户去共享目录下读写文件的时候,就不会受到限制(就相当于root用户在本地上读写)
- root_squash 与上面选项相对,客户端上的root用户收到约束,被限定成某个普通用户
- all_squash 客户端上所有用户(包括root用户)在使用NFS共享目录时都被限定为一个普通用户
- anonuid/anongid 和上面几个选项搭配使用,定义被限定用户的uid和gid
客户端上挂载
1.首先在客户端B机器上安装了rpcbind,它是由nfs-utils 这个包自动安装的
yum install -y nfs-utils
2.在B机器上安装完成后不需要启动任何服务
3.在B机器上执行 showmount -e 命令
- showmount -e 192.168.74.129 //查看在NFS服务端是否有权限
- 该ip为NFS服务端ip
[root@localhost ~]# showmount -e 192.168.5.130
clnt_create: RPC: Port mapper failure - Unable to receive: errno 113 (No route to host)
4.这时候会看到报错了,RPC: Port mapper failure说明网络不通,无法与192.168.5.130 端口通信
- 不能通信的两种情况
- 要么是对方没有开启rpcbind的服务,没有监听111端口
- 要么是防火墙导致的原因
5.因为之前在服务端已经开启了rpcbind服务,那这时只能说明是防火墙导致的,所以要想让NFS实现正常的通信,还需要把防火墙关闭,因为NFS服务比较特殊,虽然rpc可以通信,就算iptables把111端口放行但NFS也不一定能正常通信,因为它们使用了一个不固定的端口
6.这时先把A机器服务端和B机器客户端,防火墙关闭,命令systemctl stop firewalld
A机器关闭防火墙
[root@xuexi-001 ~]# systemctl stop firewalld
[root@xuexi-001 ~]# getenforce
Disabled
B机器关闭防火墙
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# getenforce
Enforcing
[root@localhost ~]# setenforce 0
[root@localhost ~]# getenforce
Permissive
7.这时再去B机器客户端来showmount -e 192.168.5.130 ,这时会看到可以能show到远程服务端192.168.5.130 这台机器,它共享的目录是/home/nfstestdir
[root@localhost ~]# showmount -e 192.168.5.130
Export list for 192.168.5.130:
/home/nfstestdir 192.168.5.0/24
8.这时候在B机器客户端上来挂载了,然后查看——>挂载的时间可能有点慢
[root@localhost ~]# mount -t nfs 192.168.5.130:/home/nfstestdir /mnt/
[root@localhost ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/sda3 18G 992M 17G 6% /
devtmpfs 479M 0 479M 0% /dev
tmpfs 489M 0 489M 0% /dev/shm
tmpfs 489M 6.8M 482M 2% /run
tmpfs 489M 0 489M 0% /sys/fs/cgroup
/dev/sda1 197M 97M 100M 50% /boot
tmpfs 98M 0 98M 0% /run/user/0
192.168.5.130:/home/nfstestdir 18G 8.4G 9.5G 47% /mnt
9.这个就是远程NFS服务端共享的目录
10.这时到B机器客户端共享的目录下创建文件
[root@localhost ~]# cd /mnt/
[root@localhost mnt]# ls
[root@localhost mnt]# touch 111.txt
[root@localhost mnt]# ls -l
总用量 0
-rw-r--r--. 1 1000 1000 0 8月 4 16:08 111.txt
11.到A机器的服务端查看,可以看到文件的属主和属组都为1000
[root@xuexi-001 ~]# ls -l /home/nfstestdir/
总用量 0
-rw-r--r-- 1 user1 user1 0 8月 4 16:08 111.txt
[root@xuexi-001 ~]# id user1
uid=1000(user1) gid=1000(user1) 组=1000(user1)
- 原因是配置 /etc/export
- 文件时,配置了anonuid=1000,anongid=1000
- 客户端显示 1000 用户
- 是因为客户端机器上并没有1000权限的用户
- 同样,服务端显示usesr1,是因为服务端上的机器user1 就是1000权限的用户
总结
在/etc/exports文件中的/home/nfstestdir
192.168.5.0/24(rw,sync,all_squash,anonuid=1000,anongid=1000) ,其中ip与(rw之间不能有空格, 否则客户端挂载的目录会变成只读..
14.4 exportfs命令
常用选项
- -a 全部挂载或者全部卸载
- -r 重新挂载
- -u 卸载某一个目录
- -v 显示共享目录
- 以下操作在服务端上 -vim /etc/exports //增加
/tmp/ 192.168.133.0/24(rw,sync,no_root_squash)
- exportfs -arv //不用重启nfs服务,配置文件就会生效
- 以下操作在客户端
- mkdir /aminglinux
- mount -t nfs -onolock 192.168.133.130:/tmp /aminglinux
- touch /aminglinux/test.txt
- ls -l !$
- -oremount,nfsvers=3
exportfs命令
- exportfs命令和nfs-utils这个包一起安装的
- 例子:
- 假设在第一次配置nfs的共享目录,之后需要新增、更改某些机器或共享的目录;
- 首先需要更改配置文件,然后重启NFS服务,但如果远程客户端正在使用NFS服务,正在挂载着,如果你需要先停止nfs服务,那远程的客户端就会挂起,就会很大的影响,造成服务异常,进程异常,有很大可能导致系统坏掉
- nfs服务不能随便重启,要重启,就需要先去服务器上,把挂载的目录卸载下来
- 在卸载目录的时候,若是在当前目录下去卸载会提示umount.nfs4: /mnt: device is busy
- 方法一:退出该目录后,再去卸载
- 方法二:在目录下卸载的时候,加 -l 选项,表示 lazy 懒惰的意思
- 在卸载目录后,在重启nfs服务
- 若是挂载了很多台机器,那么每台机器都需要去卸载,就会很麻烦,降低了工作效率
- 方法:使用exportfs命令,重新加载下
- exportfs命令
- -a 全部挂载或者全部卸载
- -r 重新挂载
- -u 卸载某一个目录
- -v 显示共享目录
1.在B机器客户端,卸载目录
[root@localhost ~]# umount /mnt/
[root@localhost ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/sda3 18G 992M 17G 6% /
devtmpfs 479M 0 479M 0% /dev
tmpfs 489M 0 489M 0% /dev/shm
tmpfs 489M 6.8M 482M 2% /run
tmpfs 489M 0 489M 0% /sys/fs/cgroup
/dev/sda1 197M 97M 100M 50% /boot
tmpfs 98M 0 98M 0% /run/user/0
2.然后在A机器服务端,使用exportfs -arv命令
exportfs -arv命令,重新使配置文件生效
[root@xuexi-001 ~]# exportfs -arv
exporting 192.168.5.0/24:/home/nfstestdir
3.验证,在A机器上的/etc/exports配置文件中,在增加一行,把 /tmp 目录单独共享给192.168.5.133 这个IP
[root@xuexi-001 ~]# vi /etc/exports
/home/nfstestdir 192.168.5.0/24(rw,sync,all_squash,anonuid=1000,anongid=1000)
/tmp 192.168.5.133(rw,sync,no_root_squash)
保存退出
4.然后在A机器服务端执行exportfs -arv命令
[root@xuexi-001 ~]# exportfs -arv
exporting 192.168.5.133:/tmp
exporting 192.168.5.0/24:/home/nfstestdir
5.在B机器客户端showmount -e看是否生效——>并没有重启nfs服务,就已经生效
[root@localhost ~]# showmount -e 192.168.5.130
Export list for 192.168.5.130:
/home/nfstestdir 192.168.5.0/24
/tmp 192.168.5.133
6.在B机器客户端挂载,将 tmp目录 挂载到 mnt 目录下
[root@localhost ~]# mount -t nfs 192.168.5.130:/tmp/ /mnt/
[root@localhost ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/sda3 18G 992M 17G 6% /
devtmpfs 479M 0 479M 0% /dev
tmpfs 489M 0 489M 0% /dev/shm
tmpfs 489M 6.8M 482M 2% /run
tmpfs 489M 0 489M 0% /sys/fs/cgroup
/dev/sda1 197M 97M 100M 50% /boot
tmpfs 98M 0 98M 0% /run/user/0
192.168.5.130:/tmp 18G 8.4G 9.5G 47% /mnt
7.现在在B机器客户端,查看到的/mnt/目录就是192.168.5.130IP下的tmp目录
[root@localhost ~]# ls /mnt/
aming.sock systemd-private-cca061734a284ab68452996f54b9a3e7-chronyd.service-UKFBkE
mysql.bak systemd-private-cca061734a284ab68452996f54b9a3e7-vgauthd.service-fXSgVu
mysql.sock systemd-private-cca061734a284ab68452996f54b9a3e7-vmtoolsd.service-zsXw2n
php-fcgi.sock user.bak
8.再到A机器上查看tmp目录,会看到两个目录下的文件内容会一样的
[root@xuexi-001 ~]# ls /tmp/
aming.sock systemd-private-cca061734a284ab68452996f54b9a3e7-chronyd.service-UKFBkE
mysql.bak systemd-private-cca061734a284ab68452996f54b9a3e7-vgauthd.service-fXSgVu
mysql.sock systemd-private-cca061734a284ab68452996f54b9a3e7-vmtoolsd.service-zsXw2n
php-fcgi.sock user.bak
9.这时在B机器客户端的mnt目录下创建文件,并查看目录下的文件,能看到新建的1212.txt文件的属主和属组都是root
[root@localhost ~]# cd /mnt/
[root@localhost mnt]# touch 1212.txt
[root@localhost mnt]# ls -l /mnt/
总用量 652
-rw-r--r--. 1 root root 0 8月 4 16:38 1212.txt
srw-rw-rw-. 1 root root 0 8月 4 15:44 aming.sock
-rw-r--r--. 1 root root 657618 7月 25 22:07 mysql.bak
srwxrwxrwx. 1 1003 1003 0 8月 4 15:44 mysql.sock
srw-rw-rw-. 1 root root 0 8月 4 15:44 php-fcgi.sock
drwx------. 3 root root 17 8月 4 15:43 systemd-private-cca061734a284ab68452996f54b9a3e7-chronyd.service-UKFBkE
drwx------. 3 root root 17 8月 4 15:43 systemd-private-cca061734a284ab68452996f54b9a3e7-vgauthd.service-fXSgVu
drwx------. 3 root root 17 8月 4 15:43 systemd-private-cca061734a284ab68452996f54b9a3e7-vmtoolsd.service-zsXw2n
-rw-r--r--. 1 root root 7229 7月 25 22:19 user.bak
10.这时再到A机器服务端查看tmp目录,会看到1212.txt文件的属主和属组也是root
[root@xuexi-001 ~]# ls -l /tmp/
总用量 652
-rw-r--r-- 1 root root 0 8月 4 16:38 1212.txt
srw-rw-rw- 1 root root 0 8月 4 15:44 aming.sock
-rw-r--r-- 1 root root 657618 7月 25 22:07 mysql.bak
srwxrwxrwx 1 mysql mysql 0 8月 4 15:44 mysql.sock
srw-rw-rw- 1 root root 0 8月 4 15:44 php-fcgi.sock
drwx------ 3 root root 17 8月 4 15:43 systemd-private-cca061734a284ab68452996f54b9a3e7-chronyd.service-UKFBkE
drwx------ 3 root root 17 8月 4 15:43 systemd-private-cca061734a284ab68452996f54b9a3e7-vgauthd.service-fXSgVu
drwx------ 3 root root 17 8月 4 15:43 systemd-private-cca061734a284ab68452996f54b9a3e7-vmtoolsd.service-zsXw2n
-rw-r--r-- 1 root root 7229 7月 25 22:19 user.bak
11.这就是因为在A机器服务端的配置文件中,使用了no_root_squash ,所以root用户不受约束,在B机器上到挂载点下,到共享目录下,就可以像在本地磁盘使用root用户一样,是不受限制的(通常情况下,不限制root用户的比较多)
14.5 NFS客户端问题
- NFS客户端问题
- NFS 4版本会有该问题
- 客户端挂载共享目录后,不管是root用户还是普通用户,创建新文件时属主、属组为nobody
- 客户端挂载时加上 -o nfsvers=3
- 客户端和服务端都需要
- vim /etc/idmapd.conf //
- 把“#Domain = local.domain.edu” 改为 “Domain = xxx.com” (这里的xxx.com,随意定义吧),然后再重启rpcidmapd服务
NFS知识点
- 在centos6中,遇到的问题比较多,针对的NFS 4版本有这个问题
- 问题:客户端挂载共享目录后,不管是root用户还是普通用户,创建新文件时属主、属组为nobody,虽然已经定义了 no_root_squash 不在限制root用户,最终创建完文件后发现属主和属组不是root或者是限定的1000,而是显示的是 nobody ,这就是NFS 4版本出现的问题,尤其是在centos6 系统上
- 解决问题:
- 方法一:是在客户端挂载的时候,加上-o nfsvers=3 ,意思就是指定NFS的版本为 3 ,不在用4的版本
- mount -t nfs -o nfsvers=3 192.168.202.130:/tmp/ /mnt/
- 若是不想卸载,直接挂载,可以使用mount -t nfs -oremount,nfsvers=3 192.168.202.130:/tmp/ /mnt/ (前提是先挂载上去)
- 方法二:更改配置文件vim /etc/idmapd.conf ,把“#Domain = local.domain.edu” 改为 “Domain = xxx.com” (这里的xxx.com,随意定义吧),然后再重启rpcidmapd服务
- 在cnetos7中,本身是没有rpcidmapd服务的,只需要重启rpcbind服务就可以了