CentOS 下 Keepalived 高可用配置:从原理到实战的保姆级指南
关键词:Keepalived、高可用、VRRP、虚拟IP、CentOS、主备切换、健康检查
摘要:本文以“给小学生讲故事”的通俗语言,结合生活案例与技术细节,系统讲解 CentOS 下 Keepalived 高可用配置的全流程。从核心概念(如 VRRP 协议、虚拟 IP)到实战操作(安装、配置、测试),再到常见问题与未来趋势,帮你彻底掌握“服务器永不宕机”的魔法。
背景介绍
目的和范围
想象一下:你开了一家24小时营业的包子铺,只有1个厨师(主服务器)。如果厨师突然生病(服务器宕机),包子铺就得关门(服务中断),顾客全跑了(业务损失)。这时候,你需要1个“备用厨师”(备服务器),当主厨师生病时,备用厨师立刻顶上——这就是“高可用”(High Availability,HA)的核心需求。
本文将教你用 Keepalived 工具,在 CentOS 系统上搭建这样的“主备厨师团队”,覆盖:
Keepalived 核心原理(为什么能实现高可用?)
具体配置步骤(如何让主备服务器“接力”?)
实战测试与问题排查(如何验证切换成功?)
预期读者
运维工程师:需要保障业务连续性的一线操作者
开发工程师:想了解后端高可用方案的技术支持者
技术爱好者:对“服务器永不宕机”好奇的探索者
文档结构概述
本文采用“从概念到实战”的递进结构:
先讲“为什么需要 Keepalived”(背景)
再用生活案例解释核心概念(VRRP、虚拟 IP 等)
然后手把手教配置(安装→改配置→写检查脚本→测试)
最后总结常见问题与未来趋势
术语表
核心术语定义
高可用(HA):系统在部分组件故障时仍能持续提供服务的能力(如包子铺主厨师生病,备用厨师顶上)。
VRRP:虚拟路由冗余协议(Virtual Router Redundancy Protocol),Keepalived 的核心协议,负责协调主备节点“谁来干活”。
虚拟 IP(VIP):对外暴露的“共享车牌”,主节点正常时由它使用,主节点故障时备节点接管(顾客只认车牌,不用管具体是哪辆车)。
主节点(Master):当前负责处理业务的服务器(主厨师)。
备节点(Backup):随时待命的备用服务器(备用厨师)。
相关概念解释
健康检查:Keepalived 定期“敲主节点的门”,确认它是否存活(如检查 Nginx 进程是否运行)。
脑裂:主备节点因网络问题都认为对方故障,导致同时接管 VIP(相当于两个厨师都认为对方生病了,同时开始做包子,顾客会混乱)。
核心概念与联系:用“包子铺”故事讲明白
故事引入:包子铺的“永不关门”计划
你开了一家超火的包子铺,顾客每天排队买包子(用户访问服务器)。但有个大问题:只有1个厨师(主服务器),如果他突然生病(服务器宕机),包子铺就得关门(服务中断)。
为了解决这个问题,你做了两个关键动作:
找了个备用厨师(备服务器):他平时在厨房待命,主厨师正常时他休息,主厨师生病时他立刻顶上。
挂了块共享招牌(虚拟 IP):顾客只认这块招牌(VIP),不管当前是主厨师还是备用厨师在做饭(真实服务器 IP)。
但问题来了:
怎么让备用厨师知道主厨师生病了?(健康检查)
怎么让顾客自动切换到备用厨师的招牌?(VRRP 协议)
这就是 Keepalived 要解决的问题——它相当于“包子铺的大管家”,负责监控主厨师状态,协调主备切换,管理共享招牌。
核心概念解释(像给小学生讲故事)
核心概念一:VRRP 协议——主备的“裁判”
VRRP 就像包子铺的“裁判”,负责决定“当前该谁做饭”。它让主备服务器组成一个“虚拟路由组”,通过广播“我还活着”的消息(VRRP 通告)来沟通。主服务器优先级高(比如 100),备服务器优先级低(比如 90)。正常时主服务器发通告,备服务器“听”到后就乖乖待命;如果主服务器不发通告了(超过一定时间),备服务器就认为主服务器生病了,自己“升级”为主服务器开始做饭。
核心概念二:虚拟 IP(VIP)——顾客的“共享招牌”
虚拟 IP 是顾客访问包子铺的“统一入口”(比如 192.168.1.100)。主服务器正常时,VIP 绑定在它的网卡上(顾客访问 192.168.1.100 会跳转到主服务器的真实 IP);主服务器故障时,Keepalived 会把 VIP 切换到备服务器的网卡上(顾客访问 192.168.1.100 自动跳转到备服务器的真实 IP)。顾客完全感觉不到变化——他们只认招牌,不认具体是哪个厨师。
核心概念三:健康检查——主服务器的“体检医生”
健康检查是 Keepalived 的“体检医生”,定期检查主服务器是否真的能做饭(比如检查 Nginx 进程是否运行、80 端口是否监听)。如果主服务器的 Nginx 挂了(但服务器本身没宕机),健康检查会“告诉” Keepalived:“主厨师虽然没生病,但他的锅坏了,做不了包子!”这时候 Keepalived 也会触发主备切换,让备服务器接管 VIP。
核心概念之间的关系(用包子铺比喻)
VRRP 与 VIP 的关系:VRRP 是“裁判”,VIP 是“共享招牌”。裁判决定当前由谁拿招牌——主厨师健康时他拿,主厨师生病时备用厨师拿。
健康检查与 VRRP 的关系:健康检查是“体检医生”,给裁判提供主厨师的健康报告。如果医生说“主厨师生病了”,裁判就会让备用厨师接管招牌。
VIP 与健康检查的关系:VIP 是顾客访问的入口,健康检查确保拿到 VIP 的服务器真的能提供服务(比如备用厨师接管招牌后,医生也会检查他的锅是否正常)。
核心概念原理和架构的文本示意图
用户请求 → 虚拟 IP(VIP:192.168.1.100)
│
├─ 主服务器(IP:192.168.1.101,优先级100)
│ ├─ Keepalived 进程(运行 VRRP 协议,发送“我活着”通告)
│ └─ 健康检查(定期检查 Nginx 进程/80端口)
│
└─ 备服务器(IP:192.168.1.102,优先级90)
├─ Keepalived 进程(监听主服务器通告,待命)
└─ 健康检查(备用时也检查自身状态,确保随时能接管)
Mermaid 流程图:主备切换流程
graph TD
A[用户访问VIP] --> B{VIP绑定在谁的网卡?}
B -->|正常时| C[主服务器处理请求]
C --> D[主服务器Keepalived发送VRRP通告]
D --> E[备服务器收到通告,保持备用]
C --> F[健康检查:主服务器Nginx/端口正常?]
F -->|是| G[继续服务]
F -->|否/主服务器宕机| H[主服务器Keepalived停止发送通告]
H --> I[备服务器超时未收到通告]
I --> J[备服务器升级为主,绑定VIP]
J --> K[用户请求自动路由到备服务器]
核心算法原理 & 具体操作步骤
Keepalived 的核心是 VRRP 协议实现 + 健康检查模块。VRRP 协议通过以下步骤协调主备:
主备服务器加入同一个 VRRP 组,协商优先级(数值越高越优先)。
主服务器定期(默认 1 秒)发送 VRRP 通告(包含自己的优先级、状态)。
备服务器监听通告:若收到,确认主服务器存活;若超时未收到(默认 3 秒),认为主服务器故障,自己升级为主。
升级为主的服务器将 VIP 绑定到本地网卡,开始处理请求。
具体操作步骤(以 CentOS 7 为例)
步骤 1:准备两台 CentOS 服务器
主服务器(Master):IP 192.168.1.101, hostname master
备服务器(Backup):IP 192.168.1.102, hostname backup
虚拟 IP(VIP):192.168.1.100(需与主备服务器同网段)
步骤 2:安装 Keepalived
两台服务器都执行以下命令:
# 安装(CentOS 7 可用 yum)
yum install -y keepalived
# 查看版本(验证安装成功)
keepalived -v
# 输出类似:
# keepalived v2.0.19 (09/24,2019)
步骤 3:配置 Keepalived(关键!)
主服务器(192.168.1.101)配置文件:/etc/keepalived/keepalived.conf
global_defs {
router_id LVS_MASTER # 标识当前节点的名称(自定义,主备不同)
}
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh" # 健康检查脚本路径
interval 5 # 每5秒检查一次
weight -20 # 检查失败时,当前节点优先级降低20(触发切换)
}
vrrp_instance VI_1 {
state MASTER # 主节点状态(MASTER/Backup)
interface ens33 # 绑定VIP的网卡(ifconfig查看)
virtual_router_id 51 # VRRP组ID(主备必须相同,0-255)
priority 100 # 优先级(主>备,比如主100,备90)
advert_int 1 # 发送VRRP通告的间隔(秒)
authentication { # 认证(防伪造通告)
auth_type PASS
auth_pass 1111 # 密码(主备必须相同)
}
virtual_ipaddress { # 虚拟IP(可多个,每行一个)
192.168.1.100/24 # VIP及子网掩码
}
track_script {
check_nginx # 关联上面定义的健康检查脚本
}
}
备服务器(192.168.1.102)配置文件:/etc/keepalived/keepalived.conf
global_defs {
router_id LVS_BACKUP # 备节点名称
}
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh" # 与主节点相同脚本
interval 5
weight -20
}
vrrp_instance VI_1 {
state BACKUP # 备节点状态
interface ens33
virtual_router_id 51 # 必须与主节点相同!
priority 90 # 低于主节点
advert_int 1
authentication {
auth_type PASS
auth_pass 1111 # 与主节点相同!
}
virtual_ipaddress {
192.168.1.100/24
}
track_script {
check_nginx
}
}
步骤 4:编写健康检查脚本(关键防误切!)
两台服务器都创建脚本 /etc/keepalived/check_nginx.sh,并赋予执行权限:
# 创建脚本
vi /etc/keepalived/check_nginx.sh
# 输入以下内容(检查Nginx是否运行):
#!/bin/bash
# 检查Nginx进程是否存在
if [ $(ps -C nginx --no-headers | wc -l) -eq 0 ]; then
# 如果不存在,尝试重启Nginx
systemctl restart nginx
# 等待2秒后再次检查
sleep 2
if [ $(ps -C nginx --no-headers | wc -l) -eq 0 ]; then
# 重启失败,通知Keepalived切换(返回非0状态码)
exit 1
fi
fi
exit 0
# 赋予执行权限
chmod +x /etc/keepalived/check_nginx.sh
脚本逻辑解释:
第1次检查:如果 Nginx 进程不存在,尝试重启。
第2次检查:如果重启后还是不存在(说明 Nginx 故障严重),返回 exit 1,Keepalived 会降低当前节点优先级(通过 weight -20),触发主备切换。
步骤 5:启动 Keepalived 并设置开机自启
两台服务器都执行:
# 启动服务
systemctl start keepalived
# 设置开机自启
systemctl enable keepalived
# 查看状态(主服务器应显示Master,备显示Backup)
systemctl status keepalived
数学模型和公式:用简单公式理解切换逻辑
Keepalived 的主备切换本质是 优先级竞争,可用以下公式描述:
当前有效优先级 = 初始优先级 + 健康检查权重 当前有效优先级 = 初始优先级 + 健康检查权重 当前有效优先级=初始优先级+健康检查权重
初始优先级:主节点 100,备节点 90(配置文件中 priority 字段)。
健康检查权重:检查成功时为 0,检查失败时为 -20(配置文件中 weight -20)。
举例:
主节点正常时:有效优先级 = 100 + 0 = 100,备节点有效优先级 = 90 + 0 = 90 → 主节点优先。
主节点 Nginx 故障(健康检查失败):有效优先级 = 100 + (-20) = 80,备节点有效优先级 = 90 + 0 = 90 → 备节点优先级更高,接管 VIP。
项目实战:代码实际案例和详细解释说明
开发环境搭建
硬件:2 台 CentOS 7 服务器(推荐 2C4G 以上,模拟生产环境)。
软件:
CentOS 7(内核 3.10 以上)
Keepalived 2.0+(yum 默认版本可能较旧,可编译安装最新版)
Nginx(作为测试服务,验证切换后服务可用)
源代码详细实现和代码解读
前面的配置文件和健康检查脚本就是“源代码”,这里重点解读关键参数:
vrrp_instance 块核心参数
| 参数名 | 说明 | 主节点值 | 备节点值 |
|---|---|---|---|
state |
节点初始状态(MASTER/BACKUP) | MASTER | BACKUP |
interface |
绑定 VIP 的网卡(ifconfig 查看,如 ens33) |
ens33 | ens33 |
virtual_router_id |
VRRP 组 ID(主备必须相同,0-255) | 51 | 51 |
priority |
初始优先级(数值越高越优先) | 100 | 90 |
advert_int |
发送 VRRP 通告的间隔(秒,默认 1) | 1 | 1 |
authentication |
认证(防伪造通告,主备密码必须相同) | auth_pass 1111 | auth_pass 1111 |
virtual_ipaddress |
虚拟 IP(可多个,格式:IP/子网掩码) | 192.168.1.100/24 | 192.168.1.100/24 |
vrrp_script 块核心参数
| 参数名 | 说明 | 值 |
|---|---|---|
script |
健康检查脚本路径(需可执行) | /etc/keepalived/check_nginx.sh |
interval |
检查间隔(秒) | 5 |
weight |
检查失败时,当前节点优先级调整值(正数提升,负数降低) | -20 |
代码解读与分析
为什么主备的 virtual_router_id 必须相同?
VRRP 组通过 virtual_router_id 区分不同的高可用组。如果主备的 ID 不同,它们会认为属于不同的组,无法通信和切换。
为什么健康检查脚本要重启 Nginx 后再检查?
避免因 Nginx 短暂故障(如重启)触发误切换。比如,手动重启 Nginx 时,进程会短暂消失,脚本尝试重启后恢复,避免 Keepalived 误判为主节点故障。
advert_int 可以调大吗?
可以,但需权衡“检测速度”和“网络开销”。调大(如 2 秒)会减少网络广播,但故障检测时间会延长(切换延迟增加);调小(如 0.5 秒)检测更快,但可能增加网络负担。
实际应用场景
Keepalived 高可用方案广泛应用于以下场景:
1. Web 服务器高可用
场景:企业官网、电商平台等 Web 服务,通过 Keepalived 绑定 VIP,主备服务器部署 Nginx/Apache,确保某台服务器宕机时服务不中断。
2. 数据库高可用(配合主从复制)
场景:MySQL 主从复制架构中,主数据库宕机时,Keepalived 切换 VIP 到从数据库(需结合 read_only 配置,避免数据冲突)。
3. 负载均衡器高可用
场景:LVS(Linux 虚拟服务器)作为负载均衡器时,Keepalived 可为 LVS 提供高可用,确保负载均衡器本身不成为单点故障。
工具和资源推荐
官方资源
Keepalived 官方文档:最权威的配置指南,包含所有参数说明。
VRRP 协议 RFC 文档:想深入理解底层原理的必读材料。
社区与工具
监控工具:Prometheus + Grafana 监控 Keepalived 状态(通过 keepalived_exporter 采集指标,如 vrrp_instance_state)。
日志分析:journalctl -u keepalived 查看 Keepalived 运行日志(定位切换问题的关键)。
未来发展趋势与挑战
趋势 1:与云原生结合
随着 Kubernetes 普及,Keepalived 开始与 kube-vip 等工具结合,为云原生应用提供基于 VRRP 的 Service 高可用方案(替代传统的 LoadBalancer)。
趋势 2:支持多节点高可用
传统 Keepalived 是主备模式(1主N备),未来可能支持多主模式(多个节点同时提供服务,VIP 流量负载均衡),提升资源利用率。
挑战:脑裂问题
当主备节点因网络分区(如交换机故障)无法通信时,可能出现“脑裂”——主备都认为对方故障,同时绑定 VIP。解决方案:
心跳线:部署独立的心跳网络(如串口线),避免因业务网络故障导致误判。
仲裁机制:引入第三方节点(如磁盘锁、云存储),主备节点切换时需向仲裁节点申请“锁”,确保只有一个节点能接管 VIP。
总结:学到了什么?
核心概念回顾
VRRP 协议:主备的“裁判”,通过优先级和通告协调谁接管 VIP。
虚拟 IP(VIP):用户访问的“共享招牌”,主备切换时自动迁移。
健康检查:“体检医生”,确保接管 VIP 的节点真的能提供服务。
概念关系回顾
VRRP 决定“谁来拿招牌”,健康检查决定“拿招牌的人是否能干活”,VIP 是“用户看到的统一入口”。
思考题:动动小脑筋
如果主服务器的网络卡了(能发通告但延迟很高),备服务器会误切换吗?如何避免?(提示:调整 advert_int 和 master_down_interval)
你能为 MySQL 主从架构设计一个 Keepalived 高可用方案吗?需要注意哪些问题?(提示:主从复制延迟、从库 read_only 状态)
如果有 3 台服务器(1主2备),如何配置 Keepalived 实现“主→备1→备2”的级联切换?
附录:常见问题与解答
Q1:启动 Keepalived 后,VIP 没绑定到主服务器?
可能原因:
主备节点的 virtual_router_id 不一致。
防火墙阻止了 VRRP 通告(VRRP 使用 UDP 224.0.0.18 端口)。
解决方法:
检查配置文件 virtual_router_id 是否相同。
关闭防火墙或放行 VRRP 流量:
firewall-cmd --add-multicast=224.0.0.18 --permanent
firewall-cmd --reload
Q2:健康检查脚本执行了,但 Keepalived 没切换?
可能原因:
脚本没有执行权限(chmod +x 漏掉了)。
脚本返回值不是 0(健康检查失败时需返回非 0)。
解决方法:
手动执行脚本,查看输出(如 sh /etc/keepalived/check_nginx.sh)。
检查脚本逻辑,确保故障时返回 exit 1。
Q3:切换后,备服务器接管了 VIP,但用户请求还是到主服务器?
可能原因:
客户端本地 DNS 缓存(VIP 对应旧的服务器 IP)。
交换机 ARP 缓存未更新(VIP 的 MAC 地址未同步)。
解决方法:
客户端执行 ipconfig /flushdns(Windows)或 systemctl restart systemd-resolved(Linux)刷新 DNS 缓存。
主服务器故障后,Keepalived 会发送 ARP 广播更新交换机的 MAC 映射(正常流程会自动处理,无需手动操作)。
扩展阅读 & 参考资料
《Linux 服务器高可用架构实战》(机械工业出版社)
Keepalived 官方 GitHub 仓库
阿里云官方文档:使用 Keepalived 搭建高可用集群


















暂无评论内容