1. 为什么需要Keepalived双主模式?
在传统的高可用架构中,Keepalived通常采用主备(Active-Standby)模式,即一个节点处于MASTER状态,另一个节点处于BACKUP状态。这种模式虽然简单可靠,但在某些场景下会存在资源利用率低的问题——备份节点长期处于闲置状态,直到主节点故障才会接管服务。
双主模式(Active-Active)的核心价值在于:
- 两个节点同时处于MASTER状态
- 各自承载不同的业务流量
- 互为对方的备份节点
- 实现负载均衡与高可用的统一
典型的应用场景包括:
- Web服务器集群:两个节点同时处理用户请求
- 数据库读写分离:主库写,备库读
- 多业务系统:节点A处理业务X,节点B处理业务Y
注意:双主模式不是Keepalived的默认配置方式,需要特别调整VRRP协议参数才能实现。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 双主模式的实现原理
2.1 VRRP协议的工作机制
Keepalived基于VRRP(Virtual Router Redundancy Protocol)协议实现高可用。在标准VRRP中:
- 每个虚拟路由器(VRRP实例)有唯一的VRID(1-255)
- 通过优先级(priority)选举MASTER(默认100)
- MASTER定期发送Advertisement报文
- 如果BACKUP超过3个Advertisement间隔未收到报文,则发起选举
bash复制# 查看Keepalived日志中的VRRP状态变化
$ tail -f /var/log/keepalived.log
2.2 双主模式的配置关键
要实现双主模式,需要在两个节点上:
- 配置不同的VRRP实例(不同VRID)
- 每个实例设置各自的MASTER优先级
- 绑定不同的虚拟IP(VIP)
- 确保两个VIP的路由可达
示例拓扑:
code复制节点A:
- 物理IP:192.168.1.10
- VIP1:192.168.1.100(VRID 51)
- VIP2:192.168.1.101(VRID 52)
节点B:
- 物理IP:192.168.1.11
- VIP1:192.168.1.101(VRID 52)
- VIP2:192.168.1.100(VRID 51)
3. 完整配置实战
3.1 节点A的keepalived.conf
conf复制vrrp_instance VI_51 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
192.168.1.100/24
}
}
vrrp_instance VI_52 {
state BACKUP
interface eth0
virtual_router_id 52
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
192.168.1.101/24
}
}
3.2 节点B的keepalived.conf
conf复制vrrp_instance VI_51 {
state BACKUP
interface eth0
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
192.168.1.100/24
}
}
vrrp_instance VI_52 {
state MASTER
interface eth0
virtual_router_id 52
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
192.168.1.101/24
}
}
3.3 服务管理与调试
启动服务:
bash复制systemctl start keepalived
systemctl enable keepalived
检查状态:
bash复制ip addr show eth0 | grep "inet"
4. 常见问题与解决方案
4.1 脑裂问题(Split-Brain)
症状:
- 两个节点同时宣称自己是MASTER
- 相同的VIP出现在两个节点上
- 网络通信出现异常
解决方案:
- 确保advert_int设置合理(通常1秒)
- 配置多播检测:
conf复制global_defs {
vrrp_strict
router_id node1
enable_script_security
script_user root
}
- 使用第三方仲裁(如ping检测):
conf复制vrrp_script chk_ping {
script "ping -c 2 192.168.1.1"
interval 2
weight -20
}
4.2 状态切换延迟
优化建议:
- 减小advert_int(但会增加网络负载)
- 调整preempt_delay(默认0秒)
conf复制vrrp_instance VI_51 {
preempt_delay 5 # 等待5秒后再抢占
}
4.3 防火墙配置要点
必须放行的流量:
- VRRP协议(IP协议号112)
- 多播地址224.0.0.18
- 配置的advert_int端口
iptables示例:
bash复制iptables -A INPUT -p vrrp -j ACCEPT
iptables -A INPUT -d 224.0.0.18/32 -j ACCEPT
5. 高级配置技巧
5.1 基于权重的负载均衡
通过调整priority实现流量分配:
conf复制vrrp_instance VI_51 {
track_script {
chk_load
}
}
vrrp_script chk_load {
script "/etc/keepalived/check_load.sh"
interval 5
weight 10
}
5.2 与LVS集成
实现四层负载均衡:
conf复制virtual_server 192.168.1.100 80 {
delay_loop 6
lb_algo wrr
lb_kind DR
protocol TCP
real_server 192.168.1.10 80 {
weight 1
TCP_CHECK {
connect_timeout 3
}
}
}
5.3 多网卡绑定配置
对于bonding接口:
conf复制vrrp_instance VI_51 {
interface bond0
mcast_src_ip 192.168.1.10
unicast_peer {
192.168.1.11
}
}
6. 监控与日志分析
关键日志位置:
- /var/log/keepalived.log
- /var/log/messages(取决于系统配置)
重要日志事件:
code复制VRRP_Instance(VI_51) Transition to MASTER STATE
VRRP_Instance(VI_51) Received higher prio advert
VRRP_Instance(VI_51) Entering BACKUP STATE
监控指标建议:
- VRRP状态变化次数
- Advertisement报文间隔
- 优先级动态变化
- 虚拟IP漂移事件
7. 性能优化实践
7.1 参数调优建议
conf复制global_defs {
vrrp_garp_master_delay 5
vrrp_garp_master_repeat 2
vrrp_garp_lower_prio_delay 5
vrrp_garp_lower_prio_repeat 2
vrrp_garp_master_refresh 60
vrrp_garp_master_refresh_repeat 2
}
7.2 大规模部署建议
对于超过50个VRRP实例的场景:
- 使用unicast替代multicast
conf复制vrrp_instance VI_51 {
unicast_src_ip 192.168.1.10
unicast_peer {
192.168.1.11
}
}
- 分批次配置advert_int
- 考虑使用Keepalived的BFD功能
8. 与其他技术的集成
8.1 与Docker/Kubernetes集成
容器环境注意事项:
- 需要--net=host网络模式
- 避免使用iptables规则干扰
- 考虑使用kube-keepalived-vip项目
8.2 与云平台配合
AWS/Azure特殊配置:
conf复制vrrp_instance VI_51 {
garp_master_refresh 30
dont_track_primary
track_interface {
eth0
}
}
8.3 与数据库集群配合
MySQL双主示例:
conf复制vrrp_script chk_mysql {
script "/etc/keepalived/check_mysql.sh"
interval 2
weight 2
}
vrrp_instance VI_51 {
track_script {
chk_mysql
}
}
