高可用-Keepalived 全解析
HA 集群能解决哪些问题?
当计划使用HA集群时候,有一个重要的问题需要回答:服务放到HA集群中,可用性是否会增加?
回答这个问题,需要弄清楚服务的能力和该服务的客户端如何配置。
取决于解决方案,例如DNS和LDAP自带故障转移或者负载均衡,放到HA集群中没什么好处。DNS或者LDAP服务使用多个服务,具备master/slave角色,或者多个master关系。该服务可在多个服务器之间配置数据冗余。DNS和LDAP的客户端也可以使用多个服务器,这里就没有故障转移,因此,这种服务放置到HA集群中不会增加服务的可用性。
那些未自带Failover或者LB的服务,如果配置为HA集群,将会有很多好处。例如在 Openstack 平台解决方案中,将 RabbitMQ 和 Galera 放置到HA集群中,可以带来很多好处。
并不是每个可用性问题都可以通过HA集群解决:
如果应用程序存因bug导致crash,即使配置为HA集群,应用同样会crash。这种情况下,服务将会转移到其他节点。但是其他节点上的应用也存在相同的bug问题,同样会导致crash。
HA集群同样不提供端到端的冗余。集群本身可以正常提供服务,但是网络架构存在问题,导致集群不可达,客户端仍然无法访问服务。因此需要慎重考虑集群架构,避免单点故障,包括集群中的任何组件。
Keepalived 介绍
Keepalived 是一个用 C 语言编写的路由软件。这个项目的主要目标是为 Linux 系统和基于 Linux 的基础设施的负载平衡和高可用性提供简单而健壮的设施。
Keepalived 起初是为LVS设计的,专门用来监控集群系统中各个服务节点的状态,它根据TCP/IP参考模型的第三、第四层、第五层机制检测每个服务节点的状态,如果某个服务器节点出现异常,或者工作出现故障,Keepalived将检测到,并将出现的故障的服务器节点从集群系统中剔除,这些工作全部是自动完成的,不需要人工干涉,需要人工完成的只是修复出现故障的服务节点。
后来 Keepalived 又加入了VRRP的功能,VRRP(Vritrual Router Redundancy Protocol,虚拟路由冗余协议)出现的目的是解决静态路由出现的单点故障问题,通过VRRP可以实现网络不间断稳定运行,因此Keepalvied 一方面具有服务器状态检测和故障隔离功能,另外一方面也有HA cluster功能。
VRRP 原理
VRRP 协议
在现实的网络环境中,主机之间的通信都是通过配置静态路由或者(默认网关)来完成的,而主机之间的路由器一旦发生故障,通信就会失效。因此这种通信模式当中,路由器就成了一个单点瓶颈,为了解决这个问题,就引入了VRRP协议。
VRRP协议是一种主备模式的协议,通过VRRP可以在网络发生故障时透明的进行设备切换而不影响主机之间的数据通信。
VRRP 工作原理
Keepalived通过VRRP实现高可用性,它还能实现对集群中服务器运行状态的监控以及故障隔离。
Keepalived工作在TCP/IP 参考模型的 三层、四层、七层,也就是分别为:网络层,传输层和应用层。
VRRP 脑裂
脑裂的定义
在keepalived高可用集群中,脑裂(Split-Brain)是指主从节点(或双主节点)之间因通信中断,导致各自认为对方故障,从而同时争抢资源(如虚拟 IP),引发集群状态混乱的现象。
脑裂产生的原因
脑裂的核心是节点间心跳检测失败,但实际节点均正常运行,常见情况可能导致:
- 网络问题:主从节点间的心跳线路(如专用网线、交换机)故障、断网或延迟过高。
- 防火墙规则:节点间的
VRRP协议端口(默认112端口,UDP 协议)被防火墙屏蔽。 - 资源耗尽:某节点因 CPU、内存耗尽或负载过高,无法响应心跳请求。
- 配置错误:
keepalived配置中vrrp_instance的state、priority或authentication等参数不一致,导致节点间无法正常协商。
脑裂的危害
- 双节点同时持有虚拟 IP(VIP),导致客户端请求混乱(部分请求成功,部分失败)。
- 若集群管理的是数据库、存储等资源,可能引发数据不一致(如双写冲突)。
- 集群失去高可用意义,甚至因资源竞争导致服务崩溃。
如何避免脑裂?
通过多重检测机制和资源隔离策略预防脑裂,常用方案如下:
增加心跳检测线路
除了主网络,添加备用通信线路(如独立网卡、交叉网线),避免单线路故障导致心跳中断。
在 keepalived.conf中指定多网卡检测:
vrrp_instance VI_1{state MASTER interface eth0# 主网卡virtual_router_id51priority100advert_int1# 同时检测备用网卡(如eth1)track_interface{eth0 eth1}}启用 VRRP 认证
配置节点间的认证机制,防止非法节点干扰集群,同时确保心跳信息的可靠性。
vrrp_instance VI_1{# ... 其他配置authentication{auth_type PASS# 认证类型(PASS或AH)auth_pass123456# 密码(所有节点必须一致)}}配置防火墙规则
允许节点间通过 VRRP协议通信(开放 UDP 112 端口):
# 允许VRRP协议(CentOS示例)firewall-cmd --add-protocol=vrrp--permanentfirewall-cmd--reload部署第三方检测工具
使用
fence机制(如fence_virsh、fence_ipmilan)或脚本,当检测到脑裂时强制隔离异常节点。示例:在 keepalived.conf中配置 notify 脚本,检测到节点成为主节点后,检查对方是否存活,若存活则强制关闭对方服务:
vrrp_instance VI_1 { # ... 其他配置 notify_master "/etc/keepalived/check_split_brain.sh master" notify_backup "/etc/keepalived/check_split_brain.sh backup" }脚本逻辑:通过 ping、端口检测等方式确认对方状态,若脑裂则执行
kill或
reboot操作。
降低脑裂影响范围
- 结合业务层设计,如数据库使用主从复制 + 读写分离,避免双写冲突;存储使用分布式锁(如 Redis)控制资源独占。
- 限制虚拟 IP 的使用场景,仅在确认集群状态正常时对外提供服务。
监控与告警
通过
zabbix、prometheus等工具监控keepalived状态(如vrrp_script检测),当发现双主节点同时存在时及时告警。
总结
脑裂的本质是节点通信失效与状态判断不一致,预防核心在于“多重检测 + 自动隔离”:通过多线路心跳、认证机制降低误判概率,结合脚本和第三方工具在脑裂发生时快速隔离异常节点,同时配合监控及时干预,保障集群稳定。
Keepalvied 高可用技术实践
网络拓扑
| 主机名 | IP地址 | 服务器角色 |
|---|---|---|
| client1.ggg.cloud | 10.1.8.21 | 客户端 |
| web1.ggg.cloud | 10.1.8.11 | Web 服务器 |
| web2.ggg.cloud | 10.1.8.12 | Web 服务器 |
基础配置
#所有主机的/etc/hosts127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain610.1.8.11 web1.ggg.cloud web110.1.8.12 web2.ggg.cloud web210.1.8.21 client.ggg.cloud client配置 web
[root@web1-2 ~]## 部署 webyuminstall-ynginxechoWelcome to$(hostname)>/usr/share/nginx/html/index.html systemctlenablenginx.service--now# 访问后端 nginx[root@client ~13:52:35]# curl http://10.1.8.11/Welcome to web1.ggg.cloud[root@client ~13:57:26]# curl http://10.1.8.12/Welcome to web2.ggg.cloud配置 keepalived
先配置 web2
web2 作为备节点
[root@web2 ~13:59:00]# yum install -y keepalived.x86_64[root@web2 ~14:00:44]# cp /etc/keepalived/keepalived.conf{,.ori}[root@web2 ~14:04:18]# vim /etc/keepalived/keepalived.conf!Configuration Fileforkeepalived global_defs{router_id web2}vrrp_instance nginx{state BACKUP interface ens32 virtual_router_id51priority100advert_int1authentication{auth_type PASS auth_pass ggg@123}virtual_ipaddress{10.1.8.10/24}}说明:
router_id web2,定义路由器名称,每个节点使用不同的名称。state BACKUP,定义节点角色为备节点,MASTER则代表主节点。interface ens32,定义VIP配置到该接口。virtual_router_id 51,定义虚拟路由器ID,范围1-255,每个节点使用相同名称。priority 100,定义节点优先级,值越大优先级越高。authentication,定义心跳认证。virtual_ipaddress,定义虚拟VIP。
# 启动 keepalived 服务[root@web2 ~14:17:58]# systemctl enable keepalived.service --now# 查看 IP发现多了一个[root@web2 ~14:13:04]# nmcli device show ens32|grep IP4.ADDRESSIP4.ADDRESS[1]:10.1.8.12/24 IP4.ADDRESS[2]:10.1.8.10/24配置 web1
web1 作为主节点。
[root@web1 ~13:58:13]# yum install -y keepalived.x86_64[root@web1 ~14:14:02]# cp /etc/keepalived/keepalived.conf{,.ori}[root@web1 ~14:14:22]# vim /etc/keepalived/keepalived.conf!Configuration Fileforkeepalived global_defs{router_id web1}vrrp_instance nginx{state MASTER interface ens32 virtual_router_id51# master节点优先级要高于BACKUP节点priority110advert_int1authentication{auth_type PASS auth_pass ggg@123}virtual_ipaddress{10.1.8.10/24}}# 启动服务[root@web1 ~14:16:01]# systemctl enable keepalived.service --now# 查看 IP,VIP 切换到 web1[root@web1 ~14:16:39]# nmcli device show ens32|grep IP4.ADDRESSIP4.ADDRESS[1]:10.1.8.11/24 IP4.ADDRESS[2]:10.1.8.10/24高可用验证
# 访问 web[root@client ~14:13:27]# curl http://10.1.8.10/Welcome to web1.ggg.cloud# 关闭 web1 的 keepalive服务,再次访问[root@client ~14:19:07]# systemctl stop keepalived.service[root@client ~14:19:10]# curl http://10.1.8.10/Welcome to web2.ggg.cloud# 再次启动 web1 的keepalive服务,再次访问[root@web1 ~]# systemctl start keepalived.service[root@client ~14:26:19]# curl http://10.1.8.10/Welcome to web1.ggg.cloudkeepalived 配置文件
配置文件位置:/etc/keepalived/keepalived.conf
配置文件主要包括三部分:
- GLOBAL,全局配置部分
- VRRPD,VRRP协议配置部分
- LVS,LVS服务管理配置部分
示例:
!Configuration Fileforkeepalived# 全局配置global_defs{# 邮件接收者清单notification_email{acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc}# 邮件发送者notification_email_from Alexandre.Cassen@firewall.loc# 邮件发送服务器smtp_server192.168.200.1# 连接邮件服务器超时时间smtp_connect_timeout30# 标识本机名称,集群中主机身份标识名称不能重复router_id LVS_DEVEL# 检查一个VRRP通告中的所有地址是很耗时的。设置这个标志意味着,如果这个通告和之前接收到的通告来自同一个主路由器,则不会执行检查。vrrp_skip_check_adv_addr# 严格遵守VRRP协议。vrrp_strict# 接口发送免费ARP消息的延迟毫秒数vrrp_garp_interval0# 接口发送未经请求的NA消息的延迟毫秒数vrrp_gna_interval0}# VRRP协议配置# VI_1是虚拟实例名称,可自定义vrrp_instance VI_1{# 指定当前节点角色,可以值MASTER和BACKUP,角色由priority决定,这里的值不重要。state MASTER# VIP使用的接口interface eth0#从0到255的任意唯一数字,用于区分VRRPD的多个实例,同一个高可用集群使用相同的idvirtual_router_id51# 用于选举为MASTER,高于其他节点50,将成为MASTERpriority100# VRRP通告之间间隔,1sadvert_int1# VRRP通告认证凭据authentication{auth_type PASS auth_pass1111}# 提供的VIP列表,还可以通过<IPADDR>/<MASK>指定多个地址virtual_ipaddress{192.168.200.16192.168.200.17192.168.200.18}}# LVS服务管理配置# 虚拟服务器是 192.168.200.100 443virtual_server192.168.200.100443{# delay timer for service pollingdelay_loop6# LVS scheduler,支持lb_algo rr|wrr|lc|wlc|lblc|sh|dhlb_algo rr# LVS forwarding method,支持NAT|DR|TUNlb_kind NAT# LVS persistence timeout in seconds, default 6 minutespersistence_timeout50# L4 protocol,支持TCP|UDP|SCTPprotocol TCP# one entry for each realserverreal_server192.168.201.100443{# relative weight to use, default: 1weight1}}详细信息参考keepalived.conf (5)
Keepalived 日志
# 以下步骤在 web1 和 web2 节点完成vim/etc/sysconfig/keepalived# 把 KEEPALIVED_OPTIONS="-D"# 修改为:KEEPALIVED_OPTIONS="-D -d -S 0"# 重启 keepalived,查看日志systemctl restart keepalived.servicevim/etc/rsyslog.d/keepalived.conf local0.* /var/log/keepalived.log# 重启日志服务systemctl restart rsyslog# 监控日志tail-f/var/log/keepalived.logKeepalived 心跳
参数:mcast_src_ip。
!Configuration Fileforkeepalived global_defs{router_id Cluster1}vrrp_instance Nginx{state MASTER interface ens36 mcast_src_ip20.0.0.11 virtual_router_id51priority110advert_int1authentication{auth_type PASS auth_pass ggg@123}virtual_ipaddress{10.1.1.10/24}}