1、原理回顾

1.1、集群知识回顾

集群特点:

1)高性能performance。 一些需要很强的运算处理能力比如天气预报,核试验等。这需要上千台计算器协同来完成这个工作的,共同分担计算任务。

2)价格相对便宜且可集中管理: 通常一套系统集群架构,只需要几台或数十台服务器主机即可,且这些计算机的性能实际使用中也不必太高,甚至可利旧老式的服务器,与动则上百王的专用超级计算机具有更高的性价比。

3)弹性伸缩性: 当服务器负载压力增长的时候,系统扩展将变得相对容易,从而来满足业务增长需求,且不降低服务质量。

4)高可用性: 尽管部分硬件和软件发生故障,整个系统的服务必须是7*24小时运行的,集群内成员节点故障对用户透明。一部分服务器宕机了业务不受影响,一般耦合度没有那么高,依赖关系没有那么高。

********************************* 集群架构按照功能和结构一般分以下几类*****************************

1)负载均衡集群(Loadbalancingclusters)简称LBC

2)高可用性集群(High-availabilityclusters)简称HAC

3)高性能计算集群(High-perfomanceclusters)简称HPC

4)网格计算(Gridcomputing)

常主要用前三个,负载均衡和高可用集群式在互联网行业尤其是最常用的集群架构。

(1)负载均衡集群

负载均衡集群为:把很多客户集中访问的请求负载压力可能尽可能平均的分摊到计算机集群中处理。客户请求负载通常包括应用程度处理负载和网络流量负载。这样的系统非常适合向使用同一组应用程序为大量用户提供服务。每个节点都可以承担一定的访问请求负载压力,并且可以实现访问请求在各节点之间动态分配,以实现负载均衡。从而实现集群分担访问流量(负载均衡)和保持业务的连续性(高可用)。

负载均衡集群的实现方式,一般通过一个或多个前端负载均衡器将客户访问请求分发到后端一组服务器(即我们的RS上:真实服务器)上,从而达到整个系统的高性能和高可用性。一般高可用性集群和负载均衡集群会使用类似的技术,或同时具有高可用性与负载均衡的特点。

(2)高可用性集群

一般是指当集群中的任意一个节点失效的情况下,节点上的所有任务自动转移到其他正常的节点上,并且此过程不影响整个集群的运行,不影响业务的正常对外访问。

这类集群中通常运行着两个或两个以上的一样的节点,当某个主节点出现故障的时候,那么其他作为从 节点的节点就会自动接替主节点上面的任务。从节点可以接管主节点的资源(IP地址,架构身份等),此时用户不会发现提供服务的对象从主节点转移到从节点。

高可用性集群的作用:当一个机器宕机另一台进行接管,对用户透明。比较常用的高可用集群开源软件有:keepalive,heardbeat。

(3)高性能计算集群

高性能计算集群采用将计算任务分配到集群的不同计算节点儿提高计算能力,因而主要应用在科学计算领域。比较流行的HPC采用Linux操作系统和其它一些免费软件来完成并行运算。这一集群配置通常被称为Beowulf集群。这类集群通常运行特定程序以发挥HPCcluster的并行能力。这类程序一般应用特定的运行库, 比如专为科学计算设计的MPI库。HPC集群特别适合于在计算中各计算节点之间发生大量数据通讯的计算作业,比如一个节点的中间结果或影响到其它节点计算结果的情况。

常用集群软硬件:

常用开源集群软件有:lvs,keepalived,haproxy,nginx,apache,heartbeat

常用商业集群硬件有:F5,Netscaler,Radware,A10

1.2、LVS原理

LVS(linux virtual server)linux虚拟服务器,是一个虚拟的服务器集群系统,可以在unix/linux平台下实现负载均衡集群功能。该项目在1998年5月由我国章文嵩博士组织成立。该集群基于IP层基于内容请求分发的负载平衡调度解决方法,并在Linux内核中实现了这些方法,将一组服务器构成一个实现可伸缩的、高可用网络服务的虚拟服务器。

lvs集群和上联交换机运行 OSPF lvs nginx集群_keepalive


lvs集群和上联交换机运行 OSPF lvs nginx集群_原理_02


如上图所示,一组服务器通过高速的局域网或者地理分布的广域网相互连接,在它们的前端有一个负载调度器(Load Balancer)(负载调度器能够支持绝大多数的TCP和UDP协议)。负载调度器能无缝地将网络请求调度到真实服务器上,从而使得服务器集群的结构对客户是透明的,客户访问集群系统提供的网络服务就像访问一台高性能、高可用的服务器一样。客户程序不受服务器集群的影响不需作任何修改。系统的伸缩性通过在服务机群中透明地加入和删除一个节点来达到,该集群中通过检测节点或服务进程故障和正确地重置系统达到高可用性。由于该方案负载调度技术是在Linux内核中实现的,章教授团队为之起名为Linux虚拟服务器(Linux Virtual Server)。LVS提供了一个实现可伸缩网络服务的Linux Virtual Server框架。

一般来说,LVS集群采用三层结构,层与层之间相互独立,每一个层次提供不同的功能,但三者会通过高速网络相连接,如100Mbps交换网络、Myrinet和Gigabit网络等。使用高速的网络,主要为避免当系统规模扩大时互联网络成为整个系统的瓶颈。

负载调度器(load balancer,又称为DR<Director Server>),它是整个集群对外面的前端机,负责将客户的请求发送到一组服务器上执行,而客户认为服务是来自一个IP地址(我们可称之为虚拟IP地址)上的,即我们的VIP(虚拟IP地址)。调度器是服务器集群系统的唯一入口点(Single Entry Point),它可以采用IP负载均衡技术、基于内容请求分发技术或者两者相结合。在基于内容请求分发技术中,服务器可以提供不同的服务,当客户请求到达时,调度器可根据请求的内容选择服务器 执行请求。因为所有的操作都是在Linux操作系统核心空间中将完成的,它的调度开销很小,所以它具有很高的吞吐率。另外,为保证集群的高可用,调度器上有资源监测进程来时刻监视各个服务器结点的健康状况。当服务器对ICMP ping不可达时或者探测她的网络服务在指定的时间没有响应时,资源监测进程通知操作系统内核将该服务器从调度列表中删除或者失效。这样,新的服务请求就 不会被调度到坏的结点。资源监测进程能通过电子邮件或传呼机向管理员报告故障。一旦监测进程到服务器恢复工作,通知调度器将其加入调度列表进行调度。另 外,通过系统提供的管理程序,管理员可发命令随时可以将新机器加入服务来提高系统的处理性能,针对调度器本身,一般也设置主从结构,保证DR的高可用,集群DR上配置两个心跳(Heartbeat)进程[分别在主、从调度器上运行,它们通过串口线和UDP等心跳线来相互定时地汇报各自的健康状况。当从调度器不能听得主调度器的心跳时,从调度器通过ARP欺骗 (Gratuitous ARP)来接管集群对外的Virtual IP Address,同时接管主调度器的工作来提供负载调度服务。当主调度器恢复时,这里有两种方法,一是主调度器自动变成从调度器,二是从调度器释放 Virtual IP Address,主调度器收回Virtual IP Address并提供负载调度服务。这里,多条心跳线可以使得因心跳线故障导致误判(即从调度器认为主调度器已经失效,其实主调度器还在正常工作)。另外为了防止主DR宕机切换从DR时,用户会话/已建立连接的状态丢失,LVS调度器在Linux 内核中实现一种高效状态同步机制,将主调度器的状态信息及时地同步到从调度器。当从调度器接管时,绝大部分用户已建立的连接会持续下去。

服务器池(server pool),是一组真正执行客户请求的服务器,执行的服务有WEB、MAIL、FTP和DNS等。根据业务不同峰值,可弹性扩展服务器池,整个系统的性能基本上可以随着服务器池的结点数目增加而线性增长。

共享存储(shared storage),它为服务器池提供一个共享的存储区,这样很容易使得服务器池拥有相同的内容,提供相同的服务;共享存储通常是数据库、网络文件系统或者分布式文件系统。动态更新的数据一般存储在数据库系统中,同时数据库会保证并发 访问时数据的一致性。静态的数据可以存储在网络文件系统(如NFS/CIFS)中,但网络文件系统的伸缩能力有限,一般来说,NFS/CIFS服务器只能支持3~6个繁忙的服务器结点。对于规模较大的集群系统,可以考虑用分布式文件系统,如AFS、GFSCoda和 Intermezzo等。分布式文件系统可为各服务器提供共享的存储区,它们访问分布式文件系统就像访问本地文件系统一样,同时分布式文件系统可提供良好的伸缩性和可用性。此外,当不同服务器上的应用程序同时读写访问分布式文件系统上同一资源时,应用程序的访问冲突需要消解才能使得资源处于一致状 态。这需要一个分布式锁管理器(Distributed Lock Manager),它可能是分布式文件系统内部提供的,也可能是外部的。开发者在写应用程序时,可以使用分布式锁管理器来保证应用程序在不同结点上并发访 问的一致性。之所以使用共享存储,是考虑到当网络服务需要有相同的内容,非共享架构中每台服务器需要将相同的内容复制到本地硬盘上。当系统存储的内容越多,这种无共享结构(Shared-nothing Structure)的代价越大,因为每台服务器需要一样大的存储空间,任何的更新需要涉及到每台服务器,系统的维护代价会非常高。

Graphic Monitor是为系统管理员提供整个集群系统的监视器,它可以监视系统的状态。Graphic Monitor是基于浏览器的,所以无论管理员在本地还是异地都可以监测系统的状况。为了安全的原因,浏览器要通过HTTPS(Secure HTTP)协议和身份认证后,才能进行系统监测,并进行系统的配置和管理。

在LVS框架中,提供了含有三种IP负载均衡技术的IP虚拟服务器软件IPVS、基于内容请求分发的内核Layer-7交 换机KTCPVS和集群管理软件。可以利用LVS框架实现高可伸缩的、高可用的Web、Cache、Mail和Media等网络服务;在此基础上,可以开 发支持庞大用户数的、高可伸缩的、高可用的电子商务应用。LVS服务器集群系统具有良好的伸缩性,可支持几百万个并发连接。配置100M网卡,采用VS/TUN或VS/DR调度技术,集群系统的吞吐量可高达1Gbits/s;如配置千兆网卡,则系统的最大吞吐量可接近10Gbits/s。LVS集群系统已被应用于很多重负载的站点。

LVS:Linux Vritual Server,项目的主页(http://www.LinuxVirtualServer.org/

LVS由ipvs和ipvsadm两部分组成:

1)ipvs:ipvs是工作在内核空间netfilter的input链上的框架,通过用户空间工具进行管理,其中是真正生效实现调度的代码。

2)ipvsadm:ipvsadm负责为ipvs内核框架编写规则,是管理配置内核中ipvs程序的用户空间的管理工具。

