LVS负载均衡内功心法+外功招式

时间:2022-07-22
本文章向大家介绍LVS负载均衡内功心法+外功招式,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

LVS是Linux Virtual Server的缩写,即Linux虚拟服务器,是由章文嵩博士主导开发的开源负载均衡项目,目前LVS已经被集成到Linuxd内核模块中。章文嵩博士曾任淘宝网技术总监、阿里副总裁、阿里云CTO,2016年任滴滴出行高级副总裁。章博士曾经总结道:做技术不仅要有一份执着和细致的心,还要有一份平静的心态。就拿开源项目来讲,都是免费的,没有收入,收获的是自己的满足感,而非金钱,这时候更需要冷静和平和的心态。把这句话送给我自己,也送给大家。(貌似有点扯远了)

时代背景

21世纪人类进入以网络为中心的信息时代,人们对互联网的使用呈指数级增长,单机模式已经无法满足业务服务高性能、高可用、可伸缩的需求了。

通过高性能网络或局域网互联的服务器集群正成为实现高性能、高可用、可伸缩的有效架构。LVS项目给出了基于IP的数据请求负载均衡调度方案。在LVS集群中,服务器集群对客户端来说是透明的,客户端访问负载均衡服务器,请求会发给LVS调度器,调度器根据设定的算法决定将请求发送给后端某台真实的服务器。后端多台服务器共同实现了集群的高性能,可伸缩性是通过在集群中透明的加入和剔除一个节点来达到,通过监测后端节点、重置系统达到集群的高可用性。

LVS集群的体系结构

LVS集群架构主要由三部分组成:

1.负载调度器:负责客户请求的分发,根据预设的算法选中后端一台真实的服务器上,然后将请求发送到这台真实服务器上。它可以是基于IP负载均衡技术的负载调度器,也可以是基于内容请求分发的负载调度器,或者是两者的结合。

2.服务器池:是一组真正执行客户请求的服务器。

3.后端存储:为服务器池提供一个共享的存储区,这样很容易使得服务器池拥有相同的内容,提供相同的服务。如果不采用共享存储的方式,这就要求每个后端服务器上都要有相同的内容。

LVS术语

1.VS:Virtual Server,虚拟服务器。

2.DS:Director Server,指负载均衡节点。

3.RS:Real Server,后端真实的服务器。

4.VIP:Virtual IP,用户请求的目标IP地址,指LVS上的虚拟IP。

5.RIP:Real Server IP,后端服务器的IP地址。

6.CIP:Client IP,客户端的IP地址。

基于IP的负载均衡技术

VS/NAT

NAT(Network Address Translation)即网络地址转换,其原理是通过对数据报文头(目标地址、源地址和端口等)的修改,使位于企业内部的私有IP可以访问外网,以及外部用户可以访问位于公司内部的私有IP。,该模式下LVS调度器一般配置两块网卡设置不同的IP。当客户通过VIP(Virtual IP Address)访问网络服务时,调度器会根据连接调度算法从后台真实服务器中选出一台,将报文的目标地址VIP改写成选中的服务器的IP地址,报文的目标端口改写成选中的服务器的对应端口,最后将修改后的报文发给选中的服务器。同时,调度器会在连接Hash表记录这个连接,当这个连接的下一个报文到达时,从连接 Hash 表中可以得到原选定服务器的地址和端口,进行同样的改写操作,并将报文传给原选定的服务器。当来自真实服务器的响应报文经过调度器时,调度器将报文的源地址和源端口改为VIP和相应的端口,再把报文发给用户。这样,客户所看到的只是在VIP上提供的服务,而服务器集群的结构对用户是透明的。

举个例子:

1.第一步用户通过对外提供的VIP(126.124.1.1:80)访问服务器。这时候请求报文中含有以下源地址、目标地址和端口。

source

202.103.2.1:40124

dest

126.124.1.1:80

2.LVS收到请求后,会根据预设定的算法从后端选出一台真实的服务器。在转发报文之前会把报文中的目标IP和端口修改为被选中的后端真实服务器的IP和端口(假设192.168.94.2被选中),然后将数据包转发给真实服务器。

修改后:

source

202.103.2.1:40124

dest

192.168.94.2:8080

3.后端真实服务器处理完之后将响应报文返回给LVS,此时报文的源地址端口是后端真实服务的IP端口,调度器得到响应报文后会将源地址修改为VIP和调度器对应端口。

修改前:

source

192.168.94.2:8080

