Keepalived高可用全解析

Keepalived 高可用全解析------用 VRRP 给服务上双保险

上一篇把 LVS 四层负载均衡讲透了,结尾留了个钩子:生产环境里 LVS 本身也是个单点,它挂了怎么办?答案就是今天的主角 Keepalived。它基于 VRRP 协议,给负载均衡器、网关、Web 服务等任何需要"主备"的场景加一层自动故障切换,让服务不中断。

这篇文章从"高可用到底能解决什么问题"聊起,把 VRRP 原理掰开揉碎,重点攻下最难理解的"脑裂",最后用三节点拓扑跑一遍完整的故障切换实验。


一、HA 集群能解决什么问题?

上高可用之前,得先回答一个问题:把这服务丢进 HA 集群,可用性真的会变高吗?

答案是"不一定"。关键看两件事:这个服务自带什么能力,它的客户端又是怎么配置的。

拿 DNS 和 LDAP 来说,它们天生自带故障转移和负载均衡------本身就能配成多台服务器、master/slave 或多 master,客户端也能同时指向多个服务端。这种服务放进 HA 集群,纯属多此一举,没什么收益。

反过来,像 OpenStack 里的 RabbitMQ、Galera 这类自身没有 failover 能力的服务,扔进 HA 集群收益就很大。

还有两个边界要认清:

  1. HA 救不了 bug。应用因为代码 bug 崩溃,切到备节点,备节点跑的是同一份代码、同一个 bug,照样崩。
  2. HA 不提供端到端冗余 。集群本身活得好好的,但如果网络架构有单点(比如就一根上联交换机挂了),客户端还是连不上。所以集群里的每一个组件都得排查,不能留单点。

二、Keepalived 是什么?

Keepalived 是一个用 C 语言写的路由软件,目标就是给 Linux 系统提供一套简单又健壮的负载均衡 + 高可用设施。

它最初是为 LVS 设计的,专门盯着集群里各服务节点的健康状况。按 TCP/IP 的第三、四、五层机制去探测每个节点,一旦发现某台机器异常或故障,就自动把它从集群里踢出去------全程无人干预,人工要做的只是事后去修那台坏机器。

后来 Keepalived 又引入了 VRRP(Virtual Router Redundancy Protocol,虚拟路由冗余协议)。VRRP 的诞生就是为了解决静态路由的单点故障,让网络能不间断运行。于是 Keepalived 就有了双重身份:

  • 健康检测 + 故障隔离(监控节点、剔除故障)
  • 高可用集群(主备切换)

三、VRRP 原理:从"单网关"的痛点说起

局域网里的终端,通常配一个默认网关就能上网。麻烦在于:这个网关一旦挂了,所有终端的出网流量全部中断

解决方案看起来很简单------多部署几个网关做备份。但新问题来了:多个网关之间怎么协调?谁的优先级高?主挂了谁顶上?全靠人工手切根本不现实。

VRRP 就是干这个的:既实现网关备份,又解决多网关冲突

3.1 VRRP 的核心思路:虚拟出一台路由器

VRRP 把几台真实路由器联合起来,虚拟出一台逻辑上的"虚拟路由器"。当主路由器的下一跳出问题时,及时把业务切到备份路由器,保证通讯不中断。

一个具体例子:

复制代码
R1:192.168.1.251/24
R2:192.168.1.252/24
虚拟路由器:192.168.1.254   ← 所有 PC 的默认网关都指向它

所有 PC 只管把网关设成 192.168.1.254,底层到底是 R1 还是 R2 在干活,客户端完全无感。

3.2 一网打尽 VRRP 基本概念

概念 说明
VRRP 路由器 运行 VRRP 协议的路由器(如 R1、R2),VRRP 配置在接口上、也基于接口工作
VRID 虚拟路由器标识符,同一个 VRRP 组的路由器用同一个 VRID 协作,一组只出一台 Master
虚拟路由器 VRRP 抽象出来的逻辑设备,一个组只会产生一台
虚拟 IP / MAC 虚拟路由器有自己的 IP 和 MAC。IP 由管理员指定(通常当网关用);MAC 格式固定为 0000-5e00-01xxxx 就是 VRID
Master 路由器 承担报文转发任务,组里只有 Master 会响应虚拟 IP 的 ARP 请求,并周期性发 VRRP 报文报平安
Backup 路由器 备份角色,实时监听 Master 的 VRRP 报文,随时准备接班
Priority 选举依据,取值 0~255,越大越优先;相等时比接口 IP,大的赢

