架构篇-keepalived高可用
一、keepalived实现原理
查看文件:Nginx-Keepalived.html
二、部署keepalived
节点信息
节点名称 | IP 地址 | 角色 |
---|---|---|
node1 | 10.0.0.5 | Master |
node2 | 10.0.0.6 | Backup |
VIP | 10.0.0.3 | 虚拟 IP |
LB01 上的 Keepalived 部署步骤
- 这一步部署的为主备,抢占式
1.安装 Keepalived
[root@lb01 ~]# yum -y install keepalived
2.配置 Keepalived(/etc/keepalived/keepalived.conf
)
global_defs { #全局配置
router_id lb01 #标识身份->名称
}
vrrp_instance VI_1 {
state MASTER #标识角色状态
interface ens33 #网卡绑定接口
virtual_router_id 50 #虚拟路由id,50小组
priority 150 #优先级
advert_int 1 #监测间隔时间
authentication { #认证,同一50小组
auth_type PASS #认证方式
auth_pass 1111 #认证密码
}
virtual_ipaddress {
10.0.0.3 #虚拟的VIP地址
}
}
3.启动服务
LB02 上的 Keepalived 部署步骤
1.安装 Keepalived
[root@lb02 ~]# yum -y install keepalived
2.配置 Keepalived(/etc/keepalived/keepalived.conf
)
global_defs { #全局配置
router_id lb02 #标识身份->名称
}
vrrp_instance VI_1 {
state BACKUP #标识角色状态
interface ens33 #网卡绑定接口
virtual_router_id 50 #虚拟路由id
priority 100 #优先级
advert_int 1 #监测间隔时间
authentication { #认证
auth_type PASS #认证方式
auth_pass 1111 #认证密码
}
virtual_ipaddress {
10.0.0.3 #虚拟的VIP地址
}
}
3.启动服务
三、抢占式,查看测试
查看虚拟 IP 及相关测试
- 查看虚拟 IP 地址分配情况
- 在 Linux 系统中,使用
ip a
命令可以查看网络接口信息,包括虚拟 IP(VIP)是否正确绑定到相应的网络接口。例如,在部署了 Keepalived 的节点(如 LB01 或 LB02)上执行:
[root@lb01 ~]# ip a
- 输出结果中会显示网络接口信息,查找是否有
10.0.0.3
这个 VIP 地址绑定在指定的网卡(如ens33
)上。如果 Keepalived 正常工作,在 Master 节点上应该能看到该 VIP 地址已成功绑定。
- 通过 hosts 解析进行访问测试
- 在 Windows 系统中位于
C:\Windows\System32\drivers\etc\hosts
),添加一条记录将域名映射到虚拟 IP 地址10.0.0.3
。 - 然后在浏览器或其他客户端工具中,通过访问 域名
www.wp.com
来测试是否能够正常访问到由 Keepalived 提供高可用服务的后端应用。如果配置正确且服务正常运行,应该能够成功连接到相应的服务。
- 在 Windows 端查看 MAC 地址(使用
arp -a
命令)
- 在 Windows 操作系统中,打开命令提示符(CMD),输入
arp -a
命令。该命令会显示本地 ARP 缓存中的 IP 地址与 MAC 地址映射关系。 - 查找与虚拟 IP
10.0.0.3
对应的 MAC 地址。当 Keepalived 正常工作时,在客户端的 ARP 缓存中,10.0.0.3
的 MAC 地址应该是 Master 节点的 MAC 地址。这是因为 Keepalived 通过虚拟路由器冗余协议(VRRP)控制虚拟 IP 的 MAC 地址响应,确保客户端的流量总是被导向到当前的 Master 节点。
主 Keepalived 节点故障测试
- 停止主 Keepalived 服务
- 在主节点(如 LB01)上执行以下命令停止 Keepalived 服务:
[root@lb01 ~]# systemctl stop keepalived
- 再次查看虚拟 IP 及测试
- 再次在备节点(LB02)上执行
ip a
命令,确认虚拟 IP10.0.0.3
是否已经漂移到备节点。如果 Keepalived 配置正确且故障转移正常,此时应该在备节点上看到10.0.0.3
绑定到相应的网络接口。 - 在 Windows 端再次执行
arp -a
命令,查看10.0.0.3
的 MAC 地址是否已经更新为备节点的 MAC 地址。这表明客户端的流量将被自动导向到新的 Master 节点(即原来的备节点 LB02),实现了高可用的故障转移功能。 - 通过访问
myservice.example.com
再次进行测试,确保服务仍然能够正常访问,验证在主节点故障情况下,Keepalived 能够成功将虚拟 IP 切换到备节点,并且后端服务不受影响,持续为用户提供服务。
四、配置非抢占式
一、非抢占式配置说明
- 抢占式模式是 Keepalived 的默认行为,即根据节点配置的优先级(
priority
)来决定主节点,配置高的节点优先成为主节点并可在自身状态变化或检测到更高优先级节点时抢占主角色。然而,在某些场景下,如节点配置相同且希望减少不必要的角色切换时,可采用非抢占式配置。 - 非抢占式配置下,即使有更高优先级的节点上线或恢复,当前的主节点也不会被抢占,除非主节点自身故障下线。
二、配置步骤
- LB01(原 Master)配置修改
- 编辑 Keepalived 配置文件
/etc/keepalived/keepalived.conf
:
vrrp_instance VI_1 {
state BACKUP # 将状态改为 BACKUP,非抢占式下主节点也设为 BACKUP 状态
interface ens33 # 网卡绑定接口
virtual_router_id 50 # 虚拟路由 id
priority 150 # 优先级仍保持较高,用于初始主节点选举
advert_int 1 # 监测间隔时间
authentication { # 认证
auth_type PASS # 认证方式
auth_pass 1111 # 认证密码
}
virtual_ipaddress {
10.0.0.3 # 虚拟的 VIP 地址
}
nopreempt # 配置不抢占参数,即使有更高优先级节点,也不主动让出主角色
}
- 修改完成后,重启 Keepalived 服务使配置生效:
[root@lb01 ~]# systemctl restart keepalived
- LB02(原 Backup)配置修改
- 同样编辑
/etc/keepalived/keepalived.conf
:
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 50
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3
}
nopreempt # 配置不抢占参数
}
- 重启 Keepalived 服务:
[root@lb02 ~]# systemctl restart keepalived
三、测试过程
- 初始状态检查
- 在配置完成后,首先检查 VIP 的位置。使用
ip a
命令分别在 LB01 和 LB02 上查看,由于 LB01 优先级较高,VIP10.0.0.3
应该在 LB01 上绑定到ens33
网卡。 - 在客户端通过之前配置的
hosts
解析(如myservice.example.com
映射到10.0.0.3
)进行访问测试,确保服务正常。
- 模拟主节点恢复场景
- 假设 LB01 曾因某种原因(如网络短暂中断或服务重启)下线,此时 VIP 会漂移到 LB02,因为 LB02 是备份节点且 Keepalived 会检测到主节点故障并进行切换。
- 当 LB01 恢复正常后,再次查看 VIP 位置,由于配置了非抢占式,VIP 仍然会保留在 LB02 上,不会因为 LB01 恢复且优先级较高而切换回 LB01。
- 在客户端持续进行访问测试,验证服务在主节点恢复但未发生 VIP 切换的情况下仍然正常运行,确保非抢占式配置在实际场景中的有效性。
- 查看日志与状态信息
- 在 LB01 和 LB02 上查看 Keepalived 的日志信息(通常位于
/var/log/messages
或/var/log/syslog
,具体取决于系统配置),搜索与 VRPP 相关的日志条目,确认在主节点恢复时是否有关于非抢占式配置的日志记录,如 “Not preempting. Received higher prio advert.” 等信息,进一步验证非抢占式配置的正确性和 Keepalived 的运行状态。
五、脑裂,抢占式
零、脑裂粗鲁总结说明
- 两台都认为自己是MASTER,master
- 都收不到对方的心跳信息
- 其实底层还是通过mac地址访问,
- 谁最后通告的arp的mac地址是谁,客户端就还去找谁
1、服务器网线松动等网络故障
2、服务器硬件故障发生损坏现象而崩溃
3、主备都开启firewalld防火墙
一、脑裂现象概述
- 脑裂是在 Keepalived 高可用集群环境中可能出现的一种异常状态。在这种状态下,集群中的两台服务器(如原本的主节点和备份节点)都错误地认为自己是主(MASTER)节点,导致整个集群出现分裂,无法正常提供统一的、协调一致的服务。
- 其核心原因是主备节点之间的心跳信息传递出现问题,使得双方无法知晓对方的真实状态,从而各自为政。
二、脑裂产生原因
- 网络故障导致心跳中断
- 例如服务器网线松动,这可能会使主备节点之间的网络连接中断,心跳包无法在节点之间正常传输。即使节点本身运行正常,但由于无法接收到对方的心跳信息,就会按照 Keepalived 的故障检测机制,认为对方节点已经失效,进而都有可能尝试切换为主节点。
- 网络中的其他故障,如交换机故障、网络拥塞严重导致心跳包丢失等情况,也可能引发类似的问题,导致主备节点之间的通信中断,最终引发脑裂。
- 服务器硬件故障引起的异常
- 当服务器硬件发生损坏现象而崩溃时,可能会出现部分故障情况。例如,主节点的网络接口硬件损坏,导致其无法发送心跳信息,但服务器的其他部分仍在运行,并且由于收不到备份节点的心跳回复(实际上是因为自身无法发送心跳),就会认为备份节点故障,而备份节点由于长时间未收到主节点心跳,也会认为主节点故障,从而都进入主节点状态,引发脑裂。
- 防火墙配置不当
- 如果主备节点都开启了
firewalld
防火墙,并且没有正确配置防火墙规则以允许 Keepalived 的心跳包(通常是基于 VRRP 协议的数据包)通过,那么就会导致心跳信息被防火墙拦截,节点之间无法正常通信,进而产生脑裂现象。
三、脑裂引发的问题
- 由于客户端实际上是基于底层的 MAC 地址进行访问的,在脑裂发生前,客户端通过 ARP 协议获取到了主节点的 MAC 地址,并将其缓存。当脑裂发生后,虽然两个节点都认为自己是主节点,但客户端仍然会按照之前缓存的 MAC 地址将请求发送到最初的主节点(即使它可能已经不是真正的主节点了),这就会导致服务的混乱和不一致性。部分客户端请求可能会被错误地处理,而新的连接可能会被分散到两个自认为是主节点的服务器上,导致数据不一致、服务中断或其他异常情况,严重影响整个系统的可用性和稳定性。
四、预防与解决脑裂的措施
- 网络层面
- 采用冗余网络设计,如使用多条网线连接服务器,通过链路聚合技术提高网络连接的可靠性,避免因单条网线故障导致心跳中断。
- 定期检查网络设备和服务器网络接口的健康状况,及时发现和修复潜在的网络问题。
- 硬件层面
- 实施服务器硬件监控,对服务器的关键硬件组件(如 CPU、内存、硬盘、网络接口等)进行实时监测,一旦发现硬件故障风险或异常,及时进行预警和处理,避免因硬件故障引发脑裂。
- 防火墙配置层面
- 正确配置
firewalld
防火墙或其他防火墙软件,允许 Keepalived 的心跳包通过。例如,可以添加特定的规则允许 VRRP 协议(通常使用 UDP 端口 112)的数据包在主备节点之间传输,确保节点之间的心跳通信正常。
六、Keepalived结合Nginx
- 如果keepalived服务没挂,nginx挂了怎么办
- 无法地址漂移
一、配置目的
通过将 Keepalived 与 Nginx 结合,实现对 Nginx 服务的高可用性监控与故障转移。当 Nginx 服务出现故障时,Keepalived 能够检测到并尝试重启 Nginx,如果重启后 Nginx 仍无法正常工作,则停止 Keepalived 服务,将虚拟 IP(VIP)切换到备份节点,以确保客户端对服务的持续访问。
二、配置步骤
- 定义检测 Nginx 的脚本
- 创建一个名为
check_web.sh
的脚本:
[root@lb01 ~]# cat check_web.sh
#!/bin/bash
# 检查 Nginx 是否在监听 80 端口,统计相关进程数量
Nginx=`netstat -tanulp|grep 80|wc -l`
# 如果 Nginx 未在监听 80 端口(即 Nginx 可能出现故障)
if [ $Nginx -eq 0 ];then
# 尝试重启 Nginx 服务
systemctl restart nginx
# 再次检查 Nginx 是否在监听 80 端口
Nginx=`netstat -tanulp|grep 80|wc -l`
# 如果重启后 Nginx 仍未正常监听 80 端口
if [ $Nginx -eq 0 ];then
# 停止 Keepalived 服务,触发故障转移
systemctl stop keepalived
fi
fi
- 此脚本首先通过检查
netstat
命令输出中与 80 端口相关的进程数量来判断 Nginx 是否正常运行。如果未检测到,则尝试重启 Nginx,并再次检查。若重启后仍无响应,则停止 Keepalived,使 VIP 漂移到备份节点。
- 赋予脚本执行权限
[root@lb01 ~]# chmod +x check_web.sh
- 将脚本写入 Keepalived 配置文件
- 编辑
/etc/keepalived/keepalived.conf
文件: - 添加以下内容调用脚本:
#每5秒执行一次脚本,脚本执行内容不能超过5秒,否则会中断再次重新执行脚本
vrrp_script check_web {
script "/root/check_web.sh"
interval 5
}
........配置
#调用执行脚本,在vrrp_instance模块下
track_script {
check_web
}
}
global_defs { #全局配置
router_id lb01 #标识身份->名称
}
# 定义一个名为 check_web 的 VRRP 脚本
vrrp_script check_web {
script "/root/check_web.sh" # 指定脚本路径
interval 5 # 脚本执行间隔时间为 5 秒
}
vrrp_instance VI_1 {
state MASTER #标识角色状态
interface ens33 #网卡绑定接口
virtual_router_id 50 #虚拟路由 id
priority 150 #优先级
advert_int 1 #监测间隔时间
authentication { #认证
auth_type PASS #认证方式
auth_pass 1111 #认证密码
}
virtual_ipaddress {
10.0.0.3 #虚拟的 VIP 地址
}
# 关联定义的 VRRP 脚本,使其生效
track_script {
check_web
}
}
- 在
keepalived.conf
文件中,首先定义了vrrp_script
部分,指定了检测脚本的路径和执行间隔。然后在vrrp_instance
部分通过track_script
关联了之前定义的检测脚本,使 Keepalived 能够按照设定的规则调用脚本对 Nginx 进行监控。
- 重启服务
三、后续维护与注意事项
- 脚本优化
- 上述脚本仅简单地通过检查 80 端口来判断 Nginx 状态,可能存在误判情况。例如,Nginx 进程可能存在但处于异常状态无法正常处理请求,此时仅检查端口并不全面。可以考虑进一步优化脚本,如检查 Nginx 日志文件中的错误信息、发送测试请求到 Nginx 并检查响应等,以更精准地判断 Nginx 服务的健康状况。
- 日志监控
- 定期查看 Keepalived 和 Nginx 的日志文件,以便及时发现潜在问题。Keepalived 的日志文件通常位于
/var/log/messages
或/var/log/syslog
中,可查看与 VRRP 脚本执行、主备切换等相关的日志信息。Nginx 的日志文件则记录了 Nginx 服务的运行状态、访问请求、错误信息等,通过分析这些日志,可以提前发现 Nginx 可能出现的故障迹象,并及时采取措施进行修复或优化。
- 备份与恢复
- 定期备份 Keepalived 和 Nginx 的配置文件以及相关数据。在出现配置错误或服务器故障时,能够快速恢复到之前的正常状态,减少服务中断时间。同时,在对配置进行重大修改之前,建议先备份当前配置,以便在修改出现问题时可以回滚。