打造不断网的旁路由:基于 Keepalived 的高可用方案

#Homelab #Keepalived #OpenWrt #VRRP #网络

Table of Contents

在家庭网络中,我采用硬路由+旁路由的架构。硬路由负责拨号、流量统计等基础功能,旁路由运行一些额外服务。这种架构有个致命问题:一旦折腾旁路由导致其挂掉,全屋网络就会中断

之前的解决方案是在主路由上运行脚本,定期 ping 8.8.8.8,如果 ping 不通就切换网关。但这种方式会导致 10 秒左右的网络中断,WiFi 也会断开。简直太不优雅了。

周末研究了下 VRRP 协议,找到了更好的解决方案:使用 Keepalived 实现路由器高可用。软路由作为 MASTER 主节点,华硕路由作为 BACKUP 备用节点,当主节点挂掉时自动切换到备用节点,切换时间仅 2 秒,无感知

为什么选择硬路由做主路由

我的家庭网络架构选择:

  1. 硬路由(华硕):负责基础功能
    • 拨号和流量统计
    • DHCP 服务
    • 作为备用网关
  2. 软路由(OpenWrt):运行额外服务
    • 魔法上网
    • 其他自定义服务
    • 作为主网关

选择硬路由做主路由的原因:

  • 华硕官方提供定期的系统更新
  • 系统稳定,不需要频繁折腾
  • 软路由经常折腾,容易导致全屋断网

VRRP 协议简介

什么是 VRRP

VRRP(Virtual Router Redundancy Protocol,虚拟路由冗余协议)是一种网络协议,通过多个路由器组成冗余路由器组来提高网络的可靠性和可用性。

简单来说,VRRP 创建一个虚拟路由器,多个物理路由器共享同一个虚拟 IP 地址。客户端设备使用这个虚拟 IP 作为默认网关,当主路由器故障时,备用路由器自动接管,对客户端来说是透明的。

工作原理

VRRP 的核心机制:

  1. 虚拟路由器:创建一个虚拟 IP 地址(VIP),作为客户端的默认网关
  2. 角色分配
    • MASTER(主):负责处理所有数据流量
    • BACKUP(备):监控主路由器状态,随时准备接管
  3. 优先级机制:范围 0-255,优先级最高的成为 MASTER
  4. 心跳检测:MASTER 定期发送 VRRP 广播包,BACKUP 通过心跳监控主路由器状态
  5. 故障切换:当 BACKUP 检测到 MASTER 心跳停止,立即接管虚拟 IP

核心优势

  • 高可用性:提供冗余路径,单点故障不影响网络
  • 快速切换:故障切换时间仅 2-3 秒
  • 透明接管:客户端无需任何配置变更
  • 灵活配置:可配置多个 VRRP 组实现负载均衡

实施方案

架构说明

在开始配置前,明确我们的架构设计:

  • 虚拟 IP:192.168.0.5(客户端使用的网关地址)
  • OpenWrt(软路由):192.168.0.2,MASTER,优先级 100
  • ASUS(硬路由):192.168.0.1,BACKUP,优先级 50

客户端设备将网关设置为 192.168.0.5,正常情况下流量走软路由,软路由故障时自动切换到硬路由。

配置 ASUS 路由器(BACKUP)

1. 安装 Entware

华硕梅林固件需要先安装 Entware 包管理器,参考官方文档完成安装。

2. 安装 Keepalived

opkg update
opkg install keepalived

3. 备份默认配置

mv /opt/etc/keepalived/keepalived.conf /opt/etc/keepalived/keepalived.conf.bak

4. 创建配置文件

cat > /opt/etc/keepalived/keepalived.conf <<-EOF
global_defs {
    router_id ASUS_BACKUP
}

vrrp_instance VI_1 {
    interface br0           # LAN 口网卡名,通过 ip a 查看
    state BACKUP            # 备用节点
    virtual_router_id 1     # 虚拟路由器 ID,组内必须一致
    priority 50             # 优先级,低于主节点
    advert_int 1            # 心跳间隔(秒)
    
    authentication {
        auth_type PASS
        auth_pass 1234      # 认证密码,组内必须一致
    }
    
    virtual_ipaddress {
        192.168.0.5         # 虚拟 IP 地址
    }
}
EOF

配置说明

  • interface br0:华硕路由的 LAN 口网卡名通常为 br0
  • priority 50:优先级低于 OpenWrt,确保作为备用节点
  • virtual_router_id 1:两个路由器必须使用相同的 ID
  • auth_pass:两个路由器必须使用相同的密码

5. 启动服务

