【分享】LVS DR/TUN 模式下的ARP配置问题总结

LVS ARP问题描述:

在LVS的DR模式下,有一个必须要处理的问题就是real server上的ARP响应问题。其实,这个问题不只是LVS,其他的L4 Switch方案比如Foundry的ServerIron,也需要设置real server上的ARP响应。因为这是这种方案的结构决定的。
   根据LVS官方说明,在LVS 的DR模式下,前端的director接收到用户请求以后,director根据后端real server的负载情况,动态地选择一台real server,不修改也不封装IP报文,而是将数据帧的MAC地址改为选出的real server的MAC地址,再将修改后的数据帧在后端本地局域网上发送。director本身不会关心IP层以上的信息,即使是端口号也是tcp/ip协议栈去判断是否正确,director本身主要做这么几个事:
1)接收client的请求,根据你设定的负载均衡算法选取一台realserver的ip;
2)以选取的这个ip对应的mac地址作为目标mac,然后重新将IP包封装成帧转发给这台real server;
3)在hashtable中记录连接信息。
director做的事情很少,也很简单,所以它的效率很高,不比硬件负载均衡设备差多少。
数据包、数据帧的大致流向是这样的:client –> VS –> RS –> client
因为数据帧的MAC地址是选出的real server,所以被选出来的那台real server肯定可以收到这个数据帧,从中可以获得该IP报文。当real server发现报文的目标地址VIP是在本地的loopback接口上,于是处理这个报文,然后根据路由表将响应报文直接返回给客户。
那为什么不可以将VIP设置在出口网卡上呢?答案是会响应客户端的arp request,造成client/gateway arp table紊乱,以至于整个loadbalance都不能正常工作。
从上边的LVS DR工作原理可以看到一个客户端计算机发送一个ARP广播到LVS-DR集群,因为Director和集群节点(真实服务器1)都是连接到相同的网络上的,它们都会接收到ARP广播“是谁的VIP1?”,如果director和real server都进行ARP回应,则客户端就会按照第一个接收到ARP回应发送数据包。整个负载均衡就都失效了。
这个时候我们希望的是只有前端的director来对用户进行ARP响应,其他real server不应该响应用户直接的ARP包。为了阻止真实服务器应答ARP广播,我们需要在所有真实服务器上隐藏loopback接口。
参考下边两幅引用51cto网站的图:
20180619182336
20180619182355
 
需要注意:
1、lvs在DR模式和TUN模式下需要关闭arp,而nat模式不需要
2、nat模式下,director作为所有realserver的网关,所有的进站出站流量,全部通过director(瓶颈)
3、dr模式下,需要进行物理寻址,所以director跟realserver同在一个物理网络(arp问题)
4、tun模式下,director跟realserver可以在同一个网络,也可以跨网(当在同一个网络时,有arp问题)
5、dr跟tun模式下,director跟realserver的端口必须对应,而nat下各台realserver可以使用不同的端口

LVS ARP问题解决办法:

主要设置系统的两个参数 “arp_announce” 和 “arp_ignore”  ( Linux kernel 2.6.4 and 2.4.26 之后才有)

arp_announce 参数值:

作用:设置的是发出请求包时,选择哪个IP和MAC地址供响应者缓存 ,这也符合announce的字面意思:向外通告本机的哪个IP地址和MAC地址供其他主机缓存。
0 – (默认) 在任意网络接口上的任何本地地址
1 -尽量避免不在该网络接口子网段的本地地址. 当发起ARP请求的源IP地址是被设置应该经由路由达到此网络接口的时候很有用.此时会检查来访IP是否为所有接口上的子网段内ip之一.如果改来访IP 不属于各个网络接口上的子网段内,那么将采用级别2的方式来进行处理.
2 – 对查询目标使用最适当的本地地址.在此模式下将忽略这个IP数据包的源地址并尝试选择与能与该地址通信的本地地址.首要是选择所有的网络接口的子网中外出访问子网中包含该目标IP地址的本地地址. 如果没有合适的地址被发现,将选择当前的发送网络接口或其他的有可能接受到该ARP回应的网络接口来进行发送
all/ 和{interface}/ 下两者同时比较,取较大一个值生效.