dest

202.103.2.1:40124

修改后:

source

126.124.1.1:80

dest

202.103.2.1:40124

这样,客户就认为是从126.124.1.1:80得到的响应,而不知道后端真实服务器的存在。

VS/TUN

在VS/NAT模式下,请求和响应都要通过负载调度器,当真实服务器数量较多时,调度器就会成为整个集群的瓶颈。我们知道,一般情况下请求报文一般要远小于响应报文,所以如果能将请求和响应分开处理,比如LVS只负责请求而响应直接返回给客户,这样就能极大的提高集群的处理效率。

IP隧道(IP tunneling)是将一个IP报文封装在另一个IP报文的技术,这可以使得目标为一个IP地址的数据报文能被封装和转发到另一个IP地址,从而实现将一个目标地址为调度器VIP的数据包封装,通过隧道转发给后端某台真实服务器。后端真实服务器收到报文后,先将报文解封获得原来目标地址为VIP的报文,服务器发现VIP地址被配置在本地的IP隧道设备上,所以就处理这个请求,然后根据路由表将响应报文直接返回给客户。在这里,请求报文的目标地址为VIP,响应报文的源地址也为VIP,所以响应报文不需要作任何修改,可以直接返回给客户而不需要再经过调度器,客户不会知道是哪一台服务器处理的。

VS/DR

DR模式也叫直接路由模式,该模式下LVS依然承担数据入站请求以及根据预设的算法选出合理的真实服务器,最终由后端真实服务器直接将响应包发送给客户。与TUN模式不同的事,直接路由模式要求调度器和后端真实服务器必须在同一个局域网内,VIP地址需要在调度器和后端所有服务器间共享。

在VS/DR模式下,调度器根据各个服务器的负载情况,动态地选择一台服务器,不修改也不封装IP报文,而是将数据帧的MAC地址改为选出服务器的MAC地址,再将修改后的数据帧在与服务器组的局域网上发送。因为数据帧的MAC地址是选出的服务器,所以服务器肯定可以收到这个数据帧,从中可以获得该请求报文。在 VS/DR 中,请求报文的目标地址为VIP,响应报文的源地址也为 VIP,所以响应报文不需要作任何修改,可以直接返回给客户,客户认为得到正常的服务,而不会知道是哪一台服务器处理的。

LVS调度算法

1.轮询调度(RR)

轮叫调度(Round Robin Scheduling)算法就是以轮叫的方式依次将请求调度不同的服务器。轮叫调度算法假设所有服务器处理性能均相同,调度器会将请求平均分到后端真实服务器上。

2.加权轮询调度(WRR)

加权轮询调度(Weighted Round-Robin Scheduling)比RR算法多了一个加权的概念,可以给RS设置权重,权重越高,分发的请求越多。比如服务器A的权重是1,服务器B的权重是2,则服务器B收到的分发请求一般是A的2倍。

3.目标地址散列调度(DH)

目标地址散列调度(Destination Hashing Scheduling)是针对目标IP地址的负载均衡,它会以目标地址为关键字查找一个静态hash表来获得需要的RS。

4.源地址散列调度(SH)

该算法正好与目标地址散列调度算法相反,它根据请求的源 IP 地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器。一般情况下,在一定时间内,同一个IP的请求会发往后端同一台服务器。

5.最小连接调度(LC)

最小连接调度是一种动态调度算法,它通过服务器当前所活跃的连接数来估计服务器的负载情况。比如RS1的连接数比RS2少,那么调度器就会优先把下一个请求发给RS1。

6.加权最小连接调度(WLC)

这个比LC算法多了一个加权的概念,当连接数相近时,权重越大,越优先被分配请求。

7.基于局部性的最少链接(LBLC)

LBLC调度算法先根据请求的目标IP地址找出该目标IP地址最近使用的服务器,若该服务器是可用的且没有超载,将请求发送到该服务器;若服务器不存在,或者该服务器超载且有服务器处于其一半的工作负载,则用“最少链接”的原则选出一个可用的服务器,将请求发送到该服务器。

8.带复制的基于局部性最少链接(LBLCR)

该算法也是针对目标 IP 地址的负载均衡,目前主要用于Cache集群系统,不太常用。

LVS常用命令

1.ipvsadm 参数

-A添加一个虚拟服务,使用IP地址、端口号、协议来定义一个虚拟服务。

-E编辑一个虚拟服务

-D删除一个虚拟服务

-C情况虚拟服务