LVS是工作在linux内核空间的tcp/ip栈的应用程序,其程序名称为ipvs。ipvs会监听input链上的请求,一旦请求的是集群服务的话,ipvs钩子函数会将请求拉出并进行报文修改,强制转发到postrouting处理,关系如下图所示:

lvs集群和上联交换机运行 OSPF lvs nginx集群_lvs集群和上联交换机运行 OSPF_03


对于客户端来说,LVS就是一个真实的应用服务器。客户端向LVS发送请求信息,LVS接收数据报文至内核空间,工作在input链上的ipvs模块会判断用户请求是不是定义的后端服务器,如果用户请求的就是定义的后端集群服务,数据报文传送到input链上时,input链会强行将数据报文转发给postrouting,postrouting将数据报文传送给后端真实服务器。LVS的特点在于超强的分流功能,但它只能负责调度流量的去向,没有办法实现在业务层分流负载。

LVS可以独立使用,但我们实际常将其与Keepalived一起使用,LVS提供负载均衡,Keepalived提供健康检查,故障转移,提高系统的可用性。Keepalived中的LVS配置包括虚拟主机组(Virtual Server Group)和虚拟主机(Virtual Server)。这些配置会传递给ipvsadm作为参数。采用这样的架构以后,很容易对现有系统进行扩展,在后端添加或者减少realserver后,只需要更改Keepalived配置文件中的LVS部分即可。

这里我们在Linux平台主要应用IPvs软件实现,从2.4.24以后IPVS已经成为linux官方标准内核的一部分;IPVS软件实现了这三种IP负载均衡技术

1)Virtual Server via Network Address Translation(LVS/NAT)

通过网络地址转换,调度器重写请求报文的目标地址,根据预设的调度算法,将请求分派给后端真实服务器;真实服务器的响应报文通过调度器时,报文的源地址被重写,再返回给客户,完成整个负载调度过程。

Virtual Server via IP Tunneling(LVS/TUN)
采用NAT技术时,由于请求和响应报文都必须经过调度器地址重写,当客户请求越来越多时,调度器的处理能力将成为瓶颈。为了解决这个问题,调度器把请求报文通过IP隧道转发至真实服务器,而真实服务器将响应直接返回给客户,所以调度器只处理请求报文。由于一般网络服务应答比请求报文大许多,采用 LVS/TUN技术后,集群系统的最大吞吐量可以提高10倍。

2)Virtual Server via Direct Routing(LVS/DR)

DR通过改写请求报文的MAC地址,将请求发送到真实服务器,而真实服务器将响应直接返回给客户。同LVS/TUN技术一样,LVS/DR技术可极大地提高集群系统的伸缩性。这种方法没有IP隧道的开销,对集群中的真实服务器也没有必须支持IP隧道协议的要求,但是要求调度器与真实服务器都有一块网卡连在同一物理网段上。

针对不同的网络服务需求和服务器配置,IPVS调度器实现了如下八种负载调度算法:

轮循(Round Robin)
调度器通过"轮叫"调度算法将外部请求按顺序轮流分配到集群中的真实服务器上,它均等地对待每一台服务器,而不管服务器上实际的连接数和系统负载。

加权轮循(Weighted Round Robin)

调度器通过"加权轮叫"调度算法根据真实服务器的不同处理能力来调度访问请求。这样可以保证处理能力强的服务器处理更多的访问流量。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。

最少链接(Least Connections)

调度器通过"最少连接"调度算法动态地将网络请求调度到已建立的链接数最少的服务器上。如果集群系统的真实服务器具有相近的系统性能,采用"最小连接"调度算法可以较好地均衡负载。

加权最少链接(Weighted Least Connections)

在集群系统中的服务器性能差异较大的情况下,调度器采用"加权最少链接"调度算法优化负载均衡性能,具有较高权值的服务器将承受较大比例的活动连接负载。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。

基于局部性的最少链接(Locality-Based Least Connections)

“基于局部性的最少链接” 调度算法是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。该算法根据请求的目标IP地址找出该目标IP地址最近使用的服务器,若该服务器 是可用的且没有超载,将请求发送到该服务器;若服务器不存在,或者该服务器超载且有服务器处于一半的工作负载,则用"最少链接"的原则选出一个可用的服务 器,将请求发送到该服务器。

带复制的基于局部性最少链接(Locality-Based Least Connections with Replication)

"带复制的基于局部性最少链接"调度算法也是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。它与LBLC算法的不同之处是它要维护从一个 目标IP地址到一组服务器的映射,而LBLC算法维护从一个目标IP地址到一台服务器的映射。该算法根据请求的目标IP地址找出该目标IP地址对应的服务 器组,按"最小连接"原则从服务器组中选出一台服务器,若服务器没有超载,将请求发送到该服务器,若服务器超载;则按"最小连接"原则从这个集群中选出一 台服务器,将该服务器加入到服务器组中,将请求发送到该服务器。同时,当该服务器组有一段时间没有被修改,将最忙的服务器从服务器组中删除,以降低复制的 程度。

目标地址散列(Destination Hashing)

"目标地址散列"调度算法根据请求的目标IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。

源地址散列(Source Hashing)

"源地址散列"调度算法根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。

1.3 LVS集群架构案例

1.3.1、可伸缩Web服务

lvs集群和上联交换机运行 OSPF lvs nginx集群_keepalive_04


