LVS DR模式的一些问题


原文链接: LVS DR模式的一些问题

最近一年,接触了大名鼎鼎的LVS,碰到一些问题,记录一下。由于工作中只用到 DR 模式,所以只写 DR 模式的一些问题。

LVS 只是内核的一个模块,只负责怎么把网络包负载均衡到 RS 上,这也符合 Unix/Linux 的设计哲学,一个模块只做一件事情,通过多个模块协作,完成整个功能。负载均衡系统除了负载功能,还需要考虑 RS 服务的健康检查,负载均衡系统本身的 HA 问题,而这些都是由其它模块完成的。工作中主要用 keepalived ,协作配合 LVS 来做负载均衡的。

lvs核心概念

1. LVS/DR如何处理请求报文的,会修改IP包内容吗?

1.1 vs/dr本身不会关心IP层以上的信息,即使是端口号也是tcp/ip协议栈去判断是否正确,vs/dr本身主要做这么几个事:

1)接收client的请求,根据你设定的负载均衡算法选取一台realserver的ip;

2)以选取的这个ip对应的mac地址作为目标mac,然后重新将IP包封装成帧转发给这台RS;

3)在hash table中记录连接信息。

vs/dr做的事情很少,也很简单,所以它的效率很高,不比硬件负载均衡设备差多少。

数据包、数据帧的大致流向是这样的:client --> VS --> RS --> client

1.2 前面已作了回答,vs/dr不会修改IP包的内容.

2. RealServer为什么要在lo接口上配置VIP?在出口网卡上配置VIP可以吗?

2.1 既然要让RS能够处理目标地址为vip的IP包,首先必须要让RS能接收到这个包。

在lo上配置vip能够完成接收包并将结果返回client。

2.2 答案是不可以将VIP设置在出口网卡上,否则会响应客户端的arp request,造成client/gateway arp table紊乱,以至于整个load balance都不能正常工作。

3. RealServer为什么要抑制arp帧?

这个问题在上一问题中已经作了说明,这里结合实施命令进一步阐述。我们在具体实施部署的时候都会作如下调整:

   echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
   echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
   echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
   echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce

我相信很多人都不会弄懂它们的作用是什么,只知道一定得有。我这里也不打算拿出来详细讨论,只是作几点说明,就当是补充吧。

3.1

echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce

这两条是可以不用的,因为arp对逻辑接口没有意义。

3.2 如果你的RS的外部网络接口是eth0,那么

echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce

其实真正要执行的是:

echo "1" >/proc/sys/net/ipv4/conf/eth0/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/eth0/arp_announce

所以我个人建议把上面两条也加到你的脚本里去,因为万一系统里上面两条默认的值不是0,那有可能是会出问题滴。

4. LVS/DR load balancer(director)与RS为什么要在同一网段中?

从第一个问题中大家应该明白vs/dr是如何将请求转发给RS的了吧?它是在数据链路层来实现的,所以director必须和RS在同一网段里面。

  1. 为什么director上lo接口除了VIP另外还要在eth0配一个ip(即DIP)?

5.1 如果是用了keepalived等工具做HA或者Load Balance,则在健康检查时需要用到DIP。

5.2 没有健康检查机制的HA或者Load Balance则没有存在的实际意义。

  1. LVS/DR ip_forward需要开启吗?

不需要。因为director跟realserver是同一个网段,无需开启转发。

  1. director的vip的netmask一定要是255.255.255.255吗?

lvs/dr里,director的vip的netmask 没必要设置为255.255.255.255,也不需要再去

route add -host $VIP dev eth0:0

director的vip本来就是要像正常的ip地址一样对外通告的,不要搞得这么特殊.

  1. LVS/DR如何进行tcp的三次握手?


相信一般的小公司用的最多的还是DR和NAT模式,关于DR和NAT模式的原理请看看下图,我们先从lvs的DR和NAT模式特性聊聊一些问题。
图片描述
图片描述

问题1、lvs的DR模式和NAT模式核心缺陷有哪些?
DR模式的缺陷
1:Realserver和 lvs的vip提供服务的端口必须一致。
也就是说:vip的端口对外端口为 80,但后端服务的真实端口为8080,通过lvs的DR模式是实现不了的。
2:Realserver和LVS不能在同一台机器上
3: Realserver 和LVS需要在同一个vlan或者局域网下。
NAT模式的缺陷
1:NAT模式流量的入和出都需要通过LVS服务器。
2: 效率相比DR模式,性能和效率上会差一些。

为什么呢?别着急如果你不太了解,下面来解释为什么?

问题2、为什么Realserver和 lvs,vip提供服务的端口必须一致?
原因:因为LVS的DR模式,改写的就是数据包的目的MAC地址,并不会对数据报文IP和端口地址层修改,所以就作不到端口改写了。

问题3、为什么DR模式下,Realserver和LVS不能在同一台机器上?
原因:假设lvs主服务器上的数据包发送给自己备份节点(也是realserver) eth0 接口。备lv不能正常的被监听指定端口的程序所接收,因为数据包会首先先经过 ip_vs()来接受处理了.
不仅如此,备份节点还会将50%的机率将数据包转发给lvs主,这样一直主和备一直转发,就形成死循环了。所以客户端会发现,一次正常能请求,一次会出现
超时的情况。

