Cluster了解+LB{ LVS(四种模式)+ipvs+lvs持久连接 }

Posted jerryzao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cluster了解+LB{ LVS(四种模式)+ipvs+lvs持久连接 }相关的知识,希望对你有一定的参考价值。

Cluster:
    系统扩展的两种思路:
        scale up:向上扩展 -- 性能更好的主机,替换旧的主机
        scale out:横向扩展 -- 添加服务器(但是服务是可以分开的,独立的)

        cookie:服务器端生成一个cookie-id,发送给客户端,客户端每次访问,都会将cookie发送给服务器端
        session:服务器端会比对cookie和seesion的对应情况(服务器内存中)

        实现 LB(负载均衡)-- 问题所在
            1、DNS:
                不要使用dns 去实现 LB,因为DNS 解析会缓存,所以效果很差
            2、前端实现一个调度器:
                如果请求和响应都通过 调度器,导致压力很大。

        集群类型:
            LB:负载均衡,均衡负载,调度到不同的服务器访问资源(同一或不同资源)
            HA:高可用,提高冗余,服务器一直在线,一个down掉,其他服务器取而代之
            HP:集中式的高性能服务器 不同于 分布式

            平均无故障时间/(平均无故障时间 + 平均修复时间)
                -- 90% 95% 99% 99.9% 99.99%

        系统:
            可扩展性
            可用性:
                服务器是否随时可用
            容量:

        系统运维:可用 ---> 标准化 --- > 自动化

        ****构建高可扩展性系统的重要原则:在系统内部尽量避免串行和交互

        GLSB:Global Service Load Blancing
            SLB:Service Load Blancing

            静态内容的响应远大于动态响应,动态服务器是无法缓存的,基于CDN的都是静态服务器
                缓存是KEY-value存储,所以查询缓存要快很多。但是如果数据过期了,查缓存时间就多了。

        构建一个系统:
            1、分层:每个功能一个层,每个服务器制作自己的事
            2、分割:不同应用分割道不同服务器
            3、分布式:无法分割的
                分布式应用
                分布式静态资源
                分布式数据和存储
                分布式计算

            通过量:
            容纳量:
            吞吐量:最大吞吐量
                保证可接受容量的条件下,平均吞吐量。

    LB 集群的实现:
        后台服务器具有全部的数据集
            硬件实现:
                F5 BIG-IP
                Citrix NetScaler
                A10
            软件:
                LVS
                Haproxy
                nginx
                ats(apache traffic server)

                httpd(proxy模块)
                varnish
                perlbal

                基于工作的协议层次划分:
                    传输层:
                        LVS, haproxy(mode可以模拟tcp)
                    应用层:(反向代理)
                        nginx -- 应用程序
                        haproxy -- 应用程序
                        ats
                        perlbal

                    注意:
                        LVS 依附于netfilter工作于内核,只需要 端口

                        对于应用程序,本身就需要一个套接字,而端口最多65535个,所以并发数最多65535个

                        监听套接字 已连接套接字

                        网站并发连接数2-3w,pv量就达到千万级别了

                        所以一般不会用到lvs 这种百万级别的并发量的并发,而且一般这个级别的时候,可能用CDN了,不会直接到达服务器了。


    LVS:工作在传输层的LB均衡器
        工作于netfilter上的

        LVS:Linux Virtual Server虚拟服务器,不是真正提供服务的

        LVS也称为---L4:4层路由,
        根据请求报文的目标IP 和PORT 将其转发后端主机集群中的某一台(根据挑选算法)

        netfilter:
            PREROUTING ---> INPUT
            PREROUTING ---> FORWARD ---> POSTROUTING
            OUTPUT ---> POSTROUTING

        DNAT:
            PREROUTING上
            在路由转发之前,发现ip不是本机,就不会转发了

        LVS:
            工作在INPUT 上,发现是集群服务(例如:某个端口作为集群服务),就强行改变,到POSTROUTING
            PREROUTING ---> INPUT --> POSTROUTING 
        在内核中工作 就不是服务

        LVS:
            用户空间:ipvsadm命令行工具,用于管理集群服务, 增删查改
            内核空间:ipvs工作于内核中INPUT连上

            内核编译时加载的模块: /boot/config-2.6.32-696.el6.x86_64 
                y:已经加载
                m:可以手动在加载

            支持的协议:
                TCP,UDP ,EST,AH_EXT,SCTP等

        lvs arch:
            调度器:director,dispatcher,balancer
            后端:real server

            CIP VIP DIP RIP

        lvs 类型:
            lvs-nat
            lvs-dr(diretct routing)
            lvs-tun(隧道)
            lvs-fullnat

                lvs-nat:
                    DIP,RIP:内网地址
                    VIP:外网
                    请求:
                        CIP-VIP
                            CIP-DIP
                                CIP-RIP

                        PREROUTING --> INPUT --> POSTROUTING

                    响应:
                        RIP-CIP
                            VIP-CIP

                        PREROUTING --> FORWARD --> POSTROUTING

                    维持 NAT 会话表

                    多目标的DNAT(iptables):通过修改请求报文的目标IP地址(同时可能会修改目标端口)至挑选出的某RS 的RIP地址,实现转发。

                        1、RS应该和DIP 应该使用私有网址,RS的网关指向DIP
                        2、请求和响应的报文 都要经由director转发,极高负载场景中,direxctor会成为瓶颈
                        3、支持端口映射
                        4、RS 可以使用 windows,Linux等任意OS
                        5、RIP 和 DIP 必须在同一IP 网络(加个路由,没必要)

                lvs-dr:直接转发
                    通过修改请求报文的目标MAC地址进行转发的。

                    在网路上传输,经过路由和网关,sip dip是不会变的,但是mac是会变的。直到LAN
                        D:DIP,VIP
                        R:RIP,VIP
                        D 通过arp广播,获取的是RS的mac地址,到达D,发现mac变为RS,在转发到RS

                    1、保证前端路由器将目标IP 为VIP的请求报文发送给director
                        解决方案:
                            路由器跟D 绑定(但是D挂了,还得重新绑定)
                            修改RS 内核参数

                    2、RS的RIP 可以使用私有地址,可以使用公网地址
                    3、RS 和 D 必须在同一物理网络中
                    4、请求报文 通过 D 调用,响应报文一定不能经过D
                    5、不支持端口映射:请求80,RS回应8080,就错了被
                    6、RS可以大多数os
                    7、RS的网关不能指向DIP

                lvs-tun:
                    不修改请求报文的ip 首部,而是通过在原有的ip首部外面再封装一个ip首部
                        响应:rs直接响应客户端
                        cip ---> vip  再封装一个ip首部(dip ---> rip)
                    1、RIP DIP VIP全部是公网
                    2、RS的网关 不能指向DIP
                    3、请求报文必须经由D 调度,响应报文不能D调度
                    4、不支持端口映射
                    5、RS的os 必须支持隧道功能

                lvs-fullnat:
                    ups:备用电源
                    D:同时修改原地址和目标地址

                    1、VIP是公网地址, rip和dip 是私网地址,二者无须同一网络中
                    2、RS 接收到的请求报文的原地址为DIP,因此要响应给DIP
                    3、请求报文和响应报文都必须经由 D
                    4、支持端口映射
                    5、RS的os可以使用任意OS


    http:stateless无状态
        session保持机制:
            session绑定:
                将来自于同一用户的请求始终定向至同一个服务,维持一个会话表:追踪同一个用户
                ip_hash:原地址hash,太粗糙,基于snet-ip访问,就不行了
                cookie绑定:session绑定上实现,LVS无法实现

                但是某服务器宕机后,session就没了
            session集群
                同步session信息

                但是网络中充斥大量的session,浪费带宽。

            session服务器
                集中管理。session持久化的话,即便关机,也是没关系的 --- redis


    调度算法:
         cat /boot/config-2.6.32-696.el6.x86_64
             静态方法:仅根据算法本身进行调度,起点公平
                 RR:round robin轮询
                 WRR:weight rr 权重
                 SH:source hash 原地址hsah, 实现session保持 -- 损坏负载均衡效果,来自同一IP的请求始终调度到同一服务器
                 DH:destation hash,类似:访问同一个资源,会定向到同一个服务器(lvs无法实现url调度,只能ip和port,只是举例说明)    
                     同一个防火墙出去的,通过同一个防火墙进来。
             动态方法:根据算法及各RS的当前负载状态进行调度,结果公平
                     Overhead(当前负载)= 
                 LC:least connection,哪个服务器链接数最少,就调度到哪个
                     刚开始或者Overhead一样:自上而下挑选
                     Overhead= active * 256 + inactive
                 WLC:weight LC
                     overhead = (active * 256 + inactive) / weight
                     缺陷:
                         如果计算后都一样的值,这是从上往下选,但是正好,第一个负载很重
                 SED:最短期望延迟
                     初始连接高权重优先
                     (active+1)* 256 /weight
                     缺陷:
                         如果两台:weight=4,1 则来的都是在4 上
                 NQ:never queue
                     sed的改进  第一轮均匀分配,后续SED
                 LBLC:locality-Base LC :动态的DH 算法
                     大量缓存的时候,才会用
                     正向代理情形下的cache server 调度
                 LBLCR:带复制的LBLC
                     解决LBLC负载不均衡,从负载重的复制到负载轻的


    ipvs:的集群服务

        1、一个ipvs主机可同时定义多个cluster service
        2、一个cluster service 上至少有一个real server
            定义时:指明lvs-type,以及lvs 调度算法
    ipvsadm用法:
        1、管理集群服务
            ipvsadm -A|E -t|u|f service-address [-s scheduler]
            ipvsadm -D -t|u|f service-address
          
            service-address:
                tcp: -t ip:port
                udp: -u ip:port
                fwm: -f mark 防火墙标记,表示从这通过的
            -s:
                默认wlc

        2、管理集群服务中的RS

            ipvsadm -a|e -t|u|f service-address -r server-address
               [-g|i|m] [-w weight] [-x upper] [-y lower]
            ipvsadm -d -t|u|f service-address -r server-address

            server-address:
                ip[:port]

            -g:dr 模型。默认
            -i:ipip tun模型
            -m:nat

         查看和清理:
             ipvsadm -C
               ipvsadm -L|l [options]
                   -n:基于数字格式显示地址和端口
                   -c:显示ipvs连接
                   --stats:
                           入站 包个数,入站字节数
                   --rate:速率

                       pps:每妙包个数
                       Bps:字节数
                   --exact:显示精确值

         保存和重载:
               ipvsadm -R
               ipvsadm -S [-n]
          置零计数器
               ipvsadm -Z [-t|u|f service-address]


          测试:
              nat:
                  A --- > director
                      eth0: vip
                      eth1: dip
                  web1 --->
                      eth0 rip1
                  web2 --->
                      eth0 rip2


                  1、iptables 关闭***或者清空****
                  2、/etc/sysctl.conf 开启转发
                  3、规则:
                      ipvsadm -A -t vip:80 -s rr
                      ipvsadm -L -n ---查看

                      ipvsadm -a -t vip:80 -r rip1 -m
                      ipvsadm -a -t vip:80 -r rip2 -m
                      ipvsadm -L -n ---查看

                      ipvsadm -S > /etc/sysconfig/ipvsadm  保存

                      ipvsadm -C 清空
                      ipvsadm -L -n ---查看
                      ipvsadm -R 重载

                  修改:
                      修改算法:
                          ipvsadm -E -t vip:80 -s sh
                      端口映射
                          ipvsadm -e -t  vip:80 -r rip1:8080 -m
                      删除:
                          ipvsadm -d -t vip:80 -r rip1:8080

                      删除集群:
                          -D

                      **web是https的话,每个服务器用同一个证书和私钥
                          因为lvs是内核中工作,不会代替c和s 之间建立ssl会话
                          又因为访问的是同一个域名,所以,需要同一个证书和秘钥

                      短连接 和 长连接的问题**
                      有些特殊协议是不能lvs调度的
                      例如ftp:被动模式的ftp端口问题

              dr:
                      director:
                          eht0 ---> dip
                          eth0:0 ---> vip/32

                      web1:
                          eth0 rip1
                          lo:0 vip
                      web2:
                          eth0 rip2
                          lo:0 vip

                      arp广播:
                          annouce:是否通告别人
                              0:把自己所有的地址都告诉别人
                              1:尽量避免不要同不是同一网络的  告诉别人
                              2:只能通过网卡出去
                          ignore:响不响应
                              0:有,就通知
                              1:从哪个接口进来,只有配置到该进来的接口 才响应

                          内核参数:
                            # echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
                            # echo 2 > /proc/sys/net/ipv4/conf/all/arp_annouce

                            # echo 1 > /proc/sys/net/ipv4/conf/INTERFACE/arp_ignore
                            # echo 2 > /proc/sys/net/ipv4/conf/INTERFACE/arp_annouce

                            注意:INTERFACE为你的物理接口;

                            # ifconfig lo:0 $vip netmask 255.255.255.255 broadcast $vip up
                            # route add -host $vip dev lo:0