第一层是负载调度器,一般采用IP负载均衡技术,可以使得整个系统有较高的吞吐率;第二层是 Web服务器池,在每个结点上可以分别运行HTTP服务或HTTPS服务、或者两者都运行;第三层是共享存储,它可以是数据库,可以是网络文件系统或分布 式文件系统,或者是三者的混合。集群中各结点是通过高速网络相连接的。

1.3.2、可伸缩媒体服务

lvs集群和上联交换机运行 OSPF lvs nginx集群_lvs集群和上联交换机运行 OSPF_05


IPVS负载调度器一般使用直接路由方法(即LVS/DR方法,),来架构媒体集群系统。调度器将媒体服务请求较均衡地分发到 各个服务器上,而媒体服务器将响应数据直接返回给客户,这样可以使得整个媒体集群系统具有很好的伸缩性。

媒体服务器可以运行各种媒体服务软件。目前,LVS集群对于Real Media、Windows Media和Apple Quicktime媒体服务都有很好的支持,都有真实的系统在运行。一般来说,流媒体服务都会使用一个TCP连接(如RTSP协议:Real-Time Streaming Protocol)进行带宽的协商和流速的控制,通过UDP将流数据返回客户。这里,IPVS调度器提供功能将TCP和UDP集中考虑,保证来自同一客户 的媒体TCP和UDP连接会被转发到集群中同一台媒体服务器,使得媒体服务准确无误地进行。

共享存储是媒体集群系统中最关键的问题,因为媒体文件往往非常大(一部片子需要几百兆到几千兆的存储空间),这对存储的容量和读的速度 有较高的要求。对于规模较小的媒体集群系统,例如有3至6个媒体服务器结点,存储系统可以考虑用带千兆网卡的Linux服务器,使用软件RAID和日志型 文件系统,再运行内核的NFS服务;对于规模较大的媒体集群系统,最好选择对文件分段(File Stripping)存储和文件缓存有较好支持的分布式文件系统;媒体文件分段存储在分布式文件系统的多个存储结点上,可以提高文件系统的性能和存储结点 间的负载均衡;媒体文件在媒体服务器上自动地被缓存,可提高文件的访问速度。

1.3.3、可伸缩Cache服务

lvs集群和上联交换机运行 OSPF lvs nginx集群_原理_06


第一层是负载调度器,一般采用IP负载均衡技术,可以使得整个系统有较高的吞吐率; 第二层是Cache服务器池,一般Cache服务器放置在接近主干Internet连接处,它们可以分布在不同的网络中。调度器可以有多个,放在离客户接 近的地方。

IPVS负载调度器一般使用IP隧道方法(即VS/TUN方法,将在以后文章中详细叙述),来架构Cache集群系统,因为Cache服务器可能被 放置不同的地方(例如在接近主干Internet连接处),而调度器与Cache服务器池可能不在同一个物理网络中。采用VS/TUN方法,调度器只调度 Web Cache请求,而Cache服务器将响应数据直接返回给客户。在请求对象不能在本地命中的情况下,Cache服务器要向源服务器发请求,将结果取回,最 后将结果返回给客户;若采用NAT技术的商品化调度器,需要四次进出调度器,完成这个请求。而用VS/TUN方法(或者VS/DR方法),调度器只调度一 次请求,其他三次都由Cache服务器直接访问Internet完成。所以,这种方法对Cache集群系统特别有效。

Cache服务器采用本地硬盘来存储可缓存的对象,因为存储可缓存的对象是写操作,且占有一定的比例,通过本地硬盘可以提高I/O的访 问速度。Cache服务器间有专用的多播通道(Multicast Channel),通过ICP协议(Internet Cache Protocol)来交互信息。当一台Cache服务器在本地硬盘中未命中当前请求时,它可以通过ICP查询其他Cache服务器是否有请求对象的副本, 若存在,则从邻近的Cache服务器取该对象的副本,这样可以进一步提高Cache服务的命中率。

1.3.4、可伸缩邮件服务

lvs集群和上联交换机运行 OSPF lvs nginx集群_ninx_07


前端是一个采用IP负载均衡技术的负载调度器;第二层 是服务器池,有LDAP(Light-weight Directory Access Protocol)服务器和一组邮件服务器。第三层是数据存储,通过分布式文件系统来存储用户的邮件。集群中各结点是通过高速网络相连接。

用户的信息如用户名、口令、主目录和邮件容量限额等存储在LDAP服务器中,可以通过HTTPS让管理员进行用户管理。在各个邮件服务 器上运行SMTP(Simple Mail Transfer Protocol)、POP3(Post Office Protocol version 3)、IMAP4(Internet Message Access Protocol version 4)和HTTP/HTTPS服务。SMTP接受和转发用户的邮件,SMTP服务进程查询LDAP服务器获得用户信息,再存储邮件。POP3和IMAP4通 过LDAP服务器获得用户信息,口令验证后,处理用户的邮件访问请求。这里,需要有机制避免不同服务器上的SMTP、POP3和IMAP4服务进程对用户 邮件的读写冲突。HTTP/HTTPS服务是让用户通过浏览器可以访问邮件。

IPVS调度器将SMTP、POP3、IMAP4和HTTP/HTTPS请求流负载较均衡地分发到各邮件服务器上,从上面各服务的处理 流程来看,不管请求被发送到哪一台邮件服务器处理,其结果是一样的。这里,将SMTP、POP3、IMAP4和HTTP/HTTPS运行在各个邮件服务器 上进行集中调度,有利于提高整个系统的资源利用率。

系统中可能的瓶颈是LDAP服务器,对LDAP服务中B+树的参数进行优化,再结合高端的服务器,可以获得较高的性能。若分布式文件系 统没有多个存储结点间的负载均衡机制,则需要相应的邮件迁移机制来避免邮件访问的倾斜。

1.3.5、NAT实现虚拟服务器(LVS/NAT)

lvs集群和上联交换机运行 OSPF lvs nginx集群_ninx_08


在一组服务器前有一个调度器,它们是通过Switch/HUB相连接的。这些服务器 提供相同的网络服务、相同的内容,即不管请求被发送到哪一台服务器,执行结果是一样的。服务的内容可以复制到每台服务器的本地硬盘上,可以通过网络文件系 统(如NFS)共享,也可以通过一个分布式文件系统来提供。客户通过Virtual IP Address(虚拟服务的IP地址)访问网络服务时,请求报文到达调度器,调度器根据连接调度算法从一组真实服务器中选出一台服务器,将报文的目标地址 Virtual IP Address改写成选定服务器的地址,报文的目标端口改写成选定服务器的相应端口,最后将修改后的报文发送给选出的服务器。同时,调度器在连接Hash 表中记录这个连接,当这个连接的下一个报文到达时,从连接Hash表中可以得到原选定服务器的地址和端口,进行同样的改写操作,并将报文传给原选定的服务 器。当来自真实服务器的响应报文经过调度器时,调度器将报文的源地址和源端口改为Virtual IP Address和相应的端口,再把报文发给用户。我们在连接上引入一个状态机,不同的报文会使得连接处于不同的状态,不同的状态有不同的超时值。在TCP 连接中,根据标准的TCP有限状态机进行状态迁移,这里我们不一一叙述,请参见W. Richard Stevens的《TCP/IP Illustrated Volume I》;在UDP中,我们只设置一个UDP状态。不同状态的超时值是可以设置的,在缺省情况下,SYN状态的超时为1分钟,ESTABLISHED状态的超 时为15分钟,FIN状态的超时为1分钟;UDP状态的超时为5分钟。当连接终止或超时,调度器将这个连接从连接Hash表中删除。

这样,客户所看到的只是在Virtual IP Address上提供的服务,而服务器集群的结构对用户是透明的。对改写后的报文,应用增量调整Checksum的算法调整TCP Checksum的值,避免了扫描整个报文来计算Checksum的开销。

在 一些网络服务中,它们将IP地址或者端口号在报文的数据中传送,若我们只对报文头的IP地址和端口号作转换,这样就会出现不一致性,服务会中断。所以,针 对这些服务,需要编写相应的应用模块来转换报文数据中的IP地址或者端口号。我们所知道有这个问题的网络服务有FTP、IRC、H.323、 CUSeeMe、Real Audio、Real Video、Vxtreme / Vosiac、VDOLive、VIVOActive、True Speech、RSTP、PPTP、StreamWorks、NTT AudioLink、NTT SoftwareVision、Yamaha MIDPlug、iChat Pager、Quake和Diablo。

