作为一名运维老兵,我处理过不下20次生产环境的高可用故障切换。今天要分享的Keepalived,可以说是Linux环境下最轻量级的高可用解决方案之一。它基于VRRP协议实现,通过虚拟IP(VIP)漂移来保障服务连续性,特别适合Web服务器、数据库、负载均衡器等关键业务场景。
VRRP(Virtual Router Redundancy Protocol)本质上是通过多台机器组成一个虚拟路由器组,通过优先级选举出Master节点接管VIP流量。当Master不可用时,Backup节点会自动接管VIP,整个过程对客户端完全透明。这种机制完美解决了单点故障问题,切换时间通常在3秒以内。
重要提示:在实际生产环境中,务必确保所有节点的时间同步(NTP/Chrony),否则可能导致脑裂问题。我在某次故障排查中就遇到过因为时间不同步导致双主同时持有VIP的惨案。
我们先规划一个典型的主备架构:
bash复制# 所有节点统一配置hosts解析
echo "192.168.79.50 KA1
192.168.79.60 KA2
192.168.79.70 RS1
192.168.79.80 RS2" >> /etc/hosts
在KA1和KA2上执行:
bash复制dnf install keepalived -y
主节点KA1的配置文件示例(/etc/keepalived/keepalived.conf):
conf复制global_defs {
router_id LVS_DEVEL_KA1 # 唯一标识符
}
vrrp_instance VI_1 {
state MASTER # 初始状态
interface eth0 # 监听网卡
virtual_router_id 51 # 虚拟路由ID(必须相同)
priority 100 # 选举优先级(0-255)
advert_int 1 # 通告间隔(秒)
authentication {
auth_type PASS # 认证类型
auth_pass 1111 # 认证密码
}
virtual_ipaddress {
192.168.79.100/24 # 虚拟IP配置
}
}
备节点KA2只需修改:
conf复制state BACKUP
priority 90
启动服务:
bash复制systemctl enable --now keepalived
验证VIP是否绑定:
bash复制ip addr show eth0 | grep 192.168.79.100
模拟主节点故障:
bash复制# 在KA1执行
systemctl stop keepalived
# 在KA2抓包观察VRRP通告
tcpdump -i eth0 -nn host 224.0.0.18
经验之谈:生产环境中建议同时监控keepalived进程和业务端口(如80),我曾遇到过keepalived进程存活但Nginx崩溃的情况,此时需要结合脚本检测实现更精准的故障转移。
默认日志混在/var/log/messages中,调试时很不方便。优化方案:
bash复制KEEPALIVED_OPTIONS="-D -S 6" # 指定日志facility
conf复制local6.* /var/log/keepalived.log
bash复制systemctl restart rsyslog keepalived
在某些场景下,我们希望故障恢复后不自动抢回VIP:
conf复制vrrp_instance VI_1 {
...
nopreempt # 启用非抢占模式
preempt_delay 300 # 即使启用抢占也延迟5分钟
}
当主备节点跨网段时,必须使用单播通信:
conf复制unicast_src_ip 192.168.79.50 # 本机IP
unicast_peer {
192.168.79.60 # 对端IP
}
Keepalived内置LVS功能,可实现负载均衡高可用:
conf复制virtual_server 192.168.79.100 80 {
delay_loop 6
lb_algo wrr # 加权轮询
lb_kind DR # 直接路由模式
protocol TCP
real_server 192.168.79.70 80 {
weight 1
TCP_CHECK {
connect_timeout 3
connect_port 80
}
}
real_server 192.168.79.80 80 {
weight 1
TCP_CHECK {
connect_timeout 3
connect_port 80
}
}
}
bash复制# 配置ARP抑制
echo "net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2" >> /etc/sysctl.conf
# 添加VIP到lo接口
echo "DEVICE=lo:0
IPADDR=192.168.79.100
NETMASK=255.255.255.255" > /etc/sysconfig/network-scripts/ifcfg-lo:0
systemctl restart network
通过配置多个VRRP实例,可以实现双主模式:
conf复制vrrp_instance VI_WEB {
virtual_ipaddress { 192.168.79.100/24 }
priority 100
}
vrrp_instance VI_DB {
virtual_ipaddress { 192.168.79.200/24 }
priority 90
}
conf复制vrrp_instance VI_WEB {
virtual_ipaddress { 192.168.79.100/24 }
priority 90
}
vrrp_instance VI_DB {
virtual_ipaddress { 192.168.79.200/24 }
priority 100
}
bash复制dnf install postfix mailx -y
conf复制set from=monitor@yourdomain.com
set smtp=smtp.yourdomain.com
set smtp-auth-user=username
set smtp-auth-password=password
set smtp-auth=login
bash复制#!/bin/bash
TYPE=$1
NAME=$2
STATE=$3
case $STATE in
"MASTER")
echo "$(date) - 主机 $HOSTNAME 成为 $NAME 的 MASTER" | \
mailx -s "Keepalived切换告警" admin@example.com
;;
"BACKUP")
echo "$(date) - 主机 $HOSTNAME 切换为 $NAME 的 BACKUP" | \
mailx -s "Keepalived切换告警" admin@example.com
;;
"FAULT")
echo "$(date) - 主机 $HOSTNAME 进入 $NAME 的 FAULT 状态!" | \
mailx -s "Keepalived故障告警" admin@example.com
;;
*)
echo "未知状态: $STATE"
;;
esac
conf复制vrrp_instance VI_1 {
...
notify /etc/keepalived/scripts/notify.sh
}
bash复制include /etc/keepalived/conf.d/*.conf
conf复制real_server 192.168.79.70 80 {
HTTP_GET {
url {
path /health
status_code 200
}
connect_timeout 3
}
}
bash复制# 限制VRRP通信源
iptables -A INPUT -p vrrp -s 192.168.79.0/24 -j ACCEPT
iptables -A INPUT -p vrrp -j DROP
经过多年实战检验,Keepalived在保持配置简洁的同时,能够提供企业级的高可用保障。特别是在与LVS、Nginx等组件配合使用时,可以构建出非常健壮的基础架构。最后提醒一点:所有配置变更后,务必先用keepalived -t测试配置文件有效性,这个习惯帮我避免过多次午夜故障电话。