程序员社区

【深入浅出Linux】LVS的DR模式的关键点

前言

DR模式的关键点

上一篇文章地址:
【深入浅出Linux】LVS集群的通用结构:https://www.jianshu.com/p/b40f03635605

上一篇文章所说的DR的工作模式相比于NAT的工作模式在我们的使用中是最常见的,而这种模式的实现依赖于,真实服务器的上VIP地址,我们都知道客户端访问我们的负载均衡调度器是通过VIP地址来访问的,因此响应给客户端的数据包的源地址和端口也必须是当初客户端访问的目标IP和端口,因此VIP必须在负载均衡器上配置用于接受用户的请求。

但在DR模式下,对应相应回去的数据包是RealServer直接相应的,并没有通过负载均衡调度器,因此这个被选中的真实服务器上必须也要配置一个VIP才能保证,相应回去的源IP是当初客户端访问的目标IP地址。

那么问题来了,负载均衡调度器和真实服务器都在同一个局域网内部,都有VIP这个地址,那么用户发来的请求到底我们的路由就不知道该转给哪一台服务器了。

因此真实服务器的VIP地址应该配置成对外隐藏,对内可见,那么什么样的配置方式才能达到上述的效果呢,答案就是在我们的回环接口上配置这个VIP,我们都知道在linux中ifconfig可以查看当前的网络配置信息。在信息表里,我们一般都会发现一个叫lo的东西。


1.这个lo是什么呢?

其实,lo 是 loopback 的缩写,也就是环回的意思,linux系统默认会有一块名为 lo 的环回网络接口。而你真正的网卡一般则被linux系统识别成名为 eth0, eth1 这样的网络接口。

一般,lo接口对应的ip地址为 127.0.0.1, IP地址可通过ifconfig来查看。当你从一台linux主机向自身发送数据包时, 实际上的数据包是通过虚拟的lo接口来发送接受的,而不会通过你的物理网卡 eth0/eth1... 。
lo环回网卡有一个特点,就是只在网络层之上可见(包括网络层),因此不会跟LVS的VIP冲突。当然这里需要注意,真实服务器的VIP地址需要设置Non-ARP的形式。


2.为什么设置成Non-ARP的形式?

因为用户的请求想要先到达负载均衡调度器需要先通过ARP协议广播形式获取负载均衡调度器的MAC地址,然后将数据帧发到负载均衡调度服务器上,这个获取MAC地址的过程一般是通过ARP协议广播的形式,下面我们说一下ARP协议获取MAC地址的核心。

主机向自己所处的网络广播一个ARP请求(以太网帧首部的硬件地址填FF:FF:FF:FF:FF:FF表示广播),该请求包含的目标机器的网络地址,这个请求会被当前局域网内的所有主机都会收到,在数据链路层都会收到然后处理交给上层,目的主机收到广播的ARP请求,发现与IP地址与本机相符合就发一个ARP应答给源主机,将自己的MAC地址写到应答包中。而其他主机接收后发现与自己的IP不符合就会直接丢弃。之后会有一个ARP缓存,这个缓存来进行保存ip地址和MAC地址的映射关系,这样,就不需要进行多次的ARP请求了。

那如果通过ARP协议获取MAC地址的过程,真实服务器的接受到ARP请求,发现自身内部配置有相应的IP地址,那么会发一个ARP应答给源主机,导致MAC地址不是负载均衡调度器的MAC地址,这时候虽然因真实服务器在环回网卡上也绑定了VIP,所以也能正常处理请求,业务暂时不会受到影响,但时此时由于客户端请求没有发到LVS的虚拟服务IP上,所以LVS的负载均衡能力没有生效。造成的后果就是,真实服务器一直在单节点运行,业务量过大时可能会出现性能瓶颈。


3.那么我们该如何实现NonArp呢?

我们需要在Linux服务器上配置Linux内核参数arp_ignore和arp_announce。
首先看一下这个两个配置项的参数:

arp_ignore:(回应ARP)

  • 0:回应任何网口上收到的对任何本机IP地址的ARP查询请求(默认)
  • 1:只回应Target IP是接收网口的IP的ARP查询请求
  • 2:只回应Target IP是接收网口的IP的ARP查询请求,且Sender IP必须与该网口属于同一网段
  • 4-7:保留未使用
  • 8:不回应所有的arp查询

