Keepalived 高可用全解析:重点总结与实验指南

一、HA 集群能解决哪些问题?

将服务放入 HA 集群前,需先判断该服务本身是否具备故障转移或负载均衡能力:

  • 不适合放入 HA 集群的服务:如 DNS、LDAP 自身支持多 Master 或主从复制,客户端也能配置多个服务器地址,本身已解决单点故障。再加入 HA 集群收益不大。
  • 适合放入 HA 集群的服务:如 RabbitMQ、Galera(MySQL 集群)等,本身缺乏自动故障转移机制,通过 Keepalived 可显著提升可用性。

⚠️ HA 集群的局限性:无法解决应用程序自身 Bug 导致的崩溃(所有节点都有相同 Bug 照样崩溃),也无法处理集群外部的网络故障(如交换机断电、网线断开等)。


二、Keepalived 介绍

  • 定位:用 C 语言编写的路由软件,为 Linux 提供负载均衡和高可用能力。
  • 核心功能
    • 最初为 LVS(Linux Virtual Server)设计,可检测后端服务器状态,自动剔除故障节点。
    • 后续加入 VRRP(虚拟路由冗余协议),实现主备切换和虚拟 IP(VIP)漂移,解决静态路由的单点故障问题。

三、VRRP 原理简述

  • 解决的问题:单网关(默认路由)故障时,所有依赖该网关的设备会断网。
  • 实现方式:将两台(或多台)物理路由器虚拟为一台虚拟路由器,对外提供同一个 VIP(虚拟 IP)
  • 关键术语
    • VRRP 路由器:运行 VRRP 协议的设备(如 R1、R2)。
    • VRID:虚拟路由器标识符,同一 VRRP 组的设备必须使用相同 VRID。
    • Master:主路由器,实际处理流量并响应 VIP。
    • Backup:备份路由器,监听 Master 心跳,当 Master 故障时接管 VIP。
  • 工作流程:Master 定期发送 VRRP 通告(组播),Backup 收到通告则保持备用;若超时未收到,Backup 会抢占成为新 Master。

四、脑裂(Split-Brain)详解

4.1 什么是脑裂?

在主备集群中,主、备节点因通信中断,都认为对方已故障,于是同时抢占资源(如 VIP),导致集群混乱。

4.2 产生原因

类别 说明
网络问题 心跳线路故障、交换机端口坏掉、网线松动
防火墙 屏蔽了 VRRP 协议端口(UDP 112)
资源耗尽 CPU / 内存满载,无法及时处理或发出心跳包
配置错误 statepriorityauthentication 等参数不一致

4.3 危害

  • 多个节点同时持有 VIP → 客户端请求分走不同后端,部分成功部分失败。
  • 若后台是数据库 → 双写冲突,数据不一致甚至损坏。
  • 集群失效,失去高可用意义。

4.4 如何避免脑裂?

  1. 多心跳线路:除主网卡外再增加独立网卡或交叉网线,配置 track_interface 监控多个接口。
  2. 启用 VRRP 认证:使用 auth_type PASS + auth_pass,防止非法节点干扰。
  3. 防火墙放行 VRRP:开放 UDP 112 端口。
  4. 部署第三方隔离工具:通过 notify_master 脚本检测脑裂并强制关闭对方节点(如 fence_virshreboot)。
  5. 降低脑裂影响:业务层采用分布式锁、读写分离、避免双写。
  6. 监控告警:监控 keepalived 状态,发现双 Master 时立即告警。

💡 本质解决思路:多重检测 + 自动隔离


五、实验:基于 Keepalived + Nginx 搭建高可用 Web 集群

5.1 实验拓扑与规划

主机名 IP 地址 角色
client1.laogao.cloud 10.1.8.21 客户端
web1.laogao.cloud 10.1.8.11 Web 主节点
web2.laogao.cloud 10.1.8.12 Web 备节点
VIP 10.1.8.100 对外虚拟 IP

实验环境 CentOS 7 / RHEL 系,网卡名称 ens33

5.2 第一步:部署 Nginx(web1 和 web2)

在两台 Web 节点上安装 Nginx,并创建不同首页内容用于区分。

# 在 web1 和 web2 上执行

# 1. 安装 nginx
yum install -y nginx

# 2. 编写测试页面:显示各自主机名
#    注意:$(hostname) 会被 shell 替换为实际主机名
echo "welcome to $(hostname)" > /usr/share/nginx/html/index.html

# 3. 启动 nginx 并设置开机自启
systemctl enable nginx.service --now

# 4. 验证后端 nginx 是否正常(在客户端节点测试)
# curl 10.1.8.11   -> 显示 welcome to web1.laogao.cloud
# curl 10.1.8.12   -> 显示 welcome to web2.laogao.cloud

