keepalived脑裂后,近20min不能访问虚拟IP问题分析

news2025/2/24 7:55:10

问题现象和说明

真实的场景比较复杂,抽象起来可以用下面的图表示,

虚拟服务
虚拟server-VIP
server1
server2
client1
switch
Router
server3

图示说明
server1 和server2 分别部署keepalived,有一个虚拟IP (VIP).
Router和switch 是路由交换设备,这里用的功能都是一样的,并不做区别.

正常现象

正常情况下,client1 可以访问VIP,server3也可以访问VIP,这里访问采用ping方式,下同。
keepalived 切换情况下,client1 可以访问VIP,server3也可以访问VIP。

异常现象

  1. server3 可以访问 VIP
  2. client1 不能访问VIP,不做任何修改,大约20分钟后,client1又可以访问VIP了
  3. 异常前的keeplived日志(/var/log/message)有脑裂发生。

背景知识,Keepalived通过VRRP实现高可用性
keepalived基础入门可以参考一文带你浅入浅出Keepalived
VRRP协议了解可以VRRP简单概述
https://www.cnblogs.com/patrick-yeh/p/14428508.html
核心参考keepalived官网

问题复现

家里正好有几个ARM板子,一个TP-link交换机(二层),一个华为AR路由器,一台服务器,可以实现如下的场景搭建。模拟脑裂到恢复的过程

虚拟服务
VIP-172.16.22.31
server2-172.16.22.246-backup
server1-172.16.22.146-master
client1-192.168.1.168
switch
Router
server3-172.16.22.79

背景说明

  1. 抓包主要在server3上进行
  2. 路由器Router的wan口配置的IP是192.168.1.3
  3. 路由器Router的lan口分别接入server1,server2,和server3
  4. server1 和server2 的keepalived配置如下
    server1 上keepalived.conf
! Configuration File for keepalived
global_defs {
        router_id swaram02
        script_user root
}
vrrp_script chk_http_port {
        script "/etc/keepalived/check.sh"
        interval 10
        user root
}
vrrp_sync_group VG1 {
    group {
          VI_1
    }
}
vrrp_instance VI_1 {
        state BACKUP
        interface eth0
        nopreempt #非抢占模式
        virtual_router_id 31  #通过vid参数识别同一个虚拟路由器,所以两者一定要一致
        priority 100
        advert_int 3  #通告时间
        authentication {
                auth_type PASS
                auth_pass 1111
        }
        virtual_ipaddress {
                172.16.22.31/26
        }
        track_script {
           chk_http_port
        }
        notify_master "/etc/keepalived/arp1.sh"  #当切换到MASTER时,运行的脚本
}

server2上keepalived.conf配置

! Configuration File for keepalived
global_defs {
        router_id swaram02
        script_user root
}
vrrp_script chk_http_port {
        script "/etc/keepalived/check.sh"
        interval 10
        user root
}
vrrp_sync_group VG1 {
    group {
          VI_1
    }
}
vrrp_instance VI_1 {
        state BACKUP
        interface eth0
        nopreempt #非抢占模式
        virtual_router_id 31 #通过vid参数识别同一个虚拟路由器,所以两者一定要一致
        priority 90 
        advert_int 3  # 通告周期
        authentication {
                auth_type PASS
                auth_pass 1111
        }
        virtual_ipaddress {
                172.16.22.31/26
        }
        track_script {
           chk_http_port
        }
        notify_master "/etc/keepalived/arp1.sh"  #当切换到MASTER时,运行的脚本
}

其中用到两个脚本,一个是check,检查后端程序,没有写,直接使用ls代替脚本内容
还有一个arp1.sh的脚本

#!/bin/bash
VIP=172.16.22.31
GATEWAY=172.16.22.1
/sbin/arping -I eth0 -c 5 -s $VIP $GATEWAY &>/dev/null

正常情况下在server3上抓包,可以看到只有maser节点146发的vrrp报文
在这里插入图片描述
client1 保证正常情况下的通信
在这里插入图片描述

server3保证正常情况下的通信

