LVS简介
LVS是章文嵩开发的一个国产开源负载均衡软件,中文官网为http://www.linuxvirtualserver.org/zh/index.html 。LVS最初是他在大学期间的玩具,随着后来使用的用户越来越多,LVS也越来越完善,最终集成到了Linux的内核中。其全称是Linux virtual server,即Linux虚拟服务器。之所以是虚拟服务器,是因为LVS自身是个负载均衡器(director),不直接处理请求,而是将请求转发至位于它后端真正的服务器realserver上。
LVS是四层(传输层tcp/udp)、七层(应用层)的负载均衡工具,只不过大众一般都使用它的四层负载均衡功能ipvs,而七层的内容分发负载工具ktcpvs(kernel tcp virtual server)不怎么完善,使用的人并不多。ipvs是集成在内核中的框架,可以通过用户空间的程序ipvsadm工具来管理,该工具可以定义一些规则来管理内核中的ipvs。就像iptables和netfilter的关系一样。
LVS三种模式
首先要解释的是LVS相关的几种IP:
DS:Director Server。指的是前端负载均衡器节点RS:Real Server。后端真实的工作服务器VIP:virtual IP,LVS服务器上接收外网数据包的网卡IP地址。DIP:director IP,LVS服务器上转发数据包到realserver的网卡IP地址。RIP:realserver(常简称为RS)上接收Director转发数据包的IP,即提供服务的服务器IP。CIP:客户端的IP。
LVS的三种工作模式:通过网络地址转换(NAT)将一组服务器构成一个高性能的、高可用的虚拟服务器,是VS/NAT技术。在分析VS/NAT的缺点和网络服务的非对称性的基础上,提出了通过IP隧道实现虚拟服务器的方法VS/TUN(Virtual Server via IP Tunneling),和通过直接路由实现虚拟服务器的方法VS/DR(Virtual Server via Direct Routing),它们可以极大地提高系统的伸缩性。
LVS NAT模式
用户请求LVS到达director,director将请求的报文的目的IP改为RIP,同时将报文的目标端口也改为realserver的相应端口,最后将报文发送到realserver上,realserver将数据返回给director,director再把数据发送给用户。

(1). 当用户请求到达 Director Server,此时请求的数据报文会先到内核空间的 PREROUTING 链。 此时报文的源 IP 为 CIP,目标 IP 为 VIP
(2). PREROUTING 检查发现数据包的目标 IP 是本机,将数据包送至 INPUT 链
(3). IPVS 比对数据包请求的服务是否为集群服务,若是,修改数据包的目标 IP 地址为后端服务器 IP,然后将数据包发至 POSTROUTING 链。 此时报文的源 IP 为 CIP,目标 IP 为 RIP
(4). POSTROUTING 链通过选路,将数据包发送给 Real Server
(5). Real Server 比对发现目标为自己的 IP,开始构建响应报文发回给 Director Server。 此时报文的源 IP 为 RIP,目标 IP 为 CIP
(6). Director Server 在响应客户端前,此时会将源 IP 地址修改为自己的 VIP 地址,然后响应给客户端。 此时报文的源 IP 为 VIP,目标 IP 为 CIP
LVS NAT特性:
- NAT模式修改的是目的ip,直接走的是switch不需要修改mac地址,所以VIP和RIP不需要在同一个网段内
- NAT的包的进出都需要经过LVS,所以LVS可能会成为一个系统的瓶颈问题
LVS TUN原理
用户请求LVS到达director,director通过IP-TUN加密技术将请求报文的包封装到一个新的IP包里面,目的IP为VIP(不变),然后director将报文发送到realserver,realserver基于IP-TUN解密,然后解析出来包的目的为VIP,检测网卡是否绑定了VIP,绑定了就处理这个包,如果在同一个网段,将请求直接返回给用户,否则通过网关返回给用户;如果没有绑定VIP就直接丢掉这个包。

交互过程:
(1) 当用户请求到达 Director Server,此时请求的数据报文会先到内核空间的 PREROUTING 链。 此时报文的源 IP 为 CIP,目标 IP 为 VIP 。
(2) PREROUTING 检查发现数据包的目标 IP 是本机,将数据包送至 INPUT 链
(3) IPVS 比对数据包请求的服务是否为集群服务,若是,在请求报文的首部再次封装一层 IP 报文,封装源 IP 为 DIP,目标 IP 为 RIP。然后发至 POSTROUTING 链。 此时源 IP 为 DIP,目标 IP 为 RIP
(4) POSTROUTING 链根据最新封装的 IP 报文,将数据包发至 RS(因为在外层封装多了一层 IP 首部,所以可以理解为此时通过隧道传输)。 此时源 IP 为 DIP,目标 IP 为 RIP
(5) RS 接收到报文后发现是自己的 IP 地址,就将报文接收下来,拆除掉最外层的 IP 后,会发现里面还有一层 IP 首部,而且目标是自己的 lo 接口 VIP,那么此时 RS 开始处理此请求,处理完成之后,通过 lo 接口送给 eth0 网卡,然后向外传递。 此时的源 IP 地址为 VIP,目标 IP 为 CIP
(6) 响应报文最终送达至客户端
LVS TUN特性:
- TUNNEL必须在所有的realserver上绑定VIP
- realserver直接把包发给client
- 隧道模式运维起来会比较难,所以一般不用
LVS DR模式
用户请求LVS到达director,director将请求的报文的目的MAC地址改为后端的realserver的MAC地址,目的IP为VIP(不变),源IP为client IP地址(不变),然后director将报文发送到realserver,realserver检测到目的地址为自己本地的VIP,如果在同一网段,将请求直接返回给用户,如果用户跟realserver不在同一个网段,则需要通过网关返回给用户。