-R从标准输入还原虚拟服务

-S保存虚拟服务规则至标准输出,输出的规则可以用-R还原

-a在虚拟服务中增加一个real server

-e在虚拟服务中编辑一台real server

-d在虚拟服务中删除一台real server

-L显示虚拟服务列表

-t使用TCP协议,该参数后需要跟主机和端口信息

-u使用UDP协议,该参数后需要跟主机和端口信息

-s指定lvs需要使用的调度算法

-r设置真实服务器的IP地址和端口

-g设置LVS工作模式为DR模式

-i设置LVS工作模式为TUN模式

-m设置LVS工作模式为NAT模式

-w设置指定服务器的权重

-c显示连接状态,一般配合-L使用

-n数字格式输出,IP和端口信息会以数字格式输出

2.添加一个虚拟服务,设置调度算法为轮询算法,将发送到207.175.44.110:80端口的传入请求分配给后端3台真实的服务器的80端口上,本例中采用NAT模式。

ipvsadm -A -t 207.175.44.110:80 -s rr
ipvsadm -a -t 207.175.44.110:80 -r 192.168.10.1:80 -m
ipvsadm -a -t 207.175.44.110:80 -r 192.168.10.2:80 -m
ipvsadm -a -t 207.175.44.110:80 -r 192.168.10.3:80 -m

3.删除后端一台真实服务器192.168.10.1:80

ipvsadm –d –t 207.175.44.110:80 –r 192.168.10.1:80

4.编辑虚拟服务器的调度算法为加权轮询

ipvsadm –E –t 207.175.44.110:80 –s wrr

5.虚拟服务规则表的备份和还原

ipvsadm –Sn >/tmp/ipvs.bak #备份
ipvsadm –C #情况规则表
ipvsadm –R </tmp/ipvs.bak #还原规则表

6.查看IPVS调度状态

ipvsadm –Lnc

7.查看LVS规则

ipvsadm -Ln

LVS的黄金搭档-keepalived

keepalived顾名思义,保持存活,它是为Linux系统提供简单高效的负载均衡及高可用的解决方案。它通过VRRP(Virtual Router Redundancy Protocol)协议实现高可用架构。VRRP协议是为了在静态路由环境下防止单点故障而设计的主从灾备协议,它可以实现在一个集群环境中,当主机发生故障时,能将业务自动切换到备机。VRRP将多台设备虚拟成一个设备集群,对外只提供一个虚拟的IP,正常情况下,只有一个设备可以拥有这个IP,主设备会不断发送自己的状态给备机,当备机发现主机不可达时,会根据优先级选举出新的主机。

Keepalived主要配置文件是/etc/keepalived/keepalived.conf,配置文件主要分为全局配置、VRRP配置块、LVS配置块,具体核心参数解释如下:

实战操作

1.环境准备(redhat 6.9)

1) 关闭selinux:

vi /etc/selinux/config#把SELINUX=enforce   改成disabled

2) 关闭防火墙(NAT负载模式需要根据业务需求配置iptables,DR模式需要直接关掉)

chkconfig --level 2345 iptables off
chkconfig --level 2345 ip6tables off
iptables -F
service iptables stop

2.配置本地yum源(如果已有yum源,该步骤请忽略)

1) 挂载光盘

mkdir /mnt/media
mount -o loop /dev/cdrom  /mnt/media
#如果是光驱的话mount -t iso9660 /dev/sr0 /mnt/media

2) 新建本地yum源的配置文件

vi /etc/yum.repos.d/local.repo
#加入以下信息:
[Local]
name=Local
baseurl=file:///mnt/media
enable=1
gpgcheck=0
#/mnt/media根据实际挂载路径配置

3)清理yum

yum clean all

3.安装部署ipvs管理工具ipvsadm

1) 确保Linux的kernel支持ipvs算法,检查内核是否支持

modprobe -l|grep ipvs

2) 使用rpm包安装

yum install ipvsadm*
#建议用yum安装,rpm需要制定全路径
rpm -ivh ipvsadm-1.24-13.el6.x86_64.rpm

3) 激活IPVS内核模块

modprobes ip_vs

4) 检查ipvsadm是否完整安装( modprob ip_vs装载)

lsmod|grep ip_vs
#检查结果:  
ip_vs                 125694  0
libcrc32c               1246  1 ip_vs
ipv6  

4.高可用介质keepalived安装(采用编译安装的方式,也可直接安装rpm包)