3.3 VRRP 报文格式

VRRP 只有一种报文------Advertisement(通告),通过组播发送,所以只能在同一个广播域内传递。

  • 目的组播地址:224.0.0.18
字段 含义
Ver 版本。VRRPv2 仅支持 IPv4,VRRPv3 同时支持 IPv4/IPv6
Virtual Rtr ID 该报文关联的虚拟路由器标识
Priority 发送方的优先级
Count IP Addrs 报文里包含的虚拟 IP 数量
Auth Type 认证类型:0=不认证、1=纯文本密码、2=MD5
Adver Int 通告间隔,默认 1 秒
IP Address 关联的虚拟 IP,可以有多个
Authentication Data 认证所需的密码信息

3.4 两个定时器

VRRP 靠两个定时器运转:

  • ADVER_INTERVAL:Master 发通告的周期,默认 1 秒。
  • MASTER_DOWN:Backup 监听超时后,就认为 Master 挂了,自己升为 Master。

计算公式:

复制代码
MASTER_DOWN = (3 × ADVER_INTERVAL) + Skew_time
Skew_time = (256 - Priority) / 256

注意 Skew_time 的存在:优先级越高的备份,超时越短,切换越快------高优先级者先抢到 Master

3.5 主备选举过程

设备刚创建时处于 Initialize 状态。收到接口 Up 消息后,如果优先级小于 255,先切到 Backup 状态,等 MASTER_DOWN 定时器超时后再升 Master

选举分两种启动顺序:

  • 高优先级先启动:高优先级的直接进 Master;低优先级的收到高优先级的通告,乖乖待在 Backup。
  • 低优先级先启动:低优先级先由 Backup 升 Master;高优先级后启动,收到低优先级的通告后重新选举,把 Master 抢过来。

一个特殊规则:IP 地址拥有者(接口 IP 恰好等于虚拟 IP 的那台设备)无条件当 Master。此时优先级自动变成 255,而且没法手动配成 255。

3.6 主备切换

  • 主动让位 :Master 主动退出备份组时,会发一个优先级为 0 的通告,Backup 收到立刻升 Master,不用干等超时。这段切换时间就是 Skew_time。
  • 被动故障:Master 网络断了、发不出通告,Backup 无法立刻察觉,只能等 MASTER_DOWN 超时后才接管。

四、Keepalived 的 VRRP 工作原理

Keepalived 通过 VRRP 做高可用,同时还能监控集群内服务器的运行状态、做故障隔离。它在 TCP/IP 的三、四、七层(网络层、传输层、应用层)分别有对应的探测手段:

协议/手段 Keepalived 怎么做
网络层 ICMP 给每个节点发 ICMP 包(类似 ping),没响应就判定节点故障,踢出集群
传输层 TCP/UDP 用端口连接扫描判断服务端口是否正常,比如探测 Web 的 80、SSH 的 22,端口没响应就剔除对应节点
应用层 自定义 通过脚本/程序自定义检测逻辑,检测结果和预期不符就剔除该服务器

五、脑裂(Split-Brain):高可用里最头疼的病

5.1 什么是脑裂

在 Keepalived 高可用集群里,脑裂 指的是主备节点之间通信中断,两边都以为对方挂了,于是同时去抢资源(比如虚拟 IP),导致集群状态混乱。

5.2 为什么会脑裂

本质是"心跳检测失败,但节点其实都活着"。常见触发原因:

  1. 网络问题:主备之间的心跳线路(专用网线、交换机)故障、断网或延迟过高。
  2. 防火墙:VRRP 报文(IP 协议号 112)被防火墙拦了。
  3. 资源耗尽:某节点 CPU/内存打满、负载过高,响应不了心跳。
  4. 配置错误vrrp_instance 里的 statepriorityauthentication 等参数不一致,节点没法正常协商。