5.3 第二步:配置 Keepalived(web2 备节点)

# 在 web2 (10.1.8.12) 上执行

# 1. 安装 keepalived
yum install -y keepalived

# 2. 备份原始配置
cp /etc/keepalived/keepalived.conf{,.ori}

# 3. 编辑配置文件
vim /etc/keepalived/keepalived.conf

web2 配置文件内容(备节点):

! Configuration File for keepalived

global_defs {
    router_id web2          # 本路由器标识,集群内唯一
}

vrrp_instance nginx {       # 定义一个 VRRP 实例,名称为 nginx
    state BACKUP            # 角色:备节点。不抢占 VIP
    interface ens33         # VIP 绑定的物理网卡
    virtual_router_id 51    # 虚拟路由器 ID,主备必须一致,范围 1-255
    priority 100            # 优先级,值越低越“备份”,Master 通常更高
    advert_int 1            # 心跳发送间隔(秒)

    authentication {        # 认证配置,防止非法设备加入 VRRP 组
        auth_type PASS      # 简单密码认证
        auth_pass laogao@123 # 密码(最多 8 位,超过只取前 8)
                              # 注意:线上请避免弱密码
    }

    virtual_ipaddress {     # 虚拟 IP(VIP)
        10.1.8.100/24       # 网段/掩码,要和接口在同一网段
    }
}
# 4. 启动 keepalived 并加入开机自启
systemctl enable keepalived.service --now

# 5. 查看 IP 地址,应能看到 VIP (10.1.8.100) 已绑定
ip -br a show ens33
# 输出示例:
# ens33 UP 10.1.8.12/24 10.1.8.100/24 fe80::20c:29ff:fe83:619c/64

5.4 第三步:配置 Keepalived(web1 主节点)

# 在 web1 (10.1.8.11) 上执行

yum install -y keepalived
cp /etc/keepalived/keepalived.conf{,.ori}
vim /etc/keepalived/keepalived.conf

web1 配置文件内容(主节点):

! Configuration File for keepalived

global_defs {
    router_id web1          # 主节点标识名,不能和 web2 重复
}

vrrp_instance nginx {
    state MASTER            # 角色:主节点,主动持有 VIP
    interface ens33
    virtual_router_id 51    # 必须与 web2 一致
    priority 110            # 优先级高于 web2(110 > 100),确保成为 Master
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass laogao@123 # 认证密码与备节点完全相同
    }

    virtual_ipaddress {
        10.1.8.100/24
    }
}
# 启动服务
systemctl enable keepalived.service --now

# 查看 web1 的 IP —— VIP 应出现在 web1 上
ip -br a show ens33
# ens33 UP 10.1.8.11/24 10.1.8.100/24 ...

# 查看 web2 的 IP —— 备节点此时无 VIP
ip -br a show ens33
# ens33 UP 10.1.8.12/24 ...

5.5 第四步:高可用切换验证

场景1:正常访问
# 在客户端 client1 上执行
curl 10.1.8.100
# 输出应显示:welcome to web1.laogao.cloud
# 说明当前 VIP 指向 web1
场景2:模拟主节点故障(停止 web1 上的 keepalived)
# 在 web1 上执行
systemctl stop keepalived.service

# 此时 web1 不再发送 VRRP 心跳,web2 经过约 3 个通告周期(默认 3*1秒)后,会自动接管 VIP

# 在 web2 上查看 IP,会发现 VIP 出现
ip -br a show ens33
# ens33 UP 10.1.8.12/24 10.1.8.100/24 ...

# 在客户端再次访问
curl 10.1.8.100
# 输出变为:welcome to web2.laogao.cloud
# 说明已经无缝切换到 web2
场景3:主节点恢复
# 重新启动 web1 上的 keepalived
systemctl start keepalived.service

# 因为 web1 的 priority=110 高于 web2 的 100,它会重新抢占 VIP(若配置了抢占模式,默认即抢占)
# 稍等几秒后,VIP 将回到 web1

# 在 web1 上确认
ip -br a show ens33 | grep 10.1.8.100   # 应出现

# 客户端再次访问
curl 10.1.8.100
# 输出恢复为:welcome to web1.laogao.cloud

六、Keepalived 配置文件深度解析

Keepalived 配置文件 (/etc/keepalived/keepalived.conf) 可分为三大区块:

6.1 全局配置(global_defs)

