集群(Cluster):多个计算机组成,为了解决某个问题的集合,通常是为了提高系统的性能;
集群分为:负载均衡集群(LB)、高可用集群(HA)、高性能集群(HP); ------------这里只介绍LB和HA,以及HA中的keepalived

一、负载均衡集群(LB Cluster):
基于硬件实现:、F5 Big_IP、Citrix Netscaler、A10公司的A10
基于软件实现:lvs、httpd、nginx、haproxy、ats、perlbal(基于Perl语言)、pound、...
基于工作的网络协议分层实现负载均衡:传输层(四层交换技术(OSI);lvs、nginx基于stream实现、haproxy基于TCP model实现)和应用层(七层交换技术;http/https、fastcgi、mysql协议)

lvs:Linux Virtual Server(调度器接收用户请求,然后将请求转发给后台real server来响应客户端请求)
lvs的软件组成:
ipvsadm/ipvs
ipvsadm:用户空间中的命令行工具,管理集群服务规则及后端real server的管理;
ipvs:工作于内核空间中的netfilter框架中的hook_input()钩子上的一个框架;可以接受来自ipvsadm的管理命令;ipvs可以管理诸如:TCP、UDP、SCTP、AH、ESP、AH_ESP等协议,并可以对此类协议的数据报文进行调度转发;

lvs集群服务中的常用术语
vs:Virtual Server
rs:Real Server(lvs中术语),Upstream Server(nginx中的语法术语),Backend Server
地址标识术语:
CIP:Client IP客户端IP地址,即:请求发送方的IP地址,一般是公有地址;
VIP:Virtual IP,虚拟服务器的虚拟IP地址,客户端访问的目的地址;
DIP:Director IP,调度器IP地址,向后端的Real Server转发客户端请求时使用的IP地址;
RIP:Real Server IP,后端真实服务器的IP地址;

lvs的调度算法(scheduler):
根据lvs在调度时是否考虑各RS的当前负载状态,可以将调度算法分为两类:静态算法和动态算法
1.静态算法:根据算法本身的特点进行调度;注重起点公平;
RR:RoundRobin,轮询算法;
WRR:Weighted RR,带有权重的轮询算法;加权轮询;
SH:Source Hashing,源地址哈希;将来自于同一个IP地址的请求始终发往后端第一次被挑选出来的RS,从而可以实现会话粘性;
DH:Destination Hashing,目标地址哈希;将发往同一目标地址的请求,始终发送至后端第一次挑选出来的RS;一般用于正向代理服务器集群的调度;
2.动态算法:根据每个RS当前的负载状态进行调度,注重结果公平; //后端的RS的负载状态,通常使用Overhead表示,不同的算法中Overhead的计算公式不一样;
1)LC:least connections,最小连接数;
连接状态有两种:一种是active connections(活动连接),另一种是inactive connections(非活动连接)
Overhead计算公式:Overhead=active connections 256 + inactive connections
注意:第一次调度时,因为后端的RS上并没有任何的active或inactive连接,所以按照配置顺序自上而下进行调度分配;属于轮询开始;
2)WLC:Weighted LC,加权的最小连接算法;默认算法;
Overhead计算公式:Overhead=(active connections
256 + inactive connections)/weight
注意:第一次调度时,因为后端的RS上并没有任何的active或inactive连接,所以按照配置顺序自上而下进行调度分配;属于轮询开始;权重值在第一次调度时不发挥任何作用;
3)SED:Shortest Expection Deley,最短期望延迟;
Overhead计算公式:Overhead=(active connections + 1)*256/Weight
注意:SED算法可以解决起点不公平问题,但是权重差距比较大,可能会导致不公平结果;
4)NQ:Never Queue,永无队列;改进版的SED算法;首次调度时,根据后端RS的权重依次为每个RS分配一个连接,然后再按照SED算法进行调度;必然会保证后端每台RS至少有一个active connection;
5)LBLC:Locality-Based Lease Connections,基于本地的最少连接;动态的DH算法;
6)LBLCR:LBLC with Replication,带有复制功能的LBLC算法;

lvs的集群类型:
标准集群类型:lvs-nat、lvs-dr(最为常用且效率最高的模型)、lvs-tunnel:
非标准集群类型:lvs-fullnat