1.3.6、通过IP隧道实现虚拟服务器(LVS/TUN)

lvs集群和上联交换机运行 OSPF lvs nginx集群_lvs集群和上联交换机运行 OSPF_09


在VS/NAT 的集群系统中,请求和响应的数据报文都需要通过负载调度器,当真实服务器的数目在10台和20台之间时,负载调度器将成为整个集群系统的新瓶颈。大多数 Internet服务都有这样的特点:请求报文较短而响应报文往往包含大量的数据。如果能将请求和响应分开处理,即在负载调度器中只负责调度请求而响应直 接返回给客户,将极大地提高整个集群系统的吞吐量。

IP隧道(IP tunneling)是将一个IP报文封装在另一个IP报文的技术,这可以使得目标为一个IP地址的数据报文能被封装和转发到另一个IP地址。IP隧道技 术亦称为IP封装技术(IP encapsulation)。IP隧道主要用于移动主机和虚拟私有网络(Virtual Private Network),在其中隧道都是静态建立的,隧道一端有一个IP地址,另一端也有唯一的IP地址。

我们利用IP隧道技术将请求报文封装转 发给后端服务器,响应报文能从后端服务器直接返回给客户。但在这里,后端服务器有一组而非一个,所以我们不可能静态地建立一一对应的隧道,而是动态地选择 一台服务器,将请求报文封装和转发给选出的服务器。这样,我们可以利用IP隧道的原理将一组服务器上的网络服务组成在一个IP地址上的虚拟网络服务。 VS/TUN的体系结构如图4所示,各个服务器将VIP地址配置在自己的IP隧道设备上。

lvs集群和上联交换机运行 OSPF lvs nginx集群_ninx_10


VS/TUN 的工作流程如上图所示:它的连接调度和管理与VS/NAT中的一样,只是它的报文转发方法不同。调度器根据各个服务器的负载情况,动态地选择一台服务器, 将请求报文封装在另一个IP报文中,再将封装后的IP报文转发给选出的服务器;服务器收到报文后,先将报文解封获得原来目标地址为VIP的报文,服务器发 现VIP地址被配置在本地的IP隧道设备上,所以就处理这个请求,然后根据路由表将响应报文直接返回给客户。

根据缺省的TCP/IP协议栈处理,请求报文的目标地址为VIP,响应报文的源地址肯定也为VIP,所以响应报文不需要作任何修改,可以直接返回给客户,客户认为得到正常的服务,而不会知道究竟是哪一台服务器处理的。

lvs集群和上联交换机运行 OSPF lvs nginx集群_lvs集群和上联交换机运行 OSPF_11

1.3.7、通过直接路由实现虚拟服务器(LVS/DR)

lvs集群和上联交换机运行 OSPF lvs nginx集群_lvs集群和上联交换机运行 OSPF_12


VS/DR利用大多数Internet服务的非对称特点,负载调度器中只负责调度请求,而服务器直接将响应返回给客户,可以极大地提高整个集群 系统的吞吐量。该方法与IBM的NetDispatcher产品中使用的方法类似(其中服务器上的IP地址配置方法是相似的),但IBM的 NetDispatcher是非常昂贵的商品化产品,我们也不知道它内部所使用的机制,其中有些是IBM的专利。VS/DR的体系结构如图

lvs集群和上联交换机运行 OSPF lvs nginx集群_lvs集群和上联交换机运行 OSPF_13

所示:调度器和服务器组都必须在物理上有一个网卡通过不分断的局域网相连,如通过高速的交换机或者HUB相连。VIP地址为调度器和服务器组共享,调度 器配置的VIP地址是对外可见的,用于接收虚拟服务的请求报文;所有的服务器把VIP地址配置在各自的Non-ARP网络设备上,它对外面是不可见的,只 是用于处理目标地址为VIP的网络请求。

1.4 Keepalived架构

lvs集群和上联交换机运行 OSPF lvs nginx集群_lvs_14


Keepalived的作用是检测服务器的状态,如果有一台服务器宕机,或工作出现故障,Keepalived将检测到,并将有故障的服务器从系统中剔除,同时使用其它服务器代替该服务器的工作,当服务器工作正常后Keepalived自动将服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的服务器。

Keepalived是对VRRP的一个实现, VRRP(虚拟路由冗余协议,Virtual Router Redundancy Protocol)的目的是为了解决静态路由单点故障问题,它通过一种竞选(election)协议动态地将路由任务交给LAN中虚拟路由器中的某台VRRP路由器。

如上图所示Keepalived的功能体系结构,大致分两层:用户空间(user space)和内核空间(kernel space)。Keepalived的所有功能是配置keepalived.conf文件来实现的。

内核空间:主要包括IPVS(IP虚拟服务器,用于实现网络服务的负载均衡)和NETLINK(提供高级路由及其他相关的网络功能)两个部份。

1)VRRP路由器: VRRP路由器就是一台路由器,只不过上面运行了VRRPD程序来实现VRRP协议而已,是物理的路由器。一台VRRP路由器可以位于多个虚拟路由器中。

2)虚拟路由器: 虚拟路由器通常由多台VRRP路由器通过某种方式组成,就好像将这些物理路由器都丢到一个池里面去,整个池对外看起来就像是一台路由器,但其实内部有多台。虚拟路由器的标识称为VRID。

用户空间:
WatchDog:负载监控checkers和VRRP进程的状况
VRRP Stack:负载负载均衡器之间的失败切换FailOver,如果只用一个负载均稀器,则VRRP不是必须的。
Checkers:负责真实服务器的健康检查healthchecking,是keepalived最主要的功能。换言之,可以没有VRRP Stack,但健康检查healthchecking是一定要有的。
IPVS wrapper:用户发送设定的规则到内核ipvs代码
Netlink Reflector:用来设定vrrp的vip地址等。

在一个VRRP虚拟路由中,有多台物理的VRRP路由器,但是这多台物理路由并不同时工作,而是由一台称为master的负责路由工作,其它的都是backup。master并非一成不变,VRRP协议让每个VRRP路由器参与竞选,最终获胜的就是master。master有一些特权,比如拥有虚拟路由器的IP地址,我们的主机就是用这个IP地址作为静态路由的。拥有特权的master要负责转发发送给网关地址的包和响应ARP请求。

lvs集群和上联交换机运行 OSPF lvs nginx集群_原理_15

【工作原理】

Keepalived的高可用是通过组内的VRRP通信的,其中,关于VRRP又如下作用:

  1. VRRP,全称 Virtual Router Redundancy Protocol,中文名为虚拟路由冗余协议,VRRP的出现是为了解决静态路由的单点故障。
  2. VRRP是通过一种竟选协议机制来将路由任务交给某台 VRRP路由器的。
  3. VRRP用 IP多播的方式(默认多播地址(224.0_0.18))实现高可用对之间通信。
  4. 工作时主节点发包,备节点接包,当备节点接收不到主节点发的数据包的时候,就启动接管程序接管主节点的开源。备节点可以有多个,通过优先级竞选,但一般 Keepalived多以一对形式出现。
  5. VRRP使用了加密协议加密数据,但Keepalived官方目前还是推荐用明文的方式配置认证类型和密码。

   &#8194通过以上回顾,keepalive借用VRRP,它通过竞选协议来实现虚拟路由器的功能,所有的协议报文都是通过IP多播(multicast)包形式发送的,多播地址为224.0.0.18。虚拟路由器由VRID(范围0-255)和一组IP地址组成,对外表现为一个众所周知的MAC地址:00-00-5E-00-01-{VRID}。所以,在一个虚拟路由器中,不管谁是master,对外都是相同的MAC和IP(称之为VIP)。客户端主机并不需要因为master的改变而修改自己的路由配置,对它们来说,这种主从的切换是透明的。

    在一个虚拟路由器中,只有作为master的VRRP路由器会一直发送VRRP广告包(VRRP Advertisement Message),backup不会抢占master,除非它的优先级更高。当master不可用时,backup收不到广告包,多台backup中优先级最高的这台会抢占为master。这种抢占是非常快速的(<1秒),以保证服务的连续性。出于安全性考虑,VRRP包使用了加密协议进行加密。