server1上IP 和虚拟IP情况
在这里插入图片描述
server2上的IP和虚拟IP情况
在这里插入图片描述

模拟故障

  1. 在server2上配置不接收VRRP报文,等待30秒中,此时可以查看keepalived变成master(此时发生了脑裂) ,并和172.16.22.31绑定
    iptables -I INPUT -p vrrp -j REJECT 执行丢弃vrrp丢弃的报文节点并没有选择
    在这里插入图片描述
    此时从client1和server3上都可以ping 通172.16.22.31

  2. 删除 不接受vrrp的规则(iptables -F) 系统脑裂 在这里插入图片描述
    脑裂的直观体现就是两个真实的IP都和虚拟IP绑定了

虚拟服务
VIP-172.16.22.31
server2-172.16.22.246-backup
server1-172.16.22.146-master
client1-192.168.1.168
switch
Router
server3-172.16.22.79
  1. 脑裂恢复之后就从 client1 不能ping 通虚拟IP了,server3可以ping通
    在这里插入图片描述
    故障复现成功。

  2. 故障模拟脚本—test.sh
    丢弃keepalived 之间确定

iptables -A INPUT -p vrrp -j REJECT;
iptables -A OUTPUT -p vrrp -j REJECT;
sleep 1 ;
ip a  |  grep  22;
sleep 12;
ip a |  grep  22;

echo "==========recover==============="
iptables -F;
iptables -X;
sleep 5
ip a  |  grep 22

必现条件

上面的模拟如果不是在特定状态,特定节点上的操作不一定会成功
初始状态下,keepalived的vip绑定节点必须是优先级高的那个节点

由于非keepalived设置的是非抢占模式,初始状态下,VIP也可以是优先级地的节点绑定,这种情况下脑裂恢复就不会中断。测试效果如下
在这里插入图片描述

问题分析

问题定界

  1. server3 可以访问,说明VIP所在的节点至少是在提供服务的。
  2. client1 不能访问,说明这个访问说明这个异常是和网络有关。

client1 和server3 访问的差异

  1. server3 和VIP是在同一网段,根据二三层转发可以知, server3 是通过MAC学习得知VIP(172.16.22.31的所在),所以一直访问没有问题。
  2. client1和VIP不在同一网段,会经过Route,此时在client1上ping server1 或者server2 也是正常的,有问题的只是虚拟IP 的访问
    在这里插入图片描述

背景知识二三层转发原理

  1. 二层转发过程:IP和掩码与,属于同一网段,学习目的MAC,根据目的MAC转发。
  2. 三层转发过程:IP和掩码与,不属于同一网段,走三层转发,给下跳路由继续转发。
    参考二三层转发原理介绍, 网络之二三层转发
  1. client1到 VIP不通,整条链路不通的地方是在Router和vip之间,验证过程如下:
虚拟服务
VIP-172.16.22.31
server2-172.16.22.246-backup
server1-172.16.22.146-master
client1-192.168.1.168
switch
Router
server3-172.16.22.79

从client1不能ping 通虚拟IP(172.168.22.31),client1可以ping通 Router,Router 不能ping 通 VIP,可以ping通 server1和server2
在这里插入图片描述

Router为什么不能访问 VIP?

对于Router来书访问VIP,和PC是一样的,先比较 VIP和是否和接口上的某一网段是否相同,和VLAN1上面的IP网段相同,走二层转发,二层转发需要目的MAC,先查自己有没有已经学习此IP对应的MAC,有则把这个MAC作为目的MAC封装成报文发送出去,如果没有则发送ARP请求,学习此VIP对应的MAC,然后记录到ARP表项中,同上把这个VIP对应的MAC,封装成报文发送出去。所以很有必要看一下路由器的MAC表项。

  1. keepalived脑裂前
    MAC表项如下: 虚拟IP 172.16.22.31 对应的MAC地址和 172.16.22.146保持一直
    路由器中的ARP表项
    server1 的IP
    server1IP地址
    server2的IP
    在这里插入图片描述
