一. 负载均衡简介。
负载均衡(Load Balance),意思是将负载(工作任务,访问请求)进行平衡、分摊到多个操作单元(服务器,组件)上进行执行。是解决高性能,单点故障(高可用),扩展性(水平伸缩)的终极解决方案
二.负载均衡的需求
负载均衡集群提供一种廉价、有效、透明的方法,来扩展网络设备和服务器的宽带、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。
1) 把单台计算机无法承受的大规模的并发或者数据流量分担到多台节点设备上处理,减少用户等待的时间,提升用户的体验。
2) 单个重负载的运算分担到多台节点设备上做并行处理。每个节点设备处理结束后,将结果汇总,返回给用户,系统处理能力得到大幅度的提高。
3) 保证7*24的服务,任意一个或者多个有限后面的节点设备宕机都不会影响业务

三. LVS简介

LVS: Linux Virtual Server的缩写,意思是Linux虚拟服务器,是一个虚拟的服务器集群系统,同时也是一个开源的软件,由毕业于国防科技大学的章文嵩博士于1998年5月创立,是中国国内最早出现的自由软件项目之一,可以实现LINUX平台下的简单负载均衡,具有低成本、高性能、高可靠性、高可用性的特点

四. LVS的相关术语的命名约定。
linux笔记web群集之LVS-DR实战

五. LVS负载均衡群集三种工作模式的介绍

LVS的三种工作模式:

1)VS/NAT模式(Network address translation)
2)VS/TUN模式(tunneling)
3)VS/DR模式(Direct routing)

1、NAT模式-网络地址转换
Virtualserver via Network address translation(VS/NAT)
这个是通过网络地址转换的方法来实现调度的。首先调度器(LB)接收到客户的请求数据包时(请求的目的IP为VIP),根据调度算法决定将请求发送给哪个后端的真实服务器(RS)。然后调度就把客户端发送的请求数据包的目标IP地址及端口改成后端真实服务器的IP地址(RIP),这样真实服务器(RS)就能够接收到客户的请求数据包了。真实服务器响应完请求后,查看默认路由(NAT模式下我们需要把RS的默认路由设置为LB服务器。)把响应后的数据包发送给LB,LB再接收到响应包后,把包的源地址改成虚拟地址(VIP)然后发送回给客户端。

调度过程IP包详细图:
linux笔记web群集之LVS-DR实战
原理图简述:
1)客户端请求数据,目标IP为VIP
2)请求数据到达LB服务器,LB根据调度算法将目的地址修改为RIP地址及对应端口(此RIP地址是根据调度算法得出的。)并在连接HASH表中记录下这个连接。
3)数据包从LB服务器到达RS服务器webserver,然后webserver进行响应。Webserver的网关必须是LB,然后将数据返回给LB服务器。
4)收到RS的返回后的数据,根据连接HASH表修改源地址VIP&目标地址CIP,及对应端口80.然后数据就从LB出发到达客户端。
5)客户端收到的就只能看到VIP\DIP信息。

NAT模式优缺点:
1、NAT技术将请求的报文和响应的报文都需要通过LB进行地址改写,因此网站访问量比较大的时候LB负载均衡调度器有比较大的瓶颈,一般要求最多只能10-20台节点
2、只需要在LB上配置一个公网IP地址就可以了。
3、每台内部的节点服务器的网关地址必须是调度器LB的内网地址。
4、NAT模式支持对IP地址和端口进行转换。即用户请求的端口和真实服务器的端口可以不一致。

2、TUN模式
virtual server via ip tunneling模式:采用NAT模式时,由于请求和响应的报文必须通过调度器地址重写,当客户请求越来越多时,调度器处理能力将成为瓶颈。为了解决这个问题,调度器把请求的报文通过IP隧道转发到真实的服务器。真实的服务器将响应处理后的数据直接返回给客户端。这样调度器就只处理请求入站报文,由于一般网络服务应答数据比请求报文大很多,采用VS/TUN模式后,集群系统的最大吞吐量可以提高10倍。
VS/TUN的工作流程图如下所示,它和NAT模式不同的是,它在LB和RS之间的传输不用改写IP地址。而是把客户请求包封装在一个IP tunnel里面,然后发送给RS节点服务器,节点服务器接收到之后解开IP tunnel后,进行响应处理。并且直接把包通过自己的外网地址发送给客户不用经过LB服务器。

Tunnel原理流程图:

linux笔记web群集之LVS-DR实战

原理图过程简述:
1)客户请求数据包,目标地址VIP发送到LB上。
2)LB接收到客户请求包,进行IP Tunnel封装。即在原有的包头加上IP Tunnel的包头。然后发送出去。
3)RS节点服务器根据IP Tunnel包头信息(此时就又一种逻辑上的隐形隧道,只有LB和RS之间懂)收到请求包,然后解开IP Tunnel包头信息,得到客户的请求包并进行响应处理。
4)响应处理完毕之后,RS服务器使用自己的出公网的线路,将这个响应数据包发送给客户端。源IP地址还是VIP地址。(RS节点服务器需要在本地回环接口配置VIP)

3、DR模式(直接路由模式)
Virtual server via direct routing (vs/dr)
DR模式是通过改写请求报文的目标MAC地址,将请求发给真实服务器的,而真实服务器响应后的处理结果直接返回给客户端用户。同TUN模式一样,DR模式可以极大的提高集群系统的伸缩性。而且DR模式没有IP隧道的开销,对集群中的真实服务器也没有必要必须支持IP隧道协议的要求。但是要求调度器LB与真实服务器RS都有一块网卡连接到同一物理网段上,必须在同一个局域网环境。DR模式是互联网使用比较多的一种模式。

DR模式原理图:
linux笔记web群集之LVS-DR实战
DR模式原理过程简述:

VS/DR模式的工作流程图如上图所示,它的连接调度和管理与NAT和TUN中的一样,它的报文转发方法和前两种不同。DR模式将报文直接路由给目标真实服务器。在DR模式中,调度器根据各个真实服务器的负载情况,连接数多少等,动态地选择一台服务器,不修改目标IP地址和目标端口,也不封装IP报文,而是将请求报文的数据帧的目标MAC地址改为真实服务器的MAC地址。然后再将修改的数据帧在服务器组的局域网上发送。因为数据帧的MAC地址是真实服务器的MAC地址,并且又在同一个局域网。那么根据局域网的通讯原理,真实复位是一定能够收到由LB发出的数据包。真实服务器接收到请求数据包的时候,解开IP包头查看到的目标IP是VIP。(此时只有自己的IP符合目标IP才会接收进来,所以我们需要在本地的回环借口上面配置VIP。另:由于网络接口都会进行ARP广播响应,但集群的其他机器都有这个VIP的lo接口,都响应就会冲突。所以我们需要把真实服务器的lo接口的ARP响应关闭掉。)然后真实服务器做成请求响应,之后根据自己的路由信息将这个响应数据包发送回给客户,并且源IP地址还是VIP。

DR模式小结:
1、通过在调度器LB上修改数据包的目的MAC地址实现转发。注意源地址仍然是CIP,目的地址仍然是VIP地址。
2、请求的报文经过调度器,而RS响应处理后的报文无需经过调度器LB,因此并发访问量大时使用效率很高(和NAT模式比)
3、因为DR模式是通过MAC地址改写机制实现转发,因此所有RS节点和调度器LB只能在一个局域网里面
4、RS主机需要绑定VIP地址在LO接口上,并且需要配置ARP抑制。
5、RS节点的默认网关不需要配置成LB,而是直接配置为上级路由的网关,能让RS直接出网就可以。
6、由于DR模式的调度器仅做MAC地址的改写,所以调度器LB就不能改写目标端口,那么RS服务器就得使用和VIP相同的端口提供服务。

官方三种负载均衡技术比较总结表:

linux笔记web群集之LVS-DR实战

六. 关于lvs的调度算法
LVS的调度算法决定了如何在这些节点之间分布工作负荷
当director收到来自客户端计算机访问它vip上的群集服务入站请求时,director必须决定由哪个群集节点来获得请求。
在内核中的连接调度算法上,IPVS已实现了以下八种调度算法:
• 轮叫调度(Round-Robin Scheduling)
• 加权轮叫调度(Weighted Round-Robin Scheduling)
• 最小连接调度(Least-Connection Scheduling)
• 加权最小连接调度(Weighted Least-Connection Scheduling)
• 基于局部性的最少链接(Locality-Based Least Connections Scheduling)
• 带复制的基于局部性最少链接(Locality-Based Least Connections with Replication Scheduling)
• 目标地址散列调度(Destination Hashing Scheduling)
• 源地址散列调度(Source Hashing Scheduling)
具体介绍请参考http://www.linuxvirtualserver.org/zh/lvs4.html#2