5.3 脑裂的危害

  • 双节点同时持有 VIP → 客户端请求错乱,一部分成功一部分失败。
  • 如果集群管的是数据库、存储,可能引发数据不一致(双写冲突)。
  • 高可用彻底失效,甚至因资源竞争把服务拖崩。

5.4 怎么防脑裂

核心思路一句话:多重检测 + 自动隔离。常用方案:

① 加心跳线路 :主网卡之外再拉一条备用链路(独立网卡、交叉网线),用 track_interface 同时盯多张网卡:

bash 复制代码
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    track_interface {        # 同时检测备用网卡
        eth0
        eth1
    }
}

② 开 VRRP 认证:节点间加认证,防止非法节点捣乱,也保证心跳可靠:

bash 复制代码
vrrp_instance VI_1 {
    # ...
    authentication {
        auth_type PASS        # PASS 或 AH
        auth_pass 123456      # 所有节点必须一致
    }
}

③ 放行防火墙:允许 VRRP 协议通过:

bash 复制代码
# CentOS 示例
firewall-cmd --add-protocol=vrrp --permanent
firewall-cmd --reload

④ 第三方 fence 检测 :用 notify 脚本,节点升主后先探测对方是否存活,活着就强制隔离:

bash 复制代码
vrrp_instance VI_1 {
    # ...
    notify_master "/etc/keepalived/check_split_brain.sh master"
    notify_backup "/etc/keepalived/check_split_brain.sh backup"
}

脚本逻辑:ping、探测端口确认对方状态,一旦确认脑裂就执行 kill 或 reboot 干掉对方。

⑤ 从业务层降低影响:数据库做主从复制 + 读写分离,避免双写;存储用分布式锁(Redis)控制资源独占;限制 VIP 只在集群状态正常时才对外服务。

⑥ 监控告警 :用 zabbix、prometheus 监控 Keepalived 状态(如 vrrp_script),发现双主立刻报警。


六、实战:三节点搭一套 Keepalived 高可用

6.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 服务器(备)

网关统一 10.1.8.2,虚拟 IP(VIP)规划为 10.1.8.100

6.2 基础配置:主机名 + IP

三台机器分别设主机名和静态 IP:

bash 复制代码
# client1
hostnamectl set-hostname client1
nmcli connection modify ens33 ipv4.method manual ipv4.addresses 10.1.8.21/24 \
    ipv4.gateway 10.1.8.2 ipv4.dns 10.1.8.2 autoconnect yes
nmcli connection up ens33

# web1
hostnamectl set-hostname web1
nmcli connection modify ens33 ipv4.method manual ipv4.addresses 10.1.8.11/24 \
    ipv4.gateway 10.1.8.2 ipv4.dns 10.1.8.2 autoconnect yes
nmcli connection up ens33

# web2
hostnamectl set-hostname web2
nmcli connection modify ens33 ipv4.method manual ipv4.addresses 10.1.8.12/24 \
    ipv4.gateway 10.1.8.2 ipv4.dns 10.1.8.2 autoconnect yes
nmcli connection up ens33

6.3 后端 Web(两台都要配)