虚拟服务
VIP-172.16.22.31
server2-172.16.22.246-backup
server1-172.16.22.146-master
client1-192.168.1.168
switch
Router
server3-172.16.22.79

路由器中VIP(172.16.22.31)对应的MAC是2ae1-6096-7886 ,和实际的绑定关系一致,所以从client1 可以正常ping通

  1. keepalived脑裂中
    路由器的AR表项如下: VIP(172.16.22.31)对应的MAC地址是和server2的地址172.16.22.246的MAC一致,此时server2对应也有172.16.22.31的虚拟IP,所以此时也是可以ping通的。
    为什么ARP的表项会刷新,请看server2的分析。
    在这里插入图片描述
    server1 的IP
    server1IP地址
    server2的IP
    在这里插入图片描述
    脑裂后server2的状态由backup变成master,这时候会发送免费ARP报文(gratuitous ARP ,对于IPV6是发送NA message),从配置中看到还会通过脚本方式刷新网关,其实这两种方式都可以刷新网关的ARP表项,最终的效果就是ARP表项被刷新,和server2的MAC地址保持一致

可以参考keepalived官网关于vrrp_min_garp 参数的描述
# By default keepalived sends 5 gratuitions ARP/NA messages at a
# time, and after transitioning to MASTER sends a second block of
# 5 messages 5 seconds later.
# With modern switches this is unnecessary, so setting vrrp_min_garp
# causes only one ARP/NA message to be sent, with no repeat 5 seconds
# later.
vrrp_min_garp

虚拟服务
VIP-172.16.22.31
server2-172.16.22.246-backup
server1-172.16.22.146-master
client1-192.168.1.168
switch
Router
server3-172.16.22.79

  1. keepalived脑裂恢复后
    路由器中的ARP表项,并未刷新,VIP(172.16.22.31)还是和server2 (172.16.22.246)的MAC 一致。
    但是此时 server2 的keepalived状态由master变成了backup,这个过程中会删除掉VIP(172.16.22.31)。
    路由器发送,目的IP地址是172.16.22.31,MAC地址是e207-22f4-0eb6的报文后,server2收到了,发现和自己的IP地址不一致,丢弃了报文。所以出现了脑裂恢复后client1不能访问VIP的现象。

    在这里插入图片描述
    server1 的IP
    server1IP地址
    server2的IP
    在这里插入图片描述
虚拟服务
VIP-172.16.22.31
server2-172.16.22.246-backup
server1-172.16.22.146-master
client1-192.168.1.168
switch
Router
server3-172.16.22.79

解决方案

手工方案

1. 手工恢复方案1----让节点去适配路由交换设备

由于异常来于ARP表项没有刷新,重启keepalived,就会触发VIP飘逸。
在模拟的场景中,重启server1中的keepalived就可以恢复。
实际过程中有可以使用两个VIP,所以两个节点都要重启。

2. 手工恢复方案2—刷新路由交换设备的ARP表项

使用arping工具,在优先级高节点上面发送免费ARP,具体命令如下

arping -I [IP设备名称] -c [个数] -U [虚拟机IP]

实验环境中的实例
`/sbin/arping -I eth0  -c 5  -U  172.16.22.31`

基础方案

方案实现

在 keepalived的全局配置里面添加 vrrp_garp_master_refresh 20

global_defs {
router_id swaram02
script_user root
vrrp_garp_master_refresh 20
}

两个节点都添加,重启keepalived.
此方案的效果是在设定的时间范围内,可以 保证client1可以访问VIP

方案说明

vrrp_garp_master_refresh 是指 当节点变成master 节点后,循环 发送免费ARP报文,此报文可以刷新网关的ARP表项,虽然keep脑裂的时候,两个节点都会刷新ARP表项,等脑裂结束后,由于一个节点变成了backup,只有真正的master才会刷新ARP表项。

方案优点

  1. 自动刷新
  2. 配置简单

方案缺点

  1. 刷新频率不能太高,因为这是在同一网段内发的广播报文
  2. 会有可以明显感知的中断

方案效果

这次实验有9秒中中断,正常是在 0-20秒之间
在这里插入图片描述

进阶方案