arp_announce: (选择ARP宣告时候使用的Sender IP)

  • 0: (默认) 在任意网络接口(eth0,eth1,lo)上使用任何本机地址进行ARP请求。通常就是使用数据包a的源IP
  • 1:尽量避免使用不属于该发送网卡子网的本地地址作为发送arp请求的源IP地址。
  • 2:始终使用与目标IP地址对应的最佳本地IP地址作为ARP请求的源IP地址。在此模式下将忽略IP数据包的源IP地址并尝试选择能与目标IP地址通信的本机地址。

4.对arp_announce参数更详细的说明

假设一个Linux服务器X有三个网络接口,分别为:eth0,eth1和eth2。每个接口都有一个IP地址,分别为:IP0,IP1和IP2。

当本地应用程序尝试通过eth2发送IP0的IP数据包时。如果目标节点的mac地址没有解析。这个Linux服务器X将发送ARP请求来获取目标(或网关)的mac地址。在这种情况下,ARP请求包的源IP地址是什么呢?IP0(IP数据包的中的源IP)或IP2(发送ARP请求包的网络接口eth2的IP)?

其实对于大部分路由器来说ARP请求包中的源IP地址使用发送ARP请求包的网络接口上配置的IP地址(在上面的例子中为IP2)。
但是,linux服务器的行为是点不同。在Linux服务器中通过Linux的内核数据arp_announce,ARP请求中源地址的选择是完全可配置。

如果我们想在ARP请求中使用IP2而不是IP0,我们应该把arp_announce的值改为1或2。默认值为0 - 允许使用IP0作为ARP请求包中的源IP。其实arp_announce是为了解决Linux服务器作为路由器时的arp问题,因为路由器一般是动态学习ARP包的(一般动态配置DHCP的话)。当内网的Linux机器要发送一个到外部的ip包,那么它就会请求路由器的Mac地址,发送一个arp请求,这个arp请求里面包括了自己的ip地址和Mac地址。而linux默认是使用ip数据包的源ip地址作为arp里面的源ip地址,而不是使用发送设备上面网络接口卡的ip地址 (默认arp_announce的值为0)。

这样在lvs架构下,所有arp请求包的源地址都是同一个VIP地址,那么arp请求就会包括VIP地址和设备 Mac。而路由器收到这个arp请求就会更新自己的arp缓存,这样就会造成ip欺骗了,VIP被抢夺,所以就会有问题。


5.arp缓存为什么会更新了,什么时候会更新呢?

为了减少arp请求的次数,当主机接收到询问自己的arp请求的时候,就会把源ip和源Mac放入自 己的arp表里面,方便接下来的通讯。如果收到不是询问自己的包(arp是广播的,所有人都收到),就会丢掉,这样不会造成arp表里面无用数据太多导致有用的记录被删除。


6.arp设置

1,准备3台虚拟机

2,先配置3台虚拟机的网络:
eth0,配置在一个网段
DIP,RIP在一个网段

3,配置lvs的VIP
ifconfig eth0:0 192.168.9.100/24
echo “1” > /proc/sys/net/ipv4/ip_forward 

4,调整RS的响应。通告级别(每一台RS都配):
echo 1  > /proc/sys/net/ipv4/conf/eth0/arp_ignore
echo 2  > /proc/sys/net/ipv4/conf/eth0/arp_announce
echo 1  > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2  > /proc/sys/net/ipv4/conf/all/arp_announce

5,配置RS的VIP(每一台RS都配)
ifconfig lo:8 192.168.9.100 netmask 255.255.255.255

6,启动RS上的httpd
yum install httpd -y
/var/www/html
vi index.html  
from ooxxip
service httpd start
客户端验证:RIP:80 能显示
VIP:80不能显示

7,LVS——ipvsadm
yum install ipvsadm -y
ipvsadm -A -t 192.168.9.100:80 -s rr
ipvsadm -a -t 192.168.9.100:80 -r 192.168.9.12 -g 
ipvsadm -a -t 192.168.9.100:80 -r 192.168.9.13 -g
ipvsadm -ln

浏览器刷新: 访问vip
ipvsadm –lnc
netstat -natp

下一篇文章对LVS中VIP配置在环回接口上,子网掩码为什么是4个255?问题会进行分析...

敬请关注

赞(0) 打赏
未经允许不得转载:IDEA激活码 » 【深入浅出Linux】LVS的DR模式的关键点

相关推荐

  • 暂无文章

一个分享Java & Python知识的社区