Skip to content

VRRP 协议与 Keepalived:虚拟 IP 是如何“漂移”起来的

VRRP 协议原理示意图

上一章我们提到,虚拟 IP(VIP)可以在主备机器之间“漂移”,实现入口高可用。

但 VIP 到底是怎么漂起来的?背后的原理是什么?

答案就是 VRRP 协议——虚拟路由冗余协议(Virtual Router Redundancy Protocol)。

本章将从最底层的协议机制讲起,配合 Keepalived 的配置示例,彻底搞懂 VIP 漂移的来龙去脉。

一、VRRP 协议是什么?

VRRP 是一个标准的网络协议,最早在 RFC 3768 中定义。它的目标很简单:让多台路由器共享同一个虚拟 IP,实现网关的高可用

传统上,VRRP 用于路由器的主备切换。但在我们的场景中,它同样适用于普通的 Linux 服务器——Keepalived 就是 VRRP 协议的一个完整实现。

核心概念:

概念说明
虚拟路由器多台物理机器组成的逻辑组,对外表现为一台“虚拟”设备
虚拟 IP(VIP)虚拟路由器的对外 IP,客户端实际访问的地址(本文为 192.168.0.200
虚拟 MACVRRP 生成的虚拟 MAC 地址(00-00-5E-00-01-{VRID})
Master当前实际处理请求的节点,拥有 VIP
Backup备用节点,监听 Master 心跳,准备接管
VRID虚拟路由器 ID,同一网络下必须唯一

二、VRRP 的核心机制

2.1 优先级决定谁是 Master

VRRP 使用一个简单的规则来决定谁是 Master:优先级最高的节点成为 Master

yaml
# 主节点配置(192.168.0.201)
priority: 100

# 备节点配置(192.168.0.202)
priority: 90

# 备节点配置(192.168.0.203)
priority: 80

优先级范围是 1-255。数值越高,越有可能成为 Master。

当多个节点优先级相同时,IP 地址最大的节点获胜(这是一种防冲突的兜底策略)。

2.2 心跳检测:Master 定期“报平安”

Master 会每隔一段时间(默认 1 秒)向组播地址 224.0.0.18 发送 VRRP 通告报文,告诉所有 Backup 节点:“我还活着”。

通告报文中包含:

  • Master 的优先级
  • 虚拟 IP 地址(192.168.0.200
  • VRID
  • 通告间隔

2.3 故障检测:Backup 等待超时

Backup 节点会持续监听 Master 的通告。如果连续 3 秒(默认 3 个通告周期)没有收到 Master 的心跳,就判定 Master 已宕机。

2.4 抢占模式:优先级高的说了算

VRRP 默认是抢占模式。这意味着:

  1. 如果当前 Master 宕机,Backup 中优先级最高的节点接管成为新 Master
  2. 如果原来的 Master 恢复(且它的优先级更高),它会重新抢占 VIP,恢复为 Master

这种模式的好处是:永远让配置优先级最高的节点提供服务

如果需要避免频繁切换(比如网络抖动导致短暂失联),可以开启 nopreempt 非抢占模式,我们会在后续的“生产最佳实践”章节详细讨论。

2.5 MAC 地址迁移:网络拓扑如何感知切换?

VRRP 最精妙的设计是 MAC 地址漂移

每个 VRRP 虚拟路由器会生成一个虚拟 MAC 地址:

00-00-5E-00-01-{VRID}
  • 00-00-5E:IANA 分配给 VRRP 的 OUI
  • 00-01:固定值
  • {VRID}:虚拟路由器 ID(1-255)

当 Master 切换时,新 Master 会发送一个免费 ARP(Gratuitous ARP) 广播,告诉整个网络:“虚拟 MAC 地址现在在我这里,更新你们的 ARP 缓存!”

这个过程对客户端完全透明。客户端自始至终访问同一个 VIP 192.168.0.200 和对应的虚拟 MAC,不需要任何配置变更。

三、Keepalived:VRRP 的完整实现

Keepalived 是 Linux 上最流行的 VRRP 实现。它不仅实现了 VRRP 协议,还集成了健康检查机制。

3.1 Keepalived 的核心组件

组件职责
VRRP 协议栈实现心跳、竞选、抢占逻辑
VIP 管理添加/删除虚拟 IP
健康检查框架定期检查服务状态,影响优先级

3.2 一个最小化的 Keepalived 配置

下面是三台机器的主备配置示例(基于家庭网络 192.168.0.0/24 网段):

Master 节点(192.168.0.201):

bash
global_defs {
    router_id KEEPALIVED_MASTER
}

vrrp_instance VI_1 {
    state MASTER              # 初始角色:主
    interface eth0            # 监听的网卡
    virtual_router_id 51      # VRID,同一集群必须一致
    priority 100              # 优先级:主比备高
    advert_int 1              # 心跳间隔:1秒

    authentication {
        auth_type PASS
        auth_pass 1234        # 简单认证,防止恶意加入
    }

    virtual_ipaddress {
        192.168.0.200/24 dev eth0 label eth0:vip
    }
}

Backup 节点 1(192.168.0.202):

bash
global_defs {
    router_id KEEPALIVED_BACKUP_1
}

vrrp_instance VI_1 {
    state BACKUP             # 初始角色:备
    interface eth0
    virtual_router_id 51
    priority 90              # 优先级:比主低
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass 1234
    }

    virtual_ipaddress {
        192.168.0.200/24 dev eth0 label eth0:vip
    }
}

Backup 节点 2(192.168.0.203):

bash
global_defs {
    router_id KEEPALIVED_BACKUP_2
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 80              # 优先级最低
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass 1234
    }

    virtual_ipaddress {
        192.168.0.200/24 dev eth0 label eth0:vip
    }
}