问题4、为什么DR模式下,Realserver 和LVS需要在同一个vlan或者局域网下?
原因:LVS的是改写mac地址的,基于mac地址的通讯方式是2层的,所以需要限制在一个vlan或者局域网下。

问题5、为什么NAT模式下,NAT模式流量的入和出都需要通过LVS服务器?
原因:NAT模式修改的目的端的IP地址,对公网的VIP,并不会下放到realserver上,所以后端的realserver的网关必须指向lvs地址。

问题6、为什么效率相比DR模式,性能和效率上会差一些?
原因:原因和NAT模式的特性一样,出入的数据包都需要通过lvs,必然导致数量大了后,成为性能瓶颈。

DR 模式的限制

  • VIP 的端口必须和RS服务的端口一致(DR模式只修改包的 mac 地址,不会修改IP及上层的内容)
  • RS 必须对 arp 做相关设置1 2,lo 接口需要绑定VIP
  • VIP 和 RIP 不需要在同一个网段,但是 Director 要有一个网口和 RS 是通过不分段的网络连接起来3

RS 的健康检查

LVS 是内核的一个模块,而健康检查一般是应用层的逻辑,比较复杂,毕竟要解析应用层的协议,写的不好,会影响内核的运行。所以健康检查需要借助其它模块,比如 keepalived。

DR 模式中,RS 需要监听 VIP,如果 RS 只监听 VIP,健康检查就比较麻烦。因为健康检查的网络包,目的地址是 VIP,而 Director 本身就绑定了 VIP,这个包怎么发出去呢?

TCP

一般 RS TCP server 监听0.0.0.0。keepalived 通过检查 RIP:PORT 来确定 RS 的健康状况。

UDP4

如果 RS 的 UDP server 监听0.0.0.0,则响应包的原地址变成了 RIP,而不是 VIP。当然也可以用 cmsg SOL_IP/IP_PKTINFO (ipi_spec_dst)方式解决。生产中,RS 监听 VIP,健康检查简单粗暴,用 keepalived 的 MISC_CHECK, 直接写脚本 ping RIP来判断 RS 上的 UDP 服务是否存活。

VIP 相关问题

VIP 在 RS 的配置5

VIP 一般配置在 RS 的 lo 中,当然也可以配置在其它接口中。如果配置在 lo 中,子网掩码必须是255.255.255.255。原因是 lo 不仅仅响应 VIP,还响应 VIP 这个网段的所有 IP。

比如 eth0 绑定192.168.2.200/30,则 eth0 只会响应192.168.2.200这个IP的请求。但是 lo 绑定192.168.2.200/30,则会响应该段所有 IP(192.168.2.200~192.168.2.203) 的请求。

$ ifconfig lo:1 192.168.2.200/30
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet 192.168.2.200/30 scope global lo:1
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:12:96:98 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
    inet6 fe80::a00:27ff:fe12:9698/64 scope link
       valid_lft forever preferred_lft forever

192.168.2.203是广播地址,ping 不通

VIP 在 Director 的配置6

VIP 在Director里配置,子网掩码是否一定是 VIP 网段的掩码呢?根据大神说法,不是必须的。假设 DIP 配置在 eth0,并且/proc/sys/net/ipv4/conf/eth0/promote_secondaries是关闭的,VIP 是 secondary address,netmask 可以是 DIP 的 netmask,或者32。是不是因为 LVS 只关注 mac 地址,不涉及路由,所以 VIP 的 netmask 可以随意?不晓得

keepalived 配置中,如果没有为 VIP 指定 netmask,默认为32

virtual_ipaddress {	
    192.168.1.100   # default netmask is 32
}

tcpdump抓包为什么会显示两条记录

  • 第一条记录是客户端请求的包,四元组是(cip:cport,vip:vport)
  • 第二条记录是 LVS 负载均衡的包,LVS 将包转发给 RS,整个包的 IP 内容并没有变化,还是(cip:cport,vip:vport)。所以抓包会显示两条同样的记录


不要把 LB Director 和 RS 放在同一台机器上7

localnode 就是 LB Director 和 RS 在同一台机器上。当年还没有虚拟机,所以为了提高机器的使用率,一台物理机器会跑很多的应用。所以可能会在一台机器跑 LVS 和 RS。

如果 LVS 主备都是 localnode,并且 backup 的 LVS rules 已经启用(比如 keepalived),那么就会出现下面的情况

  • client 发 SYN 包给 master director
  • 50% 机会 master director 把包转给 backup (因为 backup 也是 RS)
  • 因为 backup 的 LVS rules 已经启用,所以50%机会 backup 把包转给 master
  • master 收到包后,又把包转给 backup,然后陷入死循环。 (这里是不是50%机会?如果没有开 persistence 也会这样吗,不太清楚转发机制?)

如果用 telnet 测试,发现 telnet 收不到响应。而 LVS 上会发现 SYN 包不停的在转发,一会儿就把 LVS 搞挂了。

localnode 这个问题,有两种解决方案。

fliter by Mac address

sysctl flag backup_only8

大神提到在 kernel 3.9+ 上,新增了一个 flag: backup_only=1,解决这个问题。生产中没有用这么新的 kernel,没有试过,不太清楚如果主备切换,flag 怎么做。

Reference

`