一、前言
为了避免nfs单点问题导致的服务不可用,使用以下架构实现nfs的高可用,keepalived+inotify+rsync+nfs,keepalived实现nfs的高可用,inotify持续监控nfs数据目录的变化,发生变化后通过rsync进行同步到备节点,这里使用两台主机实现nfs高可用
主机信息
|------------|------------------------------|
| ip | 服务 |
| 10.1.60.22 | nfs、rsync、inotify、keepalived |
| 10.1.60.23 | nfs、rsync、inotify、keepalived |
| 10.1.60.6 | vip |
二、部署
nfs部署参考:nfs部署-CSDN博客
部署rsync和inotify服务 (主备节点都需要安装)
yum -y install rsync inotify-tools
编辑rsync配置文件(主节点)
vi /etc/rsyncd.conf
bash
uid = root
gid = root
port = 873
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
log file = /var/log/rsyncd.log
log format = %t %a %m %f %b
use chroot = no
max connections = 200
read only = false
list = false
fake super = yes
ignore errors
[master_nfs]
path = /share #同步的路径
auth users = rsync #同步用户
comment = master_nfs
read only = no
list = no
secrets file = /etc/rsyncd.passwd #存储同步所用的用户名和密码
hosts allow = 10.1.60.0/24 #允许同步的网段
备用节点的配置文件编辑和主节点有点不一样
vi /etc/rsyncd.conf #备用节点
bash
uid = root
gid = root
port = 873
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
log file = /var/log/rsyncd.log
log format = %t %a %m %f %b
use chroot = no
max connections = 200
read only = false
list = false
fake super = yes
ignore errors
[slave_nfs] #更改备用节点的模块名称
path = /share
auth users = rsync
comment = slave_nfs #更改备用节点的模块名称
read only = no
list = no
secrets file = /etc/rsyncd.passwd
hosts allow = 10.1.60.0/24
编辑rsync的用户名密码 #以下操作主备节点都要配置
vi /etc/rsyncd.passwd
bash
rsync:12345678
编辑rsync同步时调用的密码文件,在执行同步操作时不用手动输入密码,调用该文件即可
vi /opt/rsyncd.passwd
bash
12345678
设置两个文件的权限,必须时600,不然会报错
chmod 600 /etc/rsyncd.passwd
chmod 600 /opt/rsyncd.passwd
启动rsync服务
systemctl start rsyncd && systemctl enable rsyncd
检测rsync服务是否启动
ps -ef |grep rsync
使用nfs共享目录测试rsync功能是否正常同步 #在主节点执行
创建目录
mkdir /share/123
同步测试
rsync -avzp --delete /share/ rsync@10.1.60.23::slave_nfs --password-file=/opt/rsyncd.passwd
-a
:归档模式。保留权限、所有者、时间戳,并递归地复制目录。
-v
:详细模式。增加传输过程中显示的信息。
-z
:在传输过程中压缩数据,以减少网络使用。
-p
:保留源文件的权限。
--delete
:该选项确保目标(目标)上不存在于源中的文件将被删除。这有助于保持目标与源的同步
/share/:将该目录下的文件同步过去
slave_nfs:调用23主机的rsync服务配置的模块
--password-file:使用密码文件进行用户身份验证,即使用rsync用户访问23主机rsync服务的密码
在备节点查看是否存在123目录
使用rsync+inotify进行自动同步配置
创建脚本存放目录 #主备节点均需执行
mkdir /opt/nfs-rsync && cd /opt/nfs-rsync
主节点脚本文件配置
配置自动检测目录文件变化并进行同步的脚本,该脚本是个死循环脚本,所以会一直执行持续进行目录的检测和同步
bash
#!/bin/bash
host=10.1.60.23 #同步到的主机
src=/share/ #需要同步过去的目录
des=slave_nfs #使用的模块
password=/opt/rsyncd.passwd #用户的密码文件
user=rsync #同步使用的用户
inotifywait=/usr/bin/inotifywait #检测目录文件变化的服务
$inotifywait -mrq --timefmt '%Y%m%d %H:%M' --format '%T %w%f%e' -e modify,delete,create,attrib $src \ #检测目录文件变化的命令
| while read files ;do #循环检测目录文件是否发生变换
rsync -avzP --delete --timeout=100 --password-file=${password} $src $user@$host::$des #同步命令
echo "${files} was rsynced" >>/opt/nfs-rsync/rsync.log 2>&1
done
配置检测vip是否存在当前节点来判断是否执行同步脚本
bash
#!/bin/bash
vip_status=`ip add |grep 10.1.60.6|wc -l` #检测vip是否存活
inotify_status=`ps -ef |grep inotifywait|grep -v grep|wc -l` #检测inotifywait检测目录命令是否存活
wechat_alert() { #告警
key="----------xx环境监控报警---------"
host="10.1.60.22"
env="pro"
zt="nfs组件异常"
webhook='https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=123456'
error="检测到nfs组件未在运行,已启用10.1.60.23备机,请检查组件是否出现异常!!"
content="${key} \n主题:${zt} \n环境:${env} \n主机地址:${host} \n详情: ${error}"
curl $webhook -H 'Content-Type: application/json' -d ' {"msgtype": "text", "text": {"content":"'" ${content}"'"}}' &>/dev/null
}
if [ $vip_status -eq 0 ]; then #判断vip是否存在当前节点上
wechat_alert #如果vip不在当前节点,就调用告警函数执行告警
if [ $inotify_status -eq 0 ]; then
exit 0
else #vip不在当前节点,需要执行关闭同步脚本的命令,因为同步脚本是死循环会一直执行,需要手动关闭
ps -fe |grep inotifywait|grep -v grep|awk '{print $2}'|xargs kill -9
ps -fe |grep rsync-inotify.sh|grep -v grep|awk '{print $2}'|xargs kill -9
fi
else
if [ $inotify_status -eq 0 ]; then
nohup sh /opt/nfs-rsync/rsync-inotify.sh &
else
exit 0
fi
fi
备节点脚本文件配置
配置自动检测目录文件变化并进行同步的脚本
bash
#!/bin/bash
host=10.1.60.22
src=/share/
des=master_nfs
password=/opt/rsyncd.passwd
user=rsync
inotifywait=/usr/bin/inotifywait
$inotifywait -mrq --timefmt '%Y%m%d %H:%M' --format '%T %w%f%e' -e modify,delete,create,attrib $src \
| while read files ;do
rsync -avzP --delete --timeout=100 --password-file=${password} $src $user@$host::$des
echo "${files} was rsynced" >>/opt/nfs-rsync/rsync.log 2>&1
done
配置检测vip是否存在当前节点来判断是否执行同步脚本
bash
#!/bin/bash
vip_status=`ip add |grep 10.1.60.6|wc -l`
inotify_status=`ps -ef |grep inotifywait|grep -v grep|wc -l`
wechat_alert() {
key="----------xx环境监控报警---------"
host="10.1.60.23"
env="pro"
zt="nfs组件异常"
webhook='https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=12345678'
error="检测到nfs组件未在运行,已启用10.1.60.22主机,请检查组件是否出现异常!!"
content="${key} \n主题:${zt} \n环境:${env} \n主机地址:${host} \n详情: ${error}"
curl $webhook -H 'Content-Type: application/json' -d ' {"msgtype": "text", "text": {"content":"'" ${content}"'"}}' &>/dev/null
}
if [ $vip_status -eq 0 ]; then
wechat_alert
if [ $inotify_status -eq 0 ]; then
exit 0
else
ps -fe |grep inotifywait|grep -v grep|awk '{print $2}'|xargs kill -9
ps -fe |grep rsync-inotify.sh|grep -v grep|awk '{print $2}'|xargs kill -9
fi
else
if [ $inotify_status -eq 0 ]; then
nohup sh /opt/nfs-rsync/rsync-inotify.sh &
else
exit 0
fi
fi
脚本赋权 #主备节点均需执行
chmod +x rsync-inotify.sh
chmod +x vip-monitor.sh
部署keepalived服务
这里说明一下keepalived需要用到非抢占模式和keepalived状态检测执行脚本,非抢占模式是为了避免master节点故障恢复数据还未进行同步就立刻将vip抢占回来,keepalived状态检测执行脚本是为了实现对vip的监控从而进行数据的同步,当keepalived的状态发生变化时都会执行对应的脚本检测vip是否存在从而进行数据是否同步的操作
yum -y install keepalived #主备节点均需执行
编辑主节点keepalived配置文件
vi /etc/keepalived/keepalived.conf
bash
! Configuration File for keepalived
global_defs {
script_user root
enable_script_security
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id nfs01
# vrrp_skip_check_adv_addr
# vrrp_strict
# vrrp_garp_interval 0
# vrrp_gna_interval 0
}
vrrp_script check_nfs {
script "/etc/keepalived/check_nfs.sh" #持续进行检测nfs服务是否存活脚本
interval 3
}
vrrp_instance VI_4 {
state BACKUP #都配置backup状态
interface ens192
virtual_router_id 53
priority 90
advert_int 1
nopreempt #优先级高的配置非抢占模式
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.1.60.6
}
track_script {
check_nfs
}
notify "/opt/nfs-rsync/vip-monitor.sh" #keepalived状态发生变化时执行该脚本检测vip是否存在
notify_stop "/opt/nfs-rsync/vip-monitor.sh" #keepalived服务挂掉时执行该脚本检测vip是否存在
}
编辑备节点keepalived配置文件
vi /etc/keepalived/keepalived.conf
bash
! Configuration File for keepalived
global_defs {
script_user root
enable_script_security
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id nfs02
# vrrp_skip_check_adv_addr
# vrrp_strict
# vrrp_garp_interval 0
# vrrp_gna_interval 0
}
vrrp_script check_nfs {
script "/etc/keepalived/check_nfs.sh"
interval 3
}
vrrp_instance VI_4 {
state BACKUP #都配置backup状态
interface ens192
virtual_router_id 53
priority 80 #优先级低的不需要配置非抢占模式
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.1.60.6
}
track_script {
check_nfs
}
notify "/opt/nfs-rsync/vip-monitor.sh"
notify_stop "/opt/nfs-rsync/vip-monitor.sh"
}
编辑检测nfs服务脚本 #主备节点均需执行
vi /etc/keepalived/check_nfs.sh
bash
#!/bin/bash
status=`ps -ef |grep nfsd|grep -v grep|wc -l`
if [ $status -eq 0 ]; then
systemctl stop keepalived #检测到nfs不存活时,关掉keepalived服务使vip漂移
else
exit 0;
fi
脚本赋权 #主备节点均需执行
chmod +x /etc/keepalived/check_nfs.sh
启动keepalived服务,需要先启动主节点的再启动备节点
systemctl start keepalived && systemctl enable keepalived
检查主节点同步是否生效
ps -ef |grep rysnc
ps -ef |grep inotify
也可以通过查看rsync同步日志
tail -f /opt/nfs-rsync/rsync.log