桥接:
    目前的以太网都是通过交换机通信的
    物理机的物理网卡,模拟成物理交换设备,虚拟机交换机与之相连
    在同一网段中就可以通信

NAT:物理机上虚拟一个网卡 与 虚拟交换机建立关系,虚拟机网关指向虚拟网卡
    经过物理网卡时,地址转换为网卡的地址

HOST-Only:没有nat

虚拟通道:
    vmnet2.... 不跟物理机通信



            防火墙标记: -f 选项
                fwm:用户请求到达时,在 PREROUTING 设置标记
                    -j MARK --set-mark 10


            ipvs:
                -A -f 10


            将两种不同的服务一起调度:
                一台服务器有如下服务:
                    一个443
                    一个80
                        打上同一个标记 如 10
                        ipvs规则直接用10 即可,否则每个都得定义成各自服务的集群

                        示例:
                            ~]# iptables -t mangle -A PREROUTING -d 172.16.100.9 -p tcp --dport 80 -j MARK --set-mark 99
                            ~]# iptables -t mangle -A PREROUTING -d 172.16.100.9 -p tcp --dport 443 -j MARK --set-mark 99
                            ~]# ipvsadm -A -f 99 -s rr -p
                            ~]# ipvsadm -a -f 99 -r 172.16.100.68 -g
                            ~]# ipvsadm -a -f 99 -r 172.16.100.69 -g



            lvs 持久连接:
                    session保持:
                        绑定:
                        复制:
                        服务器:

                        session绑定:
                            对多个共享同一组RS的服务,统一进行帮定(sh 算法无法解决)

                    lvs persistence:lvs的持久连接
                        功能:无论ipvs使用何种调度方法,其都能事项将来自于同一个client的请求始终定向至第一次调度时挑选出的RS

                        持久连接模板:独立于算法外:(第一次请求时,或者倒计时变为0了,使用定义的算法调度)
                            sourceip -- RS -- timer

                       -p选项,默认300秒

                       示例:
                            ~]# iptables -t mangle -A PREROUTING -d 172.16.100.9 -p tcp --dport 80 -j MARK --set-mark 99
                            ~]# iptables -t mangle -A PREROUTING -d 172.16.100.9 -p tcp --dport 443 -j MARK --set-mark 99
                            ~]# ipvsadm -A -f 99 -s rr -p
                            ~]# ipvsadm -a -f 99 -r 172.16.100.68 -g
                            ~]# ipvsadm -a -f 99 -r 172.16.100.69 -g


                持久连接的实现:
                    每端口持久:PPC,单服务持久调度,sh算法实现的功能

                    每fwm持久:PFWMC,单FWM持久调度

                    每客户端持久:PCC,单客户端持久调度,
                        director会将用户的任何请求都识别为集群服务,并向RS调度,而且绑定到同一个RS上
                            1-65535
                    端口0:表示所有服务
                        ipvsadm -A -t  172.16.100.68:0 -s rr


    HA:
        SPOF:单点故障    

        lvs HA功能:
        director:在节点级别进行冗余;HA集群解决方案:keepalived,;
        real server:让director    健康状态检测,并能够完成自动上下线;
            健康时:online
            非健康时:offline

        如何对real server做健康状态检测:
            (1) ip层:探测主机的存活状态 ping;----单服务 并不一定 正常,如 web服务器,虽然主机好了,但是web就好吗?
            (2) 传输层:探测端口的可用性;----端口好,不一定网页就能访问
            (3) 应用层:请求关键的某资源;----直接请求某资源

            状态变化:
                ok --> failure --> failure --> failure
                    rs: down

                    soft state --> hard state

                failure --> ok
                    rs: up

                backup(sorry_server):
 










             示例脚本:
            #!/bin/bash
            #
            fwm=6
            sorry_server=127.0.0.1
            rs=(172.16.100.21 172.16.100.22)
            rw=(1 2)
            type=-g
            chkloop=3
            rsstatus=(0 0)
            logfile=/var/log/ipvs_health_check.log

            addrs() {
                ipvsadm -a -f $fwm -r $1 $type -w $2
                [ $? -eq 0 ] && return 0 || return 1
            }

            delrs() {
                ipvsadm -d -f $fwm -r $1
                [ $? -eq 0 ] && return 0 || return 1
            }
            
            chkrs() { 
                local i=1
                while [ $i -le $chkloop ]; do
                    if curl --connect-timeout 1 -s http://$1/.health.html | grep "OK" &> /dev/null; then
                        return 0
                    fi
                    let i++
                    sleep 1
                done
                return 1
            }

            initstatus() {
                for host in `seq 0 $[${#rs[@]}-1]`; do 
                    if chkrs ${rs[$host]}; then
                        if [ ${rsstatus[$host]} -eq 0 ]; then
                            rsstatus[$host]=1
                        fi
                    else
                        if [ ${rsstatus[$host]} -eq 1 ]; then
                            rsstatus[$host]=0
                        fi
                    fi
                done
            }
            
            initstatus
            while :; do
                for host in `seq 0 $[${#rs[@]}-1]`; do 
                    if chkrs ${rs[$host]}; then
                        if [ ${rsstatus[$host]} -eq 0 ]; then
                            addrs ${rs[$host]} ${rw[$host]}
                            [ $? -eq 0 ] && rsstatus[$host]=1
                        fi
                    else
                        if [ ${rsstatus[$host]} -eq 1 ]; then
                            delrs ${rs[$host]} ${rw[$host]}
                            [ $? -eq 0 ] && rsstatus[$host]=0
                        fi
                    fi
                done
                sleep 5
            done

    附:director和rs的示例脚本

        DR类型director脚本示例:
            #!/bin/bash
            #
            vip=172.16.100.33
            rip=(172.16.100.8 172.16.100.9)
            weight=(1 2)
            port=80
            scheduler=rr
            ipvstype=-g

            case $1 in
            start)
                iptables -F -t filter
                ipvsadm -C
                
                ifconfig eth0:0 $vip broadcast $vip netmask 255.255.255.255 up
                
                echo 1 > /proc/sys/net/ipv4/ip_forward

                ipvsadm -A -t $vip:$port -s $scheduler
                [ $? -eq 0 ] && echo "ipvs service $vip:$port added."  || exit 2
                for i in `seq 0 $[${#rip[@]}-1]`; do
                    ipvsadm -a -t $vip:$port -r ${rip[$i]} $ipvstype -w ${weight[$i]}
                    [ $? -eq 0 ] && echo "RS ${rip[$i]} added."
                done
                touch /var/lock/subsys/ipvs
                ;;
            stop)
                echo 0 > /proc/sys/net/ipv4/ip_forward
                ipvsadm -C
                ifconfig eth0:0 down
                rm -f /var/lock/subsys/ipvs
                echo "ipvs stopped."
                ;;
            status)
                if [ -f /var/lock/subsys/ipvs ]; then
                    echo "ipvs is running."
                    ipvsadm -L -n
                else
                    echo "ipvs is stopped."
                fi
                ;;
            *)
                echo "Usage: `basename $0` {start|stop|status}"
                exit 3
                ;;
            esac


            DR类型RS脚本示例:
            #!/bin/bash
            #
            vip=172.16.100.33
            interface="lo:0"

            case $1 in
            start)
                echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
                echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
                echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
                echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce

                ifconfig $interface $vip broadcast $vip netmask 255.255.255.255 up
                route add -host $vip dev $interface
                ;;
            stop)
                echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
                echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
                echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
                echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce

                ifconfig $interface down
                ;;
            status)
                if ifconfig lo:0 |grep $vip &> /dev/null; then
                    echo "ipvs is running."
                else
                    echo "ipvs is stopped."
                fi
                ;;
            *)
                echo "Usage: `basename $0` {start|stop|status}"
                exit 1
            esac

 

以上是关于Cluster了解+LB{ LVS(四种模式)+ipvs+lvs持久连接 }的主要内容,如果未能解决你的问题,请参考以下文章

LVS四种实现模式详解

LVS负载均衡群集

81-linux cluster : lvs

负载均衡集群介绍(LB集群) LVS介绍LVS NAT模式LVS DR模式

Linux自学笔记——linux cluster 之lvs

配置LVS/DR模式的LB集群