3.3 Keepalived + Nginx 健康检查

生产环境中,我们希望 Keepalived 不仅检测机器是否存活,还要检测 Nginx 是否正常工作。

bash
# 健康检查脚本(三台机器都需要配置)
cat > /usr/local/bin/check_nginx.sh << 'EOF'
#!/bin/bash
if pgrep -x "nginx" > /dev/null; then
    exit 0   # Nginx 存活,正常
else
    exit 1   # Nginx 挂了,触发切换
fi
EOF

chmod +x /usr/local/bin/check_nginx.sh

在 Keepalived 配置中引用这个脚本:

bash
vrrp_script check_nginx {
    script "/usr/local/bin/check_nginx.sh"
    interval 2        # 每2秒检查一次
    weight -20        # 检查失败时,优先级减20
    fall 2            # 连续失败2次才判定失败
    rise 2            # 连续成功2次才判定恢复
}

vrrp_instance VI_1 {
    # ... 其他配置 ...
    track_script {
        check_nginx
    }
}

工作原理:

  • 正常情况下,Master(192.168.0.201)优先级为 100
  • 如果 Master 的 Nginx 挂了,优先级降至 80(100 - 20)
  • 此时 Backup 1(192.168.0.202)优先级为 90 > 80,Backup 1 接管成为新 Master
  • Nginx 恢复后,优先级回到 100,重新抢占

四、VRRP 状态机

VRRP 定义了三种状态,理解了状态机就理解了整个协议:

状态拥有 VIP发送通告监听心跳
Initialize
Backup
Master

五、常见问题与误区

Q1:VRRP 和 Keepalived 是什么关系?

VRRP 是协议标准(RFC 3768),Keepalived 是 VRRP 的一个具体实现。除了 VRRP,Keepalived 还集成了健康检查、负载均衡(LVS)等功能。

Q2:VIP 必须和物理 IP 在同一网段吗?

是的。 VIP 192.168.0.200 必须与物理 IP(192.168.0.201/202/203)处于同一子网 192.168.0.0/24,否则交换机无法正确转发数据包。

Q3:Master 和 Backup 之间需要独立的网络吗?

不必须,但推荐。 生产环境中建议使用独立的心跳网络,避免业务流量抖动影响心跳检测。

Q4:VRRP 能跨网段吗?

不能。 VRRP 的通告报文是二层组播(224.0.0.18),TTL 为 1,无法跨路由器。VIP 漂移只能在同一广播域内发生。

Q5:如果网络分区(脑裂)发生会怎样?

脑裂是 VRRP 最棘手的问题。当 Master 和 Backup 之间的网络中断时,两边都收不到对方的心跳,都会认为自己是 Master,同时拥有 VIP 192.168.0.200

解决方案我们会在第 7 章详细展开(独立心跳网络、非抢占模式、外部仲裁等)。

六、实践环境回顾

本系列的实战环境使用以下家庭网络配置:

配置项说明
网段192.168.0.0/24标准家庭局域网
网关192.168.0.1路由器地址
VIP192.168.0.200虚拟 IP,不实际绑定网卡
node1192.168.0.201优先级 100,初始 Master
node2192.168.0.202优先级 90,Backup 1
node3192.168.0.203优先级 80,Backup 2

💡 如果你的家庭网络网段不同(如 192.168.1.0/24),只需将所有 192.168.0.x 替换为你自己的网段即可。

七、小结

本章深入讲解了 VRRP 协议的核心机制:

  1. 优先级决定角色:优先级最高的节点成为 Master(本例中 192.168.0.201 优先级 100)
  2. 心跳检测故障:Master 每秒发送通告,Backup 超时 3 秒后接管
  3. MAC 地址迁移:通过免费 ARP 通知网络拓扑变更
  4. Keepalived 实现:VRRP + 健康检查的完整方案

理解这些原理后,下一章我们将进入实战环节:用 Golang + Gin 实现一个“会说话”的健康检查服务,为后续的 Nginx 和 Keepalived 部署做好准备。


💡 本文是《分布式高可用入口架构实战系列》第 2 篇

最后更新2026/06/21 16:32
如果你觉得这篇文章有帮助,或者想聊聊技术、工作,欢迎通过下面方式联系我:
contact fishfinal