七. 手动搭建一个简单的LVS实验

实验环境拓扑图

linux笔记web群集之LVS-DR实战
一. 负载均衡器LVS-36端配置
1.安装lvs软件
我这里选择yum安装,也可以自行在官方下载软件编译安装
[root@RS-36 ~]# yum install lvs –y

安装后把lvs加载到内核模块中
[root@RS-36 ~]# ipvsadm
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
检查是否成功
出现以下信息说明加载成功
[root@RS-36 ~]# lsmod | grep ip_vs
ip_vs_wrr 12697 1
ip_vs 140944 3 ip_vs_wrr
nf_conntrack 105745 1 ip_vs
libcrc32c 12644 2 xfs,ip_vs

2.配置vip地址
查看本机ip
[root@RS-36 ~]# ifconfig
在你的网卡配置一个虚拟ip作为vip,我这里的网卡是ens34,我把ens34也就是与物理机桥接的网卡地址作为vip地址,请根据你的环境按实际情况配置

[root@RS-36 ~]# ifconfig

ens34: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.4.102.36 netmask 255.255.255.0 broadcast 10.4.102.255
inet6 fe80::20c:29ff:fe94:8327 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:94:83:27 txqueuelen 1000 (Ethernet)
RX packets 20634 bytes 2075900 (1.9 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2013 bytes 283161 (276.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 0 (Local Loopback)
RX packets 98 bytes 6876 (6.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 98 bytes 6876 (6.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

3.手动添加LVS服务并添加两台RS服务器(RS-35和RS-37)
[root@RS-36 ~]# ipvsadm –C 清除内核虚拟服务器的所有记录
[root@RS-36 ~]# ipvsadm -L 查看虚拟服务器的记录
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn

可以看到没有任何记录,我们还没有配置

[root@RS-36 ~]# ipvsadm -A -t 10.4.102.36:80 -s rr
[root@RS-36 ~]# ipvsadm -a -t 10.4.102.36:80 -r 10.4.102.35:80 -g -w 1
[root@RS-36 ~]# ipvsadm -a -t 10.4.102.36:80 -r 10.4.102.37:80 -g -w 1

检查配置结果
[root@RS-36 ~]# ipvsadm -L -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.4.102.36:80 rr
-> 10.4.140.35:80 Route 1 0 0
-> 10.4.140.37:80 Route 1 0 0

这样LVS负载均衡端就配置完成了
关于ipvsadm的用法参考如下:

ipvsadm -A|E -t|u|f virutal-service-address:port [-s scheduler] [-p [timeout]] [-M netmask]
ipvsadm -D -t|u|f virtual-service-address
ipvsadm -C
ipvsadm -R
ipvsadm -S [-n]
ipvsadm -a|e -t|u|f virtual-service-address:port -r real-server-address:port
[-g|i|m] [-w weight]
ipvsadm -d -t|u|f virtual-service-address -r real-server-address
ipvsadm -L|l [options]
ipvsadm -Z [-t|u|f virtual-service-address]
ipvsadm --set tcp tcpfin udp
ipvsadm –h
-A --add-service 在内核的虚拟服务器列表中添加一条新的虚拟IP记录。也就是增加一台新的虚拟服务器
-E --edit-service 编辑内核虚拟服务器列表中的一条虚拟服务器记录
-D --delete-service 删除内核虚拟服务器列表中的一条虚拟服务器记录
-C --clear 清除内核虚拟服务器列表中的所有记录
-R --restore 恢复虚拟服务器规则
-S --save 保存虚拟服务器规则,输出为-R 选项可读的格式
-a --add-server 在内核虚拟服务器列表的一条记录里添加一天新的Real Services记录。也就是在一个虚拟服务器中添加一台新的RealServer
-e --edit-server 编辑一条虚拟服务器记录中的某条Real Server记录
-d --delete-server 删除一条虚拟服务器记录中的某条Real Server记录
-L --list 显示内核中虚拟服务器列表
-L --timeout 显示“tcp tcpfin udp”的timeout值,如:ipvsadm -L --timeout
-L --daemon 显示同步守护进程状态,例如:ipvsadm -L –daemon
-L --stats 显示统计信息,例如:ipvsadm -L –stats
-L --rate 显示速率信息,例如:ipvsadm -L --rate
-L --sort 对虚拟服务器和真实服务器排序输出,例如:ipvsadm -L --sort
-Z --zero 虚拟服务器列表计数器清零 清空当前的连接数量
--set tcp tcpfin udp 设置连接超时值
-t 说明虚拟服务器提供的是tcp 服务,此选项后面跟如下格式:
[virtual-service-address:port] or [real-server-ip:port]
-u 说明虚拟服务器提供的是udp 服务,此选项后面跟如下格式:
[virtual-service-address:port] or [real-server-ip:port]
-f fwmark 说明是经过iptables标记过的服务类型
-s 此选项后面跟LVS使用的调度算法
有这样几个选项: rr|wrr|lc|wlc|lblc|lblcr|dh|sh,默认算法是wlc
-p timeout 在某个Real Server上持续的服务时间。也就是说来自同一个用户的多次请求,将被同一个Real Server处理。此参数一般用于有动态请求的操作中,timeout 的默认值为300 秒。例如:-p 600,表示持续服务时间为600秒。
-r 指定Real Server的IP地址,此选项后面跟如下格式:
[real-server-ip:port]
-g --gatewaying 指定LVS的工作模式为直接路由模式DR(此模式是LVS 默认工作模式)
-i -ipip 指定LVS 的工作模式为隧道模式TUN
-m --masquerading 指定LVS 的工作模式为NAT模式
-w --weight weight 指定Real Server的权值
-c --connection 显示LVS目前的连接信息 如:ipvsadm -Lnc

二.Realserver RS-35和RS-37端配置
1.在RS-35和RS-37端安装简单的http服务
[root@RS-35 ~]# yum install httpd –y
[root@RS-37 ~]# yum install httpd –y

安装成功后为了测试方便,更改httpd默认的index文件
[root@RS-35 ~]# echo "35" > /var/www/html/index.html
[root@RS-37 ~]# echo "37" > /var/www/html/index.html

2.在物理机端测试安装httpd是否成功。
出现以下画面说明安装成功
linux笔记web群集之LVS-DR实战
linux笔记web群集之LVS-DR实战

3.手工绑定vip
[root@RS-35 ~]# ifconfig lo 10.4.102.36 netmask 255.255.255.255 up
[root@RS-37 ~]# ifconfig lo 10.4.102.36 netmask 255.255.255.255 up

检查执行结果
[root@RS-35 ~]# ifconfig

eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.4.102.35 netmask 255.255.255.0 broadcast 10.4.102.255
inet6 fe80::20c:29ff:fe11:7528 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:11:75:28 txqueuelen 1000 (Ethernet)
RX packets 25603 bytes 2678861 (2.5 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1938 bytes 204986 (200.1 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 10.4.102.36 netmask 255.255.255.255
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 0 (Local Loopback)
RX packets 7155 bytes 493322 (481.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 7155 bytes 493322 (481.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

[root@RS-37 ~]# ifconfig

eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.4.102.37 netmask 255.255.255.0 broadcast 10.4.102.255
inet6 fe80::20c:29ff:fe3a:345a prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:3a:34:5a txqueuelen 1000 (Ethernet)
RX packets 20218 bytes 1958240 (1.8 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 605 bytes 63965 (62.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 10.4.102.36 netmask 255.255.255.255
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 0 (Local Loopback)
RX packets 2220 bytes 152714 (149.1 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2220 bytes 152714 (149.1 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

4. 抑制lo 环回接口的ARP响应

[root@RS-37 ~]# echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
[root@RS-37 ~]# echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
[root@RS-37 ~]# echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
[root@RS-37 ~]# echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce

[root@RS-35 ~]# echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
[root@RS-35 ~]# echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
[root@RS-35 ~]# echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
[root@RS-35 ~]# echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce

5.在物理机打开浏览器测试是否成功

linux笔记web群集之LVS-DR实战
linux笔记web群集之LVS-DR实战

为了验证实验的准确性,我们检查一下10.4.102.36这台机器是否打开了80端口
[root@centos6 ~]# netstat -lnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:139 0.0.0.0: LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:
LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0: LISTEN
tcp 0 0 0.0.0.0:445 0.0.0.0:
LISTEN
tcp6 0 0 :::139 ::: LISTEN
tcp6 0 0 :::22 :::
LISTEN
tcp6 0 0 ::1:25 ::: LISTEN
tcp6 0 0 :::445 :::
LISTEN

可以看到LVS并没有打开80端口,说明是通过负载均衡分别实现了对两台RS服务器的访问