tail -f /var/log/messages|grep -i keepalived  #输出如下

Oct 30 19:28:55 localhost Keepalived_vrrp[84358]: Warning - script chk_mysql is not used
Oct 30 19:28:55 localhost Keepalived_vrrp[84358]: Registering gratuitous ARP shared channel
Oct 30 19:28:55 localhost Keepalived_vrrp[84358]: Registering gratuitous NDISC shared channel
Oct 30 19:28:55 localhost Keepalived_vrrp[84358]: (VI_1) removing VIPs.
Oct 30 19:28:55 localhost Keepalived_vrrp[84358]: (VI_1) removing E-VIPs.
Oct 30 19:28:55 localhost Keepalived_vrrp[84358]: (VI_1) Entering BACKUP STATE (init)
Oct 30 19:28:55 localhost Keepalived_vrrp[84358]: VRRP sockpool: [ifindex(  3), family(IPv4), proto(112), fd(14,15)]
Oct 30 19:28:56 localhost Keepalived_healthcheckers[84357]: TCP connection to [100.2.7.13]:tcp:3306 success.
Oct 30 19:28:57 localhost Keepalived_healthcheckers[84357]: TCP connection to [100.2.7.12]:tcp:3306 success.
Oct 30 19:29:01 localhost Keepalived_healthcheckers[84357]: TCP connection to [2409:8080::0:13]:tcp:3306 success.
Oct 30 19:29:02 localhost Keepalived_healthcheckers[84357]: TCP connection to [2409:8080::0:12]:tcp:3306 success.

2、LVS+keepalived实现负载均衡&高可用(来源网络)

2.1 案例1:Keepalived+LVS+MySQL双主复制实现读写负载均衡及高可用

lvs集群和上联交换机运行 OSPF lvs nginx集群_keepalive_16


1、【环境】:

172.16.1.124:Keepalived + LVS Master
172.16.1.125:Keepalived + LVS Slave
172.16.1.126:MySQL Replication Master
172.16.1.127:MySQL Replication Master
172.16.1.100:VIP
注:本案中之所以要使用MySQL双主复制而不是主从复制,是因为本方案中并没有涉及读写分离,而是在两个等价的MySQL服务器之间做读写负载均衡。

2、部署配置:

1)124和125这2台DR上安装LVS和Keepalived,执行:

yum -y install ipvsadm
 wget -q http://www.keepalived.org/software/keepalived-1.2.13.tar.gz
 tar -zxvf keepalived-1.2.13.tar.gz
 cd keepalived-1.2.13
 ./configure && make && make install
 cp /usr/local/etc/rc.d/init.d/keepalived /etc/rc.d/init.d/  //在编译后的keepalived目录下
 cp /usr/local/etc/sysconfig/keepalived /etc/sysconfig/
 mkdir /etc/keepalived
 cp /usr/local/etc/keepalived/keepalived.conf /etc/keepalived/
 cp /usr/local/sbin/keepalived /usr/sbin/
 chkconfig --add keepalived
 chkconfig --level 345 keepalived on
 systemctl start keepalived
 systemctl status keepalived  //验证vip是否正常
 telnet vip port //验证虚拟服务是否正常

2)配置:

1> master的keepalived配置文件如下: vi /etc/keepalived/keepalived.conf

global_defs {
   router_id LVS_HA   //唯一标识,一组内的要相同;
    #vrrp_strict                #配置这个参数将不能直接访问本机服务
} 

vrrp_sync_group VG1 {  ##VRRP同步组,Sync Group里面任一个实例出现问题都会触发切换
group {
VI_1					##同步组中VRRP实例名
}
}

vrrp_instance VI_1 {    ##配置VRRP实例
    state BACKUP		##VRRP实例的初始状态。两台路由都启动后,马上会发生竞争,高priority的会竞选为Master
    interface ens32   ##实例绑定的网卡
    virtual_router_id 51   ##虚拟路由ID标记,默认51;同一vrrp_instance 下virtual_router_id必须相同
    priority 100    ## 优先级高的为master
    advert_int 1  ##实例状态检查时间间隔,默认为1s;
    nopreempt   ##表不抢占,该配置只能设置在state为BACKUP的主机上,当MASTER出现问题后,BACKUP会竞选为新的MASTER,那么当之前的MASTER重新在线后,如未配置不抢占,之前的master会重新抢占称为新master,导致业务切换;因nopreempt配置只能用在state为BACKUP的主机上,因此MASTER的state也需配置为BACKUP,通过不同的priority,优先级高的抢占为初始master主机。
    authentication {				##设置认证类型和认证密码
        auth_type PASS     		##认证类型,支持PASS、AH两种
        auth_pass 1234			##明文认证密码。同一VRRP的2个实例必须使用相同的密码才能正常通信
    }
    virtual_ipaddress {
        172.16.1.100
    }
}
    virtual_server 172.16.1.100 3306 {	# 定义虚拟服务器,地址与上面的virtual_ipaddress相同
    delay_loop 3			        # 健康检查时间间隔,3秒
    lb_algo rr				        # 负载均衡调度算法:rr|wrr|lc|wlc|sh|dh|lblc
    lb_kind DR				        # 负载均衡转发规则:NAT|DR|TUN
    # persistence_timeout 5	        # 会话保持时间5秒,动态服务建议开启
    protocol TCP			        # 转发协议protocol,一般有tcp和udp两种
   
    sorry_server 172.16.1.129 1358   #定义备用服务器,当所有RS都故障时用sorry_server来响应客户端


    #后端真实服务器,有几台就设置几个
    real_server 172.16.1.126 3306 {
        weight 1			        # 权重越大负载分越大,0表示失效
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
        }
    }
    real_server 172.16.1.127 3306 {
        weight 1
        TCP_CHECK {
            connect_timeout 3   ##定义连接超时时间,单位是秒
            nb_get_retry 3         ##指定重连次数
            delay_before_retry 3   ##指定重连的时间间隔,单位是秒
            connect_port 3306    ##指定健康检查的端口
        }
    }
}

#其他
global_defs { //全局配置

notification_email { //定义报警收件人邮件地址

acassen@firewall.loc

failover@firewall.loc

sysadmin@firewall.loc

}

notification_email_from Alexandre.Cassen@firewall.loc //定义报警发件人邮箱

smtp_server 192.168.200.1 //邮箱服务器地址

smtp_connect_timeout 30 //定义邮箱超时时间
……
}

2> slave的keepalived配置文件如下:

global_defs {
   router_id LVS_HA    ##运行Keepalived的机器的一个标识
} 

vrrp_sync_group VG1 {
group {
VI_1   #与master一致
}
}
#添加一个周期性执行的脚本。脚本的退出状态码会被调用它的所有的VRRP Instance记录。//注意:至少有一个VRRP实例调用它并且优先级不能为0.优先级范围是1-254.

vrrp_script <SCRIPT_NAME> {

script "/path/to/somewhere" //指定要执行的脚本的路径。

interval <INTEGER> //指定脚本执行的间隔。单位是秒。默认为1s。

timeout <INTEGER> //指定在多少秒后,脚本被认为执行失败。

weight <-254 --- 254> //调整优先级。默认为2.

rise <INTEGER> //执行成功多少次才认为是成功。

fall <INTEGER> //执行失败多少次才认为失败。

user <USERNAME> [GROUPNAME] //运行脚本的用户和组。

init_fail //假设脚本初始状态是失败状态。

//weight说明: 1. 如果脚本执行成功(退出状态码为0),weight大于0,则priority增加。2. 如果脚本执行失败(退出状态码为非0),weight小于0,则priority减少。3. 其他情况下,priority不变。
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens32  
    virtual_router_id 51
    priority 90  ##
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1234
    }
     virtual_ipaddress {
        172.16.1.100
    }
}

	virtual_server 172.16.1.100 3306 {	# 定义虚拟服务器,地址与上面的virtual_ipaddress相同
    delay_loop 3			        # 健康检查时间间隔,3秒
    lb_algo rr				        # 负载均衡调度算法:rr|wrr|lc|wlc|sh|dh|lblc,这里采用轮训
    lb_kind DR				        # 负载均衡转发规则:NAT|DR|TUN,这里采用直连
    # persistence_timeout 5	        # 会话保持时间5秒,动态服务建议开启
    protocol TCP			        # 转发协议protocol,一般有tcp和udp两种
 
    #后端真实服务器,有几台就设置几个
    
    real_server 172.16.1.126 3306 {
        weight 1			        # 权重越大负载分越大,0表示失效
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
        }
    }
    real_server 172.16.1.127 3306 {
        weight 1
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
        }
    }
}

