Linux LVS集群

Source

Linux LVS集群
    Cluster:
        系统扩展方式:
            scale up:向上扩展,也就是升级硬件,但是成本比较高;
            scale out:向外扩展,也就是当现有的服务器无法承受当前的负载时,通过添加更多的服务器来分担当前的负载;
        集群类型:
            LB:load balance,负载均衡;
            HA:high available,高可用;
            HP:high performancing,高性能;
        衡量一个系统的优劣:
            可扩展性
            可用性
            容量
            性能
            一般容量和性能是成反比的,比如:一台服务器一秒可以响应20个请求,如果想要它响应更多的请求就要增加时间,例如改正两秒30个请求;
        搭建服务器的长期考虑:保证可用 → 标准化 → 自动化;
        构建高可扩展性系统的重要原则:在系统内部尽量避免串行和交互;
        LB集群的实现:
            硬件:
                F5 BIG-IP , Citrix NetScaler , A10 A10等
            软件:
                LVS,haproxy,nginx,ats(apache traffic server)等
                基于工作的协议层次划分:
                    传输层:lvs,haproxy(mode tcp,模拟)
                    应用层:haproxy,nginx,ats等
        LVS:Linux Virtual Server
            LVS服务器可以看成是虚拟的监听(其实是通过分析数据包,从而得到请求包的目标端口)于某个接口的服务器,但是它并不提供这个服务,而是将请求转给后端真正提供这种服务的服务器;也就是根据报文的目标IP和PORT并且根据负载均衡算法将其转发至后端主机集群中的某一台主机;
            netfilter:  
                数据包处理流程:        
                    目的为本机:PREROUTING→ INPUT
                    转发:PREROUTING→ FORWARD→ POSTROUTING
                    本机为发送源:OUTPUT→ POSTROUTING
                lvs依附于netfilter的INPUT链上,工作于内核中TCP/IP协议栈上;
                当请求包到来时,lvs会将欲到达本机的数据包直接拦下,然后转发给POSTROUTING;
                    PREROUTING → INPUT → POSTROUTING
            ipvsadm:在用户空间中,通过调用ipvs的接口,设置各种转发(负载到后端)规则,管理集群服务;
            ipvs:真正工作于内核中的netfilter的INPUT链上的东西;需要在内核中编译安装后才可以使用;
            支持基于TCP,UDP,AH,EST,AH_EST,SCTP等协议进行负载均衡;
            lvs各种术语:
                director|dispatcher|balancer:调度器
                RS,Real Server:后端真正提供服务的服务器
                CIP,Client IP:客户端IP
                VIP,Virtual IP:在director上,接受客户端请求的IP地址,一般同外网接口使用同一块网卡
                DIP,director IP:与后端RS进行通信的IP地址
                RIP,Real server IP:后端RS的IP地址
            lvs的工作模式:
                1.lvs-nat:基于NAT的LVS模式负载均衡(DNAT)
                    NAT(Network Address Translation)即网络地址转换,其作用是通过修改数据报头,使得位于企业内部的私有IP地址可以访问外网,以及外部用用户可以访问位于公司内部的私有IP主机。LVS/NAT工作模式拓扑结构一般是一个director连接多个后端RS,LVS负载调度器可以使用两块网卡配置不同的IP地址,eth0设置为私网IP与内部RS通过交换设备相互连接,eth1设备为外网IP与外部网络联通。
                    第一步,用户通过互联网DNS服务器解析到公司负载均衡设备上面的外网地址,相对于真实服务器而言,LVS外网IP又称VIP(Virtual IP Address),用户通过访问VIP,即可连接后端的真实服务器(Real Server),而这一切对用户而言都是透明的,用户以为自己访问的就是真实服务器,但他并不知道自己访问的VIP仅仅是一个调度器,也不清楚后端的真实服务器到底在哪里、有多少真实服务器。
                    第二步,用户将请求发送至VIP,此时LVS将根据预设的负载均衡算法选择后端的一台真实服务器,将数据请求包转发给真实服务器,并且在转发之前LVS会修改数据包中的目标地址以及目标端口,目标地址与目标端口将被修改为选出的真实服务器IP地址以及相应的端口。
                    第三步,真实的服务器将响应数据包返回给LVS调度器,调度器在得到响应的数据包后会将源地址和源端口修改为VIP及调度器相应的端口,修改完成后,由调度器将响应数据包发送回客户端,另外,由于LVS调度器有一个连接Hash表,该表中会记录连接请求及转发信息,当同一个连接的下一个数据包发送给调度器时,从该Hash表中可以直接找到之前的连接记录,并根据记录信息选出相同的真实服务器及端口信息。
                    1)RS的RIP应该使用私网地址,且RS的网关要指向DIP;
                    2)请求和响应报文都要经由director转发;极高负载场景中调度器可能成为性能瓶颈;
                    3)支持端口映射;
                    4)RS可以使用任意操作系统;
                2.lvs-dr:基于DR的LVS负载均衡
                    DR模式也叫直接路由模式(direct routing),通过修改请求报文的目标MAC地址进行转发,由于所有的数据请求及响应的数据包都需要经过调度器转发,如果后端服务器的数量大于10台,则调度器就会成为整个集群环境的瓶颈.我们知道,数据请求包往往远小于响应数据包的大小.因为响应数据包中包含有客户需要的具体数据,所以lvs-dr的思路就是将请求与响应数据分离,让调度器仅处理数据请求,而让真实服务器响应数据包直接返回给客户端.
                    其体系结构一般是使用一台交换机连接外网的路由器,然后director和RS直接连接到交换机上并且RS服务器还具有公网地址,直接连接到公网路由器上;直接路由模式(DR模式)要求调度器与后端服务器必须在同一个局域网内,VIP地址需要在调度器与后端所有的服务器间共享,因为客户端请求服务时是请求的VIP地址,所以最终的真实服务器给客户端回应数据包时源IP地址必须为VIP地址,目标IP为客户端IP,这样客户端访问的是调度器的VIP地址,回应的源地址也依然是该VIP地址(真实服务器上的VIP),客户端是感觉不到后端服务器存在的.由于多台计算机都设置了同样一个VIP地址,所以在直接路由模式中要求调度器的VIP地址是对外可见的,客户端需要将请求数据包发送到调度器主机,而所有的真实服务器的VIP地址必须配置在Non-ARP的网络设备上,也就是该网络设备并不会向外广播自己的MAC及对应的IP地址,真实服务器的VIP对外界是不可见的,但真实服务器却可以接受目标地址VIP的网络请求,并在回应数据包时将源地址设置为该VIP地址.调度器根据算法在选出真实服务器后,通过ARP协议寻找被选中的RS的MAC地址,然后在不修改数据报文的情况下,将数据帧的MAC地址修改为选出的真实服务器的MAC地址,通过交换机将该数据帧发给真实服务器.整个过程中,真实服务器的VIP不需要对外界可见.
                    1)保证前端路由器将目标IP为VIP的请求报文发送给director;
                        解决方案:
                            静态绑定
                            arptables:可以在RS上设置arptables规则,使之不响应关于IP地址为VIP的RIP请求;
                            修改RS主机内核的参数;
                    2)RS的RIP可以使用私有地址,也可以使用公网地址;
                    3)RS和director必须在同一物理网络中;
                    4)请求报文经由director调度,但响应报文不会经由director;
                    5)不支持端口映射;
                    6)RS可以是大多数操作系统;
                    7)RS的网关不能指向DIP;
                3.lvs-tun:基于TUN的LVS负载均衡
                    在lvs-tun模式的集群环境中,可以使不在同一网络中的director和RS连通,从而使实现就算RS和调度器分别处于大洋彼岸也能够实现数据的交互(RIP与DIP不在同一网段);其中,IP隧道(IP tunning)是一种数据包封装技术,它可以将原始数据包(cip←→ vip)封装并添加新的包头(dip←→rip)(内容包括新的源地址及端口、目标地址及端口),从而实现将一个目标为调度器的VIP地址的数据包封装.通过隧道转发给后端的RS,通过将客户端发往调度器的原始数据包封装,并在其基础上添加新的数据包头(修改目标地址为调度器选择出来的真实服务器的IP地址及对应端口),lvs-tun模式要求真实服务器可以直接与外部网络连接,真实服务器在收到请求数据包后直接给客户端主机响应数据。
                    1)RIP,DIP,VIP全都是公网地址;
                    2)RS的网关不能指向DIP;
                    3)请求报文必须经由director调度,但是响应报文不能经由director;
                    4)不支持端口映射;
                    5)RS的操作系统必须支持隧道功能;    
                4.lvs-fullnat:非标准类型
                    director通过同时修改请求报文的目标地址和源地址进行转发;可以起到隐藏RS地址的目的,提高内网安全性;
                    1)VIP是公网地址,RIP和DIP是私网地址且二者无需在同一网络中;
                    2)RS接收到的请求报文的源地址为DIP,因此要响应给DIP,RS和diretcor无需再共享同一个VIP了;
                    3)请求报文和响应报文都要经由director;
                    4)支持端口映射;
                    5)RS为任意操作系统;
                    Note:想要使用fullnat模式,需要到淘宝开源项目的官方站点上下载相关代码,然后编译进内核;
            http:stateless
                session保持:
                    会话保持是指在负载均衡器上的一种机制,可以识别客户端与服务器之间交互过程的关连性,在作负载均衡的同时还保证一系列相关连的访问请求都会分配到一台机器上。用人话来表述就是:在一次会话过程中发起的多个请求都会落到同一台机器上。
                session绑定:(SH算法)
                    source ip hash : LVS
                        请求经过服务器,请求的ip信息及转发信息被记录到一个表中,继续转发请求
                        下次有请求过来,根据ip信息去找到对应的转发信息,继续转发请求,实现会话保持
                        缺点:当多个客户端通过代理或者地址转换的方式来访问服务器的时候,那么由于来源地址是一样的,那么所有的请求都会被分配到同一台服务器上,这样也会到时服务器之间的负载失衡严重。
                    cookie :nginx等
                        同过给客户端发送cookie来标识客户端,然后根据cookie来关联director的转发方式;
                lvs persistence:lvs的持久连接:
                    对多个共享同一组RS的服务器,进行统一绑定;
                    比如:在购物商城购物,一般情况下,当我们选择商品的时候使用的都是http,但是当我们进行付账结算的操作时,会自动使用https,那么问题就来了,两种服务啊,lvs通过调度算法有概率会将其调度到不同的RS上,这样的话我们结算时的商品就都没了啊,所以这就需要使用lvs持久连接功能来将其始终调度到同一台RS上;它可以实现不管lvs使用什么调度算法,只要在一定时间之内,都会将其调度到同一台RS上;
                    持久连接模板:独立于算法之外的
                        其中保存着:sourceip(客户端来源),rs(被调度的RS),timer(超时计时器);
                        例子:ipvsadm –A –t 192.168.0.7:80 –s rr –p 350
                    持久连接的实现方式:
                        每端口持久:PPC,单服务持久调度;
                            只要是来自同一服务的请求,就调度至同一个RS上;
                        每FWM持久:单防火墙标记持久调度;
                            只要是属于同一个mark的请求,就调度至同一个RS上;可以解决http和https的问题;
                        每客户端持久:PCC,单客户端持久调度;
                            director会将用户的所有请求都识别为集群服务,并向RS进行调度;
                            例子:ipvsadm –A –t 192.168.0.7:0 –s rr -p
                                其中端口号为0则表示将任何服务都定义为需要向后端调度的集群服务;
            lvs scheduler:lvs调度算法
                根据当前的情况(比如后端RS的负载情况等)来选择将请求分发给哪个后端RS;
                静态方法:仅根据算法本身进行调度;
                1.轮询调度
                    轮询调度(Round Robin 简称'RR')算法就是按依次循环的方式将请求调度到不同的服务器上,该算法最大的特点就是实现简单。轮询算法假设所有的服务器处理请求的能力都一样的,调度器会将所有的请求平均分配给每个真实服务器。
                2.加权轮询调度
                    加权轮询(Weight Round Robin 简称'WRR')算法主要是对轮询算法的一种优化与补充,LVS会考虑每台服务器的性能,并给每台服务器添加一个权值,如果服务器A的权值为1,服务器B的权值为2,则调度器调度到服务器B的请求会是服务器A的两倍。权值越高的服务器,处理的请求越多。
                3.目标地址散列调度
                    目标地址散列调度(Destination Hashing 简称'DH')算法先根据请求的目标IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且并未超载,将请求发送到该服务器,否则返回空。不管是谁发出的请求,只要是发往某个特定地址的,就都发送到同一台RS上,可以增加缓存的命中率;
                4.源地址散列调度
                    源地址散列调度(Source Hashing 简称'SH')算法先根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且并未超载,将请求发送到该服务器,否则返回空。它采用的散列函数与目标地址散列调度算法的相同,它的算法流程与目标地址散列调度算法的基本相似。不管是请求什么资源,只要是同一个IP发送来的都将它分发到同一台RS上;(可以用来实现session保持,但是会有损负载均衡的效果)
                动态方法:根据算法以及各RS的当前负载状态进行调度;
                1.最小连接调度:Overhead(当前负载)=Active*256+Inactive(乘以256是因为活动连接占用的资源比较多,所以样做是为了更好的评估负载情况)
                    最小连接调度(Least Connections 简称'LC')算法是把新的连接请求分配到当前连接数最小的服务器。最小连接调度是一种动态的调度算法,它通过服务器当前活跃的连接数来估计服务器的情况。调度器需要记录各个服务器已建立连接的数目,当一个请求被调度到某台服务器,其连接数加1;当连接中断或者超时,其连接数减1。
(集群系统的真实服务器具有相近的系统性能,采用最小连接调度算法可以比较好地均衡负载。)
                2.加权最小连接调度: Overhead=(Active*256+Inactive)/weight,结果小的为被选中的主机;
                    加权最少连接(Weight Least Connections 简称'WLC')算法是最小连接调度的超集,各个服务器相应的权值表示其处理性能。服务器的缺省权值为1,系统管理员可以动态地设置服务器的权值。加权最小连接调度在调度新连接时尽可能使服务器的已建立连接数和其权值成比例。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。
                
                3.最短的期望的延迟    
                    最短的期望的延迟调度(Shortest Expected Delay 简称'SED')算法基于WLC算法。举个例子吧,ABC三台服务器的权重分别为1、2、3 。那么如果使用WLC算法的话一个新请求进入时它可能会分给ABC中的任意一个。使用SED算法后会进行一个运算:
A:(1+1)/1=2   B:(1+2)/2=3/2   C:(1+3)/3=4/3   就把请求交给得出运算结果最小的服务器。
                4.最少队列调度
                    最少队列调度(Never Queue 简称'NQ')算法,无需队列。如果有real server的连接数等于0就直接分配过去,不需要在进行SED运算。类似于先按权重大小依次分配,然后在根据SED算法,进行之后的分发;
                5.基于局部的最少连接
                    基于局部的最少连接调度(Locality-Based Least Connections 简称'LBLC')算法是针对请求报文的目标IP地址的负载均衡调度,目前主要用于Cache集群系统,因为在Cache集群客户请求报文的目标IP地址是变化的。这里假设任何后端服务器都可以处理任一请求,算法的设计目标是在服务器的负载基本平衡情况下,将相同目标IP地址的请求调度到同一台服务器,来提高各台服务器的访问局部性和Cache命中率,从而提升整个集群系统的处理能力。LBLC调度算法先根据请求的目标IP地址找出该目标IP地址最近使用的服务器,若该服务器是可用的且没有超载,将请求发送到该服务器;若服务器不存在,或者该服务器超载且有服务器处于一半的工作负载,则使用'最少连接'的原则选出一个可用的服务器,将请求发送到服务器。(类似动态的DH算法)
                6.带复制的基于局部性的最少连接
                    带复制的基于局部性的最少连接(Locality-Based Least Connections with Replication 简称'LBLCR')算法也是针对目标IP地址的负载均衡,目前主要用于Cache集群系统,它与LBLC算法不同之处是它要维护从一个目标IP地址到一组服务器的映射,而LBLC算法维护从一个目标IP地址到一台服务器的映射。按'最小连接'原则从该服务器组中选出一一台服务器,若服务器没有超载,将请求发送到该服务器;若服务器超载,则按'最小连接'原则从整个集群中选出一台服务器,将该服务器加入到这个服务器组中,将请求发送到该服务器。同时,当该服务器组有一段时间没有被修改,将最忙的服务器从服务器组中删除,以降低复制的程度。
            ipvs的集群服务:tcp,udp,ah,esp,ah_esp,sctp等;
                一个ipvs主机可以同时定义多个cluster service即可以同时实现mysql和web的集群功能,只不过是后端分别有mysql-RS和web-RS罢了;
            ipvsamd的用法:
                管理集群服务:指明哪个协议的哪个端口是集群服务;
                    指明lvs-type和lvs-scheduler;
                    ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask]
                            service-address : ip:port
                            -A, --add-service        添加一个虚拟服务; 虚拟服务即指搭建的集群服务;
                            -E, --edit-service        编译虚拟服务;
                               -t, --tcp-service service-address    指定为TCP协议
                            -s, --scheduler scheduling-method        设置调度算法
                            -f, --fwmark-service integer    设定一个防火墙标记
                    ipvsadm -D -t|u|f service-address
                            -D, --delete-service    删除一个虚拟服务
                            -p, --persistent [timeout]  设置持久连接时间
                管理集群服务中的RS:指明集群服务中有哪些RS;
                    ipvsadm -a|e -t|u|f service-address -r server-address  [-g|i|m] [-w weight] [-x upper] [-y lower]
                        -g, --gatewaying        DR类型
                        -i, --ipip        Tunnel类型
                        -m, --masquerading    NAT类型
                        -a, --add-server    向虚拟服务中添加一个RS
                        -e, --edit-server    编辑虚拟服务中的RS
                        -d, --delete-server    删除虚拟服务中的RS
                        -t, --tcp-service service-address
                        -f, --fwmark-service integer
                        -r, --real-server server-address        指定RS地址
                查看和清理:
                    ipvsadm -L|l [options]
                        -L, -l, --list
                    ipvsadm -C
                        -C, --clear    清除虚拟服务器表(本身以及其中包含的RS);
                保存和重载:因为设定好的规则是保存在内存中的,所以设置之后记得保存,就像iptables一样;
                    ipvsadm -R
                        -R, --restore
                    ipvsadm -S [-n]
                        -S, --save
            防火墙标记(FWM):
                我们可以在防火墙的mangle表的PREROUTING链上规则,来实现将具有某一特性的数据包进行统一处理(比如请求80端口的数据包都发送到某一台主机上),这种规则就可以通过设置防火墙标记来实现,将所有的请求80端口的数据包看都打上标记,然后通过标记来进行下一步处理;
                例子:设置防火墙时使用iptables,而设置lvs时要使用ipvsadm;
                    iptables –t mangle –A PREROUTING –d 192.168.0.7 –p tcp –-dport 80 –j MARK –set-mark 10
                    ipvsadm –A –f 10 –s rr
                    ipvsadm –a –f 10 –r 172.16.10.10 –g
                    ipvsadm –a –f 10 –r 172.16.10.11 –g    
                    当我们想要添加另一种服务,并且也让其进行负载均衡时,我们可以将其监听的端口也打上同一个mark,从而来减少配置步骤;
                    iptables –t mangle –A PREROUTING –d 192.168.0.7 –p tcp –-dport 8080 –j MARK –set-mark 10 
            
            例子:lvs-nat(使用vmware)
                拓扑结构:一台Centos6作为director,两台Centos7作为RS;
                    为了显示效果在两台Centos7分别编辑了不同的网页;一个内容为1,一个内容为2,然后使用本机访问网站来查看调度效果;
                准备:iptables -F    关闭所有主机的防火墙;
                    1.在Centos6上安装ipvsadm
                    2.设置三台主机的网卡vmware中为host-only,所以地址是随机生成的,只要跟两个Centos7同一网段即可;其中Centos6有两块网卡,另一块为桥接,为了连接物理主机
                    3.在两台Centos7上安装并启动httpd服务
                操作:
                    Centos6:
                        设置内核支持转发功能:
                            vim /etc/sysctl.conf
                                net.ipv4.ip_forward=1
                            sysctl -p
                        填写规则:
                            ipvsadm -A -t 192.168.0.7:80 -s rr
                            ipvsadm -a -t 192.168.0.7:80 -r 172.16.45.128:80 -m
                             ipvsadm -a -t 192.168.0.7:80 -r 172.16.45.129:80 -m
                            ipvsadm -S
                            ipvsadm -L -n
            例子:lvs-dr
                (使用DR模式配置RS时可以将VIP配置到lo接口的别名上,让数据包先经过物理网卡进入主机,然后再将数据包转发给内部的lo接口,再由lo接口将数据包发送给内核,就像客户端请求数据时是直接发送给RS一样,当RS响应数据包时,会将数据包的源地址填写成lo接口的地址,也就是VIP,从而完成数据的响应;)← 这不重要,不需要看,为了提醒我自己写的;
                拓扑结构:

                arp_announce:是否接受其他主机的arp通告以及自己是否将自己的地址通告其他主机;
                    0:将自己拥有的接口地址全部通告出去;
                    1:尽量不将非本网络的接口地址通告给对端;
                    2:仅将本接口地址通告出去,其他接口不会被通告;我们想要的→ 在RS上不会通告VIP地址,但是可以通告RIP地址;
                arp_ignore:是否响应其他人的arp广播请求;
                    0:只要是本机有的,其他主机请求了,就会向其返回结果;
                    1:请求报文是从哪个接口进入的,就仅返回这个接口的地址;我们想要的→ 仅通告RIP接口地址;
                操作:
                    direcrot:
                        ifconfig eth0:0 172.16.100.10/32 broadcast 172.16.100.10
                        route add -host 172.16.100.10 dev eth0:0
                    RS:
                        sysctl net.ipv4.conf.eth0.arp_announce=2
                        sysctl net.ipv4.conf.eth0.arp_ignore=1
                        sysctl -p
                        ifconfig lo:0 172.16.100.10/32 broadcast 172.16.100.10
                        route add -host 172.16.100.10 dev lo:0
                    director:添加集群规则
                        ipvsadm -A -t 172.16.100.10:80 -s rr
                        ipvsadm -a -t 172.16.100.10:80 -r 172.16.100.21 -g
                        ipvsadm -a -t 172.16.100.10:80 -r 172.16.100.22 -g
            HA:
                SPOF,Single Point Of Failure:单点故障;
                director:搭建高可用集群;
                如果后端某台RS突然掉线,如果没有相关机制,Director是还会将请求调度至掉线的RS上的,这样就会导致这些请求无法的到回应,从而降低用户体验,所以我们要通过一些机制来解决这个问题(健康检测机制);
                realserver:让realserver对其进行健康状态检测,并且根据检测的结果自动完成添加或移除等管理功能;
1.    基于协议层次的检查
a)    ip:icmp
b)    传输层:检查端口的开放状态;
c)    应用层:请求获取关键性的资源;
Note:层次越高精确度越高,效率越差;层次越低精确度越低,效率越高;
2.    检查频度
定义检查的次数,太频繁会造成资源浪费,次数过少会造成检查RS状态不及时;
3.    状态判断
判断服务器是否为掉线状态时进行多次确认,以避免误判;如在判断RS为下线状态时,会经过多次确认,比如经过3次都是失败则确认其已下线;判断RS是否可以上线时,只要状态检查成功,则确认其上线;
                    Note:LVS不具有状态检查机制;keepalive支持

         注:根据马哥视频做的学习笔记,如有错误,欢迎指正;侵删;
          借鉴文章:https://blog.csdn.net/weixin_40470303/article/details/80541639
                    https://www.cnblogs.com/aftree/p/9133333.html#undefined
                    https://blog.csdn.net/li12412414/article/details/81026209