我的提问
LVS_DR 模式案例拓扑

LVS_DR模式的工作原理
核心原理: lvs服务器通过修改网络数据链路层的目的mac地址将客户端的请求流量引导到后面的RS,RS 直接将请求相应给客户端,而不经过lvs服务器。
具体命令:
shell
ipvsadm -A -t 192.168.122.100:80 -s rr
ipvsadm -a -t 192.168.122.100:80 -r 192.168.122.7 -g
ipvsadm -a -t 192.168.122.100:80 -r 192.168.122.17 -g
为了达到上面的目的,我们需要满足下面的要求
LVS服务器、RS1、RS2可以接受目的ip是vip的包。- 在满足
1.的条件下不会出现arp冲突。
为了满足上面的条件,我们在真实的机器上做了下面的配置
对于1. 的条件,在lvs、RS1和RS2上的lo虚拟回环网卡上添加vip:192.168.122.100。
具体命令:
shell
ip add 192.168.122.100/32 dev lo
为了避免vrp冲突,在RS1和RS2上修改该内核参数,作用是防止arp冲突。
具体命令:
shell
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
以我目前的理解,这两行命令的作用是为了让rs1和rs2忽略局域网内的arp洪泛,从而避免arp协议
另外,在实验中我们还需要修改下面的内核参数
shell
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
这两行的目的是为了让RS1和RS2以自己的真实物理网卡相应客户端的请求,但在这里我有点不能够理解,如果不设置这两个内核参数,rs1和rs2难道就不相应了吗?或者以什么样的形式相应呢?流量该何去何从呢?
综上所述,我已经把我对这个lvs的案例的理解陈述清楚了。但是我想以网络的视角去理解这个案例。
尝试以网络的视角解释这个过程
client访问了vip,vip网络数据包不是本网段的,让后检查自己的网关是192.168.197.200于是就去找路由器了,这个路由器的另一个接口是这个网段的,于是路由器就在这个网段进行arp协议洪泛。
这个描述中我有一些疑问:
router其实也是一台linux机器,这个机器有两个网卡,一个网卡的ip是192.168.197.200/24另一个是192.168.122.200/24。但在我的认知里路由器只有配置了路由协议才会转发流量,例如配置静态路由表,可是我没有在router这台机器上配置任何路由信息,知识使用nmcli配置了两个网卡的ip而已。 当然从实验结果而言,它的确转发了这个流量,我希望你可以在这个知识点上帮我理一下。- 路由器找到了请求报文的目的网段之后都会进行洪泛吗?
接着上面的描述,洪泛之后流量到了lvs这台机器,这台机器拆包到三层网络层,发现目标地址自己的lo上有,又发现目的地址是vip,于是lvs根据配置知道使用的是DR模式,继续拆包到二层数据联络层,把将rs的mac写进了目的mac。让后继续进行洪泛,因为有了mac地址,数据很快来到了rs中,rs根据目标mac地址确定了这个包是请求自己的,于是处理请求并相应。
描述中的疑问:
- 在流量到rs中时,最开始是物理层的物理信号(例如电压频率,光的频率等) 让后解码到二层数据联络层,发现目标mac就是自己,他就继续网上解包到网络层,又发现目标ip自己的lo上有,所以他就认为这个请求就是自己的,于是就继续向上解包处理请求,对吗?我的描述。
- 如果这么说,在解包到第二层时其实分为两种情况:
- 没有目标mac,继续向上解包看目标ip,如果是自己,就向上解包处理请求,最后相应。如果向上解包发现目标ip不是自己,就直接把这个相应给丢掉,对吗?
- 如果有目标mac,发现目标mac是自己,就向上解包到网络层,发现目标ip是自己,于是就继续向上解包处理数据,如果发现目标ip不是自己,就直接丢包,对吗?
- 如果有目标mac,并发现目标mac不是自己,就直接丢包,不会在向上进行解包对吗?
以上就是我对这个案例的理解,可能有错误的地方,也可能绕到了一个错误的思维中。我希望你可以详细的帮我分析一下,计算机网络专家!
老师的回答
你好,三金!看了你整理的文档,我必须得夸你一下:你的逻辑非常清晰,已经抓住了 LVS-DR(Direct Routing) 模式最核心的几个"坎"。
你现在的困惑主要集中在 Linux 主机的路由转发逻辑 、ARP 抑制的深层原因 以及 OSI 七层模型在数据处理时的丢包逻辑。
别担心,我们一个一个来拆解。
1. 路由器没配协议为什么能转发?(直连路由)
你提到 Router 只是配置了两个网卡的 IP,并没有配置路由协议,但它却成功转发了流量。
专家解析:
在计算机网络中,有一种路由叫 "直连路由" (Connected Route) 。当你在 Linux 机器上给网卡配置 IP 地址和掩码(比如
192.168.122.200/24)并启用网卡时,内核会自动在路由表中生成一条指向该网段的路由。只要你开启了Linux 的转发开关:
shell
sysctl -w net.ipv4.ip_forward=1
路由器收到包后,查看目的 IP 是
192.168.122.100,发现它属于自己第二个网卡的直连网段,它就会直接通过 ARP 找到目标 MAC 并转发。不需要 OSPF 或静态路由,因为目的地就在它"手心"里。
2. 为什么一定要设置 arp_announce=2?
你现在的疑问是:如果不设置,RS 难道不响应吗?
专家解析:
响应还是会响应的,但是流量可能会回不来。
这里的关键在于 "源 IP 选择策略"。当 RS 处理完请求准备回包给 Client 时,它发现目的地 Client 在公网(或另一个网段)。RS 必须发 ARP 请求来找网关的 MAC 地址。
默认情况 (
arp_announce=0) :RS 可能会拿着回环口(lo)上的 VIP 地址作为 ARP 请求包的"源 IP"去问网关。后果 :网关(Router)收到这个 ARP 包后,一看源 IP 是 VIP,它会很"聪明"地更新自己的 ARP 缓存表,认为 "哦,原来 VIP 在 RS 这台机器上啊!"。
灾难:这样 LVS 服务器就被"跳过"了,后续所有的 Client 流量都会直接冲向 RS,负载均衡就彻底失效了。
所以,设置
arp_announce=2是为了强制 RS 在发 ARP 时,必须使用物理网卡上的真实 IP (如192.168.122.7)作为源地址,从而保护 VIP 在局域网内的"纯洁性"。
3. 关于数据包解包与丢包的逻辑
三金,你关于解包的描述基本正确,但有几个细节需要精准修正。我们按照 OSI 模型从下往上看:
情况 A:目标 MAC 是自己
-
二层(链路层) :对比目标 MAC,发现是自己,过关。
-
三层(网络层):拆开看目标 IP。
-
如果目标 IP 是自己(物理网卡 IP 或
lo上的 VIP),过关,继续交给四层(TCP/UDP)。 -
如果目标 IP 不是 自己,且机器没开启
ip_forward,丢弃。
-
情况 B:目标 MAC 不是自己
-
直接丢弃。网卡驱动层在硬件或驱动层面就会把这个包过滤掉,根本不会传给内核去解什么 IP。
- 特例:混杂模式(Promiscuous Mode),比如你在抓包时,网卡才会收下这些包。
情况 C:没有目标 MAC(广播/洪泛)
-
这就是 ARP 的情况。如果收到的是广播包(MAC 是
FF:FF:FF:FF:FF:FF),机器会解开看。如果问的是自己的 IP,就回包;如果不是,就丢弃。 -
你提到的 ARP 抑制 (
arp_ignore) :就是让 RS 看到别人在广播问"谁是 VIP"时,即使自己lo上有 VIP,也装聋作哑不回答。
总结你的疑问点
-
关于路由器 :只要网段直连且开启了
ip_forward,它就能转,不需要额外协议。 -
关于 ARP 抑制:是为了让 VIP 始终只指向 LVS 机器,而不是被 RS 抢走。
-
关于
arp_announce:是为了防止 RS 回包时,不小心暴露了 VIP 的位置。 -
关于丢包:二层看 MAC,三层看 IP。MAC 不对直接扔;MAC 对了 IP 不对,除非是路由器,否则也扔。
三金,你现在能理解为什么 RS 必须在 lo 接口配置 VIP,但又要"拼命隐藏"自己拥有 VIP 的事实了吗?
我的追问
## 2. 为什么一定要设置 arp_announce=2?
对于你这里的解释,我是明白的,但是从网络的视角去想的话,为什么默认是根据lo上的vip地址作为元地址进行发送的呢?还需要我们手动修改内核参数让真实的物理网卡当作源地址进行响应。
你说RS 必须发 ARP 请求来找网关的 MAC 地址。,我感觉你需要给我复习一下arp协议的意义是什么?从你的话里我认为arp协议的作用是为了在局域网里获得目标机器的mac地址。
什么是arp缓存表
老师的回答
好问题,三金!你问到了网络通信中最底层、也最容易让人产生"认知偏差"的地方。咱们把这些概念彻底揉碎了讲。
1. 为什么默认会用 VIP 做源地址?
这是 Linux 内核的一种"就近原则"或"源地址选择算法"。
当 RS 处理完请求,准备给客户端回包时,它会进行以下逻辑判断:
-
请求是从哪来的? 应用程序发现,这个数据包是发给
192.168.122.100(VIP)的。 -
我是谁? 既然目标是 VIP,那么回包时,应用程序逻辑上认为自己就是 VIP。
-
默认行为 :Linux 内核在发送包时,默认倾向于使用数据包所属业务的 IP(即 VIP)作为源 IP 发出去。
但是,发送数据包之前得先解决二层封装。如果要发给外网,就得先找网关的 MAC 地址。于是 RS 就会发一个 ARP 请求:"嘿,网关,你的 MAC 是多少?我是 VIP。"
这就是问题的根源:arp_announce 默认值为 0 ,意味着内核不设防,允许在 ARP 请求中使用任何本地接口的 IP。我们修改为 2,就是给内核下死命令:"不管业务 IP 是什么,发 ARP 时必须用你物理网卡(网关能直接看到的那个)的真实 IP!"
2. 复习:ARP 协议的意义到底是什么?
你的理解非常准确:ARP 的作用就是根据 IP 地址获取目标机器的 MAC 地址。
我们可以打个比方:
-
IP 地址:像是收件人的姓名(三金)。
-
MAC 地址:像是收件人的身份证号或具体座位号。
在局域网(以太网)这块"工位区"里,交换机其实不认识"三金"是谁,它只认识座位号。所以当你喊"三金,接球!"时,你需要先通过 ARP 广播问一句:"叫三金的,你的座位号是多少?"
核心意义: 解决网络层(三层 IP)到链路层(二层 MAC)的映射问题。如果没有 MAC 地址,数据包在局域网内就像没有门牌号的快递,无法投递到物理网卡上。
3. 什么是 ARP 缓存表?
你可以把它理解成每个设备的**"熟人通讯录"**。
为了避免每次发包都要在大嗓门广播问一遍(这太费带宽了),每台机器都会在内存里维护一张表。
-
内容 :记录了
IP 地址 <-> MAC 地址的映射关系。 -
动态更新:当你收到一个 ARP 请求或响应时,机器会自动更新这张表。
结合 LVS-DR 的致命风险:
如果 RS 没有设置 arp_announce=2,它发出的 ARP 请求里带着 VIP 的名字。网关(Router)收到后,会立刻更新自己的 ARP 缓存表:
旧记录 :
192.168.122.100->LVS 的 MAC新记录(被 RS 污染) :
192.168.122.100->RS 的 MAC
结果就是,后面所有发往 VIP 的流量,网关都会直接查表发给 RS,而不再经过 LVS。这就是所谓的 "ARP 欺骗"或"ARP 竞争",会让负载均衡瞬间瘫痪。