nohup /opt/sbin/keepalived -n -f /opt/etc/keepalived/keepalived.conf &

# 确认启动成功
ps | grep keepalived | grep -v grep

6. 设置开机启动

适用于梅林固件:

cat >> /jffs/scripts/post-mount <<-EOF
nohup /opt/sbin/keepalived -n -f /opt/etc/keepalived/keepalived.conf &
EOF

# 添加执行权限
chmod +x /jffs/scripts/post-mount

配置 OpenWrt(MASTER)

1. 安装 Keepalived

opkg update
opkg install keepalived

2. 备份默认配置

mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak

3. 创建配置文件

cat > /etc/keepalived/keepalived.conf <<-EOF
global_defs {
    router_id OPENWRT_MASTER
}

vrrp_instance VI_1 {
    interface br-lan        # LAN 口网卡名,通过 ip a 查看
    state MASTER            # 主节点
    virtual_router_id 1     # 虚拟路由器 ID,与 ASUS 一致
    priority 100            # 优先级,高于备用节点
    advert_int 1            # 心跳间隔(秒)
    
    authentication {
        auth_type PASS
        auth_pass 1234      # 认证密码,与 ASUS 一致
    }
    
    virtual_ipaddress {
        192.168.0.5         # 虚拟 IP 地址
    }
}
EOF

配置说明

  • interface br-lan:OpenWrt 的 LAN 口网卡名通常为 br-lan
  • priority 100:优先级高于 ASUS,确保作为主节点
  • 其他参数必须与 ASUS 路由器保持一致

4. 停用系统服务

这里有个坑:OpenWrt 安装后 keepalived 会作为 service 启动,但不会读取我们的配置文件。需要先停用系统服务。

service keepalived stop
service keepalived disable

5. 手动启动 Keepalived

nohup /usr/sbin/keepalived -n -f /etc/keepalived/keepalived.conf &

# 确认启动成功
ps | grep keepalived | grep -v grep

6. 设置开机启动

sed -i '/exit 0/i\nohup \/usr\/sbin\/keepalived -n -f \/etc\/keepalived\/keepalived.conf &' /etc/rc.local

测试验证

基础连通性测试

配置完成后,从客户端测试虚拟 IP:

ping 192.168.0.5

应该能正常 ping 通,此时流量走的是 OpenWrt(MASTER)。

故障切换测试

在 OpenWrt 上停止 keepalived 模拟故障:

killall keepalived

观察 ping 结果:

  • 会有大约 2 秒钟的中断
  • 随后自动恢复,流量切换到 ASUS(BACKUP)
  • 客户端无需任何操作

恢复测试

重新启动 OpenWrt 的 keepalived:

nohup /usr/sbin/keepalived -n -f /etc/keepalived/keepalived.conf &

流量会自动切回 OpenWrt(MASTER)。

查看状态

在路由器上查看虚拟 IP 是否绑定成功:

ip addr show | grep 192.168.0.5

主节点应该能看到虚拟 IP 绑定在 LAN 口上。

注意事项

  1. 虚拟路由器 ID:两个路由器的 virtual_router_id 必须相同
  2. 认证密码:两个路由器的 auth_pass 必须相同
  3. 网卡名称:使用 ip a 命令确认实际的网卡名称
  4. 防火墙规则:确保 VRRP 协议(IP 协议号 112)未被防火墙拦截
  5. IP 冲突:虚拟 IP 不能与现有设备 IP 冲突
  6. 开机启动:确保两个路由器都设置了开机自启动

进阶配置

配置多个 VRRP 组

可以配置多个虚拟 IP 实现负载均衡:

# 第二个 VRRP 组
vrrp_instance VI_2 {
    interface br-lan
    state BACKUP            # OpenWrt 在第二组作为备用
    virtual_router_id 2
    priority 50
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 5678
    }
    virtual_ipaddress {
        192.168.0.6
    }
}

部分设备使用 192.168.0.5 作为网关(走 OpenWrt),部分使用 192.168.0.6(走 ASUS),实现流量分担。

至此,一个高可用的家庭路由器方案就搭建完成了。

总结一下这个方案的优势:

  • 快速切换:故障切换时间仅 2 秒,几乎无感知
  • 自动恢复:主路由恢复后自动接管流量
  • 配置简单:相比传统脚本方案,配置更简洁优雅
  • 标准协议:基于 VRRP 标准协议,稳定可靠

再也不用担心折腾软路由导致全屋断网了。可以放心地在旁路由上测试各种新功能,即使挂掉也能自动切换到硬路由,保证网络的持续可用。

如果你也有类似的需求,不妨试试这个方案。