LVS DR特性:
- 前端路由将目标地址为VIP报文统统发给Director Server
- RS跟Director Server必须有一个网卡在同一个物理网络中
- 所有的请求报文经由Director Server,但响应报文必须不能进过Director Server
- 所有的real server机器上都有VIP地址
三种模式比较
- 是否需要VIP和realserver在同一网段:DR模式因为只修改包的MAC地址,需要通过ARP广播找到realserver,所以VIP和realserver必须在同一个网段,也就是说DR模式需要先确认这个IP是否只能挂在这个LVS下面;其他模式因为都会修改目的地址为realserver的IP地址,所以不需要在同一个网段内。
- 是否需要在realserver上绑定VIP:realserver在收到包之后会判断目的地址是否是自己的IP。DR模式的目的地址没有修改,还是VIP,所以需要在realserver上绑定VIP;IP TUN模式值是对包重新包装了一层,realserver解析后的包的IP仍然是VIP,所以也需要在realserver上绑定VIP
- 四种模式的性能比较:DR模式、IP TUN模式都是在包进入的时候经过LVS,在包返回的时候直接返回给client;所以二者的性能比NAT高,但TUN模式更加复杂,所以性能不如DR,性能比较:DR>TUN>NAT
LVS负载均衡十种算法
- 轮叫调度 rr
均等地对待每一台服务器,不管服务器上的实际连接数和系统负载 - 加权轮叫 wrr
调度器可以自动问询真实服务器的负载情况,并动态调整权值 - 最少链接 lc
动态地将网络请求调度到已建立的连接数最少的服务器上
如果集群真实的服务器具有相近的系统性能,采用该算法可以较好的实现负载均衡 - 加权最少链接 wlc
调度器可以自动问询真实服务器的负载情况,并动态调整权值
带权重的谁不干活就给谁分配,机器配置好的权重高 - 基于局部性的最少连接调度算法 lblc
这个算法是请求数据包的目标 IP 地址的一种调度算法,该算法先根据请求的目标 IP 地址寻找最近的该目标 IP 地址所有使用的服务器,如果这台服务器依然可用,并且有能力处理该请求,调度器会尽量选择相同的服务器,否则会继续选择其它可行的服务器 - 复杂的基于局部性最少的连接算法 lblcr
记录的不是要给目标 IP 与一台服务器之间的连接记录,它会维护一个目标 IP 到一组服务器之间的映射关系,防止单点服务器负载过高。 - 目标地址散列调度算法 dh
该算法是根据目标 IP 地址通过散列函数将目标 IP 与服务器建立映射关系,出现服务器不可用或负载过高的情况下,发往该目标 IP 的请求会固定发给该服务器。 - 源地址散列调度算法 sh
与目标地址散列调度算法类似,但它是根据源地址散列算法进行静态分配固定的服务器资源。 - 最少期望延迟 sed
不考虑非活动链接,谁的权重大,优先选择权重大的服务器来接收请求,但权重大的机器会比较忙 - 永不排队 nq
无需队列,如果有realserver的连接数为0就直接分配过去
实战篇
ipvsadm命令
ipvsadm的选项中,大写选项管理虚拟服务virtual service,小写选项管理关联了虚拟服务的真实服务器RealServer,”-L”和”-l”除外,它们同义。
管理virtual services
1
2
3
4
5
6
7
8
9
10
11添加:-A -t|u|f service-address [-s scheduler]
-t:tcp协议的集群
-u:udp协议的集群
service-address格式为IP:PORT
-f:firewall-mark防火墙标记
service-address:a num for mark
-s:调度算法
修改:-E -t|u|f service-address [-s scheduler] 和-A使用方法一样
删除:-D -t|u|f service-address
示例:
# ipvsadm -A -t 172.16.10.20:80 -s rr (对外的地址,也就是VIP)管理virtual service中的RealServer,主要是
-g/-i/-m是指定lvs的类型。1
2
3
4
5
6
7
8
9
10
11
12
13添加:-a -t|u|f service-address -r server-address [-g|i|m] [-w weight]
-t|u|f service-address:指定Real server所绑定的virtual service
-r server-address:某RS地址,在NAT模型中,可IP:PORT实现端口映射,即端口无需等于VIP对应的port
-g|i|m:指定lvs的类型,有三种:
-g:gataway即DR类型(默认的模型)
-i:--ipip,即TUN类型
-m:masquerade地址伪装即NAT
-w:指定权重(需要调度算法支持权重)
修改:-e和-a用法一样
删除:-d -t|u|f service-address -r server-address表示从哪个virtual service中删除哪个realserver
示例:
# ipvsadm -a -t 172.16.10.20:80 -r 192.168.100.99 -m
# ipvsadm -a -t 172.16.10.20:80 -r 192.168.100.10 -m其他项
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15-L或者-l:列出状态信息,配合以下选项用于显示更精确数据
-n:只显示数字格式,不反解IP地址和端口
--stats:显示统计信息
--rate:显示速率信息(每秒的值)
--timeout:显示tcp/tcpfin/udp的会话超时时间长度
--daemon:显示进程状态和多播端口(不太用)
--sort:对-n列出来的进行排序(按协议、IP、端口号升序排序)
-c:显示当前ipvs的连接状况(不能和stats选项同用)
-Z:清空统计数据
-C:删除一个或所有virtual service,连同与之绑定的real server也删除
-S:保存规则 ipvsadm -S > /path/to/somefile 或者使用ipvsadm-save > /path/to/somefile
-R:载入规则 ipvsadm -R < /path/to/somefile 或者使用ipvsadm-restore < /path/to/somefile
service ipvsadm save
service ipvsadm restore
nat模式
环境准备:
graph LR
A[client 192.168.1.111]-->|vip 192.168.1.77|B{Diretor}
B-->|DIP 172.16.1.77|C[rip 172.16.1.55]
B-->|DIP 172.16.1.77|D[rip 172.16.1.66]
Diretor上要准备2张网卡,一个是做vip使用,另一个是跟后端通信的DIP。realserver准备2台即可。
realserver配置
安装apache为http服务器
1 | yum -y install httpd |
lvs-server配置
先安装ipvsadm以及开启IP转发
1 | [root@localhost ~]# yum install ipvsadm -y |
然后运行脚本:
1 | [root@localhost ~]# cat lvs_nat.sh |
测试如下:
1 | [root@localhost ~]# curl http://192.168.1.77/ |
注意:lvs-server不能安装docker,可能会有影响。
tun模式
关键点是虚拟IP 192.168.10.10,lvs-server配置如下:
1 | ifconfig tunl0 192.168.10.10 netmask 255.255.255.255 up |
realserver如下:
1 | ifconfig tunl0 192.168.10.10 netmask 255.255.255.255 up |
DR直接路由模式
环境准备:
graph LR
A[client 192.168.1.111]-->B{Diretor vip 192.168.1.88}
B-->C[rip 192.168.1.55]
B-->D[rip 192.168.1.66]
这时vip也做为dip来使用的,此时也需要在RS上面配置这个vip,但是是配置在lo上面的,realserver配置如下:
1 | ip addr add 192.168.1.88/32 dev lo |
在lvs-server上需要配置2个IP,一个是管理IP,一个是vip:
1 | [root@localhost ~]# ip addr add 192.168.1.88/32 dev eth0 label eth0:0 |
再配置ipvs:
1 | [root@localhost ~]# cat lvs_dr.sh |
在另外一台进行测试:
1 | [root@localhost ~]# curl 192.168.1.88 |
我们从抓包上面来看:

首先发了一个arp包,回复192.168.1.88的mac为00:15:5d:af:b3:0a,然后192.168.1.5就发起SYN请求,目的IP为192.168.1.88,目的mac为00:15:5d:af:b3:0a,然后192.168.1.88就回复了SYN+ACK包,这个看到源mac变成了00:15:5d:af:b3:03,说明不是vip这台机器回复的,是RS回复的包。由此可见,DR的最核心的工作原理就是替换MAC。
keepalived+lvs
一般keepalived是跟lvs结合使用的,keepalived实现故障转移的功能是通过VRRP(virtual router redundancy protocol虚拟路由器冗余协议)协议来实现的。 在keepalived正常工作的时候,主节点(master)会不断的发送心跳信息给备节点(backup),当备节点不能在一定时间内收到主节点的心跳信息时,备节点会认为主节点宕了,然后会接管主节点上的资源,并继续向外提供服务保证其可用性。当主节点恢复的时候,备节点会自动让出资源并再次自动成为备节点。
安装keepalived很简单,直接使用yum安装即可。直接复用上例的LVS的DR模式配置。realserver不需要修改。只需要在lvs-server上面安装keepalived(这里要新增一台服务器做Diretor,配置省略),且写入以下配置。相关的配置解释可以参考:https://www.cnblogs.com/f-ck-need-u/p/8483807.html
1 | [root@localhost ~]# cat /etc/keepalived/keepalived.conf |
启动keepalived之后,先查看IP是否存在,再使用ipvsadm查看lvs配置:
1 | [root@localhost ~]# ip -4 -o addr |
keepalived+httpd
keepalived是可以单独使用的,如跟apache结合使用,可以实现主备的高可用,如下配置:
1 | [root@localhost keepalived]# cat keepalived.conf |