mysql监测脚本:

#!/bin/bash
. /home/mysql/.bashrc
count=1

while true
do

mysql -uroot -S /data/mysql.sock -e "show status;" > /dev/null 2>&1
i=$?
ps aux | grep mysqld | grep -v grep > /dev/null 2>&1
j=$?
if [ $i = 0 ] && [ $j = 0 ]
then
   exit 0
else
   if [ $i = 1 ] && [ $j = 0 ]
   then
       exit 0
   else
        if [ $count -gt 5 ]
        then
              break
        fi
   let count++
   continue
   fi
fi

done

从上可知,master与slave的keepalived配置文件中只有priority设置不同,master为100,slave为90,其它全一样。

3> 编写RealServer的网络配置脚本

在172.16.1.126和172.16.1.127上建立/etc/init.d/realserver文件,内容如下:

#!/bin/sh
VIP=172.16.1.100
. /etc/rc.d/init.d/functions

case "$1" in
# 禁用本地的ARP请求、绑定本地回环地址
start)
    /sbin/ifconfig lo down
    /sbin/ifconfig lo up
    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
    /sbin/sysctl -p >/dev/null 2>&1
    /sbin/ifconfig lo:0 $VIP netmask 255.255.255.255 up # 在回环地址上绑定VIP,设定掩码,与Direct Server上自身的IP保持通信
    /sbin/route add -host $VIP dev lo:0
    echo "LVS-DR real server starts successfully.\n"
    ;;
stop)
    /sbin/ifconfig lo:0 down
    /sbin/route del $VIP >/dev/null 2>&1
    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
echo "LVS-DR real server stopped.\n"
    ;;
status)
    isLoOn=`/sbin/ifconfig lo:0 | grep "$VIP"`
    isRoOn=`/bin/netstat -rn | grep "$VIP"`
    if [ "$isLoON" == "" -a "$isRoOn" == "" ]; then
        echo "LVS-DR real server has run yet."
    else
        echo "LVS-DR real server is running."
    fi
    exit 3
    ;;
*)
    echo "Usage: $0 {start|stop|status}"
    exit 1
esac
exit 0

4> 授权脚本并加入开机启动:
chmod +x /etc/init.d/realserver
echo “/etc/init.d/realserver” >> /etc/rc.d/rc.local

5> 启动realserver服务:
systemctl start realserver

6> master上和slave上启动keepalived
/etc/init.d/keepalived start

7> 查看LVS集群状态:
ipvsadm -Ln

8>mysql 数据库登录验证:
mysql>mysql -umysql -p123456 -h172.16.1.100 -e “show variables like ‘server_id’”

±--------------±------+
| Variable_name | Value |
±--------------±------+
| server_id | 126 |
±--------------±------+

mysql>mysql -umysql -p123456 -h172.16.1.100 -e “show variables like ‘server_id’”

±--------------±------+
| Variable_name | Value |
±--------------±------+
| server_id | 127 |
±--------------±------+
参考:

2.2 案例2:LVS+keepalived实现MySQL读写分离+负载均衡

1)环境配置:
主机A:192.168.150.171
主机B:192.168.150.172
W-VIP:192.168.150.173 (负责写入)
R-VIP:192.168.150.174 (负责读取)

2)实现原理:
1>serverA和B,通过mysql的slave进程使用binlog同步数据。
2>通过keepalived启用两个虚IP:W-VIP/R-VIP,一个负责写入,一个负责读取,实现读写分离。
3>A和B都存在时,W-VIP下将请求转发至主机A,R-VIP将请求转发给A和B,实现负载均衡。
4>当主机A异常时,B接管服务,W-VIP/R-VIP此时漂到了主机B上,此时这两个虚IP下都是主机B,实现高可用
5>当主机B异常时,R-VIP会将B踢出,其它不变

其中,keepalived具有3~5层交换功能,3层机理是发送ICMP数据包即PING给某台服务器,如果不痛,则认为其故障,并从服务器群中剔除。4层机理是检测TCP端口号状态来判断某台服务器是否故障,如果故障,则从服务器群中剔除。5层机理是根据用户的设定检查某个服务器应用程序是否正常运行,如果不正常,则从服务器群中剔除。其主要作用是检测web服务器的状态,如果某台web服务器故障,Keepalived将检测到并将其从系统中剔除,当该web服务器工作正常后Keepalived自动将其加入到服务器 群中,这些工作全部自动完成,而不需要人工干预,只需要人工修复故障的web服务器即可。

3)软件部署

1>安装lvs

下载:wget http://www.linuxvirtualserver.org/software/kernel-2.6/ipvsadm-1.24.tar.gz
tar -zxvf ipvsadm-1.24.tar.gz
cd tar -zxvf ipvsadm-1.24
make
make install
yum install ipv* 安装
ipvsadm –v  //验证

2>安装keepalived

tar –zxvf keepalived-1.2.12.tar.gz
cd keepalived-1.2.12
./configure --prefix=/usr/local/keepalived/   //输出结果要返回,注意Use IPVS Framework、IPVS sync daemon support 、Use VRRP Framework要返回yes,否则无法关联ipvs功能
make
make install
ln -s /usr/local/keepalived/etc/keepalived /etc/
ln -s /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/rc.d/init.d/
ln -s /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
ln -s /usr/local/keepalived/bin/genhash /bin/
ln -s /usr/local/keepalived/sbin/keepalived /sbin/

注:/etc/keepalived目录安装时默认是没有安装的,需要手动创建。可将keepalived的安装目录下对应文件映射到系统目录下:
/etc/keepalived/keepalived.conf
/etc/rc.d/init.d/keepalived
/etc/sysconfig/keepalived
另外,keepalived启动时不会检查配置文件的语法是否正确,所以我们在编写配置文件时要特别小心,别写错了,否则会出现一些意想不到的现象。

设置keepalived服务开机启动:

chkconfig keepalived on
service keepalived start #启动服务
service keepalived stop #停止服务
service keepalived restart #重启服务

3>安装mysql
同上

4)配置mysql的主从

1>mysql-master:编辑/etc/my.cnf,添加以下内容

server-id = 1    ##master ID
binlog-do-db = ppl  ##允许同步的库
binlog-ignore-db = mysql  ##忽略同步的库,mysql是系统自带的库,可不用同步
log-bin = mysql-bin

完成之后执行:

mysql> grant replication slave on *.* to ‘repdb01’@’%’ identified by '123456';
mysql>create database db01;
mysql>flush logs;
mysql>show master status;
mysql>use db01
mysql> create table test(name char);

2>mysql-Slave配置:编辑/etc/my.cnf,添加以下内容

server-id = 2  ##slave ID
master-host = 192.168.150.171  ##指定master的地址
master-user = repdb01    ##同步所用的账号
master-password = 123456   ##同步所用的密码
master-port = 3306     ##master上mysql的端口
replicate-do-db = db01   ##要同步的库名
replicate-ignore-db = mysql  ##忽略的库名
slave-skip-errors = 1062   ##当同步异常时,那些错误跳过,本例为1062错误
#log-slave-updates  ##同步的同时,也记录自己的binlog日志,如果还有台slave是通过这台机器进行同步,那需要增加此项,
#skip-slave-start  ##启动时不自动开启slave进程
#read-only  ##将库设为只读模式,只能从master同步,不能直接写入(避免自增键值冲突)

登录mysql执行:

mysql>create database db01;
mysql>change master to master_log_file=’mysql-bin.000007’,master_log=106;
mysql>slave start;
mysql>show slave status \G    //确认slave_IO_Runing与slave_SQL_Runing的值都为Yesslave_IO_Runing与slave_SQL_Runing的值均为Yes

3>读写分离配置:

1 》》》Master-keepalived配置,编辑/etc/keepalived/keepalived.conf文件,

global_defs {
   router_id MySQL-HA
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 90   
    priority 100        ##权重
    advert_int 1
    notify_master "/usr/local/mysql/bin/remove_slave.sh"
    nopreempt
    authentication {
        auth_type PASS
        auth_pass abcd1234
    }
    virtual_ipaddress {
        192.168.150.173 label eth0:1
        192.168.150.174 label eth0:2
    }
}

virtual_server 192.168.150.173 3306 {
delay_loop 2
lb_algo wrr
lb_kind DR
    persistence_timeout 60
    protocol TCP
    real_server 192.168.150.171 3306 {
    weight 3
    notify_down /usr/local/mysql/bin/mysql.sh
    TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
        }
    }
}

virtual_server 192.168.150.174 3306 {
    delay_loop 2
    lb_algo wrr
    lb_kind DR
    persistence_timeout 60
    protocol TCP
    real_server 192.168.150.171 3306 {
    weight 1
    notify_down /usr/local/mysql/bin/mysql.sh
    TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
        }
    }
    real_server 192.168.150.172 3306 {
    weight 3
    TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
        }
    }
}

Mysql主从切换脚本创建,/usr/local/mysql/bin/remove_slave.sh

#!/bin/bash
user=root
password=123456
log=/root/mysqllog/remove_slave.log
#--------------------------------------------------------------------------------------
echo "`date`" >> $log
/usr/bin/mysql -u$user -p$password -e "set global read_only=OFF;reset master;stop slave;change master to master_host='localhost';" >> $log
/bin/sed -i 's#read-only#\#read-only#' /etc/my.cnf

完成之后赋予脚本执行权限:chomd 755 /usr/local/mysql/bin/remove_slave.sh

MySQL服务宕机动作脚本创建:/usr/local/mysql/bin/mysql.sh

#!/bin/bash
/etc/init.d/keepalived stop

2 》》》Slave-keepalived配置:/etc/keepalived/keepalived.conf

global_defs {
   router_id MySQL-HA  ##与master保持一致
}

vrrp_instance VI_1 {
    state BACKUP    ##均为从角色,以实现主角色的选举切换
    interface eth0
    virtual_router_id 90   ##与master保持一致
    priority 99    ##权重低,自动降级为从角色
    advert_int 1
    notify_master "/usr/local/mysql/bin/remove_slave.sh"
    authentication {
        auth_type PASS
        auth_pass ppl.com
    }
    virtual_ipaddress {
        192.168.150.173 label eth0:1
        192.168.150.174 label eth0:2
    }
}

virtual_server 192.168.150.173 3306 {
    delay_loop 2
    lb_algo wrr
    lb_kind DR
    persistence_timeout 60
    protocol TCP
    real_server 192.168.150.172 3306 {
    weight 3
    notify_down /usr/local/mysql/bin/mysql.sh
    TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
        }
    }
}

virtual_server 192.168.150.174 3306 {
    delay_loop 2
    lb_algo wrr
    lb_kind DR
    persistence_timeout 60
    protocol TCP
    real_server 192.168.150.172 3306 {
    weight 3
    notify_down /usr/local/mysql/bin/mysql.sh
    TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
        }
    }
#    real_server 192.168.150.172 3306 {
#        weight 3
#        TCP_CHECK {
#            connect_timeout 10
#            nb_get_retry 3
#            delay_before_retry 3
#            connect_port 3306
#        }
#    }
}

Mysql主从读写切换脚本创建/usr/local/mysql/bin/remove_slave.sh

#!/bin/bash
user=root
password=123456
log=/root/mysqllog/remove_slave.log
#--------------------------------------------------------------------------------------
echo "`date`" >> $log
/usr/bin/mysql -u$user -p$password -e "set global read_only=OFF;reset master;stop slave;change master to master_host='localhost';" >> $log
/bin/sed -i 's#read-only#\#read-only#' /etc/my.cnf

同理:chomd 755 /usr/local/mysql/bin/remove_slave.sh

动作脚本:/usr/local/mysql/bin/mysql.sh

#!/bin/bash
/etc/init.d/keepalived stop

【Mysql管理脚本】:/usr/local/keepalived/bin/lvs-rs.sh

#!/bin/bash
WEB_VIP=192.168.150.174

/etc/rc.d/init.d/functions

case "$1" in
start)
       ifconfig lo:0 $WEB_VIP netmask 255.255.255.255 broadcast $WEB_VIP
       /sbin/route add -host $WEB_VIP dev lo:0
       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
       sysctl -p >/dev/null 2>&1
       echo "RealServer Start OK"
       ;;
stop)
       ifconfig lo:0 down
       route del $WEB_VIP >/dev/null 2>&1
       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
       echo "RealServer Stoped"
       ;;
