一、 keepalived 简介
keepalived是一个开源的软件,用于在Linux系统上实现高可用性和负载均衡。它提供了一种简单而可靠的方法来监控和管理多个服务器实例,以确保服务的持续可用性。keepalived使用虚拟路由冗余协议(VRRP)来实现服务器之间的故障转移和负载均衡。它可以将多个服务器配置为一个虚拟IP地址,如果其中一个服务器发生故障,其他服务器将接管该地址,并继续提供服务。这使得keepalived成为构建高可用性系统的重要工具。
起初是为LVS设计的,专门用来监控集群系统中各个服务节点的状态.
如果某个服务器节点出现故障,Keepalived将检测到后自动将节点从集群系统中剔除.
而在故障节点恢复正常后,Keepalived又可以自动将此节点重新加入集群中.
这些工作自动完成,不需要人工干预,需要人工完成的只是修复出现故障的节点.
特点:
- 部署简单,只需要配置一个配置文件即可
- 加入了虚拟路由冗余协议,可以保证业务或网络不间断稳定运行
二、vrrp协议与工作原理
VRRP(Virtual Router Redundancy Protocol)是一种网络协议,用于实现路由器的冗余和故障转移。它允许多个路由器共享一个虚拟IP地址,从而提供冗余和负载均衡。 VRRP协议的工作原理如下:
- 在一个VRRP组中,有一个主路由器和一个或多个备用路由器。主路由器负责处理传入和传出的网络流量。
- 所有路由器都通过VRRP协议通信,以选择主路由器。它们使用一种优先级算法来确定主路由器。
- 主路由器负责维护虚拟IP地址,并将其与自己的物理接口关联。备用路由器监听主路由器的状态。
- 如果主路由器发生故障或离线,备用路由器中的一个将接管虚拟IP地址,并成为新的主路由器。这个过程是无缝的,对网络用户来说是透明的。
- 一旦主路由器恢复正常,它将重新成为主路由器,并继续处理网络流量。 通过使用VRRP协议,网络管理员可以实现高可用性和故障转移,确保即使某个路由器出现故障,网络服务仍将继续正常运行。
三、keepalived高可用脑裂
Keepalived脑裂(Split Brain)是指在使用Keepalived实现高可用性时可能发生的一种情况。当Keepalived中的多个节点无法正常通信时,可能会导致脑裂问题。
脑裂问题可能发生在以下情况下:
- 网络分区:当Keepalived节点之间的网络出现故障或分区时,节点无法相互通信,导致无法协调和选择一个主节点。
- 节点故障:如果Keepalived节点之间的通信链路中断或节点发生故障,可能会导致节点无法相互感知,从而导致脑裂问题。
脑裂问题可能导致以下影响:
- 多个主节点:当网络分区或节点故障发生时,可能会导致多个Keepalived节点都认为自己是主节点,从而导致服务的不一致性和冲突。
- 数据不一致:不同的主节点可能会有不同的数据状态,这可能导致数据的不一致性和损坏。
为了解决脑裂问题,可以采取以下措施:
- 心跳检测:使用可靠的心跳检测机制确保节点之间的通信正常。这可以包括使用专用的网络链路或其他可靠的通信方式。
- 投票机制:使用投票机制来选择主节点,以确保只有一个节点被选为主节点。这可以通过配置节点的优先级和投票权重来实现。
四、实现部署
两台 centos7:
Proxy-master 192.168.188.145 192.168.188.200(VIP)
Proxy-slave 192.168.188.146 192.168.188.200(VIP)
1.安装 nginx web服务
[root@proxy-master ~]# yum -y install nginx
[root@proxy-slave ~]# yum -y install nginx
[root@proxy-master ~]# nginx
[root@proxy-slave ~]# nginx
[root@proxy-master ~]# echo "Proxy-master" > /usr/share/nginx/html/index.html
[root@proxy-slave ~]# echo "Proxy-slave" > /usr/share/nginx/html/index.html
访问测试,记得关闭防火墙和selinux
2.安装 keepalived 并配置
[root@proxy-master ~]# yum -y install keepalived
[root@proxy-slave ~]# yum -y install keepalived
[root@proxy-master ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived global_defs { router_id directory1 #辅助改为directory2 } vrrp_instance VI_1 { state MASTER #定义主还是备 interface ens33 #VIP绑定接口 virtual_router_id 80 #整个集群的调度器一致 priority 100 #back改为50 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.188.200/24 # vip } }
[root@proxy-slave ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived global_defs { router_id directory2 } vrrp_instance VI_1 { state BACKUP #设置为backup interface ens33 nopreempt #设置到back上面,不抢占资源 virtual_router_id 80 priority 50 #辅助改为50 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.188.200/24 } }
[root@proxy-master ~]# systemctl start keepalived
[root@proxy-master ~]# systemctl enable keepalived
[root@proxy-slave ~]# systemctl start keepalived
[root@proxy-slave ~]# systemctl enable keepalived
查看IP
master:
slave:
到此:可以解决心跳故障keepalived,不能解决Nginx服务故障 .
解决:让Keepalived以一定时间间隔执行一个外部脚本,脚本的功能是当Nginx失败,则关闭本机的Keepalived。
[root@proxy-master ~]# vim /etc/keepalived/check_nginx_status.sh
#!/bin/bash
/usr/bin/curl -I http://localhost &>/dev/null
if [ $? -ne 0 ];then
# /etc/init.d/keepalived stop
systemctl stop keepalived
fi
[root@proxy-master ~]# chmod a+x /etc/keepalived/check_nginx_status.sh
! Configuration File for keepalived
..........
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx_status.sh"
interval 5
}
vrrp_instance VI_1 {
........
track_script {
check_nginx
}
.......
}
最后,我们可以添加邮件通知(内容根据自己的邮箱修改):
master和slave均配置:
# yum install -y mailx
# vim /etc/mail.rc
set from=max@163.com
set smtp=smtp.163.com
set smtp-auth-user=max@163.com
set smtp-auth-password=XXXXXXXXXXXXXX #邮箱授权码
set smtp-auth=login
set ssl-verify=ignore
vim /etc/keepalived/check_nginx_status.sh
# 脚本代码
#!/bin/bash
to_email='123456789@qq.com'
ipaddress=`ip -4 a show dev ens33 | awk '/brd/{print $2}'`
notify() {
mailsubject="${ipaddress}to be $1, vip转移"
mailbody="$(date +'%F %T'): vrrp 飘移, $(hostname) 切换到 $1"
echo "$mailbody" | mail -s "$mailsubject" $to_email
}
case $1 in
master)
notify master
;;
backup)
notify backup
;;
fault)
notify fault
;;
*)
echo "Usage: $(basename $0) {master|backup|fault}"
exit 1
;;
esac
配置文件(master):
! Configuration File for keepalived
global_defs {
router_id directory1
}
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx_status.sh"
interval 5
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 80
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.188.200/24
}
track_script {
check_nginx
}
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
systemctl restart keepalived
停掉nginx, 查看邮件: