Keepalived配置:高可用服务构建的基石
在构建高可用(High Availability)系统时,Keepalived是Linux平台下广泛使用的解决方案之一。它通过实现VRRP(Virtual Router Redundancy Protocol)协议来提供网络服务的高可用性,并且可以与LVS(Linux Virtual Server)无缝集成,提供强大的负载均衡能力。深入理解Keepalived的配置,是确保服务不间断运行的关键。
【是什么?】Keepalived配置的核心概念
Keepalived的“配置”究竟是什么?它主要指的是对keepalived.conf文件的编写和管理,这个文件定义了Keepalived如何运行、如何检测服务状态、以及如何在不同节点间进行故障转移。
Keepalived配置的主要构成要素:
- 全局定义(Global Definitions): 配置Keepalived守护进程的通用行为,例如路由ID、邮件通知设置等。
- VRRP实例(VRRP Instance): 这是Keepalived实现高可用的核心。每个VRRP实例代表一个虚拟路由器,它包含一个或多个虚拟IP地址(VIP),并在多个物理服务器之间进行状态同步和主备切换。主要配置包括:
state: 定义初始状态(MASTER/BACKUP)。interface: 监听VRRP心跳包的网络接口。virtual_router_id: 虚拟路由器的唯一标识符,同一VRRP组内必须相同。priority: 定义节点的优先级,优先级高的节点将成为MASTER。advert_int: VRRP通告(心跳)间隔。authentication: VRRP通信的认证方式和密码。virtual_ipaddress: 浮动IP地址,即对外提供的服务IP。track_script: 绑定外部脚本,用于检测服务或系统健康状态,并根据结果动态调整优先级。nopreempt: 非抢占模式,防止MASTER恢复后立即抢占。
- 虚拟服务器(Virtual Server): 当Keepalived与LVS结合使用时,这部分配置定义了LVS的虚拟服务。它指定了对外服务的IP和端口,以及后端真正的服务器(Real Server)列表和它们的健康检查方式。
delay_loop: 健康检查的间隔时间。lb_algo: 负载均衡算法(如rr、wlc、lc、lblc、sh、dh)。lb_kind: 负载均衡类型(如DR、NAT、TUN)。protocol: 虚拟服务的协议(TCP、UDP、SCTP)。real_server: 后端真实服务器的IP、端口、权重,以及对它们的健康检查方式(如TCP_CHECK, HTTP_GET, SSL_GET)。
【为什么?】配置Keepalived的必要性与收益
配置Keepalived的根本原因是为了解决单点故障(Single Point of Failure)问题,并提升服务的可用性和可靠性。
核心驱动力与收益:
- 高可用性(High Availability): 这是最主要的理由。当作为主服务器的节点出现故障时(无论是硬件故障、操作系统崩溃还是应用程序停止响应),Keepalived能够自动检测到问题,并将虚拟IP地址迅速漂移到备用服务器,从而确保服务的不中断。
- 故障自动转移(Automatic Failover): 无需人工干预,Keepalived能实现秒级的故障检测和切换,大大缩短了服务中断时间。
- 负载均衡(Load Balancing): 通过与LVS的集成,Keepalived不仅提供高可用,还能将来自客户端的请求分发到后端多台真实服务器上,有效分担了单台服务器的压力,提高并发处理能力。
- 简化管理(Simplified Management): 对外提供统一的虚拟IP,无论是前端应用还是DNS解析,都只需要指向这个固定的VIP,而无需关心后端实际是哪台服务器在提供服务,简化了架构和维护。
- 应用健康检查(Application Health Check): 借助
track_script和LVS的healthcheck,Keepalived可以深入到应用层面进行健康检查。如果不仅仅是服务器宕机,而是某个关键服务进程停止响应,Keepalived也能检测到并触发故障转移,这比简单的网络连通性检查更为智能和可靠。
思考: 没有Keepalived,当一台提供关键服务的服务器宕机时,服务会完全中断,直到人工介入修复。这对于24/7不间断运行的在线服务是不可接受的损失。
【哪里?】配置文件的位置与状态查看
了解配置和日志文件的具体位置,对于部署、调试和维护Keepalived至关重要。
配置文件路径:
- Keepalived的主配置文件通常位于:
/etc/keepalived/keepalived.conf。 - 在某些Linux发行版上,也可能位于
/etc/keepalived.conf。 - 自定义的健康检查脚本通常放置在
/etc/keepalived/scripts/目录下或用户定义的任何可执行路径中。
日志文件位置:
- Keepalived的运行日志通常会通过Syslog服务记录,具体位置取决于Syslog的配置。常见位置包括:
/var/log/messages(CentOS/RHEL)/var/log/syslog(Debian/Ubuntu)- 或者通过
journalctl -u keepalived -f命令实时查看(Systemd系统)。
虚拟IP的体现:
当Keepalived正常运行时,虚拟IP地址(VIP)会绑定到当前MASTER服务器的网络接口上。你可以通过以下命令在MASTER服务器上看到VIP:
ip addr show <interface_name>
例如:ip addr show eth0。输出中会显示类似inet 192.168.1.100/32 scope global eth0的行,其中192.168.1.100就是配置的VIP。
【多少?】配置涉及的要素数量与参数考量
在设计Keepalived高可用架构时,需要考虑多方面的数量和参数设置。
部署数量要求:
- 最低要求: 实现高可用至少需要两台服务器(一主一备),分别配置为MASTER和BACKUP。
- 推荐数量: 考虑到容灾和维护,通常会部署两台以上,例如两台Keepalived服务器(MASTER/BACKUP)加上多台后端Real Server(LVS模式)。也可以是三台或更多Keepalived节点组成VRRP组,提供更高冗余。
- VRRP实例数量: 单个配置文件可以定义多个
vrrp_instance,每个实例可以管理一个或多个VIP。这意味着你可以为不同的服务或不同的网络接口配置独立的VRRP组。 - 虚拟IP数量: 每个
vrrp_instance可以配置多个virtual_ipaddress,满足多服务高可用的需求。
优先级与抢占设置:
- 优先级(Priority): 取值范围通常为0-255。MASTER的优先级应高于BACKUP。例如,MASTER设置为100,BACKUP设置为90。优先级数值越大代表优先级越高。
- 抢占模式(Preempt): 默认情况下,Keepalived是抢占模式。这意味着当优先级更高的节点从故障中恢复后,它会尝试重新夺回MASTER角色。可以通过
nopreempt参数禁用抢占,使故障恢复的旧MASTER保持BACKUP状态,直到当前MASTER宕机。 - 通告间隔(Advert Interval):
advert_int参数定义VRRP心跳包的发送间隔,单位为秒。通常设置为1秒。间隔越短,故障检测和转移的速度越快,但会增加网络流量和CPU开销(通常微乎其微)。
脚本与检查频率:
- 健康检查脚本数量: 可以配置多个
track_script,每个脚本对应一个需要监控的服务或系统状态。 - LVS健康检查频率:
virtual_server块中的delay_loop参数定义了对后端Real Server健康检查的间隔,通常设置为1-5秒。 - 权重(Weight): 在LVS中,
real_server可以设置权重,用于分配请求,数值越大分配的请求越多。这有助于在后端服务器性能不一致时进行精细控制。
【如何?】详细的Keepalived配置步骤与示例
本节将通过实际的配置示例,详细阐述如何部署和配置Keepalived。
前期准备与安装:
- 系统环境: 准备至少两台CentOS/RHEL或Debian/Ubuntu服务器。确保网络连通,且防火墙允许VRRP协议(协议号112)和对外服务的端口通过。
- 安装Keepalived:
- CentOS/RHEL:
sudo yum install keepalived -y - Debian/Ubuntu:
sudo apt update && sudo apt install keepalived -y
- CentOS/RHEL:
基础配置文件结构:
编辑/etc/keepalived/keepalived.conf文件。以下是一个基本的双机热备(主备模式)配置结构示例:
global_defs { router_id LVS_DEVEL # 路由ID,全局唯一 # script_fahz "/etc/keepalived/scripts/global_notify.sh" # 全局通知脚本 # enable_script_security # 启用脚本安全模式 } vrrp_instance VI_1 { state MASTER # 初始状态:MASTER或BACKUP interface eth0 # 绑定VRRP心跳的网卡接口 virtual_router_id 51 # 虚拟路由ID,同一VRRP组内必须一致 priority 100 # 优先级,数值越大越高 advert_int 1 # 心跳间隔,秒 authentication { auth_type PASS # 认证类型 auth_pass 1111 # 认证密码 } virtual_ipaddress { 192.168.1.100/24 dev eth0 label eth0:0 # 虚拟IP地址 } track_script { chk_nginx_process # 绑定下方定义的健康检查脚本 } notify_master "/etc/keepalived/scripts/notify.sh master" # 切换为MASTER时执行 notify_backup "/etc/keepalived/scripts/notify.sh backup" # 切换为BACKUP时执行 notify_fault "/etc/keepalived/scripts/notify.sh fault" # 切换为FAULT时执行 # nopreempt # 非抢占模式(仅在BACKUP机上配置有效) } # 用于track_script的脚本定义 vrrp_script chk_nginx_process { script "/etc/keepalived/scripts/check_nginx.sh" interval 2 # 每2秒执行一次 weight -20 # 如果脚本执行失败,优先级降低20 fall 2 # 连续2次失败才判定失败 rise 1 # 连续1次成功就判定成功 } # (可选) LVS虚拟服务器配置示例 # virtual_server 192.168.1.100 80 { # delay_loop 6 # 负载均衡健康检查间隔 # lb_algo rr # 负载均衡算法:轮询 (Round Robin) # lb_kind DR # 负载均衡类型:直接路由 (Direct Routing) # protocol TCP # 协议 # # real_server 192.168.1.110 80 { # weight 100 # 权重 # TCP_CHECK { # connect_timeout 3 # nb_get_retry 3 # delay_before_retry 3 # connect_port 80 # } # } # real_server 192.168.1.111 80 { # weight 100 # HTTP_GET { # url { # path /index.html # status_code 200 # } # connect_timeout 3 # nb_get_retry 3 # delay_before_retry 3 # } # } # }
VRRP实例核心配置详解:
- MASTER节点配置 (Server A – IP: 192.168.1.10):
vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 # 高优先级 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.100/24 dev eth0 label eth0:0 } track_script { chk_nginx_process } notify_master "/etc/keepalived/scripts/notify.sh master" notify_backup "/etc/keepalived/scripts/notify.sh backup" notify_fault "/etc/keepalived/scripts/notify.sh fault" } - BACKUP节点配置 (Server B – IP: 192.168.1.11):
vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 51 priority 90 # 低优先级 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.100/24 dev eth0 label eth0:0 } track_script { chk_nginx_process } notify_master "/etc/keepalived/scripts/notify.sh master" notify_backup "/etc/keepalived/scripts/notify.sh backup" notify_fault "/etc/keepalived/scripts/notify.sh fault" nopreempt # 推荐在BACKUP节点开启非抢占模式 }
优先级、状态与抢占模式:
状态(state): MASTER或BACKUP仅是启动时的初始状态。实际的MASTER角色由priority决定。优先级高的会成为MASTER。
抢占模式(preempt vs nopreempt):
- 默认是抢占模式:当故障的MASTER恢复后,如果其优先级高于当前的MASTER(原BACKUP),它会重新抢占MASTER角色。
nopreempt:在BACKUP节点配置此参数,可以禁用抢占。这意味着一旦BACKUP节点成为MASTER,即使原MASTER恢复并具有更高优先级,它也不会立即抢占,而是继续保持MASTER角色,直到它自己发生故障。这有助于避免不必要的IP漂移,尤其是在MASTER短暂恢复又再次故障的情况下。
故障检测与脚本联动(track_script):
Keepalived不仅仅可以检测服务器是否存活,更重要的是它可以检测服务器上的特定服务是否正常运行。这通过vrrp_script和track_script实现。
创建健康检查脚本示例 (/etc/keepalived/scripts/check_nginx.sh):
#!/bin/bash # 检查Nginx进程是否在运行 A=`ps -C nginx --no-header |wc -l` if [ $A -eq 0 ];then # Nginx进程不存在,尝试重启 /usr/bin/systemctl restart nginx # 再次检查,如果还是不存在,则退出非0表示失败 sleep 2 B=`ps -C nginx --no-header |wc -l` if [ $B -eq 0 ];then exit 1 # Nginx未运行,标记失败 else exit 0 # Nginx已恢复,标记成功 fi else exit 0 # Nginx正在运行,标记成功 fi
给脚本执行权限:sudo chmod +x /etc/keepalived/scripts/check_nginx.sh
在keepalived.conf中关联:
vrrp_script chk_nginx_process {
script "/etc/keepalived/scripts/check_nginx.sh"
interval 2 # 每2秒执行一次脚本
weight -20 # 如果脚本返回非0(失败),则将VRRP实例的优先级降低20
fall 2 # 连续失败2次才判定为真正故障
rise 1 # 连续成功1次即判定为恢复正常
}
vrrp_instance VI_1 {
# ... 其他配置 ...
track_script {
chk_nginx_process
}
}
当check_nginx.sh脚本返回非0(失败)时,当前节点的优先级会降低20。如果降低后的优先级低于BACKUP节点的优先级,就会触发故障转移,将MASTER角色转移给BACKUP节点。
通知机制(notify脚本):
Keepalived可以在状态发生变化时执行外部脚本,这对于日志记录、发送告警(邮件、短信、微信)或与其他系统集成非常有用。
通知脚本示例 (/etc/keepalived/scripts/notify.sh):
#!/bin/bash # notify.sh # 参数 $1 代表 Keepalived 的新状态 (master, backup, fault) STATE=$1 VIP="192.168.1.100" # 你的VIP case "$STATE" in "master") echo "$(date) $(hostname) transitioned to MASTER state, VIP: $VIP" | systemd-cat -t keepalived-notify # 可在此处添加发送邮件/短信的逻辑 # curl -X POST -H "Content-Type: application/json" -d '{"text": "<hostname> 成为 MASTER"}' https://your.webhook.url ;; "backup") echo "$(date) $(hostname) transitioned to BACKUP state, VIP: $VIP" | systemd-cat -t keepalived-notify ;; "fault") echo "$(date) $(hostname) transitioned to FAULT state, VIP: $VIP" | systemd-cat -t keepalived-notify # 紧急告警 ;; *) echo "Unknown state: $STATE" | systemd-cat -t keepalived-notify ;; esac exit 0
给脚本执行权限:sudo chmod +x /etc/keepalived/scripts/notify.sh
在keepalived.conf中配置:
vrrp_instance VI_1 {
# ... 其他配置 ...
notify_master "/etc/keepalived/scripts/notify.sh master"
notify_backup "/etc/keepalived/scripts/notify.sh backup"
notify_fault "/etc/keepalived/scripts/notify.sh fault"
# 也可以使用 notify_stop (停止时执行)
}
LVS负载均衡集成(virtual_server):
当Keepalived配置为LVS高可用时,它不仅提供VIP的漂移,还管理LVS规则和后端真实服务器的健康检查。
在MASTER节点上,除了VRRP实例配置外,还需要添加virtual_server块:
virtual_server 192.168.1.100 80 { # 虚拟服务IP和端口
delay_loop 6 # 后端健康检查间隔,秒
lb_algo rr # 负载均衡算法:rr (轮询)
lb_kind DR # 负载均衡类型:DR (直接路由)
protocol TCP # 协议
# 后端真实服务器1
real_server 192.168.1.110 80 {
weight 100 # 权重
TCP_CHECK { # TCP健康检查
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
# 后端真实服务器2
real_server 192.168.1.111 80 {
weight 100
HTTP_GET { # HTTP GET健康检查
url {
path /index.html
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
注意: LVS的DR模式要求Real Server配置特殊的ARP抑制或loopback接口,以确保响应报文直接返回给客户端。这部分配置不在Keepalived自身配置文件中,而是在Real Server的操作系统网络配置中完成。
服务的启动、停止与重载:
配置完成后,你需要管理Keepalived服务。
- 启动:
sudo systemctl start keepalived - 停止:
sudo systemctl stop keepalived - 重启:
sudo systemctl restart keepalived(会中断服务,慎用) - 重载配置:
sudo systemctl reload keepalived(推荐,不中断服务,平滑加载新配置) - 查看状态:
sudo systemctl status keepalived - 开机自启:
sudo systemctl enable keepalived
常见问题与调试:
- VIP不漂移:
- 检查两台机器的
virtual_router_id和authentication是否一致。 - 检查防火墙是否阻止了VRRP协议(协议号112)或多播(224.0.0.18)。
- 检查
priority设置是否正确。 - 查看Keepalived日志:
journalctl -u keepalived -f。
- 检查两台机器的
- 脑裂(Split-Brain): 两台服务器都认为自己是MASTER。
- 最常见原因是网络分区导致心跳不通。
- 检查
authentication是否失效。 - 确保
virtual_router_id唯一,且VRRP组内的ID相同。 - 谨慎使用
nopreempt,并在必要时结合外部脚本进行仲裁。
- 脚本不生效:
- 检查脚本路径是否正确,是否具有执行权限(
chmod +x)。 - 在Shell中手动运行脚本,检查返回值是否符合预期(0为成功,非0为失败)。
- 查看Keepalived日志,看是否有脚本执行错误信息。
- 检查脚本路径是否正确,是否具有执行权限(
- LVS后端健康检查失败:
- 检查Real Server的防火墙是否允许Keepalived服务器进行健康检查(通常是目标端口)。
- 检查Real Server上的服务是否正常运行,监听在正确的IP和端口。
- 确认LVS类型(DR/NAT/TUN)所需的Real Server端配置已完成。
【怎么?】Keepalived配置的工作原理与高级考量
理解Keepalived背后的工作原理,有助于更好地进行配置和排查问题。
VRRP心跳机制:
Keepalived的核心是VRRP协议。VRRP通过定期发送多播心跳包(VRRP Adverts)来协商和维护虚拟IP的归属。
- VRRP组内的所有成员都监听同一个
virtual_router_id。 - 优先级最高的成员成为MASTER,并周期性地向组内其他成员发送VRRP Adverts。
- BACKUP成员接收MASTER的心跳,如果在一个预设的时间(
advert_int的3倍,或配置的track_script权重降低导致MASTER优先级下降)内没有收到MASTER的心跳,BACKUP会认为MASTER已失效,并开始进行MASTER选举。 - 选举中,优先级最高的BACKUP节点将接管VIP,成为新的MASTER,并开始发送自己的心跳包。
- 当旧的MASTER恢复时,如果配置为抢占模式,且其优先级高于当前MASTER,它会发送优先级更高的心跳包,促使当前MASTER降为BACKUP。
脑裂(Split-Brain)问题与预防:
脑裂是指在HA集群中,由于网络故障等原因,导致多个节点都认为自己是MASTER的情况。这会导致VIP被多个节点同时绑定,引发IP地址冲突和数据不一致等严重问题。
预防措施:
- 心跳网络独立: 尽可能为Keepalived心跳配置独立的网络接口和线路,减少因业务网络拥堵或故障影响心跳通信。
- 认证机制: 使用
authentication确保心跳包的安全性,防止恶意或配置错误的设备加入VRRP组。 nopreempt模式: 在BACKUP节点配置,可以减少因网络抖动导致旧MASTER频繁抢占的情况。- 更高级的仲裁机制: 结合外部监测系统或应用层的健康检查(如
track_script),确保MASTER角色的转移是基于服务真正故障而非简单的网络瞬断。 - 双重检查: 编写
notify脚本,在MASTER和BACKUP切换时,执行额外的检查(例如,PING一下VIP,如果发现已有其他机器响应,则立即停止Keepalived服务),以避免两个MASTER并存。
Keepalived与应用层健康检查:
Keepalived的强大之处在于它不仅能检测网络层面(PING)或进程层面(进程是否存在)的故障,还能通过自定义脚本实现应用层的健康检查。例如,检查Web服务器是否能返回HTTP 200状态码,数据库是否能正常连接并执行查询等。这种深度检查确保了故障转移是基于服务可用性,而非简单的服务器存活状态。
配置最佳实践:
- 规划
virtual_router_id: 确保每个VRRP组的ID唯一,避免与其他VRRP组冲突。 - 合理的
priority设置: 主节点优先级高,备用节点优先级低。 - 启用
authentication: 防止非授权设备加入VRRP组。 - 利用
track_script: 配置精确的服务健康检查,让故障转移更智能。 - 合理使用
nopreempt: 在BACKUP节点启用,可以减少不必要的MASTER切换。 - 配置
notify脚本: 及时获取状态变更通知,便于故障排查和告警。 - 日志监控: 定期查看Keepalived日志(
journalctl -u keepalived),了解其运行状态和潜在问题。 - 防火墙规则: 确保VRRP协议(协议号112)和VIP相关端口在所有Keepalived节点以及客户端与VIP之间是开放的。
- 测试故障转移: 在生产环境上线前,务必进行充分的故障模拟测试,包括停止服务、关机、网络断开等,以验证配置的正确性和可靠性。
通过对这些“是什么”、“为什么”、“哪里”、“多少”、“如何”和“怎么”问题的深入探讨,我们可以构建出一个稳定、可靠、高效的Keepalived高可用系统,为关键业务提供不间断的服务保障。