**(一)lvs-nat类型**:只做目标地址转换,相当于多目标IP地址的DNAT;
            通过将请求报文中的目标IP地址和目标端口号修改为某个利用特定调度算法挑选出来的后端的RS的RIP即对应端口号的地址转换的集群服务类型;
                注意事项:
                1.RIP和DIP必须在同一逻辑网段中,并且应该都是私有IP地址,同时要求RS的网关指向调度器的DIP;
                2.客户端发送的请求报文和RS响应的报文都必须经过Director转发,Director容易称为整个集群服务系统的性能平均且容易引发单独故障;
                3.在Director上,真正的执行DNAT,因此其还可以实现端口重定向;客户端所请求的服务器端服务端口和后端RS提供的服务端口可以不同;
                4.VS必须是Linux系统,RS可以安装任意操作系统;

**(二)lvs-dr类型**:Direct Routing,直接路由;
        通过为请求报文重新封装一个数据链路层首部(MAC地址)进行报文转发;重新封装之后的数据报文的源MAC地址是Director的DIP所在网络接口的MAC地址,目的MAC地址为利用某种调度算法挑选出来的后端Real Server的RIP所在的接口的MAC地址;在整个过程中,源IP地址、目的IP地址、源端口号及目的端口号等协议封装属性均保持不变

        注意事项:
            1.确保前端路由器能够将目标IP地址为VIP的报文成功发往Director;
                1) 在前端路由器上静态绑定VIP和MAC地址的映射关系;
                2) 在所有的RS上使用arptables,进而可以过滤不期望的ARP请求和ARP应答;
                3) 在所有的RS上修改特定的内核参数以限制ARP的通告和对ARP请求的应答方式:
                        arp_ignore - INTEGER  (定义怎么样去发送应答消息)
                            arp_ignore的INTEGER属性:
                                    0:默认值,响应任意网卡上接收到的对本机IP地址的ARP请求,不考虑该目的IP地址是否在接收ARP报文的网卡上;
                                    1:只响应目的IP地址为接收网卡上的本地地址的ARP请求;
                                    2:只响应目的IP地址为接收网卡上的本地地址,并且ARP请求的源IP地址必须与接收网络在同一网段的ARP请求;
                                    3:如果ARP请求数据包所请求的IP地址对应的本地地址其作用范围为主机范围,不响应ARP请求;如果作用范围是全局或链路,就响应ARP请求;
                                    4-7:保留,未使用;
                                    8:不回应任何ARP请求;
                     arp_announce - INTEGER      (定义怎么样去发送arp的通告报文)
                         arp_announce参数的常用取值为0,1,2;
                                0:默认值,允许使用任意网卡上的IP地址作为ARP请求的源IP地址,向所有的网卡发出通告;
                                1:尽量避免使用不属于该发送网卡所在子网的本地地址作为发送ARP请求的源IP地址;
                                2:忽略IP数据包的源IP地址,选择该发送网卡上最合适的本地地址作为ARP请求的源IP地址;
             2.RS的RIP可以是私有IP地址,可以是公有IP地址;RIP和DIP应该在同一逻辑网段;RIP和VIP并不要求必须在同一网段;
             3.所有的请求报文都必须经过Director,但是所有的响应报文都无需通过调度器转发,而是直接通过路由器转发至客户端即可;
             4.不支持DNAT及端口重定向;
             5.RS必须安装Linux操作系统;
             6.IP地址的配置:
                    1) 在调度器上,物理网卡的主接口上配置DIP,接口的label上配置VIP;这样的配置可以使VIP滚动;
                    2) 在RS上,必须配置RIP和VIP,其中RIP配置在物理网卡的主接口上,而VIP配置在环回接口的label上;

 **(三)lvs-tunnel**:隧道;不对客户端的请求报文的IP首部做修改,即:源IP为CIP,目的IP为VIP,而是在原IP报文的封装格式之外再次封装一个IP首部(源IP为DIP,目的IP为RIP),将重新封装过的报文发往经过特定调度算法挑选出来的后端RS上;
         注意事项:
                1.CIP、VIP、DIP、RIP都应该是公有IP地址;
                2.所有的请求报文都必须经过Director,但是响应报文会直接从RS发往Client,而不再经过Director;
                3.不支持DNAT和端口重定向;
                4.要求Director和RS都必须支持隧道协议;IPsec
                5.在RS上必须同时配置RIP和VIP;

**(四)lvs-fullnat**:通过同时修改请求报文的源IP地址和目的IP地址实现报文转发;
            注意事项:
                1.CIP和VIP是公有地址,DIP和RIP是私有地址,并且DIP和RIP可以属于不同的逻辑网段;
                2.RS对收到的请求报文的响应报文,必须以DIP作为目的IP地址进行封装,所有此次通信的请求报文和响应报文都必须经过Director;
                3.支持SNAT、DNAT及端口重定向;
                4.此类型默认不受内核支持;