bash 复制代码
[root@web1-2 ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
[root@web1-2 ~]# yum install -y nginx
[root@web1-2 ~]# echo Welcome to $(hostname) > /usr/share/nginx/html/index.html
[root@web1-2 ~]# systemctl enable nginx.service --now

从客户端验证两个后端都正常:

bash 复制代码
[root@client1 ~]# curl 10.1.8.11
Welcome to web1.laogao.cloud
[root@client1 ~]# curl 10.1.8.12
Welcome to web2.laogao.cloud

6.4 配置 Keepalived(先配备节点 web2)

bash 复制代码
[root@web2 ~]# yum install -y keepalived
[root@web2 ~]# cp /etc/keepalived/keepalived.conf{,.ori}
[root@web2 ~]# vim /etc/keepalived/keepalived.conf
nginx 复制代码
! Configuration File for keepalived

global_defs {
    router_id web2            # 路由器名称,每个节点不同
}

vrrp_instance nginx {
    state BACKUP              # 备节点
    interface ens33           # VIP 绑在这张网卡上
    virtual_router_id 51      # 虚拟路由器 ID,范围 1~255,同组必须一致
    priority 100              # 优先级,越大越优先
    advert_int 1              # 心跳间隔 1 秒
    authentication {
        auth_type PASS
        auth_pass laogao@123  # 密码长度不能超过 8 位,超了只取前 8 位
    }
    virtual_ipaddress {
        10.1.8.100/24         # 虚拟 IP
    }
}
bash 复制代码
[root@web2 ~]# systemctl enable keepalived.service --now
[root@web2 ~]# ip -br a show ens33
ens33    UP    10.1.8.12/24 10.1.8.100/24 ...

6.5 配置主节点 web1

web1 配置基本一致,两处不同:state 改成 MASTERpriority 提高到 110

nginx 复制代码
global_defs {
    router_id web1
}
vrrp_instance nginx {
    state MASTER             # 主节点
    interface ens33
    virtual_router_id 51
    priority 110             # 比备节点高
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass laogao@123
    }
    virtual_ipaddress {
        10.1.8.100/24
    }
}
bash 复制代码
[root@web1 ~]# systemctl enable keepalived.service --now
[root@web1 ~]# ip -br a show ens33
ens33    UP    10.1.8.11/24 10.1.8.100/24 ...   # VIP 已经跑到 web1

主节点优先级更高,VIP 自动漂到 web1 上;此时 web2 上的 VIP 已经消失。

6.6 高可用验证

第一步:正常访问 VIP,返回的是主节点 web1:

bash 复制代码
[root@client1 ~]# curl 10.1.8.100
Welcome to web1.laogao.cloud

第二步:停掉 web1 的 keepalived,模拟主节点故障

bash 复制代码
[root@web1 ~]# systemctl stop keepalived.service

[root@client1 ~]# curl 10.1.8.100
Welcome to web2.laogao.cloud      # 自动切到 web2

第三步:重启 web1,抢回 Master

bash 复制代码
[root@web1 ~]# systemctl start keepalived.service

[root@client1 ~]# curl 10.1.8.100
Welcome to web1.laogao.cloud      # VIP 又漂回 web1

三次 curl 对应三种状态,VIP 跟着主节点自动漂移,客户端全程无感。


七、Keepalived 配置文件详解

配置文件位置:/etc/keepalived/keepalived.conf,主要分三块:

部分 说明
GLOBAL 全局配置
VRRPD VRRP 协议配置
LVS LVS 服务管理配置

一个完整示例(注释里把每个参数讲明白):

nginx 复制代码
! Configuration File for keepalived

# ===== 全局配置 =====
global_defs {
    notification_email {              # 邮件接收者
        acassen@firewall.loc
        failover@firewall.loc
        sysadmin@firewall.loc
    }
    notification_email_from Alexandre.Cassen@firewall.loc   # 邮件发送者
    smtp_server 192.168.200.1         # 邮件服务器
    smtp_connect_timeout 30           # 连接邮件服务器超时
    router_id LVS_DEVEL               # 本机标识,集群内不能重复
    vrrp_skip_check_adv_addr          # 来自同一 Master 的通告跳过地址检查
    vrrp_strict                       # 严格遵守 VRRP 协议
    vrrp_garp_interval 0              # 发送免费 ARP 的延迟(毫秒)
    vrrp_gna_interval 0               # 发送未请求 NA 的延迟(毫秒)
}

# ===== VRRP 协议配置 =====
vrrp_instance VI_1 {                  # VI_1 是实例名,可自定义
    state MASTER                      # 初始状态;实际按 priority 竞选
    interface eth0                    # VIP 使用的接口
    virtual_router_id 51              # 0~255 唯一,同集群相同
    priority 100                      # 越高越容易当选 Master
    advert_int 1                      # 通告间隔
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {               # VIP 列表
        192.168.200.16
        192.168.200.17
        192.168.200.18
    }
}