方案实现

在基础方案基础上

  1. 仅且仅在优先级更高的节点上,添加如下配置

notify_stop “/etc/keepalived/arp1.sh”

  1. 同时在两个keepalived 节点上
    • 在全局区域增加如下配置

    vrrp_garp_master_refresh 20
    vrrp_garp_master_repeat 2

    • 删除 notify_master的配置

在配置中的位置
master节点:

root@server1:/etc/keepalived# cat keepalived.conf 
! Configuration File for keepalived
global_defs {
        router_id swaram02
        script_user root
        vrrp_garp_master_refresh 20
        vrrp_garp_master_repeat 2
}
vrrp_script chk_http_port {
        script "/etc/keepalived/check.sh"
        interval 10
        user root
}
vrrp_sync_group VG1 {
    group {
          VI_1
    }
}
vrrp_instance VI_1 {
        state BACKUP
        interface eth0
        nopreempt
        virtual_router_id 31
        priority 100
        advert_int 3
        authentication {
                auth_type PASS
                auth_pass 1111
        }
        virtual_ipaddress {
                172.16.22.31/26
        }
        track_script {
           chk_http_port
        }
        notify_stop "/etc/keepalived/arp1.sh"  #当vrrp 停止的时候,执行通知脚本
}

backup 节点

global_defs {
        router_id swaram02
        script_user root
        vrrp_garp_master_refresh 20
        vrrp_garp_master_repeat 2
        
}
vrrp_script chk_http_port {
        script "/etc/keepalived/check.sh"
        interval 10
        user root
}
vrrp_sync_group VG1 {
    group {
          VI_1
    }
}
vrrp_instance VI_1 {
        state BACKUP
        interface eth0
        nopreempt
        virtual_router_id 31
        priority 90
        advert_int 3
        authentication {
                auth_type PASS
                auth_pass 1111
        }
        virtual_ipaddress {
                172.16.22.31/26
        }
        track_script {
           chk_http_port
        }
        #debug 1
        #notify_master "/etc/keepalived/arp1.sh"  #当切换到MASTER时,运行的脚本
}

修改完配置之后,分别重启两个节点上的keepalived服务

方案说明

脑裂之后恢复的master节点一定是优先级更高的那一个
所以在脑裂之后,优先级更高的那一个去刷新ARP表项,恢复的时间会更短,甚至不会中断。
vrrp_garp_master_repeat 2 这个参数的含义是backup节点变成master节点之后,发几个免费ARP报文,默认是5个,因为notify_stop 也会去发,这里设置比 notify_stop中少三个,目的是让notify_stop中发送的免费ARP报文最终生效。

方案优点

  1. 中断时间在5秒内,网络条件好的情况下,无中断
  2. 实现相对简单

方案缺点

  1. 概率性的还是会有小于5秒的中断

方案效果

在这里插入图片描述
网络条件差的情况下,还是大概率会中断两秒
在这里插入图片描述

系统方案

方案实现

在进阶方案基础上,修改路由器或者交换机上的设置ARP表项固化,确认后才更新ARP表项:
对于华为系列的路由器或者交换机是:

arp anti-attack entry-check send-ack enable
un arp anti-attack entry-check  enable

对于H3C 系列的交换机和路由器是:

arp active-ack enable

其他系列的交换和路由器待补充。

方案说明

路由器或者交换机中有防止ARP表项被攻击者修改的功能,keepalived脑裂的情况和攻击类似,可以使能表项确认的开关,确认原节点不可访问后再更新表项,这样就可以防止脑裂时候ARP表项被刷新。

方案的优点

可以防止脑裂的时候出现不可访问的中断。

方案的劣势

  1. 如果开始的ARP表是错误的,刷新就要等到老化时间到了。
  2. 需要交换机或者路由器支持,不同厂商的配置不同,而且不一定都实现了此功能。

方案效果

最终效果和进阶方案不中断的情况一致。

附属说明

  1. 脑裂引起的问题首先要排除脑裂发生的原因,除了网络异常抖动,之外的其他常见原因,同事已经排除,所以这里并未赘述。
  2. 脑裂的网络原因目前只是猜测,没有实锤,根据真实的网络拓扑如下,