arp_ignore 参数值:

作用:设置的是收到请求包后,在应答包中将本机的哪个IP地址和MAC地址回应给请求者以供缓存
0 – (默认值): 回应任何网络接口上对任何本地IP地址的arp查询请求(比如eth0=192.168.0.1/24,eth1=10.1.1.1/24,那么即使 eth0收到来自10.1.1.2这样地址发起的对10.1.1.1 的arp查询也会回应–而原本这个请求该是出现在eth1上,也该有eth1回应的)
1 – 只回答目标IP地址是来访网络接口本地地址的ARP查询请求(比如eth0=192.168.0.1/24,eth1=10.1.1.1/24,那么即使 eth0收到来自10.1.1.2这样地址发起的对192.168.0.1的查询会回答,而对10.1.1.1 的arp查询不会回应)
2 -只回答目标IP地址是来访网络接口本地地址的ARP查询请求,且来访IP必须在该网络接口的子网段内(比如eth0=192.168.0.1/24, eth1=10.1.1.1/24,eth1收到来自10.1.1.2这样地址发起的对192.168.0.1的查询不会回答,而对 192.168.0.2发起的对192.168.0.1的arp查询会回应)
3 – 不回应该网络界面的arp请求,而只对设置的唯一和连接地址做出回应(do not reply for local addresses configured with scope host,only resolutions for global and link addresses are replied 翻译地似乎不好,这个我的去问问人)
4-7 – 保留未使用
8 -不回应所有(本地地址)的arp查询
all/ 和{interface}/ 下两者同时比较,取较大一个值生效.

解决办法:

情况一:不需要配置

如果 RS 上面的所有网卡的 IP 和VIP 不在同一个网络里面,那么 VIP 的 ARP 广播请求都到不了 RS 上,所以这种情况下什么都不需要做,不过 RS 需要有路由能把处理的包发出去。

情况二:对lo的arp配置

如果 RS 上有IP 和 VIP (绑定到 lo 上)在同一个网络里面,那么 VIP 的 ARP 广播请求就有可能得到响应,所以要禁止相关 ARP 的通信.
临时解决:
echo”1″>/proc/sys/net/ipv4/conf/all/arp_ignore
echo”1″>/proc/sys/net/ipv4/conf/lo/arp_ignore
echo”2″>/proc/sys/net/ipv4/conf/lo/arp_announce
echo”2″>/proc/sys/net/ipv4/conf/all/arp_announce
永久解决:
# vim /etc/sysctl.conf
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
# sysctl -p

原理解读:

Real Server接收并处理了director的转发的client请求(在lo:0接口上处理),而将处理结果返回给client的时候(lo:0生成处理结果,而从其他通讯接口发出,例如eth0发出),如果此时需要进行arp请求,arp请求的源地址,使用的是发出请求接口的ip(eth0的ip),而不是产生结果的接口的ip(lo:0)…这样避免了arp请求被路由器缓存并打乱了原有的 vip 的 mac)

其他说明:

1.  只要是本机的进程跟本机的进程进行通讯,产生的流量,都是在lo接口上,而无论你使用的ip地址是eth0还是eth1的
2. 冲突域与广播域
冲突域:发生在第一层(物理层),用于隔离冲突域的设备,是二层设备(如网桥,交换机)
广播域:发生在第二层(链路层),用于隔离广播域的设备,是三层设备(如路由器,VLAN)
3. ARP广播发生在第二层(链路层,具有物理地址),而 loopbackup(lo)接口可以认为是三层设备(只有IP地址而没有物理地址。所以,其实上面对lo接口配置 arp_ingore 和 arp_announce 是不需要的!因为loopbackup(lo)接口自身并不会接收arp广播,也就不响应ARP请求,之所以能生效,因为对所有网卡all 都进行了arp设置。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享