负载均衡集群的实现(LB Cluster):
(一)基本环境配置:
使用ipvsadm/ipvs来实现LVS:
ipvs:工作于netfilter框架中的INPUT链上,内核中的TCP/IP协议栈上的框架组件;
ipvsadm:用户空间中用于编写ipvs集群服务的应用程序;

1.安装ipvsadm:
首先需要查看是否支持ipvsadm:
~]# grep -i -C 10 "ipvs" /boot/config-3.10.0-327.el7.x86_64
检查是否安装ipvsadm应用程序:在光盘的镜像中;
rpm -q ipvsadm
yum -y install ipvsadm
2.掌握ipvsadm命令:
1)管理集群服务:增、删、改
(1)增加lvs集群服务:
ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask] [--pe persistence_engine] [-b sched-flags]
--tcp-service -t service-address :基于TCP协议的集群服务;
service-address :与VIP绑定的套接字,即:VIP:PORT
--udp-service -u service-address :基于UDP协议的集群服务;
service-address :与VIP绑定的套接字,即:VIP:PORT
--fwmark-service -f fwmark :基于防火墙标记(FWM)的集群服务
service-address :通过iptables工具在mangle表上对数据设置的标记;
--scheduler -s scheduler :指定lvs集群服务挑选后端RS的调度算法;默认是lsc算法;
--persistent -p [timeout] :是否开启持久连接,并定义持久连接的超时时间,如果省略超时时间,默认值为360s;
(2)修改lvs集群服务中的属性:
ipvsadm -E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask] [--pe persistence_engine] [-b sched-flags]
--edit-service -E :编辑、修改集群服务;
(3)删除集群服务:
ipvsadm -D -t|u|f service-address
--delete-service -D :删除指定的集群服务;
(4)清除lvs集群服务:
ipvsadm -C
--clear -C : 清除所有集群服务; //不推荐使用此方式清除集群服务,如果必须要删除,可以是-D代替指定删除;

    2)管理集群中的Real Server:增、删、改
        (1)在指定的集群服务中添加Real Server:
            ipvsadm -a -t|u|f service-address -r server-address [options]
                --add-service     -A :向集群中添加RS;
                --real-server  -r server-address :指定计划要添加至服务器集群中的后端RS的IP地址及端口号;只有在使用NAT类型的lvs集群时,才能指定端口号;
                options:
                    --gatewaying   -g :指定lvs集群的类型为DR,默认类型;
              --ipip         -i :指定lvs集群的类型为TUN;
              --masquerading -m :指定lvs集群的类型为NAT;
              --weight       -w weight :为后端的RS指定权重值(一般是整数);
        (2)修改集群中的RS属性:
            ipvsadm -e -t|u|f service-address -r server-address [options]
                --edit-server     -e :编辑、修改集群中的RS属性;
        (3)从集群中删除RS:
            ipvsadm -d -t|u|f service-address -r server-address
                --delete-server   -d :从指定的集群服务中,删除指定的Real Server;

    3)查看集群服务和RS的属性及统计信息;
        ipvsadm -L|l [options]
            --list            -L|-l:列表显示指定的集群服务或RS属性;

            options注意包括:
                --numeric      -n:以数字格式显示IP和PORT等信息;
                --exact:显示精确值;
                --connection   -c:输出当前ipvs的各连接的状态;
                --stats:输出lvs集群的详细的统计信息;
                --rate:输出lvs集群中与传输速率相关的信息;
                --timeout:输出TCP、TCP的FIN标志位及UDP会话的超时时长;

        ipvs的规则的保存和重载:
                --save            -S:用于保存ipvs规则;
                    ipvsadm -S [-n] > /PATH/TO/IPVS_RULL_FILE
                    ipvsadm-save > /PATH/TO/IPVS_RULL_FILE

                --restore         -R:用于重载ipvs规则;
                    ipvsadm -R < /PATH/TO/IPVS_RULL_FILE
                    ipvsadm-restore < /PATH/TO/IPVS_RULL_FILE

            使已经被保存的规则于开机时自动载入:
                CentOS 6以前的发行版本:
                    # chkconfig ipvsadm on
                CentOS 7以后的发行版本:
                    # systemctl enable ipvsadm.service