虚拟机的宿主机
switch1
switch2
FW1
FW2
三层交互机

这个概率很低一年才出现一次,根据网络拓扑,如果出现宿主机上的虚拟机不走同一个交互机,经过其他网络设置,tll值就会小于255.

按照RFC 2338的规定,系统对收到的VRRP报文的TTL值进行检测,如果TTL值不等于255,则丢弃这个报文,并打印出VRRP报文错误的日志信息。

华为系列可以配置不丢弃 vrrp check ttl disable 参考手册来自:https://support.huawei.com/enterprise/zh/doc/EDOC1000017951/217b12b7

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/582957.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

充分发挥C/C++test的价值(上)

对于开发测试来说,最有效的环境就是能够深度集成到开发人员IDE中的统一测试解决方案。例如,团队可能会将测试工作集中在最近更新的、高风险的代码上,而Parasoft C/Ctest这样的集成工具就是最合适的解决方案。 软件验证和确认(Ver…

Vulkan Tutorial 5 顶点缓冲区

目录 16 顶点缓冲区 顶点着色器 顶点数据 管道顶点输入 17 顶点缓冲区创建 缓冲区创建 内存要求 内存分配 填充顶点缓冲区 18 暂存缓冲区 传输队列 使用暂存缓冲区 19 索引缓冲区 索引缓冲区创建 使用索引缓冲区 16 顶点缓冲区 我们将用内存中的顶点缓冲区替换…

vue-admin-template框架搭建及应用

一、框架介绍 vue-admin-template是基于vue-element-admin的一套后台管理系统基础模板(最少精简版),可作为模板进行二次开发; 可以把 vue-element-admin当做工具箱或者集成方案仓库,在 vue-admin-template 的基础上进…

FPGA基于AXI 1G/2.5G Ethernet Subsystem实现千兆UDP通信 提供工程源码和技术支持

目录 1、前言2、我这里已有的UDP方案3、详细设计方案传统UDP网络通信方案本方案详细设计说明UDP层设计AXIS-FIFOAXI 1G/2.5G Ethernet Subsystem:输出 4、vivado工程详解5、上板调试验证并演示系统配置UDP数据回环测试注意事项 6、福利:工程代码的获取 1…

SpringMVC第七阶段:SpringMVC的增删改查(01)

SpringMVC的增删改查 1、准备单表的数据库 drop database if exists springmvc;create database springmvc;use springmvc; ##创建图书表 create table t_book(id int(11) primary key auto_increment, ## 主键name varchar(50) not null, ## 书名 author varchar(50) no…

敏捷缺陷「bug」跟踪管理

一般情况下,当前迭代的缺陷,建议放到本迭代的迭代看板上,在迭代结束前修复完成。 “缺陷看板”通常存放发布后遗留的缺陷,客户反馈的缺陷,生产环境发现的缺陷等。 在Leangoo领歌的敏捷项目中,默认创建了“…

安科瑞能源管理系统基于物联网技术应用

安科瑞 徐浩竣 江苏安科瑞电器制造有限公司 zx acrelxhj 摘 要:在能源形势紧张的大趋势下,高能耗的大型公共建筑能源管理系统的建设逐渐受到重视,以物联网技术及基础的建筑能源管理平台可以提供即时、准确、高效的能源管理策略。 系统阐述了结合物联网技术的建筑能源管理构建…

关于自动映射在项目中的具体落地(dozer)

关于自动映射在项目中的具体落地(dozer) 项目开发过程中,经常需要编写model之间的转换,最常见的有: 实体转DTODTO转实体 等操作,故为了简化代码的开发工作,需要简化对象属性之间复制的步骤,目…

分类、标签设计及查询优化

文章目录 问题分类和标签的设计知名开源系统的设计jive论坛Solo博客系统的设计wordpress的数据库设计 参考链接 问题 在很多业务系统中,都有对对象的分类和标签设计。在数据库层面如何设计相应的表,以及如何做查询优化,是一个比较普遍的问题…

MKS SERVO4257D 闭环步进电机_系列5 CAN指令说明

第1部分 产品介绍 MKS SERVO 28D/35D/42D/57D 系列闭环步进电机是创客基地为满足市场需求而自主研发的一款产品。具备脉冲接口和RS485/CAN串行接口,支持MODBUS-RTU通讯协议,内置高效FOC矢量算法,采用高精度编码器,通过位置反馈&am…

客户案例 | 思腾合力GPU算力节点助力实时云渲染

客户介绍 平行云是国内领先的云化XR概念倡导者与技术先行者,LarkXR是平行云研发的云化XR PaaS平台。LarkXR能够帮助XR领域企业级客户快速实现技术、产品及平台的云化转型,高效使能企业的云化XR业务,有效保护客户的内容安全,让多种…

ANDEAWELL:国产工业RFID替代潮即将到来!

受这两年国外的芯片供应不足,价格上涨后用户难以承受等影响,越来越多的企业选择国产替代芯片。随着国产替代芯片的应用增加,东信源芯、旗连、国芯物联等出货量也开始增加,可以预见的是,国产工业RFID替代潮即将到来! 国…

解决Maven 依赖下载不全的问题 (自测有效)

问题描述:从仓库拉代码下来 发现存在部分依赖下载不了。 解决方案:去中央仓库一个个手动下载。具体步骤如下 1.清除下载一般的依赖 (以下代码是 .bat 文件) echo off rem create by NettQunrem 这里写你的仓库路径 s…

类实例化和实例初始化

就算不写main方法里面的3句,也会执行5 1 10 6 因为main方法所在的类需要先加载和初始化 执行顺序如下:先初始化父类再初始化子类 静态实例变量显示赋值和静态代码块代码从上到下顺序执行(根据书写顺序) 子类的实例化方法&am…

【9 Vue全家桶 – Vuex状态管理】

1 什么是状态管理 其实是数据管理但是为了更好的指出是由于状态的变化导致数据的变化(响应式数据),我们称之为状态管理. 2 Vuex的状态管理 组件只能直接读取state,而不能直接修改state,必须通过mutation才能修改.(pinia可以直接读取和修改state) 3 Vuex的安装 npm install …

ModDrop++:一种具有受试者内部协同训练的动态滤波网络,用于具有缺失模态的多发性硬化病变分割

文章目录 ModDrop: A Dynamic Filter Network with Intra-subject Co-training for Multiple Sclerosis Lesion Segmentation with Missing Modalities摘要本文方法Dynamic Head with Filter ScalingIntra-subject Co-training 实验结果 ModDrop: A Dynamic Filter Network wit…

1:面向对象

文章目录 1:与equals的区别2:写算法题的时候边界条件最后考虑3:高内聚低耦合4:父类引用指向子类对象5:如何重写equals方法6:java是如果实现跨平台的7:HashMap中的重点注意事项8:局部…

快速入门Python语言:人生苦短,我用Python~~Python语言经验分享

⭐方向一:“你是如何学习/自学 Python 的?” 我通过自学的方式学习Python。我的自学方法具有良好的灵活性和自控力,在这个过程中,我注重打下坚实的基础,确保学习的深度与广度,以提高对Python语言和编程的认…

[答疑]UMLChina的Logo是不是不对劲

DDD领域驱动设计批评文集>> 《软件方法》强化自测题集>> 《软件方法》各章合集>> Lynn 2023-4-6 13:55 潘老师,咱umlchina的标记是不是不太对劲,火柴人指向用例的箭头是三角形似乎不合uml的标准。 UMLChina潘加宇 是的。如果按U…

张驰咨询:六西格玛绿带培训如何帮助酒店降低成本和提高客户满意度?

六西格玛是一种质量管理方法,旨在通过减少缺陷和提高效率来提高客户满意度。在酒店行业中,六西格玛可以帮助酒店降低成本和提高客户满意度的方法有:减少浪费、提高效率、优化客户体验、降低维护成本等等。下面张驰咨询给大家分享两个真实案例…