环境
- 系统版本: CentOS Linux release 7.7.1908 (Core)
一、服务端配置
1、配置环境
1.1、配置防火墙
# 停止并禁用防火墙
[root@nfs1 ~]# systemctl stop firewalld
[root@nfs1 ~]# systemctl disable firewalld
1.2、关闭并禁用SELinux
编辑/etc/selinux/config
文件,将参数改为SELINUX=disabled
[root@nfs1 ~]# vi /etc/selinux/config
保存文件并重启系统reboot
2、安装nfs-utils和rpcbind
[root@nfs1 ~]# yum install -y nfs-utils rpcbind
3、创建存储的文件夹
检查系统的文件夹挂载详情,选择一块空间足够的专属区域,或单独挂载磁盘
[root@nfs1 ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs 1.9G 8.9M 1.9G 1% /run
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
/dev/mapper/centos-root 50G 1.4G 49G 3% /
/dev/sda1 1014M 150M 865M 15% /boot
/dev/mapper/centos-home 457G 33M 457G 1% /home
tmpfs 379M 0 379M 0% /run/user/0
创建文件夹
[root@nfs1 ~]# mkdir -p /home/nfs-data
修改专属用户和组
[root@nfs1 ~]# chown -R root:root /home/nfs-data/
4、配置NFS
# 编辑exports
[root@nfs1 ~]# vi /etc/exports
# 输入以下内容(格式:FS共享的目录 NFS客户端地址1(参数1,参数2,...) 客户端地址2(参数1,参数2,...))
/home/nfs-data 192.168.0.70/24(rw,async,no_root_squash)
# 如果设置为 /home/nfs-data *(rw,async,no_root_squash) 则对所以的IP都有效
- 常用选项:
ro
:客户端挂载后,其权限为只读,默认选项;rw
:读写权限;sync
:同时将数据写入到内存与硬盘中;async
:异步,优先将数据保存到内存,然后再写入硬盘;Secure
:要求请求源的端口小于1024;
- 用户映射:
root_squash
:当NFS客户端使用root用户访问时,映射到NFS服务器的匿名用户;no_root_squash
:当NFS客户端使用root用户访问时,映射到NFS服务器的root用户;all_squash
:全部用户都映射为服务器端的匿名用户;anonuid=UID
:将客户端登录用户映射为此处指定的用户uid;anongid=GID
:将客户端登录用户映射为此处指定的用户gid;
5、设置开机启动并启动
rpcbind
[root@nfs1 ~]# systemctl restart rpcbind
[root@nfs1 ~]# systemctl enable rpcbind
nfs
[root@nfs1 ~]# systemctl restart nfs
[root@nfs1 ~]# systemctl enable nfs
6、查看是否有可用的NFS地址
[root@nfs1 ~]# showmount -e 192.168.0.70
Export list for 192.168.0.70:
/home/nfs-data *
二、客户端配置
1、安装nfs-utils和rpcbind
[root@gitlab ~]# yum install -y nfs-utils rpcbind
2、创建挂载的文件夹
[root@gitlab ~]# mkdir -p /nfs-data
3、挂载NFS
临时挂载:这种方式在系统重启后就会失效
[root@gitlab ~]# mount -t nfs -o nolock,vers=4 192.168.0.70:/home/nfs-data /nfs-data
永久挂载:在系统重启后不会失效,但如果被挂载的机器没有启动,则会造成启动慢的情况
# 编辑 /etc/fstab 文件
[root@gitlab ~]# vi /etc/fstab
# 将挂载信息添加到文件下下方
192.168.0.70:/home/nfs-data/ /nfs-data nfs defaults 0 0
验证挂载情况:重启系统,使用df -h
命令查看是否自动挂载成功
[root@gitlab1 ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
devtmpfs 3.9G 0 3.9G 0% /dev
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 3.9G 8.9M 3.9G 1% /run
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/mapper/centos-root 50G 1.3G 49G 3% /
/dev/sda1 1014M 150M 865M 15% /boot
/dev/mapper/centos-home 198G 33M 197G 1% /home
192.168.0.70:/home/nfs-data 457G 32M 457G 1% /nfs-data
tmpfs 783M 0 783M 0% /run/user/0
三、高可用配置
1、使用rsync+inotify实现文件实时双向同步
1.1、安装rsync(两台机器都要安装)
编译环境及库文件:
[root@nfs1 ~]# yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel
yum源在线安装:
[root@nfs1 ~]# yum install -y rsync
离线安装:
[root@nfs1 ~]# wget https://download.samba.org/pub/rsync/src/rsync-3.1.3.tar.gz
[root@nfs1 ~]# tar -zxvf rsync-3.1.3.tar.gz
[root@nfs1 ~]# cd rsync-3.1.3
[root@nfs1 rsync-3.1.3]# ./configure --prefix=/usr/local/rsync
[root@nfs1 rsync-3.1.3]# make && make install
1.2、创建配置文件
yum源在线:
[root@nfs1 ~]# vi /etc/rsyncd.conf
离线配置:
[root@nfs1 ~]# vi /usr/local/rsync/rsyncd.conf
#rsync通用配置文件,配置的注释不要写在配置后面,否则会有问题
uid = root
gid = root
use chroot = 0
port = 873
#允许ip访问设置,请根据实际需要进行配置,这里为了方便设为全网段 *
# hosts allow = 192.168.0.1/255.255.255.0 198.162.145.1 10.0.1.0/255.255.255.0
hosts allow = *
max connections = 0
timeout = 300
pid file = /var/run/rsyncd.pid
ock file = /var/run/rsyncd.lock
log file = /var/log/rsyncd.log
log format = %t %a %m %f %b
transfer logging = yes
syslog facility = local3
#方括号中为模块声明,对应命名,这里master_nfs对应了主nfs机配置
[master_nfs]
#指定当前模块在rsync服务器上的同步路径,该参数是必须指定的
path = /home/nfs-data/
#注释,可以同模块名一样,从服务器可都为slave_nfs
comment = master_nfs
ignore errors
#是否允许客户端上传文件
read only = no
list = no
#指定由空格或逗号分隔的用户名列表,只有这些用户才允许连接该模块
#auth users = rsync
#保存密码和用户名文件,需要自己生成
#secrets file = /etc/rsyncd.passwd
1.3、以守护进程方式启动rsync服务
yum源在线:
[root@nfs1 ~]# /usr/bin/rsync --daemon --config=/etc/rsyncd.conf
离线方式:
[root@nfs1 ~]# /usr/local/rsync/bin/rsync --daemon --config=/usr/local/rsync/rsyncd.conf
1.4、添加开机自动启动
yum源在线:
[root@nfs1 ~]# echo "/usr/bin/rsync --daemon --config=/etc/rsyncd.conf">>/etc/rc.local
离线方式:
[root@nfs1 ~]# echo "/usr/local/rsync/bin/rsync --daemon --config=/usr/local/rsync/rsyncd.conf">>/etc/rc.local
给/etc/rc.d/rc.local
文件赋权限
chmod -x /etc/rc.d/rc.local
1.5、验证是否可以手动同步
# nfs1服务器给nfs2服务器同步
[root@nfs1 ~]# rsync -vzrtopg --delete --progress /home/nfs-data/ rsync@192.168.0.71::master_nfs
# nfs2服务器给nfs1服务器同步
[root@nfs2 ~]# rsync -vzrtopg --delete --progress /home/nfs-data/ rsync@192.168.0.70::master_nfs
1.6、安装inotify(两台服务器都要安装)
[root@nfs1 ~]# wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz --no-check-certificate
[root@nfs1 ~]# tar -zxvf inotify-tools-3.14.tar.gz
[root@nfs1 ~]# cd inotify-tools-3.14
[root@nfs1 inotify-tools-3.14]# ./configure --prefix=/usr/local/inotify
[root@nfs1 inotify-tools-3.14]# make && make install
# 查看是否安装成功
[root@nfs1 inotify-tools-3.14]# ls -alh /usr/local/inotify/bin/inotify*
-rwxr-xr-x. 1 root root 60K 1月 9 22:02 /usr/local/inotify/bin/inotifywait
-rwxr-xr-x. 1 root root 54K 1月 9 22:02 /usr/local/inotify/bin/inotifywatch
# 建立软连接
[root@nfs1 inotify-tools-3.14]# ln -s /usr/local/inotify/bin/inotifywait /usr/bin/inotifywait
[root@nfs1 inotify-tools-3.14]# ln -s /usr/local/inotify/bin/inotifywatch /usr/bin/inotifywatch
1.7、创建并配置inotify_back.sh同步监控脚本
[root@nfs1 ~]# vi /usr/local/inotify/inotify_back.sh
#!/bin/bash
# 需要同步的源路径
src=/home/nfs-data
# 目标服务器上
des=master_nfs
# 目标服务器1
ip1=192.168.0.70
cd ${src}
# 此方法中,由于rsync同步的特性,这里必须要先cd到源目录,inotify再监听 ./ 才能rsync同步后目录结构一致,有兴趣的同学可以进行各种尝试观看其效果
inotifywait -mrq --format '%Xe %w%f' -e modify,create,delete,attrib,close_write,moved_to,moved_from ./ | while read file
# 把监控到有发生更改的"文件路径列表"循环
do
# 把inotify输出切割 把事件类型部分赋值给INO_EVENT
INO_EVENT=$(echo $file | awk '{print $1}')
# 把inotify输出切割 把文件路径部分赋值给INO_FILE
INO_FILE=$(echo $file | awk '{print $2}')
echo "-------------------------------$(date)------------------------------------"
echo $file
#增加、修改、写入完成、移动进事件
#增、改放在同一个判断,因为他们都肯定是针对文件的操作,即使是新建目录,要同步的也只是一个空目录,不会影响速度。
# 判断事件类型
if [[ $INO_EVENT =~ 'CREATE' ]] || [[ $INO_EVENT =~ 'MODIFY' ]] || [[ $INO_EVENT =~ 'CLOSE_WRITE' ]] || [[ $INO_EVENT =~ 'MOVED_TO' ]]
then
echo 'CREATE or MODIFY or CLOSE_WRITE or MOVED_TO'
rsync -avzcR $(dirname ${INO_FILE}) rsync@${ip1}::${des}
fi
if [[ $INO_EVENT =~ 'DELETE' ]] || [[ $INO_EVENT =~ 'MOVED_FROM' ]]
then
echo 'DELETE or MOVED_FROM'
rsync -avzR --delete $(dirname ${INO_FILE}) rsync@${ip1}::${des}
fi
if [[ $INO_EVENT =~ 'ATTRIB' ]]
then
echo 'ATTRIB'
if [ ! -d "$INO_FILE" ]
then
rsync -avzcR $(dirname ${INO_FILE}) rsync@${ip1}::${des}
fi
fi
done
1.8、给inotify_back.sh脚本赋可执行权限
[root@nfs1 inotify]# chmod 755 inotify_back.sh
1.9、运行inotify_back.sh同步监控脚本和配置守护进程
# 创建日志文件夹
[root@nfs1 inotify]# mkdir logs
# 运行inotify_back.sh脚本
[root@nfs1 inotify]# nohup ./inotify_back.sh > logs/nohup.out &
1.10、将监听添加至自启中
因为监听程序需要守护进程启动,所以使用单独的启动脚本进行启动,后续keepalived
检测时也能用到此脚本
# 编写脚本
[root@nfs1 ~]# vi /usr/local/inotify/startup.sh
# 将下方命令添加至脚本中并保存
nohup /usr/local/inotify/inotify_back.sh > /usr/local/inotify/logs/nohup.out &
# 给脚本赋执行权限
[root@nfs1 inotify]# chmod 775 startup.sh
# 将启动脚本命令添加至rc.local文件的结尾处
[root@nfs1 inotify]# vi /etc/rc.d/rc.local
# 添加命令行
/usr/local/inotify/startup.sh
2、keepalived实现IP地址漂移
2.1、安装配置keepalived
2.1.1、安装keepalived
[root@nfs1 ~]# yum install -y keepalived
2.1.2、配置keepalived
NFS_MASTER
[root@nfs1 ~]# vi /etc/keepalived/keepalived.conf
## 配置信息
! Configuration File for keepalived
global_defs {
router_id NFS_MASTER #路由标志
}
# 集群资源监控,组合track_script进行
vrrp_script check_file_rsync {
script "/usr/local/inotify/check_file_rsync.sh" #检测 inotify 状态的脚本路径
interval 2 #检测时间间隔
weight -50 #条件成立 权重减50
}
vrrp_instance VI_1 {
state MASTER # 设置当前主机为主节点,如果是备用节点,则设置为BACKUP
interface ens192 # 指定HA监测网络接口,可以用ifconfig查看来决定设置哪一个
virtual_router_id 51 # 虚拟路由标识,同一个VRRP实例要使用同一个标识,主备机
priority 150 # 设置优先级,确保主节点的优先级高过备用节点
advert_int 1 # 用于设定主备节点间同步检查时间间隔
#nopreempt # 设置高可用集群中不抢占功能,在主机down后,从机接管,当主机重新恢复后,设置此功能,备机将继续提供服务,从而避免因切换导致的隐患
# 设置主备节点间的通信验证类型及密码,同一个VRRP实例中需一致
authentication {
auth_type PASS
auth_pass bbrightway
}
# 集群资源监控,组合vrrp_script进行
track_script {
check_file_rsync
}
# 设置虚拟IP地址,当keepalived状态切换为MASTER时,此IP会自动添加到系统中
# 当状态切换到BACKUP时,此IP会自动从系统中删除
# 可以通过命令ip add查看切换后的状态
virtual_ipaddress {
192.168.0.75 #虚拟ip配置完之后就用它访问
}
}
# 启动keepalived
[root@nfs1 ~]# systemctl start keepalived && systemctl enable keepalived
NFS_BACKUP
[root@nfs2 ~]# vi /etc/keepalived/keepalived.conf
## 配置信息
! Configuration File for keepalived
global_defs {
router_id NFS_BACKUP
}
vrrp_script check_file_rsync {
script "/usr/local/inotify/check_file_rsync.sh" #检测 inotify 状态的脚本路径
interval 2 #检测时间间隔
weight -50 #条件成立 权重减50
}
vrrp_instance VI_1 {
state BACKUP
interface ens192
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass bbrightway
}
track_script {
check_file_rsync
}
virtual_ipaddress {
192.168.0.75
}
}
# 启动keepalived
[root@nfs2 ~]# systemctl start keepalived && systemctl enable keepalived
启动后查看虚拟IP地址是否存在
[root@nfs1 ~]# ip a | grep 192.168.0.75
inet 192.168.0.75/32 scope global ens192
在使用中发现,只有keeplived将虚拟IP飘到的机器上才能查到虚拟IP,没被飘到的机器查不到虚拟IP
2.2、编写监听脚本
keepalived
只能监听keepalived
本身是否存活,只有在keepalived
进程宕掉、网络不通或服务器宕掉时,keepalived
才会将请求漂移到备份keepalived
中;如果keepalived
进程没有宕,但是NFS
进程或同步守护进程宕掉时,则不能成功的挂载NFS
,所以要检测这些进程宕掉的情况,酌情关闭选择keepalived
。
编写脚本:
[root@nfs1 ~]# vi /usr/local/inotify/check_file_rsync.sh
监听脚本:
#!/bin/bash
# 查看同步进程是否启动
A=`ps -C rsync --no-header | wc -l`
# 查看文件动态监听进程是否启动
B=`ps -C inotifywait --no-header | wc -l`
# 查看文件监听守护进程是否启动
C=`ps -C inotify_back.sh --no-header | wc -l`
# 查看NFS进程是否启动
D=`ps -C nfsd --no-header | wc -l`
# 查看rpcbind进程是否启动
E=`ps -C rpcbind --no-header | wc -l`
# 如果NFS进程未启动,直接关闭keepalived
if [ $D -eq 0 ];then
systemctl stop keepalived
fi
# 如果rpcbind进程未启动,直接关闭keepalived
if [ $E -eq 0 ];then
systemctl stop keepalived
fi
# 如果同步进程未启动
if [ $A -eq 0 ];then
#启动同步进程
rm -rf /var/run/rsyncd.pid
/usr/bin/rsync --daemon --config=/etc/rsyncd.conf
sleep 2
if [ `ps -C rsync --no-header | wc -l` -eq 0 ];then
systemctl stop keepalived
fi
fi
#如果文件动态监听进程未启动
if [ $B -eq 0 ];then
#启动文件动态监听进程
/usr/local/inotify/startup.sh
sleep 2
if [ `ps -C inotifywait --no-header | wc -l` -eq 0 ];then
systemctl stop keepalived
fi
fi
#如果文件动态监听守护进程未启动
if [ $C -eq 0 ];then
#启动文件动态监听守护进程
/usr/local/inotify/startup.sh
sleep 2
if [ `ps -C inotify_back.sh --no-header | wc -l` -eq 0 ];then
systemctl stop keepalived
fi
fi
重启keepalived,并测试
[root@nfs1 ~]# systemctl restart keepalived