三、四层负载均衡LVS
1、LVS简介
1. LVS概述
LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统。本项目在1998年5月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。
LVS作为一个开源的负载均衡项目,目前已经被集成到Linux内核模块中。该项目在Linux内核中实现了基于IP的数据请求负载均衡方案,其体系结构如上图所示,终端互联网用户的Web请求会发送给LVS调度器,调度器根据某种调度算法(比如轮询算法,可以将外部的请求平均分发给后端所有的服务器)决定将该请求发送给哪台真实的Web服务器。真实服务器集群是镜像的,不论哪台都提供相同的服务,这样整个集群对用户来说就是透明的。
根据LVS工作模式的不同,真实服务器会选择不同的方式将用户需要的数据发送到终端用户。LVS工作模式包含三种:NAT模式、DR模式,以及TUN模式。(后面内容会分别说明)
2. LVS与Nginx的区别
LVS负载均衡是四层,客户端和服务器通信时,只是经过LVS负载到后端服务器集群中的某一台,因为是镜像的,所以提供相同的服务。客户端只会和服务器通过三次握手建立Socket连接,进而发送数据进行通信,期间LVS只负责hold住流量并基于数据包进行流量的分发,因此,LVS具有以下特点:
- 用于hold住流量,只要网速够快,就没有上限;
- 特别的快;
- 数据包转发级别;
- 不会和Client端握手;
- 后端服务器是镜像的。
Nginx进行反向代理时对后端服务器的负载均衡是基于七层的,客户端要访问某个服务时,只会和Nginx反向代理服务器进行三次握手建立Socket通信,再由Nginx和后端服务器握手连接,这样客户端的请求才会转发至提供服务的真实服务器。Nginx具有如下特点:
- 用于hold住握手,且拥有负载上限;
- 速度相对较慢;
- 后端服务器不是必须镜像的,可以提供不同的服务,而客户端对于后端服务器是无感知的。
注:Tomcat慢的原因也是因为Tomcat服务器在七层,而且它是Java语言开发的,又需要运行在JVM上。
3. LVS四层负载均衡
首先我们来看一下服务器为什么需要负载均衡:
业务初期,单台服务器即可满足对外提供服务。随着后期的业务不断扩大,流量也越来越大。随着访问量的攀升,服务器所承受的压力进而增大,其性能也将无法满足实际业务需求,一旦超出承受上限就会崩掉。我们一定要避免此类事情发送,就要采取分流的方案,由一变多,即将多台服务器组成集群来提高整体处理性能,使用同一入口(流量调度器)的方式通过均衡的算法对外提供服务,将用户大量的请求均衡地分发到后端集群不同服务器上。这就是通过负载均衡来分担服务器的压力,它能带来诸多好处,诸如提高系统的整体性能、扩展性,和可用性(即HA 高可用)。
如上图所示,即为LVS四层负载均衡的流程:
- 客户端通过Internet互联网去访问服务器,首先需要封装一个源IP地址为CIP、目标IP地址为VIP的数据包;
- 该数据包会经过层次网络路由,最终转发到LVS负载均衡服务器;
- 再由LVS负载均衡调度器,更加某种调度算法(如RR轮询),由DIP将数据包转发至后端某台真实服务器的RIP;
- 最后由该服务器展开数据包,根据对应端口来寻找处理进程,最终再将响应数据回送给客户端。
这里会根据LVS工作模式的不同,真实服务器会选择不同的方式将用户需要的数据发送到终端用户,即下文会分别介绍其过程及原理。
相关语义/语境:
- CIP:客户端的IP地址;
- VIP:负载均衡服务器的虚拟IP地址;
- DIP:负载均衡服务器的转发IP地址;
- RIP:真实服务器的IP地址。
2、三种工作模式
上图中就提及到的LVS的三种工作模式就是前文提到的NAT模式、DR模式,以及TUN模式,下面详细介绍。
1. 基于NAT的LVS负载均衡
NAT(Network Address Translation),是指网络地址转换,1994年提出的。NAT是用于在本地网络中使用私有地址,在连接互联网时转而使用全局IP地址的技术。NAT实际上是为解决IPv4地址短缺而开发的技术。
NAT旨在通过将一个外部IP地址和端口映射到更大的内部IP地址集来转换IP地址。基本上,NAT使用流量表将将流量从一个外部(主机)IP地址和端口号路由到与网络上的终结点关联的正确内部IP地址。
NAT进行IP地址转换分为源IP地址转换S-NAT和目标IP地址转换D-NAT两种模式,下面分别介绍。S-NAT模式是我们日常通过Windows系统电脑上网时的模式,而这里重点要讨论的基于NAT的LVS负载均衡。了解下S-NAT模式,是为了先熟悉一下NAT模式的网络地址转换操作。
S-NAT模式
S-NAT模式就是修改源IP地址的模式,如上图所示:
- 有两台电脑,IP分别为192.168.1.8和192.168.1.6连接在一个路由器上,默认网关为网卡1的IP地址192.168.1.1;
- 路由器的网卡2的IP地址是6.6.6.6,可以通过Internet访问到百度,比如这里百度的IP和端口号为8.8.8.8:80;
- 此时两台电脑都要去访问百度,封装的数据包源包含源IP地址+端口,恰巧都是12121端口,同时走到路由器进行转发;
- 那么对于这个情况,路由要怎么处理,才不会导致两台电脑的数据混淆呢?路由器会生成两个路由条目–自身不同端口映射<->不同电脑的IP+端口,如321映射的就是192.168.1.6:12121;
- 此时经过路由器的S-NAT地址转换就变成了6.6.6.6:321去访问百度;
- 百度收到该数据包,响应数据包再经过路由器的地址转换转发到1.6电脑上。
以上流程中,我们看到通过路由器转发数据后,源IP+端口发生了变化,这就是S-NAT模式。
D-NAT模式
我们再来看D-NAT模式下的负载均衡,如上图所示:
- 客户端要携带自身CIP要去访问服务器,而它并不知道真实服务器的IP地址,只知道负载均衡服务器的IP地址,所以传输数据包中:源IP地址
CIP -> VIP
目标IP地址; - 数据包在负载均衡服务器中进行NAT地址转换,源IP不变,目标IP修改为要转发至某台真实服务器的IP地址,通过DIP转发出去,此时数据包中变为:源IP地址
CIP -> RIP
目标IP地址; - 当真实服务器收到数据,给客户端响应数据时,会再封一个数据包:源IP地址
RIP -> CIP
目标IP地址,发送至负载均衡服务器进行转发; - 在负载均衡服务器中再次进行IP地址转换:
VIP -> CIP
,这样服务器的响应数据就发送到客户端了,完成了一次Socket通信。
在上面的流程中,我们看到是基于D-NAT模式的LVS负载均衡,基于3-4层,每次修改的都是目标IP地址。
D-NAT模式优缺点
优点:
- 负载均衡服务器不必和RS在同一个局域网。
缺点:
- 通信时是非对称的;
- 带宽称为瓶颈;
- 消耗算力;
- 要求真实服务器RS的默认网关GW指向负载均衡服务器。
2. 基于DR的LVS负载均衡
DR模型称为直接路由模型,它是基于2层的,如上图所示:
- 客户端发送的请求数据包同样是:
CIP -> VIP
,先到达负载均衡服务器,进行数据转发; - 此时由于负载均衡服务器和真实服务器RS在同一个局域网,转发数据时直接在数据包外面再包上一层某台RS的MAC地址,转发至RS;
- 由于RS中存在着隐藏VIP(对外隐藏,对内可见),接收到数据包拆开后,发现源IP地址是CIP,响应数据时就不再经过负载均衡服务器,而是直接通过
VIP -> CIP
发送数据至客户端。
基于DR的LVS负载均衡,是基于MAC地址欺骗,可以看到RS在响应Client数据时不必经过负载均衡服务器。这种模式也是现在企业用的最多的一个负载模式。
DR模式的优缺点
优点:
- 速度快,成本低;
缺点:
- 要求LVS负载均衡服务器必须和RS在同一局域网。
3. 基于TUN的LVS负载均衡
基于TUN隧道技术的LVS负载均衡,可以解决前面DR模式要求负载均衡服务器必须和RS在同一局域网的弊端。TUN采取的方案是封装好一个DIP -> RIP
的数据包,携带着客户端发送的数据包CIP -> VIP
,通过调度算法转发至某一台RS。平时的VPN和翻墙,就是基于TUN隧道技术。
3、LVS负载均衡调度算法(十种调度算法)
常用的调度算法分为静态调度和动态调度两种(这里暂只介绍轮询调度):
1. 静态调度算法
- RR:轮询调度(Round Robin)算法就是按依次循环的方式将请求调度到不同的服务器上,该算法最大的特点就是实现简单。轮询算法假设所有的服务器处理请求的能力都是一样的调度器会将所有的请求平均分配给每个真实服务器;
- WRR:加权轮询(Weight Round Robin);
- DH:目标地址散列调度(Destination Hashing);
- SH:源地址散列调度(Source Hashing);
2. 动态调度算法
- LC:最少连接调度(Lease Connections);
- WLC:加权最少连接调度(Weight Lease Connections);
- SED:最短期望延迟调度(Shortest Expected Delay);
- NQ:最少队列调度(Never Queue)算法,无需队列;
- LBLC:基于本地的最少连接(Locality-Based Least Connections );
- LBLCR:基于本地的带复制功能的最少连接(Locality-Based Lease Connections with Replication)。
4、LVS负载均衡案例
本案例会基于DR模式手动搭建一个LVS负载均衡服务器:
- 案例中采用三台Linux虚拟机来进行搭建(在VMWare中创建3台虚拟机),它们默认网关GW为192.168.150.2,在本地Windows电脑中为VMWare分配了一个相同网段的IP地址192.168.150.1,即本地Windows电脑一个网关GW,本地电脑浏览器可以通过它们和3台虚拟机进行Socket通信;
- 将LVS搭建在node01上,其VIP为192.168.150.100,是对外可见的;
- 在node02和node03上部署相同的服务,并且设置VIP同样为192.168.150.100,对外隐藏,对内可见;
- 实现的效果是浏览器通过HTTP协议请求192.168.150.100:80,经过LVS负载均衡的调度(比如RR轮询)将请求分发给node02或node03虚拟机,访问到其中的httpd:80服务,并响应数据给客户端的浏览器。
案例具体搭建及细节,下文分别说明。
1. 修改Linux内核,设置隐藏VIP
要在Linux中设置隐藏VIP,首先要修改其内核Kernel的两个参数,即调整其网卡的响应级别和通告级别,响应参数及配置说明如下:
隐藏VIP方法:对外隐藏,对内可见 :
kernel parameter:
目标mac地址为全F,交换机触发广播
/proc/sys/net/ipv4/conf/*IF*/
arp_ignore: 定义接收到ARP请求时的响应级别;
0:只要本地配置的有相应地址,就给予响应;
1:仅在请求的目标(MAC)地址配置请求
到达的接口上的时候,才给予响应;
arp_announce:定义将自己地址向外通告时的通告级别;
0:将本地任何接口上的任何地址向外通告;
1:试图仅向目标网络通告与其网络匹配的地址;
2:仅向与本地接口上地址匹配的网络进行通告;
这里要介绍一个知识点:LO 环回接口:
- 环回接口习惯上被称为loopback接口,是路由器上的一个逻辑、虚拟接口;
- 可以根据需要创建任何数目的环回接口;
- 环回接口由于独占一个IP地址,子网掩码一般建议设置为255.255.255.255。
在Linux系统存在一块LO虚拟网卡,即环回接口,是内核级的,接口不可能与外界连通。我们可以创建它的子接口,可以配置多个IP,达到隐藏VIP的目的。
2. LVS-IPVS内核
Linux是自带LVS-IPVS内核模块的,可以用来管理集群服务,需要用到的命令如下:
一、ipvs内核模块
yum install ipvsadm -y
二、管理集群服务
添加:-A -t|u|f service-address [-s scheduler]
-t: TCP协议的集群
-u: UDP协议的集群
service-address: IP:PORT
-f: FWM: 防火墙标记
service-address: Mark Number
修改:-E
删除:-D -t|u|f service-address
ipvsadm -A -t 192.168.9.100:80 -s rr
三、管理集群服务中的RS
添加:-a -t|u|f service-address -r server-address [-g|i|m] [-w weight]
-t|u|f service-address:事先定义好的某集群服务
-r server-address: 某RS的地址,在NAT模型中,可使用IP:PORT实现端口映射;
[-g|i|m]: LVS类型
-g: DR
-i: TUN
-m: NAT
[-w weight]: 定义服务器权重
修改:-e
删除:-d -t|u|f service-address -r server-address
# ipvsadm -a -t 172.16.100.1:80 -r 192.168.10.8 –g
# ipvsadm -a -t 172.16.100.1:80 -r 192.168.10.9 -g
查看
-L|l
-n: 数字格式显示主机地址和端口
--stats:统计数据
--rate: 速率
--timeout: 显示tcp、tcpfin和udp的会话超时时长
-:c 显示当前的ipvs连接状况
删除所有集群服务
-C:清空ipvs规则
保存规则
-S
# ipvsadm -S > /path/to/somefile
载入此前的规则:
-R
# ipvsadm -R < /path/form/somefile
3. 搭建过程
LVS:Linux Virtual Service ,即Linux虚拟机服务,
一个在高并发下的负载均衡技术
LVS:
node01:
ifconfig eth0:8 192.168.150.100/24
node02~03:
1) 修改内核
echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
2) 设置隐藏的 VIP:
ifconfig lo:3 192.168.150.100 netmask 255.255.255.255
RS中的服务:
node02~03:
yum install httpd -y
service httpd start
vi /var/www/html/index.html
from 192.168.150.1x (这是html中配置内容,对于2台服务器IP地址,如 150.12~150.13)
LVS服务配置
node01:
yum install ipvsadm -y
ipvsadm -A -t 192.168.150.100:80 -s rr (先添加进来的数据包的规则,即入口规则。 -A:规则,-t:TCP协议,-s:scheduler scheduling-method 指定调度算法 ,rr:轮询)
ipvsadm -a -t 192.168.150.100:80 -r 192.168.150.12 -g -w 1 (-a:基于进来的规则,数据包向哪负载,-r:Real Serve地址,-g:轮询,-w 1:权重给1)
ipvsadm -a -t 192.168.150.100:80 -r 192.168.150.13 -g -w 1 (这几个配置即时生效)
ipvsadm -ln (查看已配置规则)
验证:
浏览器访问 192.168.150.100 看到负载 疯狂F5
node01:
netstat -natp 结论:看不到Socket连接
node02~03:
netstat -natp 结论:看到很多的Socket连接
ipvsadm -lnc 查看偷窥记录本(数据包、等待时间、状态、源地址、访问规则、负载到哪里)
涉及到排错:
TCP 00:57 FIN_WAIT 192.168.150.1:51587 192.168.150.100:80
FIN_WAIT: 连接过,偷窥了所有的包
SYN_RECV: 基本上lvs都记录了,证明lvs没事,一定是网络层出问题了
5、Keepalived高可用方案及实施
上图是为了解决LVS单点故障问题,引出使用Keepalived实现HA高可用的策略:
- 需要准备4台虚拟机,node01~node04,两台作为HA主备机,两台作为RS服务器;
- node01为主机,node04为备机,都作为LVS负载均衡服务器,且都安装Keepalived程序;
- 同样基于DR模型,在其基础上通过Keepalived实现HA高可用方案。
1. LVS存在的问题及解决策略
问题:
- LVS会挂,出现单点故障,导致业务下线;
- 真实服务器RS会挂,此时LVS还存在这个RS的负载记录,导致分发至该服务器的用户请求异常。
解决策略:
-
单点故障的解决方案:一变多,即采用多点方式,主主或主备,我们一般采用主备,主机广播或备机轮询的方式来确定主机是否活着。比如这里LVS负载均衡服务器有两台,一台作为主机对外提供服务,另一台作为备机使用,当主机挂了,就切换至备机提供服务。这里需要使用Keepalived做HA高可用,下面会详细说明;
-
RS挂了的解决方案:检测RS的状态,即验证应用层的HTTP协议,向RS发送请求,判断返回是否是200 OK。当发现RS状态发生问题时,LVS将其从负载中剔除,RS再次上线且状态正常后,再加入负载即可。这里也会用到Keepalived,下面一起说明。
注:这里着重说明一下,不能采用ping的命令去检测RS是否有问题,因为应用在七层,而IP是在4层,ping不同可能是因为网络不通导致访问不到RS,而确定不了是否RS出现了问题。
2. Keepalived介绍
介绍:
- Keepalived是一个应用程序;
- 是一个通用的工具,作为HA高可用实现;
- 可以解决单点故障问题,实现HA。
作用:
- 监控自己服务;
- Master通告自己还活着,Backup监听Master状态。Master挂了,一堆Backup推举出一个新的Master;
- 配置VIP,添加IPVS,Keepalived有自己的配置文件;
- 对后端RS做健康检查;
- Keepalived是一个通用的工具,主要作为HA实现:Nginx可以作为公司的负载均衡来使用,其单点故障问题也可以用Keepalived来解决。
弊端:
- Keepalived异常退出时,可能会出现两台主机,访问时,可能会造成数据包混乱。
3. 搭建过程
高可用:
Keepalived实验:
主机: node01~04
node01:
ipvsadm -C
ifconfig eth0:8 down
---------------------------------------------------------------------------------
node01, node04:
yum install keepalived ipvsadm -y
配置:
cd /etc/keepalived/keepalived.conf
cp keepalived.conf keepalived.conf.bak
vi keepalived.conf
node01: //node04:只修改如下2项
vrrp: 虚拟路由冗余协议!
vrrp_instance VI-1 {
state MASTER //node04 BACKUP
interface_eth0 (设置从哪个网卡传输信号)
virtual_router_id 51
priority 100 //node04 50
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress { (即 VIP,包括eth0传输信号,数据走eth0:3)
192.168.150.100/24 dev eth0 label eth0:3
}
}
virtual_server 192.168.150.12 80 {
delay_loop 6
lb_algo rr
lb_kind DR (由原来的NAT,修改为DR)
nat_mask 255.255.255.0
persistence_timeout 0 (实验环境由原来50改为0,实际生产中按需修改)
protocol TCP (以上这部分相当于ipvsadm -A 配置)
real_server 192.168.150.12 80 { (这以下对应 ipvsadm -a 配置)
weight 1
HTTP_GET { (由原来的SSL_GET修改为HTTP_GET)
url {
path /
status_code 200 (删除原来内容,改为返回200)
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
real_server 192.168.150.13 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
// 将 node01 上配置文件远程拷贝至 node04
scp ./keepalived.conf root@node04:`pwd`
可能会报错,找不到scp命令:yum install openssh-clients,在传输复制的2台都安装
// 输入 node04 的密码
// 配置完毕,启动
[root@node01 keepalived]# service keepalived start
4. Linux中vi相关命令
1、上述操作涉及命令:
ifconfig eth0:2 down 删掉配置的虚拟网卡
2、vi 相关命令:
O :向上开一行
dG :删除后面的所有
光标移到要改的位置 r 3 会把原来的字符改成 3
把光标定位到 real_server 上,在“:” 输入 .,$-1y,复制完成,走到下面位置,按 p 粘贴
(上面 $ 代表最后一行)
3、Linu 中帮助文档,可以学习Linux相关命令和如何配置文件:
yum install man
帮助命令可以查看命令的帮助,也可以查看配置文件的帮助
如:帮助文件是第 5 类:
man 5 keepalived.conf (文件名,即显示这个文件有哪些配置,怎么去写)
之后按“/”输入内容,进行查找,如“/virtual_ipaddress”,回车