global_defs {
    # 邮件通知相关(可选)
    notification_email {
        admin@example.com
    }
    notification_email_from keepalived@example.com
    smtp_server 127.0.0.1
    smtp_connect_timeout 30

    # 节点身份标识(重要,集群内唯一)
    router_id LVS_DEVEL

    # 性能与安全相关参数
    vrrp_skip_check_adv_addr   # 跳过检查 VRRP 通告中的所有地址(加速)
    vrrp_strict                # 严格遵守 VRRP 协议(建议生产环境开启)
    vrrp_garp_interval 0       # 发送免费 ARP 的延迟(秒)
    vrrp_gna_interval 0        # 发送 NA 消息的延迟
}

6.2 VRRP 实例配置(vrrp_instance)

vrrp_instance <实例名> {
    state MASTER|BACKUP        # 角色:主或备
    interface eth0             # VIP 绑定的网卡
    mcast_src_ip 192.168.1.1   # 指定发送心跳的源 IP(多网卡时有用)
    virtual_router_id 51       # VRRP 组 ID,主备一致
    priority 150               # 优先级,Master 应高于 Backup
    advert_int 1               # 心跳间隔(秒)
    
    authentication {           # 认证(防脑裂基础)
        auth_type PASS
        auth_pass secret
    }
    
    virtual_ipaddress {        # 虚拟 IP 列表
        192.168.1.100/24 dev eth0 label eth0:1
        192.168.1.200/24
    }
    
    track_interface {          # 监控的网卡,任何一块故障会触发降级
        eth0
        eth1
    }
    
    notify_master "/path/to/script.sh master"   # 成为 Master 时执行脚本
    notify_backup "/path/to/script.sh backup"   # 成为 Backup 时执行
    notify_fault "/path/to/script.sh fault"     # 故障时执行
}

6.3 LVS 配置(virtual_server)

此部分用于与 LVS 集成,可配置后端真实服务器及其权重、健康检查等。

virtual_server 10.1.8.100 80 {
    delay_loop 6              # 健康检查间隔
    lb_algo rr                # 负载均衡算法:rr|wrr|lc|sh 等
    lb_kind DR                # 模式:DR|NAT|TUN
    persistence_timeout 50    # 会话保持时间(秒)
    protocol TCP

    real_server 10.1.8.11 80 {
        weight 1
        TCP_CHECK {           # TCP 健康检查
            connect_timeout 3
            connect_port 80
        }
    }
    real_server 10.1.8.12 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 3
        }
    }
}

七、开启 Keepalived 日志(便于排错)

默认 keepalived 日志输出到系统日志,可单独拆分到文件。

# 1. 修改 /etc/sysconfig/keepalived
vim /etc/sysconfig/keepalived
# 将 KEEPALIVED_OPTIONS="-D" 改为:
KEEPALIVED_OPTIONS="-D -S 0"

# 2. 配置 rsyslog 接收 local0 日志
vim /etc/rsyslog.d/keepalived.conf
# 写入内容:
local0.*    /var/log/keepalived.log

# 3. 重启日志服务和 keepalived
systemctl restart rsyslog
systemctl restart keepalived

# 4. 实时监控日志
tail -f /var/log/keepalived.log

八、关键心跳参数 mcast_src_ip

当服务器有多个网卡时,可指定 VRRP 通告从哪个 IP 发出:

vrrp_instance Nginx {
    state MASTER
    interface ens36           # 用于通信的主接口
    mcast_src_ip 20.0.0.11    # 强制源 IP,避免路由混乱
    virtual_router_id 51
    priority 110
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass laogao@123
    }
    virtual_ipaddress {
        10.1.1.10/24
    }
}

九、总结

知识点 核心内容
Keepalived 作用 基于 VRRP 实现高可用;可搭配 LVS 做四层负载均衡,解决单点故障。
VRRP 核心 虚拟路由器 + VIP;Master 发送心跳,Backup 监听;故障时自动切换。
脑裂原因 心跳中断(网络、防火墙、高负载、配置不一致)。
脑裂解决方案 多心跳线路 + VRRP 认证 + 隔离脚本 + 业务层防双写 + 监控告警。
典型实验 Nginx + Keepalived 主备模式:VIP 自动漂移,客户端无感知访问真实服务。
配置关键点 router_id 唯一、virtual_router_id 一致、priority 主高备低、认证一致。

🔧 生产建议

  • 不要依赖单一心跳链路,至少双链路。
  • 密码长度不超过 8 位(Keepalived 限制),或改用更高版本支持更长的认证方式。
  • 结合 vrrp_script 检测业务进程(如 nginx),避免只有 VIP 但业务已死的“假存活”。

通过 Keepalived 搭建的高可用架构,能够有效保障 Web、数据库、负载均衡器等关键服务的连续性,是现代 Linux 运维工程师必须掌握的核心技能之一。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