搞懂分布式技术10:LVS实现负载均衡的原理与实践
浅析负载均衡及LVS实现
原创: fireflyc 写程序的康德 2017-09-19
负载均衡
负载均衡(Load Balance,缩写LB)是一种网络技术,它在多个备选资源中做资源分配,以达到选择最优。这里有三个关键字:
- 网络技术,LB要解决的问题本质上是网络的问题,所以它实际上就是通过修改数据包中MAC地址、IP地址字段来实现数据包的“中转”;
- 资源,这里的资源不仅仅是计算机也可以是交换机、存储设备等;
- 最优,它则是针对业务而言最优,所以一般负载均衡有很多算法;轮询、加权轮询、最小负载等;
LB是网络技术所以业内就参考OSI模型用四层负载均衡、七层负载均衡进行分类。四层负载均衡工作在OSI的四层,这一层主要是TCP、UDP、SCTP协议,这种类型的负载均衡器不管数据包是什么,只是通过修改IP头部或者以太网头部的地址实现负载均衡。七层负载均衡工作在OSI的七层,这一层主要是HTTP、Mysql等协议,这种负载均衡一般会把数据包内容解析出来后通过一定算法找到合适的服务器转发请求。它是针对某个特定协议所以不通用。比如Nginx只能用于HTTP而不适用于Mysql。四层负载均衡真正传统意义上的负载均衡,它通过修改网络数据包“中转”请求;一般工作在操作系统的内核空间(kernel space),比如通过Linux的netfilter定义的hook改变数据包。七层负载均衡并不是严格意义上的负载均衡,它必须解析出数据包的内容,根据内容来做相关的转发(比如做Mysql的读写分离);一般工作在用户空间(user space),比如通过Nginx、Mysql Proxy、Apache它们都是实现某个具体协议,很多资料都称这种软件叫代理(Proxy)。
实现LB的问题
无论哪种负载均衡都可以抽象为下面的图形:
任何负载均衡都要解决三个问题:
- 修改数据包,使得数据包可以发送到backend servers;
- frontend server要维护一个算法,可以选出最优的backend server
- frontend server要维护一张表记录Client和backend servers的关系(比如TCP请求是一系列数据包,所以在TCP关闭所有的数据包都应该发送到同一个backend server)
以Nginx为例,forntend server收到HTTP数据包后会通过负载均衡算法选择出一台backend server;然后从本地重新构造一个HTTP请求发送给backend server,收到backend server请求后再次重新封装,以自己的身份返回给客户端。在这个过程中forntend server的Nginx是工作在用户空间的它代替Client访问backend server。
LVS的实现
LVS( Linux Virtual Server)是国产开源中非常非常非常优秀的项目,作者是章文嵩博士(关于章博的简历各位自行搜索)。它是一款四层负载均衡软件,在它的实现中forntend server称为director;backend server称为real server,它支持UDP、TCP、SCTP、IPSec( AH 、ESP两种数据包 )四种传输层协议的负载。
LVS以内核模块的形式加载到内核空间,通过netfilter定义的hook来实现数据包的控制。 它用到了三个Hook(以Linux 4.8.15为例)主要“挂在”:local_in、inet_forward、local_out;所有发送给本机的数据包都会经过local_int,所有非本机的数据包都会经过forward,所有从本机发出的数据包都会经过local_out。
LVS由两部分组成(很像iptables),用户空间提供了一个ipvsadm的命令行工具,通过它定义负载均衡的“规则”;内核模块是系统的主要模块它包括:
- IP包处理模块,用于截取/改写IP报文;
- 连接表管理,用于记录当前连接的Hash表;
- 调度算法模块,提供了八种负载均衡算法——轮询、加权轮询、最少链接、加权最少链接、局部性最少链接、带复制的局部性最少链接、目标地址哈希、源地址哈希;
- 连接状态收集,回收已经过时的连接;
- 统计,IPVS的统计信息;
LVS实战
LVS术语定义:
- DS:Director Server,前端负载均衡器节点(后文用Director称呼);
- RS:Real Server,后端真实服务器;
- VIP:用户请求的目标的IP地址,一般是公网IP地址;
- DIP:Director Server IP,Director和Real Server通讯的内网IP地址;
- RIP:Real Server IP,Director和Real Server通讯的内网IP地址;
很多文章都罗列了一大堆LVS三种模式之间的区别,我最讨厌的就是简单的罗列——没有什么逻辑性很难记忆。其实LVS中三种模式只有一个区别——谁来返回数据到客户端。在LB架构中客户端请求一定是先到达forntend server(LVS中称为Director),那么返回数据包则不一定经过Director。
- NAT模式中,RS返回数据包是返回给Director,Director再返回给客户端;
- DR(Direct Routing)模式中,RS返回数据是直接返回给客户端(通过额外的路由);Director通过修改请求中目标地址MAC为选定的RS实现数据转发,这就要求Diretor和Real Server必须在同一个广播域内(关于广播域请看《程序员学网络系列》)。
- TUN(IP Tunneling)模式中,RS返回的数据也是直接返回给客户端,这种模式通过Overlay协议(把一个IP数据包封装到另一个数据包内部叫Overlay)避免了DR的限制。
以上就是LVS三种模式真正的区别,是不是清晰多了?^_^
NAT模式
NAT(Network Address Translation)模式最简单,real_server只配置一个内网IP地址(RIP),网关指向director;director配置2个IP地址分别是提供外部服务的VIP和用于内部通讯的DIP。
- 配置IP地址
VIP:10.10.10.10,DIP:192.168.122.100 RS1-DIP:192.168.122.101 RS2-DIP:192.168.122.102
注意:Director配置了双网卡,默认路由指向10.10.10.1。即——VIP所在的网卡设置网关,DIP所在的网卡不要设置网关。
- 配置director
Linux默认不会“转发”数据包,通过echo 1 > /proc/sys/net/ipv4/ip_forward
开启forward功能。开启forward后Linux表现的就像一个路由器,它会根据本机的路由表转发数据包。
echo 1 > /proc/sys/net/ipv4/ip_forward #开启forward功能ipvsadm -A -t 10.10.10.10:80 -s rr # 添加LVS集群,DR 负载均衡算法为轮询(rr)ipvsadm -a -t 10.10.10.10:80 -r 192.168.122.101 -m -w 1 RS1 # 添加LVS集群主机(10.10.10.10:80),LVS调度模式为NAT(-m)及RS权重为1ipvsadm -a -t 10.10.10.10:80 -r 192.168.122.102 -m -w 1 # RS2 同上
- 验证
通过client访问10.10.10.10的HTTP服务
NAT模式原理解析
- client发送数据包,被路由到director服务器上;
- director的netfilter local_in hook被触发,lvs模块收到该请求
- lvs查询规则库(ipvsadm生成的规则),发现10.10.10.10:80端口被定义为NAT模式,执行轮询算法
- IP包处理模块修改数据包,把目标IP地址修改为192.168.122.101,从DIP的所在网卡发送出去(所以源MAC是DIP网卡的MAC)。此时的数据包是:源MAC地址变成了00:01:3a:4d:5d:00(DIP网卡的MAC地址)源IP地址是172.10.10.10(client的IP地址),目标MAC和目标IP地址是RS1地址。通过在RS1上抓包验证这一点
注意,Linux不会“校验”源IP地址是否是本机IP地址所以即便172.10.10.10不在DIP上数据包也是可以被发送的,此时的行为相当于“路由”(想一下“网关”如何给你发送某个公网返回的数据包)。
- RS1收到请求目标MAC和IP都是本机,所以直接交给Nginx处理
- Nginx的返回数据包交给Linux协议栈,系统发现目标地址是172.10.10.10和自己不在同一个网段,则把数据包交给网关——192.168.122.100(director)。这就是Real Server必须把网关指向Director Server的原因
- director上的lvs的local_out的hook被触发,发现是返回数据包是:源MAC地址和IP地址是VIP网卡的MAC地址
这种模式虽然叫NAT模式,其实和NAT关系并不大,只是借用NAT的概念而已(发送到RS的源IP地址是客户端的IP地址而不是DIP)。
DR模式
DR(Direct Route,直接路由)和NAT模式最大的区别是RS返回数据包不经过Director而是直接返回给用户。用户到达Director后,LVS会修改用户数据包中目标MAC地址为Real Server然后从DIP所在网卡转发出去,RS的返回数据包直接从单独的链路(拓扑图中是SW2<->R1)返回给用户。
所以DR模式中要求
- Director和RS必须在同一个广播域中,也就是二层可达(实验的拓扑中是通过SW2实现的) ,因为Director要修改目标MAC地址所以数据包只能在广播域内转发;
- RS必须可以路由到用户,也就是三层可达(实验的拓扑中Director和Real server共享同一个路由),因为Real Server的返回数据包是直接返回给用户的不经过Director;
- 配置IP
VIP:10.10.10.10,DIP:192.168.122.100RS1-DIP:192.168.122.101RS2-DIP:192.168.122.102
- 配置Real Server
#绑定VIP到本机的环回口ifconfig lo:0 10.10.10.10 netmask 255.255.255.255 broadcast 10.10.10.10 up#禁用ARP响应echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignoreecho 1 > /proc/sys/net/ipv4/conf/lo/arp_ignoreecho 2 > /proc/sys/net/ipv4/conf/all/arp_announceecho 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
RS是直接返回数据给用户,所以必须绑定VIP地址;因为Director和Real Server都绑定了VIP所以RS必须禁用ARP信息,否则可能导致用户请求不是发送给Director而是直接到RS,这和LVS的期望是不相符的。。不同于NAT,在DR模式下RS的网关是指向默认网关的也就是能“返回”数据到客户端的网关(试验中R1充当默认网关)。
- 配置Director
ipvsadm -A -t 10.10.10.10:80 -s rr # 添加LVS集群,负载均衡算法为轮询(rr)ipvsadm -a -t 10.10.10.10:80 -r 192.168.122.101 -g -w 1 # 添加LVS集群主机(10.10.10.10:80),VS调度模式为DR(-g)及RS权重为1ipvsadm -a -t 10.10.10.10:80 -r 192.168.122.102 -g -w 1 # 同上
- 验证
通过client访问10.10.10.10的HTTP服务
DR模式原理解析
- client发送数据包,被路由到director服务器上;
- director的netfilter local_in hook被触发,lvs模块收到该请求
- lvs查询规则库(ipvsadm生成的规则),发现10.10.10.10:80端口被定义为DR模式,执行轮询算法
- IP包处理模块修改数据包,把目标MAC修改为选中的RS的MAC地址,从DIP的所在网卡发送出去(所以源MAC是DIP网卡的MAC)。此时的数据包是:源MAC地址变成了00:01:3a:4d:5d:00(DIP网卡的MAC地址)源IP地址是172.10.10.10(client的IP地址),目标MAC是00:01:3a:f4:c5:00(RS的MAC)目标IP地址10.10.10.10(VIP)。通过在RS1上抓包验证这一点
- RS1收到请求目标MAC和IP都是本机(VIP配置在本机的环回口),所以直接交给Nginx处理
- Nginx的返回数据包交给Linux协议栈,系统发现目标地址是172.10.10.10和自己不在同一个网段,则把数据包交给网关——192.168.122.1。在我们的试验中R1是网关,它是可以直接返回数据给客户端的,所以数据被成功返回到客户端。
注意:在操作系统中(无论是Linux或者Windows)返回数据的时候是根据IP地址返回的而不是MAC地址,RS收到数据包MAC地址是Director的而IP地址则是客户端的RS如果按MAC地址返回那么数据包就发送到Director了,很显然是不正确的。而LVS的DR模式正是利用了这一点。
TUN模式
TUN(IP Tunneling,IP通道)是对DR模式的优化。和DR一样,请求数据包经过Director到Real Server返回数据包则是Real Server直接返回客户端。区别是:DR模式要求Director和Real Server在同一个广播域(通过修改目标MAC地址实现数据包转发)而TUN模式则是通过Overlay协议。Overlay协议就是指把一个IP数据包封装在另一个数据包里面,LVS里面的Overlay协议属于比较原始的实现叫IP-in-IP,目前常见的Overlay协议包括:VxLAN、GRE、STT之类的。TUN模式要求
- Director和Real Server必须三层可达,拓扑图中故意加上一个R2用于分割两个广播域;
- Real Server必须可以路由到用户,也就是三层可达(实验的拓扑中Director和Real server共享同一个路由),因为RS的返回数据包是直接返回给用户的不经过Director;
- 因为采用Overlay协议,Real Server的MTU值必须设置为1480(1500-20)——即实际上能发送的数据要加上外层IP头部
TUN模式和DR模式没有本质区别(配置是一摸一样的,只是网络要求不一样),两者都不是特别实用所以本文就不展开介绍了。
总结
LVS的基本原理是利用Linux的netfilter改变数据包的流向以此实现负载均衡。基于性能考虑LVS提供了二种模式,请求和返回数据包都经过Director的NAT模式;请求经过Director返回数据包由Real Server独立返回的是DR和TUN模式(DR和TUN的区别是网络二层可达还是三层可达)。DR和TUN理论上可能性能更高一些,但是这种假设的前提是——性能是出现在数据包转发,而以目前软硬件的架构而言数据转发已经不成问题了。原因有两点:首先Linux引入的NAPI可以平衡网卡中断模式和Polling的性能问题,所以内核本身的转发能力已经不是1998(LVS设计的时间)的情况,一般而言千兆的网络转发是不成问题的;其次大量的“数据平面加速”方案喷涌而出如果真是数据转发的问题我们有智能网卡、DPDK等方案能很好解决。那么比较实用的只剩下NAT模式了,但是LVS的NAT模式有一个很大的缺陷——Real Server的网关是指向Director。
LVS NAT的改进
一般面向外部提供服务的集群环境中网络工程师会给我们一个外部IP,它可能是一个公网IP也可能是躲在防火墙后面的“私网IP”。总之只要我们把这个IP地址配置在某个机器上就能正常对外提供服务了。这种环境中LVS的DR模式、TUN模式显的都比较繁琐(需要满足一定网络条件),所以NAT模式是最合适的,但是LVS中的NAT要求Real Server必须把网关指向Director,这就意味着Real Server之前可以三层可达的网络现在全部不行了(比如之前可以通过网关上网,现在则不行了)回忆一下问题:当Director发送数据包的时候源地址是客户端IP地址,所以Real Server会把返回数据发送给网关,如果不把Director设置为Real Server的网关那么返回数据就“丢”了。改进方法也呼之欲出了,让Director发送数据包的时候使用DIP而不是客户端的IP地址就可以了。按道理说通过LVS+SNAT可以实现,遗憾的是LVS和Iptables是不兼容的,LVS内部处理完数据包后Iptables会忽略这个数据包,所以解决办法只剩下两个:
- 在用户空间实现一个反向代理,比如Nginx,并且VIP和DIP配置一样;
- 修改LVS代码重新编译内核
第一种方法操作非常简单,在Director上安装一个反向代理,LVS配置的VIP和DIP保持一致就可以了,比如:
ipvsadm -A -t 192.168.122.100:80 -s rripvsadm -a -t 192.168.122.100:80 -r 192.168.122.101 -m -w 1 ipvsadm -a -t 192.168.122.100:80 -r 192.168.122.102 -m -w 1
第二种方法就是阿里后来贡献的FullNat模式。
两个疑问
- 为啥LVS不直接做彻底的NAT而直接使用客户端IP地址呢?改进后的NAT怎么规避这个问题?
这是由于LVS追求的是透明,试想Real Server如何拿到客户端的IP地址?改进后的NAT Real Server只能看到Director的IP地址,客户端的IP地址通过“额外途径”发送。反向代理方案中直接通过应用层的头部(比如HTTP的 x-forwarded-for);FullNAT方案中则通过TCP的Option带到Real Server。
- Linux内核为什么不吸纳FullNAT模式?
是的,FullNAT配置简单速度也不慢所以是非常好的选择。Linux Kernel没有把它合并到内核代码的原因是认为:FullNAT本质上是LVS+SNAT,当我们提到SNAT的时候其实就是在说“用户空间”它不应该属于内核。这是Linux的一大基本原则。https://www.mail-archive.com/[email protected]/msg06046.html 这里你可以看到撕逼过程。
Iptables
前提基础:**
当主机收到一个数据包后,数据包先在内核空间中处理,若发现目的地址是自身,则传到用户空间中交给对应的应用程序处理,若发现目的不是自身,则会将包丢弃或进行转发。
iptables实现防火墙功能的原理是:在数据包经过内核的过程中有五处关键地方,分别是PREROUTING、INPUT、OUTPUT、FORWARD、POSTROUTING,称为钩子函数,iptables这款用户空间的软件可以在这5处地方写规则,对经过的数据包进行处理,规则一般的定义为“如果数据包头符合这样的条件,就这样处理数据包”。
iptables中定义有5条链,说白了就是上面说的5个钩子函数,因为每个钩子函数中可以定义多条规则,每当数据包到达一个钩子函数时,iptables就会从钩子函数中第一条规则开始检查,看该数据包是否满足规则所定义的条件。如果满足,系统就会根据该条规则所定义的方法处理该数据包;否则iptables将继续检查下一条规则,如果该数据包不符合钩子函数中任一条规则,iptables就会根据该函数预先定义的默认策略来处理数据包
iptables中定义有表,分别表示提供的功能,有filter表(实现包过滤)、nat表(实现网络地址转换)、mangle表(实现包修改)、raw表(实现数据跟踪),这些表具有一定的优先级:raw-->mangle-->nat-->filter
一条链上可定义不同功能的规则,检查数据包时将根据上面的优先级顺序检查
在讲LVS之前要先搞懂vip和loopback的概念和原理
虚拟IP原理
高可用性HA(High Availability)指的是通过尽量缩短因日常维护操作(计划)和突发的系统崩溃(非计划)所导致的停机时间,以提高系统和应用的可用性。HA系统是目前企业防止核心计算机系统因故障停机的最有效手段。
实现HA的方式,一般采用两台机器同时完成一项功能,比如数据库服务器,平常只有一台机器对外提供服务,另一台机器作为热备,当这台机器出现故障时,自动动态切换到另一台热备的机器。
怎么实现故障检测的那?
心跳,采用定时发送一个数据包,如果机器长时间没响应,就认为是发生故障,自动切换到热备的机器上去。
怎么实现自动切换那?
虚IP。何为虚IP那,就是一个未分配给真实主机的IP,也就是说对外提供数据库服务器的主机除了有一个真实IP外还有一个虚IP,使用这两个IP中的 任意一个都可以连接到这台主机,所有项目中数据库链接一项配置的都是这个虚IP,当服务器发生故障无法对外提供服务时,动态将这个虚IP切换到备用主机。
原理:开始我也不明白这是怎么实现的,以为是软件动态改IP地址,其实不是这样,其实现原理主要是靠TCP/IP的ARP协议。因为ip地址只是一个逻辑地址,在以太网中MAC地址才是真正用来进行数据传输的物理地址,每台主机中都有一个ARP高速缓存,存储同一个网络内的IP地址与MAC地址的对应关 系,以太网中的主机发送数据时会先从这个缓存中查询目标IP对应的MAC地址,会向这个MAC地址发送数据。操作系统会自动维护这个缓存。这就是整个实现 的关键。
下边就是我电脑上的arp缓存的内容。
(192.168.1.219) at 00:21:5A:DB:68:E8 [ether] on bond0 (192.168.1.217) at 00:21:5A:DB:68:E8 [ether] on bond0 (192.168.1.218) at 00:21:5A:DB:7F:C2 [ether] on bond0
192.168.1.217、192.168.1.218是两台真实的电脑,
192.168.1.217为对外提供数据库服务的主机。
192.168.1.218为热备的机器。
192.168.1.219为虚IP。
大家注意红字部分,219、218的MAC地址是相同的。
再看看那217宕机后的arp缓存
(192.168.1.219) at 00:21:5A:DB:7F:C2 [ether] on bond0 (192.168.1.217) at 00:21:5A:DB:68:E8 [ether] on bond0 (192.168.1.218) at 00:21:5A:DB:7F:C2 [ether] on bond0
这就是奥妙所在。当218 发现217宕机后会向网络发送一个ARP数据包,告诉所有主机192.168.1.219(虚IP对外提供服务)这个IP对应的MAC地址是00:21:5A:DB:7F:C2,这样所有发送到219的数据包都会发送到mac地址为00:21:5A:DB:7F:C2的机器,
也就是218的机器。
总结一下就是:
我们知道一般的IP地址是和物理网卡绑定的,而VIP相反,是不与实际网卡绑定的的IP地址。当外网的上的一个机器,通过域名访问某公司内网资源时,内网的DNS服务器会把域名解析到一个VIP上。当外网主机经过域名解析得到这个VIP后,就将数据包发往这个VIP。但是在内网中,这个VIP是不与具体的设备相连接的,所以外网发过来的目的地址是VIP的IP数据包,最终会到哪台机器是通过ARP协议来完成的。也就是说这个VIP可以映射到的MAC地址是可以控制的。VIP在内网中被动态的映射到不同的MAC地址上,也就是映射到不同的机器设备上,那么就可以起到负载均衡的效果啦。
Linux回环接口 Loopback
Loopback接口是一个虚拟网络接口,在不同的领域,其含义也大不一样。
1. TCP/IP协议栈中的loopback接口
在TCP/IP中回环设备是一个通过软件实现的虚拟网络接口,它不与任何硬件相关联。loopback接口一般被完整的集成在计算机系统的内部网络框架中。
IP协议中的loopback地址 RFC2606中明确指出了loopback地址的标准域名为localhost。在IPv4中,其对应的IP地址一直是127.0.0.1;理论上,整个127IP段(127.0.0.0~127.255.255.255)的IP地址都为loopback地址,与localhost对应。在IPv6中,localhost对应的IP地址为0:0:0:0:0:0:0:1,一般写作::1。
loopback接口的功能
- 用于网络服务测试,避免由于远程网络接入带来的安全问题; 一般用作client/server类的网络服务的测试,在测试时,client与server运行在同一台主机上,client通过使用loopback地址访问server。最常见的例子就是web服务的测试,一般我们用http://127.0.0.1/或者http://localhost/来访问本地的web服务。
- 测试IP协议栈 我们通过ping loopback地址的方式来测试操作系统中IP协议栈是否正常。
- 在网络中,所有源地址属于loopback地址的数据包将会被丢弃 IP协议规定loopback数据包是不允许在网络中传输的。网络网络接口必须丢弃接收到的loopback数据包。
2. 网络设备中的loopback 在网络设备中,loopback被用来代表某些用于管理目的的虚拟接口,其含义并没有"回环"的意思。
loopback虚拟接口会分配到一个IP地址,但是这个IP地址不会对应到实际的物理接口。网络设备中的loopback地址主要用于管理目的,例如设备发出的报警。网络设备中的应用程序(管理程序)使用loopback地址发送可接收数据流,而不是使用实际物理接口的地址。对外部来说,直接使用loopback地址来查看设备对应的信息(如报警信息),与网卡的物理地址无关。
这里我们也可以把这种地址理解为网络设备提供的某个服务的地址。
(1)网络接口的命名
这里并不存在一定的命名规范,但网络接口名字的定义一般都是要有意义的。例如:
eth0: ethernet的简写,一般用于以太网接口。
wifi0:wifi是无线局域网,因此wifi0一般指无线网络接口。
ath0: Atheros的简写,一般指Atheros芯片所包含的无线网络接口。
lo: local的简写,一般指本地环回接口。
(2)网络接口如何工作
网络接口是用来发送和接受数据包的基本设备。
系统中的所有网络接口组成一个链状结构,应用层程序使用时按名称调用。
每个网络接口在linux系统中对应于一个struct net_device结构体,包含name,mac,mask,mtu…信息。
每个硬件网卡(一个MAC)对应一个网络接口,其工作完全由相应的驱动程序控制。
(3)虚拟网络接口
虚拟网络接口的应用范围非常广泛。最着名的当属“lo”了,基本上每个linux系统都有这个接口。
虚拟网络接口并不真实地从外界接收和发送数据包,而是在系统内部接收和发送数据包,因此虚拟网络接口不需要驱动程序。
虚拟网络接口和真实存在的网络接口在使用上是一致的。
(4)网络接口的创建
硬件网卡的网络接口由驱动程序创建。而虚拟的网络接口由系统创建或通过应用层程序创建。
驱动中创建网络接口的函数是:register_netdev(struct net_device *)或者register_netdevice(struct net_device *)。
这两个函数的区别是:register_netdev(…)会自动生成以”eth”作为打头名称的接口,而register_netdevice(…)需要提前指定接口名称.事实上,register_netdev(…)也是通过调用register_netdevice(…)实现的。
2、LINUX中的lo(回环接口)
1) 什么是LO接口?
在LINUX系统中,除了网络接口eth0,还可以有别的接口,比如lo(本地环路接口)。
2) LO接口的作用是什么?
假如包是由一个本地进程为另一个本地进程产生的, 它们将通过外出链的’lo’接口,然后返回进入链的’lo’接口.具体参考包过滤器的相关内容。
为什么要把vip绑定在lo上
因为数据帧的MAC地址是选出的服务器,所以服务器肯定可以收到这个数据帧,从中可以获得该IP报文。当服务器发现报文的目标地址VIP是在本地的网络设备上,服务器处理这个报文,然后根据路由表将响应报文直接返回给客户。
收到VIP转发数据帧的,不是lo,而是real server的物理网卡。
物理网卡收到数据帧之后,拆开看到目的地址是VIP
查找路由表,自己的lo上绑着VIP,说明这个包是自己需要处理的,就把这个活接了,产生响应报文
real server返回给客户端的数据帧,源mac是real server物理网卡的mac,里面的源IP地址是VIP
客户端收到数据帧之后,看到目的mac和目的IP都是自己,就会接收。并不会去检查源mac
附:FAQ
1、LVS/DR如何处理请求报文的,会修改IP包内容吗?
vs/dr本身不会关心IP层以上的信息,即使是端口号也是tcp/ip协议栈去判断是否正确,vs/dr本身主要做这么几个事:
接收client的请求,根据你设定的负载均衡算法选取一台realserver的ip; 以选取的这个ip对应的mac地址作为目标mac,然后重新将IP包封装成帧转发给这台RS; 在hashtable中记录连接信息。 vs/dr做的事情很少,也很简单,所以它的效率很高,不比硬件负载均衡设备差多少。
2、RealServer为什么要在lo接口上配置VIP,在出口网卡上配置VIP可以吗?
既然要让RS能够处理目标地址为vip的IP包,首先必须要让RS能接收到这个包。在lo上配置vip能够完成接收包并将结果返回client。
不可以将VIP设置在出口网卡上,否则会响应客户端的arp request,造成client/gateway arp table紊乱,以至于整个loadbalance都不能正常工作。
3、RealServer为什么要抑制arp帧?
这个问题在上一问题中已经作了说明,这里结合实施命令进一步阐述。我们在具体实施部署的时候都会作如下调整:
echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignoreecho "2">/proc/sys/net/ipv4/conf/lo/arp_announceecho "1">/proc/sys/net/ipv4/conf/all/arp_ignoreecho "2">/proc/sys/net/ipv4/conf/all/arp_announce
我相信很多人都不会弄懂它们的作用是什么,只知道一定得有。我这里也不打算拿出来详细讨论,只是作几点说明,就当是补充吧。
第一 echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce 1 2 这两条是可以不用的,因为arp对逻辑接口没有意义。
第二 如果你的RS的外部网络接口是eth0,那么
echo "1">/proc/sys/net/ipv4/conf/all/arp_ignoreecho "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 loadbalancer(director)与RS为什么要在同一网段中?
从第一个问题中大家应该明白vs/dr是如何将请求转发给RS的了吧?它是在数据链路层来实现的,所以director必须和RS在同一网段里面。
5、为什么director上eth0接口除了VIP另外还要配一个ip(即DIP)?
如果是用了keepalived等工具做HA或者LoadBalance,则在健康检查时需要用到DIP, 没有健康检查机制的HA或者Load Balance则没有存在的实际意义.
6、LVS/DR ip_forward需要开启吗?
不需要。因为director跟realserver是同一个网段,无需开启转发。
7、lvs/dr里,director的vip的netmask 没必要设置为255.255.255.255,也不需要再去 route add -host $VIP dev eth0:0,director的vip本来就是要像正常的ip地址一样对外通告的,不要搞得这么特殊。
原文地址:https://www.cnblogs.com/itxiaok/p/10356665.html