【Keepalived】高可用集群
高可用集群类型
- 负载均衡集群(LB)
通过分发请求到多台服务器提升性能,避免单台服务器过载。
- 高可用集群(HA)
利用冗余机制(主备切换)确保服务持续可用,典型场景如数据库、Web服务。
- 单点故障解决方案(SPoF)
消除系统中单一故障点,例如通过冗余电源、网络链路或存储设备。
- 高性能计算集群(HPC)
用于大规模并行计算任务,如科学模拟或大数据处理。
可用性指标与计算
SLA等级
- 99.9%(三个九):年停机时间≤8.76小时
- 99.99%(四个九):年停机时间≤52.6分钟
可用性公式
[ A = \frac{MTBF}{MTBF + MTTR} ]
- MTBF:平均无故障时间
- MTTR:平均修复时间
优化方向
- 降低MTTR(快速故障恢复)
- 增加冗余(多节点、多链路)
VRRP协议核心
术语解释
- VRID:虚拟路由器标识(同一组设备需一致)
- VIP:虚拟IP(客户端访问的地址)
- VMAC:虚拟MAC(格式为
00-00-5E-00-01-{VRID}
) - Master/Backup:主设备优先处理流量,备设备监听状态
优先级规则
- 范围1-254,默认100,值越大优先级越高
- 优先级0表示主动释放Master角色
工作模式
- 抢占式:Master恢复后自动夺回VIP
- 非抢占式:需手动切换
Keepalived功能与配置
核心功能
- VIP漂移(基于VRRP)
- 健康检测(TCP/HTTP/自定义脚本)
- 自动生成IPVS规则(集成LVS)
配置文件结构
/etc/keepalived/keepalived.conf
├── global_defs # 全局参数(邮件通知、路由ID)
├── vrrp_instance # 定义VRRP组(优先级、VIP)
└── virtual_server # LVS规则(可选)
启用keepalived日志功能
把日志文件独立出来,方便后续查看
[root@KA1 ~]# vim /etc/sysconfig/keepalived
KEEPALIVED_OPTIONS="-D -S 6" #日志级别为0-7
[root@ka1 ~]#vim /etc/rsyslog.conf
[root@ka1 ~]#systemctl restart keepalived.service rsyslog.service
[root@ka1 ~]#tail -f /var/log/keepalived.log
实现独立子配置文件
当生产环境复杂时, /etc/keepalived/keepalived.conf 文件中内容过多,不易管理,可以单独区分出来
将不同集群的配置,比如:不同集群的VIP配置放在独立的子配置文件中利用include 指令可以实现包含子配置文件。
格式:
include /path/file
示例:
mkdir /etc/keepalived/conf.d -p
vi /etc/keepalived/conf.d/webvip.conf
在主配置全局,子配置路由
把你要分开放置的文件部分粘贴到该文件中(webvip_conf),源文件的这部分删掉,换成子文件
命令检查语法有没有问题,没有问题重启文件即可
健康检测示例
TCP_CHECK {connect_port 80 # 检测80端口connect_timeout 3
}
实战架构方案
单主架构
- 一个Master持有VIP,Backup监听,故障时切换。
双主架构
- 两个VRRP实例,节点互为主备,均衡负载。
IPVS高可用
- Keepalived + LVS,实现负载均衡与故障转移。
HAProxy高可用
- Keepalived监控HAProxy进程,异常时切换VIP。
关键机制详解
VRRP状态同步
- 主节点周期性发送Advertisement报文(默认1秒)。
- 备节点超时(默认3倍Advertisement间隔)未收到报文时触发切换。
健康检测联动
- 检测失败时降低优先级,触发VIP迁移。
通知脚本
- 绑定
notify
脚本,在状态切换时执行自定义操作(如告警)。
双主模式原理
- 节点A管理VIP1,节点B管理VIP2,互不冲突,提升资源利用率。
Keepalived 高可用集群总结
核心知识点
VRRP 协议用于解决单点故障问题,通过虚拟路由器实现 VIP 漂移。
Master/Backup 角色由优先级决定,优先级高的节点成为 Master 并持有 VIP。
抢占模式是默认行为,Master 恢复后重新抢占 VIP;非抢占模式需要所有节点设置为 state BACKUP
。
Keepalived 提供 VIP 管理功能,基于 VRRP 实现 IP 高可用,同时支持对后端服务(如 Nginx、MySQL)的健康检测。通知脚本可通过 notify_master/backup/fault
触发自定义动作,例如邮件告警。
高可用架构分为单主模式和双主模式。
单主模式中,一个 Master 和一个 Backup 节点管理单个 VIP;
双主模式通过两个 VIP 分别由不同节点管理,提高资源利用率。
IPVS(LVS)集成允许 Keepalived 自动配置 LVS 规则,实现负载均衡与高可用,支持 DR、NAT 和 TUN 模式。
关键配置项包括 vrrp_instance
(定义虚拟路由器、优先级和 VIP)、virtual_server
(配置 LVS 的 VIP 和后端 RS)以及 track_script
(调用自定义脚本监控服务状态)。
实验流程
环境准备:
两台虚拟机,IP在同一个网段:KA1,KA2
vi /etc/chrony.conf
安装 Keepalived:
yum install keepalived -y
systemctl enable --now keepalived
查看当前策略
如果这行注释了,就能ping了,查看策略是没有的,如果没注释,就有策略显示,但是ping不通
下面全部注释掉
基础配置(单主模式)
1. 配置 Master 节点(KA1):
vim /etc/keepalived/keepalived.conf
配置如图:
224.0.0.44是组播地址
检测文件内容有没有问题keepalived -t if /etc/keepalived/keepalived.conf
重启服务
细节说明:
2. 配置 Backup 节点(KA2)
把文件从KA1复制过来
#配置文件和master基本一致,只需修改三行
修改 state BACKUP
并设置 priority 80
。
3.测试
查看网卡,KA1优先级高,所以抢占VIP,KA2则没有
抓包观察:谁有VIP就跟组播地址说我活了,不说就是挂了
tcpdump -i eth0 -nn host 224.0.0.18
此时在KA2看到的也是KA1的IP跟组播地址传讯
如果KA1挂了,才会变成KA2跟组播地址说,这就是抢占模式
测试 VIP 漂移时,停止 KA1 的 Keepalived 并观察 VIP 是否迁移到 KA2:
ip addr show ens160
或者ifconfig
非抢占模式
默认为抢占模式preempt,即当高优先级的主机恢复在线后,会抢占低先级的主机的master角色,
这样会使vip在KA主机中来回漂移,造成网络抖动,
建议设置为非抢占模式 nopreempt ,即高优先级主机恢复后,并不会抢占低优先级主机的master角色
非抢占模块下,如果原主机down机, VIP迁移至的新主机, 后续也发生down时,仍会将VIP迁移回原主机
注意:要关闭 VIP抢占,必须将各 keepalived 服务器state配置为BACKUP
所有节点配置为 state BACKUP
并添加 nopreempt
:
vrrp_instance VI_1 {state BACKUPnopreemptpriority 100 # KA1...
}
延迟抢占模式
抢占延迟模式,即优先级高的主机恢复后,不会立即抢回VIP,而是延迟一段时间(默认300s)再抢回VIP
注意:各 keepalived 服务器state配置为BACKUP,并且不要启用 vrrp_strict
指定抢占延迟时间为10s,默认延迟300s
VIP单播配置
keepalived主机之间利用多播相互通告消息,会造成网络拥塞,可以替换成单播,减少网络流量
先查看还是组播状态时的抓包显示,谁有VIP谁发给组播IP
修改文件 :其他不变,指定对方主机的IP路线
KA1(192.168.1.50)
KA2(192.168.1.60)
重启,查看单播,50可以发
60发不了,因为没用VIP
把50停掉就60可以发了
systemctl stop keepalived
ifconfig #查看VIP,此时VIP已经被60抢占
tcpdump -i ens160 -nn src host 192.168.1.60 and dst 192.168.1.50
实现 master/master 的 Keepalived 双主架构
单主架构,同一时间只有一个Keepalived对外提供服务,此主机繁忙,而另一台主机却很空闲,利用率低下,可以使用master/master的双主架构,解决此问题。
注意:VIP是一个虚拟IP,不需要特意创建,和KA在同一个网段能ping即可
配置两个 vrrp_instance
,分别管理不同 VIP:
测试:两台机器都有自己的VIP
IPVS 高可用
环境:新建两台虚拟机充当服务器,服务器配置完文件后只做验证,不安装别的
配置 LVS-DR 模式时,后端 RS 需绑定 VIP 到 lo
并设置 ARP 抑制:
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
net.ipv4.conf.lo.arp_ignore=1
net.ipv4.conf.lo.arp_announce=2
两台KA都要装
Keepalived 集成 IPVS:
KA1节点的配置:
virtual_server 192.168.1.100 80 {delay_loop 6 #每隔六秒访问后端一次lb_algo rrlb_kind DRprotocol TCPreal_server 192.168.1.10 80 { #服务器IPweight 1HTTP_GET {url {path /status_code 200}connect_timeout 3retry 3delay_before_retry 3}}real_server 192.168.1.20 80 {weight 1TCP_CHECK {connect_timeout 2retry 3delay_before_retry 3connect_port 80 #第二台服务器给它一个端口}}}
KA2
文件配置一模一样,谁有VIP谁生效
重启文件后,策略就自动写上了
访问测试(随便开一台主机)
注意:如果可以单独curl,但是流量不显示没用发送也没用收到,停止服务后依然如此,可能是长期没用VIP休眠了需要ping一下
删掉两个KA的单播配置,此时两个主机应该都有VIP
模拟故障:
停掉其中一台的keepalived服务,查看另一台,会发现两个VIP都在
高可用的实现理念:无论那个主机挂了,都不会影响VIP
通知脚本
默认情况下是不能执行外部i脚本的
所以要先给脚本一个权限
触发切换:
安装发送邮件的
#邮箱配置
vim /etc/mail.rc
#输入
set smtp=smtp.qq.com
set smtp-auth=login
set smtp-auth-user=xxxxxxxxxn@qq.com
set smtp-auth-password=TAb9vYbWevbPtN4m #授权码
set from=xxxxxxxxx@qq.com
set ssl-verify=ignore
#如果是网易163邮箱
set smtp=smtp.163.com
set smtp-auth=login
set smtp-auth-user=xxxxx@163.com
set smtp-auth-password=TAb9vYbWevbPtN4m #授权码
set from=xxxxx@163.com
set ssl-verify=ignore
授权码如何获取?
qq邮箱
163邮箱
打开邮件投递端口25:查看有没有
发送测试
写一个发送邮件脚本
反应比较慢可以重启一下
定义脚本:
[root@KA1 + KA2 ~]# vim /etc/keepalived/mail.sh
#!/bin/bash
mail_dest='xxxxxxxxx@qq.com'mail_send()
{mail_subj="$HOSTNAME to be $1 vip 转移"mail_mess="`date +%F\ %T`: vrrp 转移,$HOSTNAME 变为 $1"echo "$mail_mess" | mail -s "$mail_subj" $mail_dest
}
case $1 inmaster)mail_send master;;backup)mail_send backup;;fault)mail_send fault;;*)exit 1;;
esac
增加执行权限
如果存在VIP,就执行脚本
如果VIP被抢走了,就生成faild文件
触发VIP切换
此时VIP会转移到KA2,做完邮件测试就可以把脚本删了,否则频繁发邮件会封号
关键原理
VRRP 协议中,Master 周期性发送组播通告(默认 224.0.0.18),Backup 监听。若超时未收到通告,Backup 接管 VIP。健康检测通过 TCP_CHECK
或 HTTP_GET
监控后端服务,失败时调整优先级触发切换。
脑裂问题可通过 vrrp_strict
严格模式避免配置冲突,或使用单播(unicast_peer
)替代组播。日志分离需配置 local6.* /var/log/keepalived.log
并重启 rsyslog
。
典型问题解决
VIP 无法访问时,检查防火墙和 ARP 抑制设置:
firewall-cmd --add-port=80/tcp
服务未注册到 systemd 时,手动创建服务文件:
vim /etc/systemd/system/nginx.service
抢占失败时,确认 nopreempt
和优先级配置正确。