写在前面
这则笔记开始,整理NFS服务的相关知识,主要包括以下内容:
NFS工作原理
NFS部署
NFS挂载
什么是NFS?
NFS 是Network File System的缩写,即网络文件系统。一种使用于分散式文件系统的协定,由Sun公司开发,于1984年向外公布。它独立于操作系统,通过网络让不同的机器、不同的操作系统能够彼此分享数据。
比如,NFS 服务器可以让你将网络远程的 NFS 服务器分享的目录,挂载到本地主机上,在本地端的机器看起来,那个远程主机的目录就好像是自己的一个磁盘分区槽一样。
对于一个大型网站而言,之所以需要NFS,主要是基于两点需求:
实现数据信息共享(数据库内容);
保持数据信息一致 (网站代码、展示内容);
NFS共享系统原理
在NFS服务端创建共享目录;
通过mount网络挂载,将NFS客户端本地目录挂载到NFS服务端共享目录上;
NFS客户端挂载目录上创建、删除、查看数据操作,等价于在服务端进行的创建 删除 查看操作;
NFS部署
NFS的工作流程
由程序在NFS客户端发起存取文件的请求,客户端本地的RPC(rpcbind)服务会通过网络向NFS服务端的RPC的111端口发出文件存取功能的请求。`
NFS服务端的RPC找到对应已注册的NFS端口,通知客户端RPC服务。
客户端获取正确的端口,并与NFS daemon联机存取数据。
存取数据成功后,返回前端访问程序,完成一次存取操作。
准备工作:准备两台虚拟机
因为nfs是在两台以上的机器之间共享文件的,因此,要完成这个实验,必须先至少有两台机器。这里的采用的方法是克隆一台虚拟机。将原来的虚拟机作为客户端local-Linux01,克隆虚拟机作为服务器端local-linux02.
第一步:克隆虚拟机:点击菜单栏 virtual machine-> create full clone
注意:这里有两个前提,负责无法创建快照。
把所有的快照snapshots都删除
虚拟机shutdown,
第二步:修改静态ip地址
1 | vi /etc/sysconfig/network-scripts/ifcfg-ens33 |
- 使用ping命 令检查网络是否联通
第三步:修改主机名
这一步不是必须 ,不过原来的虚拟机和克隆主机的hostname目前都是一样的,区分起来比较费劲,所以将原主机改为local-linux01
, 克隆主机改为local-lin ux02
,好进行区分。
1 | //原虚拟机hostname改为 local-linux01 |
第四步:配置虚拟机ssh登陆
1. 编辑配置文件
1 | vi /etc/ssh/sshd_config |
2. 生成密匙对(在虚拟机一上操作)
1 | ssh-keygen //生成密钥 |
3. 编辑认证文件 (在虚拟机二上操作)
1 | vi /root/.ssh/authorized_keys 点击I选择编辑,加上刚才复制的代码_ |
4. 远程登陆 (在虚拟机一上操作)
1 | ssh root@172.16.155.132 |
登陆之后,跟在mac上用iterm2登陆虚拟机是一样样的。
至此,两台虚拟机已经准备好,下面开始将local-linux01作为服务器;local-linux02作为客服端,安装nfs共享服务。
服务器端配置
- 关闭防火墙
1 | systemctl stop firewalld |
- 关闭selinux
1 | vi /etc/selinux/config |
- 安装
nfs-utils
、rpcbind
1 | yum install -y nfs-utils rpcbind |
- nfs配置
1 | vi /etc/exports |
- 创建共享文件夹
1 | //创建共享文件夹 |
- 设置开机启动
1 | //开启NFS服务 |
如下所示,说明成功
nfs配置解读
如前所示,nfs的配置文件为/etc/exports,他的配置文件只有一行,如下所示:
共分为三个部分:
第一部分:/home/nfstestdir/ 表示共享目录
第二部分:192.168.188.0/24 允许哪些主机访问,这里既可以是ip,也可以是ip段;
第三部分:相关权限设置
rw
读写权限;ro
只读权限;sync
同步模式,内存数据实时写入磁盘;async
异步模式,内存数据定期写入磁盘;no_root_squash
表示root用户对共享目录具有最高权限,安全性较差;root_squash
root用户权限受限,只有普通用户权限;all_squash
所有用户均为限定为普通用户身份;anonuid/anongid
与root_squash
或者all_squash
连用,指定用户被限定权限后的uid/gid。
客户端配置
第一步:安装nfs-utils
1 | [root@local-linux01 ~]# yum install -y nfs-utils |
第二步:关闭防火墙firewalld,禁止selinx
1 | //关闭firewalld |
第三步:挂在共享文件夹
- 检测服务端开放情况
1 | [root@local-linux01 ~]# showmount -e 172.16.155.132 |
TroubleShooting
:无法建立联系
之前已经关闭了firewalld 和 selinx,但是iptables还在启用,网上查了一下,果然还是端口配置的问题。
原来RPC在NFS服务启动的时候,会随机给nfs服务分配端口,但这些端口在iptables当中并没有放行,所以就无法建立联系。
解决思路无非两条:
关闭iptables;
配置iptables,开放端口;
想想看,如果在现实当中,为了运行一个共享服务,把防火墙统统干掉,还是很不安全的。所以,思路一被否决。于是,只能想办法配置iptables。
解决方法:
- 查看端口信息
这里使用rpcinfo
命令, rpcinfo -p [host]
列出所有在host用portmap注册的RPC程序,如果没有指定host,就查找本机上的RPC程序。
1 | [root@local-linux02 ~]# rpcinfo -p localhost |
- 编辑
/etc/sysconfig/nfs
,去掉注释:
- 编辑/etc/modprobe.d/lockd.conf,进行如下设置
- 重启 rpcbind和nfs
1 | //重启rpcbind |
如图所示:
- 设置iptables,加入以下规则
1 | vi /etc/sysconfig/iptables |
- 校验结果
1 | [root@local-linux01 ~]# showmount -e 172.16.155.132 |
重要补充: 既然iptables不必关闭,其实centos7默认开启了firewalld,也不用关闭,同样按照这个方法进行配置就可以。只是配置端口这个环节略有不同。
1 | //编辑firewalld中nfs服务的配置文件 |
第四步:挂载共享文件夹
1 | //新建一个空文件夹作为挂载点 |
- 校验结果
1 | [root@local-linux01 mnt]# mount |grep share |
TroubleShooting: 无法读写共享文件夹
查看一下服务器端权限设置:
估计还是文件夹权限设置的问题,突然想起来,在配置权限时设置了all_squash
这一项,不论登入NFS 的使用者身份为何, 他的身份都会被降权成为普通用户,后面跟的anonuid anongid
,必须存在于你的/etc/passwd 当中对这个普通用户进行指定,换句话说,我们规定了来自客户端的访问等同于本地指定用户。
在我们的实验当中,指定的uid1000的用户,对应的用户名是user1,而这个文件是由本地root用户创建的,所属用户是root,难怪没有权限进行访问。如下所示:
1 | //查看uid为1000的用户 |
于是,尝试更改文件夹所属用户
1 | [root@local-linux02 ~]# chown -R user1:user1 /home/sharedir |
再次尝试,果然成功
1 | // 客户端操作 |
另外,还可以通过设置777权限来解决问题。不过,为什么是777,而不是766,目前还是不清楚。
1 | chmod 777 /home/sharedir |
NFS客户端部署问题及其解决办法
NFS的版本更迭
NFS V2
NFS最早实现的版本之一,基于UDP协议实现了一个无状态的服务器版本。仅仅支持32位的系统,且不大于2GB的文件;NFS V3
在2的基础之上做了大量的改进。支持了大于2GB的文件读写,使用了TCP协议来进行数据交互,支持了客户端的异步读写来提高文件系统的性能(同时也会产生我们头疼的一致性问题);NFS V4
进一步提高了安全性,通过TCP协议实现了一个有状态的服务器版本,通过锁租约的机制来实现多客户端的读写同步。在4.1版本引入了pNFS,通过类似于一个HDFS架构来提供并行的一个分布式文件系统。
问题描述:在NFS4版本,客户端挂载共享目录后,不管是root用户还是普通用户,创建新文件时属主和属组都是nobody。
解决思路:
方法一:客户端挂载时加上-o nfsvers=3
1 | [root@local-linux01 ~]# mount -t nfs -o nfsvers=3 172.16.155.132:/tmp/share2 /mnt/sharedir2 |
方法二:客户端服务端同时进行操作
1 | vim /etc/idmapd.conf |
NFS挂载
NFS客户端自动挂载
方法一:客户端将挂载命令写入/etc/profile
1 |
|
方法二:将要挂载的NFS目录写在客户端的/etc/fatab文件中,挂载时使用mount -a
1 | vim /etc/fstab |
注意:建议使用第一种。因为如果NFS服务未启动,第二种方法可能会导致客户端无法开机。
AutoFs服务程序与Mount命令不同之处在于它是一种守护进程,只有检测到用户试图访问一个尚未挂载的文件系统时才自动的检测并挂载该文件系统。
方法三:autofs
安装autofs
[root@local-linux01 ~]# yum -y install autofs
修改配置文件(主配置+子配置)
sutofs 的配置文件是按照主配置+子配置的方式来部署的。先看主配置文件部署.
- 主配置文件部署
autofs服务程序的主配置文件中需要按照“挂载目录 子配置文件”的格式写入参数。挂载目录是设备要挂载位置的上一级目录,例如之前客户端local-linux01的挂载点是/mnt/share/,此处写/mnt/,对应的子配置文件是/etc/auto.nfs ,意思是系统访问dir1下面的文件的时候,去/etc/auto.nfs 去查找nfs的配置。
1 | vim /etc/auto.master |
- 子配置文件
子配置文件中应按照“挂载目录 挂载文件类型及权限:设备名称”的格式写入参数
1 | ///etc/auto.nfs 该配置文件需新建 |
设置开机启动
1 | systemctl restart autofs |
exportfs命令 不重启重新加载服务
前面已经配置好了nfs文件夹共享服务,但是这里还有一个隐患,就是当服务器端端配置更新改动的时候,就需要以restart的方式使改动生效。但是,在生产环境中,频繁重启nfs可能带来不必要麻烦和错误,这时,就需要借助exportnfs命令来实现不重启,但却能重新加载服务的目的。
安装exportfs
1 | yum install -y exportnfs |
语法
命令行格式
1 | exportnfs [参数] |
常用参数如下:
-a
:全部挂载(或卸载)/etc/exports
文件内的设定;-r
:重新挂载/etc/exports
中的设置,此外同步更新/etc/exports
及/var/lib/nfs/xtab
中的内容;-u
:卸载某一目录;-v
:在export时将共享的目录显示在屏幕上;
示例
- 第一步:新建一个共享目录
1 | //新建共享文件夹 |
- 第二步:修改nfs配置,增加一个共享目录;
1 | vi /etc/exports |
- 第三步:重新加载服务(服务器端执行)
1 | //服务器端执行 |
- 第四步:挂载服务
1 | //创建挂载点 |
- 校验结果
1 | //客户端操作 |