集群(Cluster):多个计算机组成,为了解决某个问题的集合,一般是为了提升系统的性能;
集群分为:负载均衡集群(LB)、高可用集群(HA)、高性能集群(HP); ------------这里只介绍LB和HA,以及HA中的keepalived前端
1、负载均衡集群(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协议)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等协议,并能够对此类协议的数据报文进行调度转发;linux
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地址;nginx
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算法;web
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集群服务的应用程序;sql
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上的配置: 一、建立集群服务: ipvsadm -A -t 172.16.72.3:80 -s rr 二、向集群中添加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
2、高可用集群(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 { <IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL> } //设置虚拟IP地址的专用上下文 nopreempt //设置当前节点为非抢占模式,默认为抢占模式; preempt_delay 300 //抢占模式开始前的延迟时间; notify_master <STRING>|<QUOTED-STRING> notify_backup <STRING>|<QUOTED-STRING> notify_fault <STRING>|<QUOTED-STRING> //设置当当前服务器状态发生变化时,所触发的脚本文件的路径及相关参数; track_script { SCRIPT_NAME } } LVS CONFIGURATION virtual server vip vport | fwmark <INT> { delay_loop <INT> //服务轮询的时间间隔设定; lb_algo rr|wrr|lc|wlc|lblc|sh|dh //指定负载均衡调度算法; lb_kind NAT|DR|TUN //指定负载均衡集群的类型; persistence_timeout <INT> //启用持久链接并设置超时时间; protocol TCP //负载均衡服务支持的协议;目前仅支持TCP; sorry_server <IPADDR> <PORT> //若是后端RS所有不可用,则须要临时删除lvs集群服务,并设置本地的http服务为sorry-server,提供友好的错误页面; real_server <IPADDR> <PORT> { weight <INT> //指定当前RS的权重; notify_up <STRING>|<QUOTED-STRING> notify_down <STRING>|<QUOTED-STRING> //当RS的状态转为UP或DOWN时,发送通知所使用的脚本路径及参数设定; HTTP_GET|SSL_GET { url { path <STRING> //指定进行后端RS健康状态检测的URL地址; digest <STRING> //比较被检测资源的md5值是否发生变化; status_code <INT> //根据响应报文的状态码进行后端RS的健康状态检测; } nb_get_retry <INT> //指定对后端RS进行健康状态检测重试的次数上限; delay_before_retry <INT> //每次重试以前的延迟时间; connect_ip <IP ADDRESS> connect_port <PORT> //向后端RS的哪一个IP地址和哪一个端口发出健康状态检测请求; bindto <IP ADDRESS> bind_port <PORT> //向后端RS发出健康状态检测请求的源IP地址和源端口号; connect_timeout <INTEGER> //链接超时时间; } TCP_CHECK { connect_ip <IP ADDRESS> connect_port <PORT> //向后端RS的哪一个IP地址和哪一个端口发出健康状态检测请求; bindto <IP ADDRESS> bind_port <PORT> //向后端RS发出健康状态检测请求的源IP地址和源端口号; connect_timeout <INTEGER> //链接超时时间; } } }