status)
        # Status of LVS-DR real server.
        islothere=`/sbin/ifconfig lo:0 | grep $WEB_VIP`
        isrothere=`netstat -rn | grep "lo:0" | grep $web_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 Running."
        fi
       ;;
*)
        # Invalid entry.
        echo "$0: Usage: $0 {start|status|stop}"
        exit 1
        ;;
esac
exit 0

完成之后,执行:

chmod 755 /usr/local/keepalived/bin/lvs-rs.sh
echo “/usr/local/keepalived/bin/lvs-rs.sh start” >>/etc/rc.local

编辑slave的 /etc/my.cnf,解注释以下2项:
#skip-slave-start
#read-only
重启MySQL后,手动启动slave:mysql>slave start;

3》》》验证:
先启动master上的keepalived,正常后再启动slave上的。然后主从mysql上查看ip可获知:
读的vip:192.168.150.174 在主备机上都可以看到
写入vip:192.168.150.173 在主上才能看到

2.3 案例3:LVS+keepalived 实现web高可用负载均衡集群

1)环境架构

主机:4台CentOS-7.5虚拟机,其中:

web-1:192.168.18.103
web-2:192.168.18.104
keepalived-1(LVS-DR模式):192.168.18.107
keepalived-2(LVS-DR模式):192.168.18.108
vip:192.168.18.110

2)软件部署:

1>2台主机分别安装keepalived+LVS

yum install keepalived ipvsadm
rpm -qa keepalived ipvsadm   //验证

2>配置keepalived和LVS

配置keepalived主节点: vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {					#第一部分,全局配置
router_id Director1
}

vrrp_instance VI_1 {				#第二部分,虚拟实例配置
state MASTER			//主节点,多配置为BACKUP
interface ens32
virtual_router_id 51
priority 150				//主节点有极限配置高点
advert_int 1
authentication {
		auth_type PASS
		auth_pass 123456
	}
virtual_ipaddress {
		192.168.18.110/24 dev ens32
	}
}

virtual_server 192.168.18.110 80 {			#第三部分,后端服务器配置
delay_loop 3
lb_algo rr				//切换算法
lb_kind DR
protocol TCP

real_server 192.168.18.103 80 {				//real1服务器
    weight 1
    TCP_CHECK {
        connect_timeout 3
            }
	}
real_server 192.168.18.104 80 {			//real2服务器
    weight 1
    TCP_CHECK {
        connect_timeout 3
            }
    }
}

配置keepalived备节点: vim /etc/keepalived/keepalived.conf ,与主节点配置文件基本一致

! Configuration File for keepalived

global_defs {
router_id Director2			
}

vrrp_instance VI_1 {
state BACKUP   //备用
interface ens32
virtual_router_id 51
priority 100			//优先级低
advert_int 1
authentication {
		auth_type PASS
		auth_pass 1111
		}
virtual_ipaddress {
192.168.18.110/24 dev ens32
		}
}

virtual_server 192.168.18.110 80 {
delay_loop 3
lb_algo rr
lb_kind DR
protocol TCP

real_server 192.168.18.103 80 {
    weight 1
    TCP_CHECK {
        connect_timeout 3
            }
  	 }

real_server 192.168.18.104 80 {
    weight 1
    TCP_CHECK {
        connect_timeout 3
            }
  	 }
}

3>启动keepalived
systemctl start keepalived
systemctl enable keepalived

4>安装web服务

yum install httpd
rpm -qa httpd
systemctl start httpd
systemctl enable httpd

5>修改web默认主页: vi /var/www/html/index.html,写入web-1,同理,第二台写入web-2,便于验证识别;
6>配置虚拟地址:(以下均在keepalived服务器上配置)
#cd /etc/sysconfig/network-scripts/
#cp ifcfg-lo ifcfg-lo:1
#vi ifcfg-lo:1

DEVICE=lo:1
IPADDR=192.168.18.110
NETMASK=255.255.255.255
ONBOOT=yes

#systemctl restart network
#ifconfig //验证
7>配置永久路由:
#vi /etc/rc.local,添加
/sbin/route add host 192.168.18.110 dev lo:1 //这里命令需要用绝对路径
8>配置永久ARP:
#vi /etc/sysctl.conf,修改或新增:

net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
net.ipv4.conf.default.arp_ignore=1
net.ipv4.conf.default.arp_announce=2
net.ipv4.conf.lo.arp_ignore=1
net.ipv4.conf.lo.arp_announce=2

#reboot //配置完以后,重启服务器使配置生效
9>验证:
#ipvsadm -L //keepalived-1端执行,观察是否可路由到后端web,及vip在哪台keepalive上
10>客户端访问验证,是否轮训
curl 192.168.18.110 //查看返回的页面结果是否满足效果
另测:
关闭master(keepalived-1)上面的keepalived服务,再次访问VIP,看是否可正常访问到web1和2
关闭web-1服务器,再次访问VIP,确认web-2可正常访问;

3、

待整理中……………………

4、附录

4.1 keepalived配置文件详解

keepalived是基于vrrp协议实现的,而VRRP(Virtual Router Redundancy Protocol)协议是用于实现路由器冗余的协议;vrrp是为消除在静态缺省路由环境下的缺省路由器单点故障引起的网络失效而设计的主备模式的协议,使得在发生故障而进行设备功能切换时可以不影响内外数据通信,不需要再修改内部网络的网络参数。VRRP协议需要具有IP地址备份优先路由选择,减少不必要的路由器间通信等功能。

VRRP协议将网络环境中两台或多台路由器设备虚拟成一个设备,对外提供虚拟路由器IP(一个或多个),而在路由器组内部,如果实际拥有这个对外虚拟IP(VIP)的路由器如果工作正常的话就是MASTER,或者是通过算法选举产生,MASTER实现针对虚拟路由器IP的各种网络功能,如ARP请求,ICMP,以及数据的转发等;其他设备不拥有该IP,状态是BACKUP,除了接收MASTER的VRRP状态通告信息外,不执行对外的网络功能。当主机失效时,BACKUP将接管原先MASTER的网络功能。

配置VRRP协议时需要配置每个路由器的虚拟路由器ID(VRID)和优先权值,使用VRID将路由器进行分组,具有相同VRID值的路由器为同一个组,VRID是一个0~255的正整数;同一组中的路由器通过使用优先权值来选举MASTER,优先权大者为MASTER,优先权也是一个0~255的正整数,数值越大,优先级越高,255是最高优先级,而0表示继续发送VRRP通告信息或进入MASTER选举。

VRRP协议使用多播数据来传输VRRP数据,VRRP数据使用特殊的虚拟源MAC地址发送数据而不是自身网卡的MAC地址,VRRP运行时只有MASTER路由器定时发送VRRP通告信息,表示MASTER工作正常以及虚拟路由器IP(组),BACKUP只接收VRRP数据,不发送数据,如果一定时间内没有接收到MASTER的通告信息,各BACKUP将宣告自己成为MASTER,发送通告信息,重新进行MASTER选举状态。

keepalived完全遵守VRRP协议,如上文架构图所述,其包含多个模块,实现各自功能。keepalived启动后会有三个进程:父进程:内存管理,子进程管理等等;子进程:VRRP子进程;子进程:healthchecker子进程;两个子进程都被系统WatchDog看管。

说回配置文件,完整的keepalived的配置文件keepalived.conf,其实可以包含三个文本块:全局定义块、VRRP实例定义块及虚拟服务器定义块。全局定义块和虚拟服务器定义块是必须的,如果在只有一个负载均衡器的场合,就无需编写VRRP实例定义块。下面是配置文件的示例,我们来看下各参数项的意义:

##全局定义块
global_defs {
      notification_email {           	#指定keepalived在发生切换时需要发送email到的对象,一行一个;
         cmcc.gc@gmail.com	
      }	
     notification_email_from  root@localhost	#指定发件人
     smtp_server  mail.cmccsp.net               #指定smtp服务器地址
     smtp_connect_timeout 3          			#指定smtp连接超时时间
     router_id LVS_kalive1             			#运行keepalived机器的标识
}	
#监控Nginx进程			
vrrp_script	chk_nginx  {	
    script "/data/script/nginx.sh"      		#监控服务脚本,需授予脚本x执行权限;
    interval 2                    				#检测时间间隔(执行脚本间隔)
    weight 2	
}				
#VRRP实例定义块				
vrrp_sync_group VG_1{                			监控多个网段的实例
        group {			 	
  VI_1                     			             实例名
  VI_2	
 }	
notify_master /data/sh/nginx.sh          		#指定当切换到master时,执行的脚本
notify_backup /data/sh/nginx.sh          		#指定当切换到backup时,执行的脚本
notify   /data/sh/nginx.sh						#发生任何切换,均执行的脚本
smtp_alert                         			    #使用global_defs中提供的邮件地址和smtp服务器发送邮件通知;
}		
vrrp_instance VI_1 {		
    state BACKUP                    			#设置主机状态,MASTER|BACKUP
	nopreempt                       			#设置为不抢占
interface eth0                   			    #对外提供服务的网络接口
lvs_sync_daemon_inteface eth0               #负载均衡器之间监控接口; 
    track_interface {               	 			#设置额外的监控,网卡出现问题都会切换;
     eth0	
     eth1	
    }	
    mcast_src_ip                 #发送多播包的地址,如果不设置默认使用绑定网卡的primary ip
    garp_master_delay            #在切换到master状态后,延迟进行gratuitous ARP请求
    virtual_router_id 50         #VRID标记 ,路由ID,可通过#tcpdump vrrp查看
    priority 90                  #优先级,高优先级竞选为master
    advert_int 5                 #检查间隔,默认5秒
    preempt_delay                #抢占延时,默认5分钟
    debug                        #debug日志级别
    authentication {             #设置认证
        auth_type PASS           #认证方式
        auth_pass 1111           #认证密码
    }
	track_script {               #以脚本为监控chk_nginx;
        chk_nginx		
    }		
    virtual_ipaddress {          #配置vip
        10.179.3.152
    }
}
##注意:如使用了脚本监控Nginx或者MYSQL,就无需如下虚拟服务器设置块。
#虚拟服务器定义块
virtual_server 10.179.3.152 3306 {
    delay_loop 6                   	#健康检查时间间隔
    lb_algo rr                     	#调度算法rr|wrr|lc|wlc|lblc|sh|dh
    lb_kind DR                     	#负载均衡转发规则NAT|DR|TUN
    persistence_timeout  5        	#会话保持时间
    protocol TCP                   	#使用的协议
    real_server 10.179.3.150 3306 {	
               weight 1            	#默认为1,0为失效
               notify_up   <string> | <quoted-string> #在检测到server up后执行脚本;
               notify_down <string> | <quoted-string> #在检测到server down后执行脚本;
               TCP_CHECK {
               connect_timeout 3    #连接超时时间;
               nb_get_retry  1      #重连次数;
               delay_before_retry 1  #重连间隔时间;
               connect_port 3306  	#健康检查的端口;
               }
       HTTP_GET {    
       url  {
          path /index.html        # 检测url,可写多个
          digest  74326580g86bee478bac72d53922507u3    #检测效验码
          #digest效验码获取方法:genhash -s IP -p 80 -u http://IP/index.html 
          status_code 200         #检测返回http状态码
      }
}
}