(二)lvs-nat的实现:
1个Director + 2个Real Server:

    都是在Director上的配置:
        1、创建集群服务:
            ipvsadm -A -t 172.16.72.3:80 -s rr
        2、向集群中添加RS:
            ipvsadm -a -t 172.16.72.3:80 -r 192.168.100.100:80 -m -w 1
            ipvsadm -a -t 172.16.72.3:80 -r 192.168.100.200:8000 -m -w 2

        注意:后端的RS的网关必须指向Director的DIP;

(三)lvs-dr的实现:
1个Director + 2个Real Server:

    在lvs-dr类型的集群中,各个主机(包括Director和各RS)都需要配置VIP;为了解决IP地址冲突的问题,通常有以下几种方法:
        1.在前端路由器上静态绑定VIP和MAC地址的对应关系;
        2.在各个RS中使用arptables对ARP报文进行过滤;
        3.在各个RS中修改对应的内核参数,以此来限制ARP报文的通告和应答级别;
            arp_ignore
                0:默认值;
                1:
                2:
            arp_announce
                0:默认值;
                1:
                2:

            常用的内核参数设定值的选择:
                arp_ignore = 1
                arp_announce =2

    配置lvs-dr类型:
        在Director上的配置:
            1.主网络接口上配置DIP;
            2.在网络接口的标签接口上配置VIP;
                ~]# ifconfig eno16777736:0 172.16.72.254 netmask 255.255.255.255 broadcast 172.16.72.254 up
            3.创建集群服务:应该在RS均正确配置之后再执行;
                ipvsadm -A -t 172.16.72.254:80 -s rr
            4.向集群服务中添加RS:
                ipvsadm -a -t 172.16.72.254:80 -r 172.16.72.5 -g -w 1
                ipvsadm -a -t 172.16.72.254:80 -r 172.16.72.6 -g -w 2

        在RS上的配置:
            1.主网络接口上配置RIP:
            2.在lo的标签接口上配置VIP;
                ~]# ifconfig lo:0 172.16.72.254 netmask 255.255.255.255 broadcast 172.16.72.254 up
            3.调整ARP相关的内核参数:
                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
            4.为了能够使响应报文从lo:0标签接口向外封装发送数据,需要指定一条特殊的静态路由:
                route add -host 172.16.72.254 dev lo:0