# ===== LVS 服务管理配置 =====
virtual_server 192.168.200.100 443 {
    delay_loop 6                      # 服务轮询间隔
    lb_algo rr                        # 调度算法 rr|wrr|lc|wlc|lblc|sh|dh
    lb_kind NAT                       # 转发方式 NAT|DR|TUN
    persistence_timeout 50            # 持久化超时
    protocol TCP                      # TCP|UDP|SCTP

    real_server 192.168.201.100 443 {
        weight 1                      # 权重,默认 1
    }
}

state 只是启动时的初始状态,最终谁当 Master 由 priority 竞选决定,别被它误导。


八、Keepalived 日志配置

默认日志会混在 /var/log/messages 里,排查起来费劲。下面把它单独抽到 /var/log/keepalived.log(web1、web2 都要做):

bash 复制代码
[root@web1,web2 ~]# vim /etc/sysconfig/keepalived
KEEPALIVED_OPTIONS="-D -d -S 0"

参数含义:

参数 含义
-D 后台守护进程模式,默认必带
-d 开 debug 调试日志,会刷大量 vrrp 细节到 messages
-S 0 syslog facility 0,用 LOG_SYSLOG 设施输出

⚠️ -d 调试模式生产环境别长期开,日志量巨大,容易刷爆 messages。排查问题时临时打开,搞定就删掉。

再配 rsyslog 把 facility 0 单独落盘:

bash 复制代码
[root@web1,web2 ~]# vim /etc/rsyslog.d/keepalived.conf
local0.*    /var/log/keepalived.log

[root@web1,web2 ~]# systemctl restart rsyslog
[root@web1,web2 ~]# systemctl restart keepalived.service

[root@web1,web2 ~]# tail -f /var/log/keepalived.log

九、心跳:多网卡环境必须指定 mcast_src_ip

关键参数:mcast_src_ip

nginx 复制代码
! Configuration File for keepalived

global_defs {
    router_id Cluster1
}

vrrp_instance Nginx {
    state MASTER
    interface ens36
    mcast_src_ip 20.0.0.11        # 心跳组播报文的源 IP,就是 ens36 上的 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 包,两台机器都以为自己该当 Master、同时抢 VIP,就闹出双主故障。指定 mcast_src_ip 就是把心跳固定从某张网卡发出去,杜绝这种乱象。


总结

Keepalived 基于 VRRP 协议做高可用,核心靠虚拟 IP(VIP)对外提供统一入口,支持主从、双主两种部署。抓住三条主线:

  1. 优先级决定主节点 ------priority 高的当 Master,主节点故障时备节点自动接管 VIP 和服务,无缝切换。
  2. 脑裂是头号敌人------本质是心跳断了但节点都活着,靠"多线路心跳 + 认证 + 脚本自动隔离 + 监控告警"四管齐下防住。
  3. 它常和 LVS、Nginx 联动------配合健康检查脚本实时探测后端,帮 Web、数据库等服务解决单点故障。

把上一篇的 LVS 和这一篇的 Keepalived 组合起来,生产环境四层负载均衡 + 高可用的完整方案就齐活了。

相关推荐
依然鸣1 小时前
PTA团体程序设计天梯赛L2真题讲解L2-005-008
开发语言·数据结构·c++·算法·深度优先·pat考试·图论
.柒宇.1 小时前
运维常见面试题_04_Nginx与DNS服务
运维·nginx·面试·dns
15Moonlight1 小时前
Linux系统(02):基础开发工具
linux·运维·服务器
君顾12 小时前
代驾跑腿业务系统实战开发指南
java·开发语言·代驾跑腿
沪上企服通2 小时前
当 RPA 遇见企服:合规链路自动化的技术演进与五类市场样本观察
运维·自动化·rpa
hxhy002 小时前
服务器挖矿排查与清理
运维·服务器
夏幻灵2 小时前
从语法坑点到 JS 内存底层:Vue 3 watch 侦听器深度全解
开发语言·javascript·vue.js
basketball6162 小时前
软考中级网络工程师 第6章 网络安全 备考总结
大数据·网络·web安全·网络工程师·软考
lightqjx2 小时前
VS Code连接Linux远端服务器的方法
linux·服务器·vs code