1) 安装编译工具

yum install make -y

2) 安装编译环境

yum install gcc* -y

3) 安装依赖程序

yum install kernel-devel -y
yum install openssl* -y
yum install popt-devel -y

4) 可以用此命令建立内核链接

ln -s /usr/src/kernels/$(uname -r)/ /usr/src/linux
#uname -r 可显示对应的内核信息

5.安装keepalived软件

1) 解压程序包

tar -zxvf keepalived1.2.2.tar.gz

2) 配置编译环境

cd keepalived-1.2.2
./configure
configure后要注意
keepalived configuration
------------------------
Keepalived version       : 1.2.2
Compiler                 : gcc
Compiler flags           : -g -O2
Extra Lib                : -lpopt -lssl -lcrypto
Use IPVS Framework       : Yes(必须是yes)
IPVS sync daemon support : Yes(必须是yes)
IPVS use libnl           : No(可以不是yes)
Use VRRP Framework       : Yes(必须是yes)
Use Debug flags          : No

注意上面的kernel的链接,如果没有做链接,很可能导致

Use IPVS Framework : Yes(必须是yes)

IPVS sync daemon support : Yes(必须是yes)

这两个地方是NO

3) 编译安装

make && make install

6.配置HA为系统服务,并设置开机启动

cp /usr/local/etc/rc.d/init.d/keepalived /etc/init.d/
cp /usr/local/etc/sysconfig/keepalived /etc/sysconfig/
cp /usr/local/sbin/keepalived /usr/sbin/
chkconfig --add keepalived
chkconfig --level 2345 keepalived on
chkconfig --level 2345 ipvsadm on

7.修改keepalived配置文件,具体配置需要根据业务场景定制,示例可参考上一章节《LVS

的黄金搭档-keepalived》中的配图,本例采用DR模式。

修改完配置文件后启动keepalived,启停命令如下:

停止:service keepalived stop启动:service keepalived start

8.在LVS(DR)模式下,所有的真实服务器都配置了VIP地址,因此需要设置服务器不进行针对VIP地址的ARP广播,linux中可以直接通过arp_ignore和arp_announce两个参数来实现。

arp_ignore:

0:代表任何网络接口接到ARP请求后,如果本机的任意接口有该IP,则予以响应。

1:某个网络接口收到ARP请求后,判断请求的IP是否在本接口,是则回应,否则不回应。LVS调度器会把客户请求发给真实服务器的某个本机接口(比如eth0)而真实服务器的VIP地址会配置在回环网卡上。

arp_announce:

0:任何网络接口接收到ARP请求后,如果本机上任何接口有该IP,则给予响应。

1:尽量避免响应MAC地址非本网络接口IP地址的ARP请求。

2:不响应MAC地址非本网络接口IP地址的ARP请求。

具体脚本如下:

#!/bin/bash
VIP=152.2.4.26
. /etc/rc.d/init.d/functions
case "$1" in
start)
        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
        ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up
        /sbin/route add -host $VIP dev lo:0  
        sysctl -p > /dev/null 2>&1
        echo "realserver start OK"
        ;;
stop)
        echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
        echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
        echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
        echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
        ifconfig lo:0 down
        /sbin/route del $VIP > /dev/null 2>&1          
        echo "realserver stoped"
        ;;
status)
        # Status of LVS-DR real server.
        islothere=`/sbin/ifconfig lo:0 | grep $VIP`
        isrothere=`netstat -rn | grep "lo:0" | grep $VIP`
        if [ ! "$islothere" -o ! "isrothere" ];then
            # Either the route or the lo:0 device not found.
            echo "LVS-DR real server Stopped."
        else
            echo "LVS-DR real server Running."
        fi
;;
*)
        echo "Usage:$0 {start|stop|status}"
        exit 1
esac
exit 0

9.注意事项

现在大多数网卡都具有lro和gro功能,即网卡收包时将同一流的小包合并成大包(tcpdump抓包时可以看到>MTU 1500 bytes的数据包)交给内核协议栈,lvs内核模块在处理>MTU(Maximum Transmission Unit,网络上传输的最大数据包,ifconfig可以查看)的数据包时,会丢弃,如果lvs传输大文件时,容易出现丢包、传输速度慢的现象。

建议关掉lro和gro。

查看网卡属性

ethtool -k eth0

关闭网卡gro和lro功能

/usr/sbin/ethtool -K eth0 gro off/usr/sbin/ethtool -K eth0 lro off