二、高可用集群(HA Cluster):(lvs本身并、不支持高可用)
高可用主要是指:服务高可用和资源高可用
在lvs集群中,可能有两种故障:
1.Director故障不可用;
keepalived:原生的lvs的Director高可用解决方案;
heartbeat
corosync/pacemaker:通用的高可用解决方案;

    2.后端RS故障不可用;
            lvs的Director不考虑后端RS的可用与否,只是按照调度算法进行客户端请求调度;
            完整的实现:周期性的对各个RS进行健康状态检测;
                检测失败:应该从lvs集群服务中将对应的RS移除;
                检测成功:将对应RS重新加入lvs集群服务中;重新创建lvs集群服务;
                所有的RS检测均失败:临时删除lvs集群服务,并使调度器本地的web服务能够响应一个相对比较友好的错误页面,sorry_server;

        检测后台服务器RS的方式:
            网络层检测;ping
            传输层检测:端口探测,nmap
            应用层检测:文件资源的存在性检测;文件访问权限检测;文件内容有效性检测;

        **HA Cluster实现方案:**
                基于VRRP协议的实现:(keepalived主要用来后端RS的健康状态检测)
                    keepalived,专用于高可用lvs的Director;
                基于AIS的实现:完备的HA集群;
                    heartbeat
                    corosync + pacemaker

            **VRRP协议**:Virtual Redundancy Router Protocol,虚拟路由器冗余协议;
                    VRRP技术术语:
                        虚拟路由器:虚拟的路由器的接口;
                        VRID:虚拟路由器标识符,描述路由器的分组;并且可以确定虚拟路由器的虚拟MAC地址,取值范围为:0-255(00-ff);
                        MASTER:虚拟IP地址的拥有者,可以利用虚拟IP地址接收用户请求,并且能够完成数据转发功能;
                        BACKUP:不参与数据转发,仅检测MASTER的健康状态;
                        虚拟IP地址:VIP,虚拟路由器接口的IP地址;
                        虚拟MAC地址:VMAC,00-00-5e-00-01-{VRID}
                        优先级:选举成为MASTER的主要的参考标准,取值范围为:0-255;
                            0:放弃MASTER选举;
                            255:虚拟IP地址和某个路由器接口的IP地址相同,则该路由器会自动获得255的优先级,从而直接成为MASTER;
                            1-254:越大越有可能成为MASTER;
                        非抢占式:如果MASTER故障导致状态发生变化,则所有的BACKUP会重新选举产生新的MASTER;此时,如果原来的MASTER从故障中恢复,则直接成为BACKUP状态,直到当前的MASTER故障之后,所有的BACKUP重新选举MASTER时,其才能重新称为新的MASTER;
                        抢占式:如果MASTER故障导致状态发生变化,则所有的BACKUP会重新选举产生新的MASTER;此时,如果原来的MASTER从故障中恢复,则立即通告自己的优先级并启动新一轮选举,之后重新成为MASTER;

                    VRRP的认证方式:无认证、简单字符串认证、MD5

                    VRRP的工作模式:
                        单个实例:MASTER/BACKUP
                        多个实例:MASTER/BACKUP, MASTER/MASTER

    **  keepalived:**
            VRRP协议在linux系统中的应用实现,为了高可用ipvs调度器;也称为"ka";
            keepalived通过调用内核中的系统调用接口完成ipvs的规则编写,从而可以用于管理lvs集群服务;所有的规则,都定义在其配置文件中;
            keepalived还可以对VIP地址进行浮动设置;
            keepalived还可以为后端各RS提供健康状态检测,可以基于传输层及应用层实现;
            keepalived还可以基于外部脚本调用接口完成脚本中定义的功能,甚至可以高可用其他的非lvs服务;
            keepalived在RHEL 6.4+或CentOS 6.4+的发行版本的操作系统中,被收录到官方系统光盘镜像之中,直接基于本地Base源使用yum命令完成安装即可;

        keepalived的组件:
            1.控制面板:配置文件分析器;
            2.内存管理组件;
            3.IO复用器组件;
            4.核心组件:
                VRRP Stack:实现VRRP协议功能的组件;
                Checkers:后端RS做健康状态检测的组件;
                SMTP:调用SMTP协议,将路由器状态转换的消息以邮件的形式发送到指定管理员邮箱;
                Watch Dog:监控Checkers和VRRP Stack的工作状态;如果异常,负责重新启动keepalived进程;
                ipvs wrapper:向内核中的ipvs框架传输ipvs规则,用于构建、管理、移除lvs集群服务及集群中的RS的组件;
                netlink reflactor:管理虚拟路由器接口;

        配置HA Cluster的前期准备:
            1.各个节点主机之间时间必须同步,可以使用时间服务器,如ntp或chrony;
            2.确保iptables和SELinux的规则不会阻碍各个节点之前的数据通信;
            3.各个节点主机之间需要通过主机名互相通信(对ka并非必须);
            4.出于安全考量,各个节点主机之间可以以root用户的身份,基于密钥认证的方式进行ssh通信(对于ka非必须);

        keepalived安装:
            在CentOS 7.2中,直接使用光盘镜像yum仓库,使用yum install keepalived安装即可;

            程序环境:
                主配置文件:/etc/keepalived/keepalived.conf
                主程序文件:/usr/sbin/keepalived
                Unit File:/usr/lib/systemd/system/keepalived.service

            主配置文件的结构:
                GLOBAL CONFIGURATION
                    Global definitions
                        global_defs {
                            notification_email {
                                         root@localhost //配置接收邮件通知的邮箱地址;
                            }
                            notification_email_from keepalived@localhost
                            smtp_server 127.0.0.1  //设定用于发送电子邮件的邮件服务器;
                            smtp_connect_timeout 30      # integer, seconds
                            router_id my_hostname //设置路由器ID,仅仅为了区分不同的设备而已;如果不修改,也不会影响keepalived服务本身;
                            vrrp_mcast_group4 224.0.0.18 //设置发送VRRP协议通过的目标组播通信地址;必须保证所有参数选举的路由器都必须有相同的组播通信地址;
                        }

                VRRPD CONFIGURATION
                    vrrp_instance inside_network { //定义VRRP的实例及实例名称;
                        state MASTER  //指定当前设备的初始状态;
                        interface eno16777736 
                            //指定被VRRP协议绑定的网络接口,即发送VRRP通过信息的网络接口;
                        virtual_router_id 51 //指定虚拟路由器标识,用于确定VRRP备份组;
                        priority 100 //指定当前节点的优先级,指定的范围为:1-254;
                        advert_int 1 //发送VRRP通过的时间间隔,单位是秒;
                        authentication {
                            auth_type PASS //设置VRRP协议各节点之间的认证方式,PASS表示简单密码
                            auth_pass MTUwPBjd //设置认证密码,不超过8个字符;
                        }
                        virtual_ipaddress {
                            / brd  dev  scope  label