CentOS 下 Keepalived 高可用配置

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_intmaster_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 搭建高可用集群

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容