负载均衡集群和高可用集群
一、集群
1、 集群概述
1.1、 什么是集群?
集群称呼来自于英文单词cluster,表示一群、一串的意思,用在服务器领域则表示大量服务器的集合体,协同起来向用户提供系统资源,系统服务。通过网络连接组合成一个计算机组,来共同完一个任务。
根据实际企业环境的不同,集群所提供的功能也各不相同,采用的技术细节也可能各有千秋,但无论哪种集群,都至少包括两台节点服务器。而对外表现为一个整体,只提供一个访问入口(域名或IP地址),为用户提供服务,组成集群的服务器称之为集群的节点。
1.2、 集群的特性:
1)高性能(performance)
一些需要很强的运算处理能力比如天气预报,核试验等。这就不是几台计算机能够搞定的。这需要上千台一起来完成这个工作的,可以获得很高的整体性能。
2)价格有效性(性价比)
通常一套系统集群架构,只需要几台或数十台服务器主机即可,与动则上百万的专用超级计算机相比具有更高的性价比。
3)可伸缩性
集群系统中的节点数目可以增长到几千个,乃至上万个,当服务器负载压力增长的时候,系统能够扩展来满足需求,且不降低服务质量。
4)高可用性
在硬件和软件上都有冗余,通过检测软硬件的故障,将故障屏蔽,由存活节点提供服务,可实现高可用性。确保整个系统的服务必须是7*24小时运行的。
1.3、 应用场景:
1.3.1、 应用场景:
高并发、高可用性、高性能场景
例如:一台web服务器,如果能够响应10000个并发,如果现在有20000个并发,一台服务器就无法响应。说明,web服务已经达到瓶颈
1.3.2、 解决这个问题的办法:
加配置: 加CPU, 加内存, 加带宽, 加SSD 这种解决方法称为“向上扩展”或“纵向扩展”, 能够解决一时, 却不能彻底解决。
加服务器: 一台==>两台, 两台==>四台 四台==>8台。使用多台服务器同时为用户提供服务,而这一种解决方法则称为“横向扩展”或“向外扩展”
向外扩展: 就是集群
1.4、 集群的种类:
根据集群所针对的目标差异,可分为以下三种类型。
l负载均衡集群(laod balance cluster,简称LB):以提高应用系统的响应能力,尽可能处理更多的访问请求,减少延迟为目标,获得高并发、高负载的整体性能。LB的负载分配依赖于主节点的分流算法,将来自客户机的访问请求分担给多个服务器节点,从而缓解整个系统的负载压力。
l高可用集群(high availability cluster,简称HA):以提高应用系统的可靠性,尽可能地减少中断时间为目标,确保服务的连续性,达到高可用(HA)的容错效果。HA的工作方式包括双工、主从两种模式------双工即所有节点同时在线,主从则只有主节点在线,但当出现故障时从节点能自动切换为主节点。
l高性能运算集群(high performance computer cluster简称HPC):这类集群致力于提供单个计算机所不能提供的强大的计算能力,以提高应用系统的CPU运算速度,扩展硬件资源和分析能力为目标,获得相当于大型、超级计算机的高性能运算能力.通过专用硬件和软件将多个服务器的CPU、内存等资源整合在一起,实现只有大型、超级计算机才具备的计算能力。
1.5、 负载均衡集群
在当今各种互联网应用中,随着站点对硬件性能、响应速度、服务稳定性、数据可靠性等的要求越来越高,单台服务器将难以承担所有的访问。除了使用价格昂贵的大型机、专用负载分流设备以外,企业还有另外一种选择来解决难题,就是构建集群服务器——通过整合多台相对廉价的普通服务器,以同一个地址对外提供相同的服务。
负载均衡集群:以提高应用系统的响应能力、尽可能处理更多的访问请求、减少延迟为目标,获得高并发、高负载的整体性能。
1.6、 负载均衡集群的分层结构
在典型的负载均衡集群中,包括三个层次的组件,如图所示:
前端至少有一个负载调度器(load balancer [ˈbælənsər],或称为director),负责接收并分发来自客户机的访问请求;后端由大量真实服务器(real server)构成服务器池(server pool),提供实际的应用服务,整个集群的伸缩性通过增加、删除服务器节点来完成,而这些过程对客户机是透明的;为了保持服务的一致性,所有节点使用共享存储设备。
第一层,负载调度器:这是访问整个集群系统的唯一入口,对外使用所有服务器共有的VIP(virtual IP,虚拟IP)地址,也称为集群IP地址。通常会配置主、备两台调度器实现热备份,当主调度器失效以后平滑替换至备用调度器,确保高可用性。
第二层,服务器池:集群所提供的应用服务(如HTTP)由服务器池承担,其中的每个节点具有独立的RIP(real IP,真实IP)地址,只处理调度器分发过来的客户机请求。当某个节点暂时失效时,负载调度器的容错机制会将其隔离,等侍错误排除以后再重新纳入服务器池。
第三层,共享存储:为服务器池中的所有节点提供稳定、一致的文件存取服务,确保整个集群的统一性,在linux/unix环境中,共享存储可以使用ceph存储或者提供NFS共享服务的专用服务器。
1.7、 负载均衡集群(LB)实现手段
硬件的实现: F5负载均衡器
软件的实现: LVS(4层,传输层) ,Nginx(7层,应用层) haproxy(既可以工作再4层,又可以工作在7层)
2、 LVS集群
2.1、 LVS(Linux Virtual Server)介绍
LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统,本项目在1998年5月由阿里巴巴的著名工程师章文嵩博士开发的一款开源软件,是中国国内最早出现的自由软件项目之一。
LVS工作在一台server上提供Director(负载均衡器)的功能,本身并不提供服务,只是把特定的请求转发给对应的real server(真正提供服务的主机),从而实现集群环境中的负载均衡。
LVS工作在ISO模型中的第四层,由于其工作在第四层,因此与iptables类似,必须工作在内核空间上。因此lvs与iptables一样,是直接工作在内核中的,叫ipvs,主流的linux发行版默认都已经集成了ipvs,因此用户只需安装一个管理工具ipvsadm即可。
官网:http://www.linuxvirtualserver.org/
中文站点: http://zh.linuxvirtualserver.org/
2.2、 LVS的组成
LVS 由2部分程序组成,包括 ipvs 和 ipvsadm。
LVS的核心组件ipvs工作在kernel中,是真正的用于实现根据定义的集群转发规则把客户端的请求转发到特定的real server。而另一个组件ipvsadm是工作在用户空间的一个让用户定义ipvs规则的工具。故我们只要在server上装了ipvsadm软件包就可以定义ipvs规则,
而在linux kernel的2.6版本之后kernel是直接支持ipvs的。
2.3、 LVS 集群工作结构图:
2.3.1、 负载调度器,:
调度器(Director): 整个集群对外的最前端主机, 负责接收用户请求, 并且根据相关的调度算法, 将请求转发到后端真实服务器上,而客户端认为服务是来自一个IP地址(我们可称之为VIP虚拟IP地址)上的。
2.3.2、 服务器池: Server Pool
真正为用户提供服务的服务器, 每一台服务器就是一台RS[RealServer],执行的服务有WEB、MAIL、FTP和DNS等。
2.3.3、 共享存储: Shared Storaged
为RS保持相同内容, 提供数据的一致性,也就是说,它为服务器池提供一个共享的存储区,这样很容易使得服务器池拥有相同的内容,提供相同的服务。
2.4、 LVS的专用名词
DS:Director Server。指的是前端负载均衡器节点。
RS:Real Server。后端真实的工作服务器。
VIP:向外部直接面向用户请求,作为用户请求的目标的IP地址。
DIP:Director Server IP,主要用于和内部主机通讯的IP地址。
RIP:Real Server IP,后端服务器的IP地址。
CIP:Client IP,访问客户端的IP地址。
2.5、 LVS的负载调度算法
针对不同的网络服务和配置需要,LVS调度器提供多种不同的负载调度算法,其中最常用的算法包括轮询、加权轮询、最少连接、权最少连接和source hashing源地址hash。
1、轮询(rr, RoundRobin):
将收到的访问请求按照顺序轮流分配给集群中的各节点(真实服务器)。
2、加权轮询(wrr, Weighted RoundRobin):
根据真实服务器的处理能力轮流分配收到的访问请求,它将依据不同RS的权重分配任务。权重较高的RS将优先获得任务,并且分配到的连接数将比权重较低的RS更多。这样可以保证处理能力强的服务器承担更多的访问流量。相同权重的RS得到相同数目的连接数。
3、最少连接(lc, Least Connections):
IPVS表存储了所有的活动的连接。把新的连接请求发送到当前连接数最小的RS。
4、加权最少连接(wlc,WeightedLeastConnections):
在服务器节点的性能差异较大的情况下,可以为真实服务器设置权重,权重较高的节点将承担更大比例的活动连接负载。假设各台RS的权重依次为Wi(i = 1..n),当前的TCP连接数依次为Ti(i=1..n),依次选取Ti/Wi为最小的RS作为下一个分配的RS。
5、source hashing源地址hash(sh)
将来自同一个ip的请求始终调度至同一RS
2.6、 LVS负载均衡模式及工作原理
2.6.1、 LVS工作模式:
LVS有三种工作模式:DR,NAT,TUN。DR是三种工作模式中性能最高的,TUN次之。
DR(Direct Routing)即直接路由模式
NAT(Network Address Translation)即网络地址映射模式
TUN(IP Tunneling)即IP隧道模式
2.6.2、 NAT(网络地址映射)
NAT: 网络地址转换
DNAT: 目标地址转换 改变的是目标地址
SNAT: 原地址转换 改变的是源地址
LVS-NAT 就是使用的SNAT和DNAT完成包的转发
负载调度器作为所有服务器节点的网关,即作为客户机的访问集群的入口,也是各节点回应客户机的访问出口。服务器节点使用私有IP地址,与负载调度器位于同一个物理网络,安全性要优于其他两种方式。
NAT方式可支持任何的操作系统,以及私有网络,并且只需一个Internet IP地址,但是整个系统的性能受到限制。因为执行NAT每次需要重写包,有一定的延迟;另外,大部分应用有80%的数据是从服务器流向客户机,也就是用户的请求非常短,而服务器的回应非常大,对负载均衡器形成很大压力,成为瓶颈。
2.6.3、 IP Tunneling(IP隧道) [ˈtʌnlɪŋ]
采用NAT技术时,由于请求和响应报文都必须经过调度器地址重写,当客户请求越来越多时,调度器的处理能力将成为瓶颈。为了解决这个问题,调度器把请求报文通过IP隧道转发至真实服务器,而真实服务器将响应直接返回给客户,所以调度器只处理请求报文。由于一般网络服务应答比请求报文大许多,采用TUN技术后,集群系统的最大吞吐量可以大大提高。但是目前支持TUN 只有Linux系统。
IP隧道(IP TUNNEL):简称TUN模式,负载调度器仅作为客户机的访问入口,各节点通过各自的INTERNET连接直接回应客户机,而不再经过负载调度器。采用开放式的网络结构,服务器节点分散在互联网中的不同位置。具有独立的公网IP地址,通过专用IP隧道与负载调度器相互通信。
real server可以在任何LAN或WAN上运行,这意味着允许地理上的分布,这在灾难恢复中有重要意义。服务器必须拥有公网IP地址用于与客户机直接通信,并且所有服务器必须支持IP隧道协议。
2.6.4、 Direct Routing(直接路由)
直接路由(direct routing):简称DR模式,采用半开放式的网络结构,与TUN模式的结构类似,但各节点并不是分散在各地,而是与调度器位于同一个物理网络。负载调度器与各节点服务器通过本地网络连接,不需要建立专用的IP隧道。
DR通过改写请求报文的MAC地址,将请求发送到真实服务器,而真实服务器将响应直接返回给客户。同TUN技术一样,DR技术可极大地提高集群系统的伸缩性。这种方法没有IP隧道的开销,对集群中的真实服务器也没有必须支持IP隧道协议的要求,但是要求调度器与真实服务器都有一块网卡连在同一物理网段上。也就是说,在这种结构中,数据从外部到内部真实服务器的访问会通过调度器进来,但是真实服务器对其的应答不是通过调度器出去。即真实服务器可以通过各自的网关或者专用的网关对数据进行外发,从而降低调度器负载。
2.6.5、 LVS优点:
1.抗负载能力强,因为lvs工作方式的逻辑是非常简单的,而且工作在网络第4层,仅作请求分发用,没有流量,所以在效率上基本不需要太过考虑。lvs一般很少出现故障,即使出现故障一般也是其他地方(如网卡或内核的承载能力已到上限)出现问题导致lvs出现问题,内存和 cpu方面基本无消耗。
2.配置性低,这通常是一大劣势同时也是一大优势,因为没有太多的可配置的选项,所以除了增减服务器,并不需要经常去触碰它,大大减少了人为出错的几率。
3.工作稳定,因为其本身抗负载能力很强,所以稳定性高,另外各种lvs都有完整的双机热备方案,所以一点不用担心负载衡器本身会出什么问题。
4.无流量,lvs仅仅分发请求,而流量并不从它本身出去,所以可以利用它这点来做一些线路分流之用。没有流量同时也保住了负载均衡器的IO性能不会受到大流量的影响。
5.lvs基本上能支持所有应用,因为lvs工作在第4层,所以它可以对几乎所有应用做负载均衡,包括http、数据库等。
Ø 二、LVS集群-DR
1、 LVS-DR集群概述
2.7、 DR模式概述:
DR模式是通过改写请求报文的目标MAC地址,将请求发给真实服务器的,而真实服务器响应后的处理结果直接返回给客户端用户。DR模式可以极大的提高集群系统的伸缩性。但是要求调度器LB与真实服务器RS都有一块网卡连接到同一物理网段上,必须在同一个局域网环境。DR模式是互联网使用比较多的一种模式。
2.8、 DR模式实际拓扑图及工作DR方式工作流程图:
Lvs-dr的工作原理:Director收到请求,将请求转发给了我们的realserver,但是接下来的工作就是我们的realserver和我们的客户端进行通讯了,所以原理图如下:
2.9、 LVS DR模式工作原理:
2.9.1、 MAC转换过程
2.9.1.1、 实例场景设备清单:
Director调度器IP: 192.168.1.70, VIP : 192.168.1.63
2.9.1.2、 client基本信息:
IP:192.168.1.101向目标vip发出请求,Director接收。此时IP包头及数据帧头信息如下:
2.9.1.3、 Director分发器根据负载均衡算法选择一台active的realserver
(假设是192.168.1.62),将此RIP所在网卡的mac地址作为目标mac地址,发送到局域网里。此时IP包头及数据帧头信息如下:
2.9.1.4、 realserver(192.168.1.62)在局域网中收到这个帧,拆开后发现目标IP(VIP)与本地匹配,于是处理这个报文。随后重新封装报文,发送到局域网。此时IP包头及数据帧头信息如下:
2.9.1.5、 如果client与LVS同一网段,那么client(192.168.1.101)将收到这个回复报文。如果跨了网段,那么报文通过gateway/路由器经由Internet返回给用户。
2.9.2、 归纳总结
DR(Direct Routing 直接路由模式)此模式时LVS 调度器只接收客户发来的请求并将请求转发给后端服务器,后端服务器处理请求后直接把内容直接响应给客户,而不用再次经过LVS调度器。LVS调度器只需要将网络帧的MAC地址修改为某一台后端服务器RS的MAC,该包就会被转发到相应的RS处理,注意此时的源IP和目标IP都没变。RS收到LVS转发来的包时,链路层发现MAC是自己的,到上面的网络层,发现IP也是自己的,于是这个包被合法地接受,RS感知不到前面有LVS的存在。而当RS返回响应时,只要直接向源IP(即客户端的IP)返回即可,不再经过LVS调度器。
1)接收client的请求,根据你设定的负载均衡算法选取一台realserver的ip;
2)以选取的这个ip对应的mac地址作为目标mac,然后重新将IP包封装成帧转发给这台RS;
3)在hash table中记录连接信息。
lvs-dr做的事情很少,也很简单,所以它的效率很高,不比硬件负载均衡设备差多少。数据包、数据帧的大致流向是这样的:client --> VS --> RS --> client
2.10、 DR模式特点
l保证前端路由将目标地址为VIP报文统统发给Director Server,而不是RS(解决方法:在前端路由器做静态地址路由绑定,将对于VIP的地址仅路由到Director Server)
lRS可以使用私有地址;也可以是公网地址,如果使用公网地址,此时可以通过互联网对RIP进行直接访问
lRS跟Director Server必须在同一个物理网络中
l所有的请求报文经由Director Server,但响应报文必须不能进过Director Server
l不支持地址转换,也不支持端口映射
lRS可以是大多数常见的操作系统
lRS的网关绝不允许指向DIP(因为我们不允许他经过director)
lRS上的lo接口配置VIP地址
缺陷:唯一的缺陷在于它要求LVS 调度器及所有应用服务器在同一个网段中,因此不能实现集群的跨网段应用。
3、 配置LVS-DR集群
3.1、 实验拓扑图
四台CentOS7.5虚拟机:
VIP(虚拟IP地址):172.16.16.172/24
其中director作为负载调度服务器:
ens33:172.16.16.173/24 ens37: 192.168.7.173/24
WEB节点1(cong11): ens33: 172.16.16.177/24 ens37: 192.168.7.177/24
WEB节点2(cong12): ens33: 172.16.16.178/24 ens37: 192.168.7.178/24
NFS共享存储:ens33: 192.168.7.250/24
客户端ip地址:172.16.16.1
说明:172.16.16.0/24网段用于外网连接。192.168.7.0/24网段用于web服务器与nfs共享存储连接通信,可以略过这部分的配置,即不部署nfs服务,网页文件直接存储在每个web节点本地。
注:关闭所有主机的防火墙和selinux
3.2、 配置提供共享存储的服务器(nfs_storage)——可选
更改主机名:
[root@localhost ~]# hostnamectl set-hostname nfs-storage
[root@localhost ~]# bash
[root@nfs-storage ~]#
关闭防火墙和selinux
[root@nfs-storage ~]# systemctl stop firewalld
[root@nfs-storage ~]# systemctl disable firewalld
[root@nfs-storage ~]# setenforce 0
[root@nfs-storage ~]# sed -i '/SELINUX/s/enforcing/disabled/' /etc/selinux/config
安装nfs-utils和rpcbind软件包
[root@nfs_storage ~]# yum -y install nfs-utils rpcbind
配置共享文件目录,编辑配置文件:
首先创建共享目录,然后在/etc/exports配置文件中编辑配置即可。
创建共享目录:
[root@nfs-storage ~]# mkdir -p /var/www/html
编辑配置文件/etc/exports,输出共享目录
[root@nfs-storage ~]# vim /etc/exports
/var/www/html 192.168.7.0/24(rw,sync,no_root_squash)
[root@nfs-storage ~]# systemctl restart rpcbind
[root@nfs-storage ~]# systemctl start nfs
[root@nfs-storage ~]# showmount -e
Export list for nfs-storage:
/var/www/html 192.168.7.0/24
3.3、 负载调度器IP配置
从lvs-dr模式的工作原理我们可以看出负载调度器ens33有2个IP地址,所以我们需要配置ens33和ens33:0两个IP
DIP===ens33=== 172.16.16.173 VIP===ens33:0=== 172.16.16.172
[root@director ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
#以配置以下信息
……..
IPADDR= 172.16.16.173
NETMASK=255.255.255.0
………
3.4、 生成ens33:0配置文件
[root@director network-scripts]# pwd
/etc/sysconfig/network-scripts
[root@xuegod63 network-scripts]# cp ifcfg-ens33 ifcfg-ens33:0
[root@xuegod63 network-scripts]# vim ifcfg-ens33:0 #红颜色部分
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=none
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33:0
UUID=34740f62-ad41-493b-989c-a8e9b2a09d16
DEVICE=ens33:0
ONBOOT=yes
IPADDR=172.16.16.172
PREFIX=24
[root@director network-scripts]# systemctl restart network
[root@director network-scripts]# ifconfig #查看是否有ens33 和ens33:0
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.16.16.173 netmask 255.255.255.0 broadcast 172.16.16.255
inet6 fe80::784:4bfa:defc:4233 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:17:92:f3 txqueuelen 1000 (Ethernet)
RX packets 476 bytes 44057 (43.0 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 321 bytes 40161 (39.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.16.16.172 netmask 255.255.255.0 broadcast 172.16.16.255
ether 00:0c:29:17:92:f3 txqueuelen 1000 (Ethernet)
3.5、 配置LVS-DR规则
LVS现在已成为Linux内核的一部分,默认编译为ip_vs模块,必要时能够自动调用。以下操作可以手动加载ip_vs模块,并查看当前系统中ip_vs模块的版本信息。
[root@director ~]# modprobe ip_vs
[root@director ~]# lsmod | grep ip_vs
ip_vs 145497 0
nf_conntrack 133095 7 ip_vs,nf_nat,nf_nat_ipv4,nf_nat_ipv6,xt_conntrack,nf_conntrack_ipv4,nf_conntrack_ipv6
libcrc32c 12644 4 xfs,ip_vs,nf_nat,nf_conntrack
[root@director ~]# cat /proc/net/ip_vs
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
安装ipvsadm软件包
[root@director ~]# yum -y install ipvsadm
使用ipvsadm创建负载分配策略:
清除策略:清除内核虚拟服务器表中的所有记录
[root@director ~]# ipvsadm -C
添加规则:
创建虚拟服务器,集群的VIP地址为172.16.16.172,针对TCP的80端口提供负载分流服务,使用的调度算法为轮询(rr代表轮循)。
[root@director ~]# ipvsadm -A -t 172.16.16.172:80 -s rr
选项:
-A 添加虚拟服务器
-t 用来指定VIP地址及TCP端口
-s 指定调度算法,rr(轮询)、wrr(加权轮询)、lc(最少连接)、wlc(加权最少连接)。
添加服务器节点:
[root@director ~]# ipvsadm -a -t 172.16.16.172:80 -r 172.16.16.177:80 -g -w 1
[root@director ~]# ipvsadm -a -t 172.16.16.172:80 -r 172.16.16.178:80 -g -w 1
选项:
-a 表示添加real server的地址
-r 指定real server的IP地址和端口
-g 表示route 也就是DR方式的LVS,(-m: NAT模式、-i:TUN模式)
-w用来设置权重(权重为0时表示暂停节点)。
保存配置或规则:
要停止selinux,否则策略不会被保存
[root@director ~]# setenforce 0
[root@director ~]# sed -i '/SELINUX/s/enforcing/disabled/' /etc/selinux/config
保存策略可以使用
LVS的规则配置文件:/etc/sysconfig/ipvsadm
[root@director ~]# ipvsadm --save > /etc/sysconfig/ipvsadm //保存以上的配置
设置ipvsadm服务为自动启动:
[root@director ~]# systemctl start ipvsadm.service
[root@director ~]# systemctl enable ipvsadm.service
查看负载均衡策略:
[root@director ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.16.172:80 rr
-> 172.16.16.177:80 Route 1 0 0
-> 172.16.16.178:80 Route 1 0 0
3.6、 两台RealServer的IP配置:
3.6.1、 Cong11主机配置IP
3.6.1.1、 关闭ARP转发(在两台RS上都需要同样的操作)。
同一个广播域: 配置了多个相同的VIP 是不允许的, 要想实现,就必须让外面的网络, 无法发现这个VIP的存在。因此在Linux里面, 可以修改内核参数, 实现接口IP的广播不响应、不广播。
arp_ignore = 1 表示只回答目标IP是访问本地网络对应接口的arp请求
arp_announce = 2 只宣告本机网卡直连网络所在的ip的arp广播。[əˈnaʊns]
临时生效:
[root@cong11 ~]# echo 1 > /proc/sys/net/ipv4/conf/ens33/arp_ignore
[root@cong11 ~]# echo 2 > /proc/sys/net/ipv4/conf/ens33/arp_announce
永久生效:(注意网卡名称)
[root@cong11 ~]# vim /etc/sysctl.conf #最后添加
net.ipv4.conf.ens33.arp_ignore = 1
net.ipv4.conf.ens33.arp_announce = 2
或:
net.ipv4.conf.ens33.arp_ignore = 1
net.ipv4.conf.ens33.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
使内核参数修改生效:
[root@cong11 ~]# sysctl -p
参数说明:
基本功能:知道目标设备的IP地址,查询目标设备的MAC地址,以保证通信的顺利进行。
arp_ignore 定义接收到 ARP 请求时的响应级别
arp_announce 定义将自己地址向外通告时的通告级别
larp_ignore:定义了网卡在响应外部ARP请求时候的响应级别,即当ARP请求发过来后发现自己正是请求的地址是否响应。
l0:默认值,不管哪块网卡接收到了ARP请求,只要发现本机有这个MAC都给与响应
l1:总是使用最合适的网卡来响应,一个主机有多块网卡,其中一块网卡接收到了ARP请求,发现所请求的MAC是本机另一块网卡的,这个时候接收到ARP请求的这块网卡就一定不响应,只有发现请求的MAC是自己的才给与响应。
larp_announce: 的作用是控制系统在对外发送arp请求时,如何选择arp请求数据包的源IP地址。
l有三个值:
l0:默认值,允许使用任意网卡上的IP地址作为arp请求的源IP。
l1:尽量避免使用不属于该发送网卡子网的本地地址作为发送arp请求的源IP地址。
l2:选择该发送网卡上最合适的本地地址作为arp请求的源IP地址。
arp_ignore和arp_announce参数示例:
(1)当arp_ignore参数配置为0时,eth1网卡上收到目的IP为环回网卡IP的arp请求,但是eth1也会返回arp响应,把自己的mac地址告诉对端。
(2)当arp_ignore参数配置为1时,eth1网卡上收到目的IP为环回网卡IP的arp请求,发现请求的IP不是自己网卡上的IP,不会回arp响应。
(3)当arp_announce参数配置为0时,系统要发送的IP包源地址为eth1的地址,IP包目的地址根据路由表查询判断需要从eth2网卡发出,这时会先从eth2网卡发起一个arp请求,用于获取目的IP地址的MAC地址。该arp请求的源MAC自然是eth2网卡的MAC地址,但是源IP地址会选择eth1网卡的地址。
(4)当arp_announce参数配置为2时,eth2网卡发起arp请求时,源IP地址会选择eth2网卡自身的IP地址。
3.6.1.2、 配置ens33接口ip
[root@cong11 ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:94:34:09 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.177/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::e411:893e:5322:6160/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3.6.1.3、 配置虚拟IP地址(VIP)
生成回环口配置文件:
[root@cong11 ~]# cd /etc/sysconfig/network-scripts/
[root@cong11 network-scripts]# cp ifcfg-lo ifcfg-lo:0
[root@cong11 network-scripts]# vim ifcfg-lo:0
DEVICE=lo:0
IPADDR=172.16.16.172
NETMASK=255.255.255.255
ONBOOT=yes
NAME=loopback
重启network服务:
[root@cong11 network-scripts]# systemctl restart network
[root@cong11 network-scripts]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.16.16.177 netmask 255.255.255.0 broadcast 172.16.16.255
inet6 fe80::e411:893e:5322:6160 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:94:34:09 txqueuelen 1000 (Ethernet)
RX packets 5394 bytes 1087392 (1.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3681 bytes 514268 (502.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 1996 bytes 167176 (163.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1996 bytes 167176 (163.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo:0: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 172.16.16.172 netmask 255.255.255.255
loop txqueuelen 1000 (Local Loopback)
3.6.1.4、 配置httpd服务
[root@cong11 ~] # yum install -y httpd
[root@cong11 ~] # systemctl start httpd
[root@cong11 ~] # echo "172.16.16.177" > /var/www/html/index.html
#(实验期间,为了测试负载均衡,各个服务器的页面不同,可以先不挂载nfs共享存储)
3.6.2、 Cong12主机配置IP
3.6.2.1、 关闭ARP转发。
[root@cong12 ~]# echo 1 > /proc/sys/net/ipv4/conf/ens33/arp_ignore
[root@cong12 ~]# echo 2 > /proc/sys/net/ipv4/conf/ens33/arp_announce
永久生效:(注意网卡名称)
[root@cong12 ~]# vim /etc/sysctl.conf #最后添加
net.ipv4.conf.ens33.arp_ignore = 1
net.ipv4.conf.ens33.arp_announce = 2
或:
net.ipv4.conf.ens33.arp_ignore = 1
net.ipv4.conf.ens33.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
使配置生效:
[root@cong12 ~]# sysctl –p
1.1.1.1、 配置ens33接口ip
[root@cong12 ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:b5:16:bd brd ff:ff:ff:ff:ff:ff
inet 172.16.16.178/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::9c2f:59c3:7ebd:7a28/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3.6.2.2、 配置虚拟ip地址(VIP)
生成回环口配置文件:
[root@cong12 ~]# cd /etc/sysconfig/network-scripts/
[root@cong12 network-scripts]# cp ifcfg-lo ifcfg-lo:0
[root@cong12 network-scripts]# vim ifcfg-lo:0
DEVICE=lo:0
IPADDR=172.16.16.172
NETMASK=255.255.255.255
ONBOOT=yes
NAME=loopback
重启network服务:
[root@cong12 ~]# systemctl restart network
[root@cong12 ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.16.16.178 netmask 255.255.255.0 broadcast 172.16.16.255
inet6 fe80::9c2f:59c3:7ebd:7a28 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:b5:16:bd txqueuelen 1000 (Ethernet)
RX packets 5164 bytes 1037953 (1013.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3495 bytes 461359 (450.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 1328 bytes 115584 (112.8 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1328 bytes 115584 (112.8 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo:0: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 172.16.16.172 netmask 255.255.255.255
loop txqueuelen 1000 (Local Loopback)
3.6.2.3、 配置httpd服务
[root@cong12 ~] # yum install -y httpd
[root@cong12 ~] # systemctl start httpd
[root@cong12 ~] # echo "172.16.16.178" > /var/www/html/index.html
#(实验期间,为了测试负载均衡,各个服务器的页面不同,可以先不挂载nfs共享存储)
3.7、 测试LVS集群:
3.7.1、 先测试real server:
http://172.16.16.177
http:// 172.16.16.178
3.7.2、 测试访问VIP:
安排多台测试机,从internet中直接访问http://172.16.16.172,将能够看到由真实服务器提供的网面内容。
http://172.16.16.172
刷新浏览器:
注: 测试时,不要在分发器上测试。那样测试是不行的
在LVS负载调度器中,通过查看节点状态可以观察当前的负载分配情况,对于轮询算法来说,每个节点所获得的连接负载应大致相当
[root@director ~]# ipvsadm -Lnc
IPVS connection entries
pro expire state source virtual destination
TCP 01:49 FIN_WAIT 172.16.16.1:5241 172.16.16.172:80 172.16.16.178:80
TCP 00:58 FIN_WAIT 172.16.16.1:5231 172.16.16.172:80 172.16.16.177:80
3.8、 会话保持
LVS提供了source hashing,源地址hash(sh)算法,这样同一个ip的客户端总是分发给同一个real server。
基于ip地址标识客户端的缺点:很多内网用户会伪装成公网ip,来访问服务器,不能人为的控制负载均衡。
3.8.1、 如何保持会话一致:
如果总是保持和一个RS会话,这台RS如果故障了,要确定另一个RS也有会话信息,所有的RS保持数据同步。
会话同步的方法:
所有的RS把自己的会话信息保存到数据库当中(如memcached/redis软件)。
4、 使用webbench测试网站性能
4.1、 webbench简介:
Webench是一款轻量级的网站测压工具,最多可以对网站模拟3w左右的并发请求,可以控制时间、是否使用缓存、是否等待服务器回复等等,且对中小型网站有明显的效果,基本上可以测出中小型网站的承受能力,对于大型的网站,如百度、淘宝这些巨型网站没有意义,因为其承受能力非常大。同时测试结果也受自身网速、以及自身主机的性能与内存的限制,性能好、内存大的主机可以模拟的并发就明显要多。
Webbench是由 Lionbridge公司(http://www.lionbridge.com)开发的网站压力测试工具,webbench不但能具有便准静态页面的测试能力,还能对动态页面(ASP,PHP,JAVA,CGI)进行测试的能力。
Webbench用C语言编写,运行于linux平台,下载源码后直接编译即可使用,非常迅速快捷,对于中小型网站的制作者,在上线前用webbench进行系列并发测试不失为一个好的测试方法。
4.2、 webbench官网:
http://home.tiscali.cz/~cz210552/webbench.html
4.3、 在web-bench上下载并安装webbench
[root@web-bench ~]# yum -y install ctags wget make apr* autoconf automake gcc gcc-c++
[root@web-bench ~]# wget http://home.tiscali.cz/~cz210552/distfiles/webbench-1.5.tar.gz
[root@web-bench ~]#tar zxvf webbench-1.5.tar.gz
[root@web-bench webbench-1.5]# cd webbench-1.5
[root@web-bench webbench-1.5]#make
[root@web-bench webbench-1.5]# mkdir -p /usr/local/man/man1
#不创建这个执行make install报错:
install: cannot create regular file `/usr/local/man/man1': No such file or directory
make: *** [install] Error 1
[root@web-bench webbench-1.5]#make install
install -s webbench /usr/local/bin
install -m 644 webbench.1 /usr/local/man/man1
install -d /usr/local/share/doc/webbench
install -m 644 debian/copyright /usr/local/share/doc/webbench
install -m 644 debian/changelog /usr/local/share/doc/webbench
4.4、 进行压力测试:在web-bench上进行测试
[root@web-bench ~]#webbench -h
测试参数解释:-c 并发用户数,-t 压测时长
4.4.1、 模拟100个并发,持续访问60秒。
[root@web-bench ~]# webbench -t 60 -c 100 http://172.16.16.172/
[root@web-bench ~]# webbench -t 60 -c 100 http://172.16.16.172/
Webbench - Simple Web Benchmark 1.5
Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.
Benchmarking: GET http://172.16.16.172/
100 clients, running 60 sec.
Speed=41019 pages/min, 186636 bytes/sec.
Requests: 41019 susceed, 0 failed.
Speed 为每分钟多个请求,Requests 成功多少个请求,失败多少个请求
4.4.2、 模拟200个并发访问并持续访问120秒
[root@web-bench ~]# webbench -t 120 -c 200 http://172.16.16.172/
Webbench - Simple Web Benchmark 1.5
Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.
Benchmarking: GET http://172.16.16.172/
200 clients, running 120 sec.
Speed=43755 pages/min, 199085 bytes/sec.
Requests: 87510 susceed, 0 failed.
4.5、 测试注意事项:
1.压力测试工作应该放到产品上线之前,而不是上线以后;
2.webbench 做压力测试时,该软件自身也会消耗CPU和内存资源,为了测试准确,请将 webbench 安装在别的服务器上;
3.测试时尽量跨公网进行,而不是内网; 如果带宽不够时,可以内网测试。
4.测试时并发应当由小逐渐加大,观察一下网站负载及打开是否流畅,直到网站打开缓慢甚至网站完全打不开; 可以一边在linux测试,一个在浏览上打开,查看是否流畅。
5.应尽量进行单元测试,如B2C网站可以着重测试购物车、推广页面等,因为这些页面占整个网站访问量比重较大。
Ø 三、keepalived+LVS-DR集群
1、 Keepalived介绍
4.6、 Keepalived
4.6.1、 Keepalived介绍:
Keepalived软件起初是专为LVS负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,主要用来提供故障切换和健康检查功能,如判断LVS负载调度器、节点服务器的可用性,及时隔离并替换为新的服务器,当故障主机恢复后将其重新加入集群。后来又加入了可以实现高可用的VRRP功能。因此,keepalived除了能够管理LVS软件外,还可以作为其他服务的高可用解决方案软件(如nginx、Mysql等应用服务)。
keepalived软件主要是通过VRRP协议实现高可用功能的。VRRP是Virtual Router Redundancy Protocol(虚拟路由冗余协议)的缩写,VRRP出现的目的就是为了解决路由器的单点故障问题的,它能保证当个别节点宕机时,整个网络可以不间断地运行。所以,keepalived一方面具有配置管理LVS的功能,同时还具有对LVS下面节点进行健康检查的功能,另一方面也可以实现系统网络服务的高可用功能。
4.6.2、 VRRP协议说明
VRRP是针对局域网中配置静态网关出现单点故障的解决方案,一个局域网络内的所有主机都设置缺省路由(默认网关),当网内主机发出的目的地址不在本网段时,报文将被通过缺省路由发往外部路由器,从而实现了主机与外部网络的通信。当缺省路由器down掉(即端口关闭)之后,内部主机将无法与外部通信,如果路由器设置了VRRP时,那么这时,虚拟路由将启用备份路由器,从而实现全网通信。
工作流程如图:
VRRP是针对路由器的一种备份解决方案-----由多台路由器组成一个热备组。这个热备组里面有一个master和多个backup。master上面有一个对外提供服务的vip,通过vip地址对外提供服务;每个热备组内同一时刻只有一台主服务器提供服务,其他服务器处于冗余状态,若当前在线的主服务器失败,其他服务器会自动接替(优先级决定接替顺序)虚拟IP地址,以继续提供服务。热备组内的每台服务器都可以成为主服务器,虚拟IP地址(VIP)可以在热备组内的服务器之间进行转移,所以也称为漂移IP地址,使用Keepalived时,漂移地址的实现不需要手动建立虚拟接口配置文件(如ens33:0),而是由Keepalived根据配置文件自动管理。
4.6.3、 Keepalived高可用是如何实现故障切换转移的?
Keepalived高可用服务对(主备)之间的故障切换转移,是通过VRRP来实现的。在keepalived服务工作时,主Master节点会不断地向备节点发送(多播的方式)心跳消息,用来告诉备Backup节点自己还活着。当主节点发生故障时,就无法发送心跳的消息了,备节点也因此无法继续检测到来自主节点的心跳了。于是就会调用自身的接管程序,接管主节点的IP资源和服务。当主节点恢复时,备节点又会释放主节点故障时自身接管的IP资源和服务,恢复到原来的备用角色。
4.7、 拓展:OSI七层和OSI七层相关协议
4.7.1、 OSI七层:
4.7.2、 OSI七层相关协议
4.8、 Keepalived工作原理
Layer3、4、5工作在IP/TCP协议栈的IP层,TCP层,及应用层。
keepalived具有3、4、5层交换及健康检测功能。
lLayer3层检测:进行ICMP ping包检测,确认主机是否存活,如果异常,则会该主机从服务器集群中剔除。Keepalived 使用 Layer3 的方式工作式时, Keepalived 会定期向集群中的服务器发送一个 ICMP 的数据包(既我们平时用的 Ping 程序),如果发现某台服务的IP地址没有激活,Keepalived 便报告这台服务器失效,并将它从集群中剔除,这种情况的典型例子是某台服务器被非法关机。Layer3 的方式是以服务器的IP地址是否有效作为服务器工作正常与否的标准。
lLayer4层检测: 进行端口检测,例如80、3306等,端口不通时,将服务器从集群中剔除;主要以TCP端口的状态来决定服务器工作正常与否。如 web server 的服务端口一般是80,如果 Keepalived 检测到 80 端口没有启动,则 Keepalived 将把这台服务器从服务器群中删除。
lLayer5层检测:这个就是基于应用的了,如http返回码是否为200,确认主机是否正常。Layer5 就是工作在具体的应用层了,比 Layer3,Layer4 要复杂一点,在网络上占用的带宽也要大一些。 Keepalived 将根据用户的设定检查服务器程序的运行是否正常,如果与用户的设定不相符,则 Keepalived 将把服务器从服务器群中剔除(例如:http返回码是否为200,确认主机是否正常)。
4.9、 Keepalived的功能和核心组件
4.9.1、 Keepalived服务的三个重要功能:
1.管理LVS
2.对LVS集群节点检查
3.作为其他网络服务的高可用功能
4.9.2、 Keepalived核心组件
下图是keepalived的组件图:
keepalived也是模块化设计,不同模块负责不同的功能,它主要有三个模块,分别是core、check和VRRP,其中:
lcore模块:为keepalived的核心组件,负责主进程的启动、维护以及全局配置文件的加载和解析;
lcheck:负责健康检查,包括常见的各种检查方式;
lVRRP模块:是来实现VRRP协议的。
其他组件:
lsystem call:系统调用
lwatch dog:监控check和vrrp进程的看管者,check负责检测健康状态,当其检测到master上的服务不可用时则通告vrrp将其转移至backup服务器上。
n大致如下:
n1.利用VRRP协议进行主备通信。组播224.0.0.18
n2.利用VRRP协议进行主备竞选,产生VIP
n3.利用VRRP协议主向备发送组播包。当备服务器接收不到主服务器的组播包,就会认为主出现故障,主动接管资源
n4.当主恢复时,根据配置决定是否抢占备服务器资源
lipvs wrapper:为集群内的所有节点生成IPVS规则
注意,keepalived和LVS完全是两码事,只不过他们各负其责,相互配合而已。
Keepalived启动后会有三个进程:
父进程:内存管理,子进程管理等等
子进程:vrrpd子进程
子进程:healthchecker子进程
由上图可知,两个子进程都被系统WatchDog看管,两个子进程各自实现自己的事,healthchecker子进程实现检查各自服务器的健康程度,例如HTTP,LVS等等,如果healthchecker子进程检查到MASTER上服务不可用,就会通知本机上的VRRP子进程,让他删除通告,并且去掉虚拟IP,转换为BACKUP状态。
4.10、 经典高可用web架构:
LVS+keepalived+nginx+tomcat(apache+php+eaccelerator)+nfs(nfs可选)
注:eaccelertor [əkˈseləreɪtər]是一个开放源代码的php加速、优化和动态内容缓存的扩展模块,它可以提升php程序的缓存性能,降低PHP程序在解析时对服务器的性能开销。eaccelerator还有对PHP优化的作用,加快其执行效率。
Nginx做反向代理,若出现Nginx单机故障,则导致整个系统无法正常运行。针对系统架构设计的高可用要求,我们需要解决Nginx出现单机故障时,系统正常运行的需求。所以系统架构引入Lvs+Keepalived组件,实现系统高可用。
4.11、 keepalived官网
http://www.keepalived.org/
4.12、 keepalived下载:
http://www.keepalived.org/download.html
5、 使用Keepalived构建LVS-DR模式的高可用集群
5.1、 网络拓扑
上图设计目的是用Keepalived构建高可用性的LVS负载均衡集群。使用Keepalived构建LVS集群更加简便易用,主要优势体现在:对LVS负载调度器实现热备切换,提高可用性,对WEB服务器池中的节点进行健康检查,自动移除失败节点,恢复后再重新加入。
在基于LVS-Keepalived实现的LVS集群结构中,至少包括两台热备的负载调度器,两台或两台以上的web节点服务器,本例将以DR模式的LVS集群为基础,增加一台从负载调度器,使用Keepalived来实现主、从调度器的热备,从而构建建有负载均衡、高可用两种能力的LVS网站集群平台。
5.2、 实验环境
参照上图可知每台主机网卡的IP地址,如下所示:至少4台主机
VIP(虚拟IP地址):172.16.16.172/24
注:关闭防火墙和selinux
Keepalived的设计目标是构建高可用的LVS负载均衡群集,可以调用ipvsadm工具来创建虚拟服务器、管理服务器池,而不仅仅用来做双机热备。使用Keepalived构建LVS群集更加简便易用,主要优势体现在:对LVS负载调度器实现热备切换,提高可用性;对服务器池中的节点进行健康检查,自动移除失效点节,恢复后再重新加入。
使用 Keepalived构建LVS群集时,也需要用到ipvsadm管理工具,但大部分工作会由Keepalived自动完成,不需要手动执行ipvsadm(除了查看和监控群集以外)
5.3、 安装keepalived
5.3.1、 第一种安装方法:
yum install –y keepalived
查看安装路径:
rpm -ql keepalived-1.3.5-1.el7.x86_64
5.3.2、 第二种安装方法(源码安装)
本文采用第二种安装方法
在主节点m_director上安装keepalived
解决依赖
[root@m_director ~]# yum -y install gcc openssl-devel pcre-devel libnl-devel
[root@m_director ~]# tar zxf keepalived-2.0.18.tar.gz
[root@m_director ~]# cd keepalived-2.0.18/
[root@m_director keepalived-2.0.18]# ./configure --prefix=/usr/local/keepalived
[root@m_director keepalived-2.0.18]# make && make install
5.4、 了解keepalived的文件
[root@m_director keepalived-2.0.18]# cd /usr/local/keepalived/
[root@m_director keepalived]# ls
bin etc sbin share
#etc下有配置文件etc/keepalived/keepalived.conf
在从节点s_director上用同样的方法安装keepalived(过程略)
5.5、 配置Keepalived+LVS-DR模式
在这种模式下,虚拟 IP 在某时刻只能属于某一个节点,另一个节点作为备用节点存在。当主节点不可用时,备用节点接管虚拟 IP,提供正常服务。
5.5.1、 配置说明:
节点m_director(主节点); 节点s_director(备用节点) ;
虚拟 IP :172.16.16.172对外提供服务的 IP。 要求默认情况下由节点m_director提供服务,当节点m_director不可用时,由节点s_director提供服务(即虚拟 IP 漂移至节点s_director)。
5.5.2、 主节点m_director配置
keepalived只有一个配置文件keepalived.conf,里面主要包括以下几个配置区域,分别是global_defs、vrrp_instance和virtual_server。
global_defs:主要是配置故障发生时的通知对象以及机器标识。
vrrp_instance:用来定义对外提供服务的VIP区域及其相关属性。
virtual_server:虚拟服务器定义。
1.1.1.1、 修改keepalived.conf配置文件
M_director主机上的keepalived.conf文件的修改:
[root@m_director ~]# ln -s /usr/local/keepalived/sbin/keepalived /usr/sbin/
[root@m_director ~]# mkdir /etc/keepalived/
[root@m_director ~]# cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
[root@m_director ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived #!表示注释
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 server地址,即发邮件服务器
smtp_connect_timeout 30 #设置smtp超时连接时间,以上参数可以不配置
router_id m_director #表示运行keepalived服务器的一个标识,这个标识(router_id)是唯一的
}
vrrp_instance lvs-dr { #定义一个实例,一个集群就是一个实例。 默认VI_1 可以随意改
state MASTER #MASTER表示指定本节点为主节点,备用节点上设置为 BACKUP。注意节点状态均大写。
interface ens33 #绑定虚拟 IP 的网络接口
virtual_router_id 51 #虚拟路由ID标识,这个标识最好是一个数字,在一个keepalived.conf配置中是唯一的, MASTER和BACKUP配置中相同实例的virtual_router_id必须是一致的。
priority 100 #节点的优先级(1-254之间),越大越优先。备用节点必须比主节点优先级低。
advert_int 1 #为同步通知间隔。MASTER与BACKUP之间心跳检查的时间间隔,单位为秒,默认为1。
authentication { #设置验证信息,两个节点必须一致,同一vrrp实例的MASTER与BACKUP使用相同的密码才能正常通信。
auth_type PASS
auth_pass 1111
}
virtual_ipaddress { #指定虚拟 IP, 两个节点设置必须一样
172.16.16.172
}
}
#至此为止以上为实现高可用配置,如只需使用高可用功能下边配置可删除
#以下为虚拟服务器定义部分
#类似添加虚拟服务器 ipvsadm -A -t 172.16.16.172:80 -s rr
virtual_server 172.16.16.172 80 { #设置虚拟服务器,指定虚拟IP和端口
delay_loop 6 #健康检查时间为6秒,即Keepalived多长时间监测一次RS。
lb_algo rr #设置负载调度算法为rr算法
lb_kind DR #设置负载均衡模式,有NAT,TUN和DR三种模式可选
nat_mask 255.255.255.0 #非NAT模式注释掉此行 注释用!号
persistence_timeout 50 #连接保持时间,单位是秒。有了这个会话保持功能,用户的请求会被一直分发到某个服务节点,直到超过这个会话的保持时间。同一IP地址的客户端50秒内的请求都发到同个real server ,这个会影响LVS的 rr 调度算法,同一IP的客户端超过50 秒后,再次访问,才会被转发到另一台real server上。Persistence是持久性的意思
protocol TCP #指定转发协议类型,有TCP和UDP两种
real_server 172.16.16.177 80 { #配置RS节点1,需要指定 realserver 的真实 IP 地址和端口,IP和端口之间用空格隔开
weight 1 ##权重,权重大小用数字表示,数字越大,权重越高
TCP_CHECK { #节点健康检查。这段内容要手动添加,把原来的内容删除
connect_timeout 3 #超时时间,表示3秒无响应超时。
nb_get_retry 3 #表示重试次数
delay_before_retry 3 #表示重试间隔
connect_port 80 #检测端口,利用80端口检查
}
}
real_server 172.16.16.178 80 { #RS节点2
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
#默认配置文件中还有两个 virtual_server 模版,把剩下的都删除了,就可以。 如:
#virtual_server 10.10.10.2 1358 { 。。。 }
#virtual_server 10.10.10.3 1358 { 。。。 }
keepalived.conf配置文件完整内容如下所示:
[root@m_director ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id m_director
}
vrrp_instance lvs-dr {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.16.16.172
}
}
virtual_server 172.16.16.172 80 {
delay_loop 6
lb_algo rr
lb_kind DR
#persistence_timeout 50
protocol TCP
real_server 172.16.16.177 80 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 172.16.16.178 80 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
5.5.2.1、 重启keepalived服务
[root@m_director ~]# systemctl restart keepalived
[root@m_director ~]# systemctl enable keepalived
[root@m_director ~]# systemctl status keepalived
5.5.2.2、 安装ipvsadm
安装完成不需要做任何配置,启动方式由keepalived控制
[root@m_director ~]# yum -y install ipvsadm
[root@m_director ~]# lsmod | grep ip_vs
[root@m_director ~]# lsmod | grep ip_vs
ip_vs_rr 12600 1
ip_vs 145497 3 ip_vs_rr
nf_conntrack 133095 1 ip_vs
libcrc32c 12644 3 xfs,ip_vs,nf_conntrack
[root@m_director ~]# ipvsadm -L –n
[root@m_director ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.16.172:80 rr
#注:没有看到 realserver,是因为两台 realserver 还没有开启 httpd 服务。
5.5.3、 备用节点s_director配置
5.5.3.1、 安装keepalived
和主节点m_director安装相同,请参考m_director的安装过程。
5.5.3.2、 修改keepalived.conf配置文件
备用节点的keepalived.conf文件配置与主节点基本相同,只是router_id,state,priority三处不同,其他配置都相同
[root@s_director ~]# mkdir /etc/keepalived
[root@s_director ~]# scp root@172.16.16.173:/etc/keepalived/keepalived.conf /etc/keepalived/
复制过来之后,还要做一定的修改:
[root@s_director ~]# vim /etc/keepalived/keepalived.conf
注:红色为改动项值
! Configuration File for keepalived
global_defs {
router_id s_director
}
vrrp_instance lvs-dr {
state BACKUP
interface ens33
virtual_router_id 51
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.16.16.172
}
virtual_server 172.16.16.172 80 {
delay_loop 6
lb_algo rr
lb_kind DR
#persistence_timeout 50
protocol TCP
real_server 172.16.16.177 80 {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 172.16.16.178 80 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
5.5.3.3、 启动keepalived:
[root@s_director ~]# systemctl enable keepalived.service
[root@s_director ~]# systemctl start keepalived.service
1.1.1.1、 安装ipvsadm
[root@m_director ~]# yum -y install ipvsadm
安装完成不需要做任何配置,启动方式由keepalived控制
5.5.4、 测试主备切换
5.5.4.1、 查看主备情况
在m_director和s_director分别执行ip addr show dev ens33命令查看m_director和s_director对VIP(群集虚拟IP)的控制权。
m_director主节点的查看结果:
[root@m_director ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:17:92:f3 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.173/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 172.16.16.172/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::784:4bfa:defc:4233/64 scope link noprefixroute
valid_lft forever preferred_lft forever
s_director从节点的查看结果:
[root@s_director ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:94:34:09 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.174/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::e411:893e:5322:6160/64 scope link noprefixroute
valid_lft forever preferred_lft forever
从上面的显示结果可以看出m_director是主服务器,s_director为备用服务器。
5.5.4.2、 测试主备vip地址漂移
主备vip漂移,只需关闭主节点的keepalived服务,主节点VIP地址消失,备节点显示VIP地址,开启主的keepalived服务,备VIP节点VIP地址消失,主节点显示VIP地址。
[root@m_director ~]# systemctl stop keepalived.service
[root@m_director ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:17:92:f3 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.173/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::784:4bfa:defc:4233/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@s_director ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:94:34:09 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.174/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 172.16.16.172/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::e411:893e:5322:6160/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@m_director ~]# systemctl start keepalived.service
[root@m_director ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:17:92:f3 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.173/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 172.16.16.172/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::784:4bfa:defc:4233/64 scope link noprefixroute
valid_lft forever preferred_lft forever
5.5.5、 keepalived脑裂现象
由于某些原因,导致两台keepalived高可用服务器在指定时间内,无法检测到对方存活心跳信息,从而导致互相抢占对方的资源和服务所有权,然而此时两台高可用服务器有都还存活。表现形式就是备节点上出现了虚拟IP, 此时主节点也是持有虚拟IP的。
脑裂产生的原因:
一般来说,裂脑的发生,有以下几种原因:
l高可用服务器对之间心跳线链路发生故障,导致无法正常通信。
因心跳线坏了(包括断了,老化)。
因网卡及相关驱动坏了,ip配置及冲突问题(网卡直连)。
因心跳线间连接的设备故障(网卡及交换机)。
l高可用服务器上开启了iptables防火墙阻挡了心跳消息传输。
l高可用服务器上心跳网卡地址等信息配置不正确,导致发送心跳失败。
l其他服务配置不当等原因,如心跳方式不同,心跳广插冲突、软件Bug等。
lKeepalived配置里同一 VRRP实例如果 virtual_router_id两端参数配置不一致也会导致裂脑问题发生。
5.5.6、 配置RS1(cong11)
5.5.6.1、 关闭ARP转发(在两台RS上都需要同样的操作)。
[root@cong11 ~]# vim /etc/sysctl.conf #最后添加
net.ipv4.conf.ens33.arp_ignore = 1
net.ipv4.conf.ens33.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
使内核参数修改生效:
[root@cong11 ~]# sysctl -p
5.5.6.2、 配置虚拟ip地址(VIP)
生成回环口配置文件:
[root@cong11 ~]# cd /etc/sysconfig/network-scripts/
[root@cong11 network-scripts]# cp ifcfg-lo ifcfg-lo:0
[root@cong11 network-scripts]# vim ifcfg-lo:0
DEVICE=lo:0
IPADDR=172.16.16.172
NETMASK=255.255.255.255
ONBOOT=yes
NAME=loopback
重启network服务:
[root@cong11 network-scripts]# systemctl restart network
[root@cong11 network-scripts]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.16.16.177 netmask 255.255.255.0 broadcast 172.16.16.255
inet6 fe80::e411:893e:5322:6160 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:94:34:09 txqueuelen 1000 (Ethernet)
RX packets 5394 bytes 1087392 (1.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3681 bytes 514268 (502.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 1996 bytes 167176 (163.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1996 bytes 167176 (163.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo:0: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 172.16.16.172 netmask 255.255.255.255
loop txqueuelen 1000 (Local Loopback)
5.5.6.3、 安装httpd
[root@cong11 ~] # yum install -y httpd
[root@cong11 ~] # systemctl start httpd
[root@cong11 ~] # echo "172.16.16.177" > /var/www/html/index.html
#(实验期间,为了测试负载均衡,各个服务器的页面不同,可以先不挂载nfs共享存储)
5.5.7、 配置RS2(cong12)
5.5.7.1、 关闭ARP转发(在两台RS上都需要同样的操作)。
[root@cong12 ~]# vim /etc/sysctl.conf #最后添加
net.ipv4.conf.ens33.arp_ignore = 1
net.ipv4.conf.ens33.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
使内核参数修改生效:
[root@cong12 ~]# sysctl -p
5.5.7.2、 配置虚拟ip地址(VIP)
生成回环口配置文件:
[root@cong12 ~]# cd /etc/sysconfig/network-scripts/
[root@cong12 network-scripts]# cp ifcfg-lo ifcfg-lo:0
[root@cong12 network-scripts]# vim ifcfg-lo:0
DEVICE=lo:0
IPADDR=172.16.16.172
NETMASK=255.255.255.255
ONBOOT=yes
NAME=loopback
重启network服务:
[root@cong12 network-scripts]# systemctl restart network
[root@cong12 network-scripts]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.16.16.178 netmask 255.255.255.0 broadcast 172.16.16.255
inet6 fe80::e411:893e:5322:6160 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:94:34:09 txqueuelen 1000 (Ethernet)
RX packets 5394 bytes 1087392 (1.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3681 bytes 514268 (502.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 1996 bytes 167176 (163.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1996 bytes 167176 (163.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo:0: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 172.16.16.172 netmask 255.255.255.255
loop txqueuelen 1000 (Local Loopback)
5.5.7.3、 安装httpd
[root@cong12 ~] # yum install -y httpd
[root@cong12 ~] # systemctl start httpd
[root@cong12 ~] # echo "172.16.16.177" > /var/www/html/index.html
#(实验期间,为了测试负载均衡,各个服务器的页面不同,可以先不挂载nfs共享存储)
5.5.8、 测试VIP
在主节点(m_director)上查看lvs的状态
[root@m_director ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.16.172:80 rr
-> 172.16.16.177:80 Route 1 0 0
-> 172.16.16.178:80 Route 1 0 0
访问VIP地址:
http://172.16.16.172
刷新页面
5.5.9、 测试主备切换
1.1.1.1、 首先在主上m_director上查看状态
[root@m_director ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:17:92:f3 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.173/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 172.16.16.172/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::784:4bfa:defc:4233/64 scope link noprefixroute
valid_lft forever preferred_lft forever
5.5.9.1、 在备上查看s_director的状态
[root@s_director ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:94:34:09 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.174/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::e411:893e:5322:6160/64 scope link noprefixroute
valid_lft forever preferred_lft forever
5.5.9.2、 在m_director上停掉keepalived服务, 模拟故障,再查看s_director
[root@m_director ~]# systemctl stop keepalived.service
[root@m_director ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
[root@s_director ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:94:34:09 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.174/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 172.16.16.172/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::e411:893e:5322:6160/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@s_director ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.16.172:80 rr
-> 172.16.16.177:80 Route 1 0 0
-> 172.16.16.178:80 Route 1 0 0
查看主从节点的日志:
[root@m_director ~]# tail -20 /var/log/messages
[root@s_director ~]# tailf /var/log/messages
当我们重启了主上的keepalived,自动从备分发器转到主分发器上。因为备的优先级低。
[root@m_director ~]# systemctl start keepalived.service
5.5.9.3、 测试RS容错,停掉cong11的httpd
使用 ipvsadm -Ln 可以看到刚才关闭的那台机器的 IP不在列表中了。
[root@m_director ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.16.172:80 rr
-> 172.16.16.178:80 Route 1 0 1
5.5.9.4、 打开主 LVS 的日志(/var/log/message),看到滚动从 LVS 中移除172.16.16.177。
5.5.10、 keepalived的常见的健康检查方式
lTCP_CHECK :tcp端口检测
lHTTP_GET :http接口检测
lMISC_CHECK :自定义脚本检测
5.5.10.1、 TCP_CHECK检测
real_server 172.16.16.177 80 {
weight 100
TCP_CHECK {
connect_port 80 #检测端口,利用80端口检查
connect_timeout 3 #连接超时时间
nb_get_retry 3 #重连次数
delay_before_retry 3 #重连间隔
}
}
5.5.10.2、 HTTP_GET检测
基于状态码的检测
real_server 172.16.16.177 80 {
weight 1
HTTP_GET {
url {
path /index.html
status_code 200 #http://172.16.16.177/index.html的返回状态码
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
5.5.10.3、 MISC_CHECK检测
自定义Shell脚本监控
real_server 172.16.16.177 80 {
weight 100
MISC_CHECK {
misc_path "/opt/mytools/check_web.sh 172.16.16.177" #脚本名,需全路径
misc_timeout 30 #脚本执行的超时时间
misc_dynamic #如果设置了misc_dynamic,healthchecker程序的退出状态码会用来动态调整服务器的权重(weight)。
}
}
用脚本来检测,脚本如果带有参数,需将脚本和参数放入双引号内。脚本的返回值需为:
#返回0:健康检查OK,权重不被修改
#返回1:健康检查失败,权重设为0
#返回2-255:健康检查OK,权重设置为:退出状态码-2,比如返回255,那么weight=255-2=253
keepalived检测脚本内容/opt/mytools/check_web.sh,返回0代表检查正常,返回1代表检查异常
/opt/mytools/check_web.sh内容如下
#!/bin/sh
serverip=$1
curl -s -m 2 http://$serverip
if [ $? -eq 0 ];then
exit 0
else
exit 1
fi
注:curl命令中的-s选项表示静音模式,不输出任何东西。-m选项表示设置数据传输的最大时间。传输的最大允许时间
5.5.11、 附件:一个配置文件模板详解
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost #设置报警邮件地址,即收件人地址
}
notification_email_from admin@localhost #设置邮件的发送地址
smtp_server 127.0.0.1 #设置smtp server的ip地址
smtp_connect_timeout 30 #设置连接smtp server的超时时间
router_id LTT #表示运行keepalived服务器的一个标识名字可以随便取,名字会显示在发邮件时邮件的主题信息
}
vrrp_instance IN_1 {
state MASTER #指定keepalived的角色,此服务为master
interface ens160 #指定监测网络的接口
virtual_router_id 22 #虚拟路由的标识
priority 100 #定义优先级,数字越大优先级越高,1-255之间
advert_int 1 #设置同步检查的时间间隔,单位是秒
authentication { #设置验证类型
auth_type PASS #验证类型为PASS
auth_pass aaaa #验证的密码
}
virtual_ipaddress {
192.168.2.111 #设置虚拟IP
}
}
virtual_server 192.168.2.111 80 { #定义虚拟服务器,需指定虚拟ip和端口
delay_loop 6 #设置健康检查时间,单位为秒
lb_algo wlc #设置负载调度算法,此处为加权轮叫算法
lb_kind DR #设置LVS实现负载均衡的模式
persistence_timeout 120 #设置会话持续时间
nat_mask 255.255.255.0 # 设置子网掩码
protocol TCP #设置转发协议的类型
real_server 192.168.2.64 80 { #定义realserver,需指定ip和端口
weight 1 #指定权重
HTTP_GET { #设置检测后端realserver的方式为获取http协议报文
url {
path /
status_code 200 #状态码为200则证明后端服务器是在线的
}
connect_timeout 3 #设置超时时间
nb_get_retry 3 #设置超时时候重试几次
delay_before_retry 3 #在重试的时候的时间间隔
}
}
virtual_server 192.168.2.111 8090 { #定义虚拟服务器,需指定虚拟ip和端口
delay_loop 6 #设置健康检查时间,单位为秒
lb_algo wlc #设置负载调度算法,此处为加权轮叫算法
lb_kind DR #设置LVS实现负载均衡的模式
persistence_timeout 120 #设置会话持续时间
nat_mask 255.255.255.0 #设置子网掩码
protocol TCP #设置转发协议的类型
real_server 192.168.2.90 80 { #定义realserver,需指定ip和端口
weight 1 #指定权重
HTTP_GET { #设置检测后端realserver的方式为获取http协议报文
url {
path /
status_code 200 #状态码为200则证明后端服务器是在线的
}
connect_timeout 3 #设置超时时间
nb_get_retry 3 #设置超时时候重试几次
delay_before_retry 3 #在重试的时候的时间间隔
}
}
}
6、 使用keepalived 实现nginx 负载均衡+主备高可用
6.1、 概述
nginx作为负载均衡器,所有请求都到nginx,可见nginx处于非常重点的位置,如果nginx服务器宕机,后端web服务将无法提供服务,影响严重。
所以在架构设计中,可以利用nginx的反向代理和负载均衡实现后端应用的负载均衡和高可用性,同时我们还需要考虑Nginx的单点故障。真正做到架构高可用性。
主要考虑以下几点:
1、Nginx服务因为意外现象挂掉
2、服务器宕机导致nginx不可用
目前主流的解决方案就是keepalived+nginx 实现nginx的故障转移,同时做好监控报警。在自动故障转移的同时能通知到相关的应用负责人检查相关应用,排查隐患,彻底解决问题。
keepalived的HA分为抢占模式和非抢占模式,抢占模式即MASTER从故障中恢复后,会将VIP从BACKUP节点中抢占过来。非抢占模式即MASTER恢复后不抢占BACKUP升级为MASTER后的VIP。
6.2、 实验环境介绍
两台nginx,一主一备:172.16.16.173和172.16.16.178
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
分别在两台服务器安装nginx和keepalived:
6.3、 在nginx-01和nginx-02两台主机上安装nginx
6.3.1、 上传软件包并解压
[root@nginx-01 ~]# ls
anaconda-ks.cfg master.tar.gz nginx-1.10.3.tar.gz ngx_cache_purge-2.3.tar.gz
[root@cong11 ~]# tar -zxvf nginx-1.10.3.tar.gz -C /usr/local/src/
6.3.2、 安装nginx依赖包
安装zlib-devel、pcre-devel等依赖包
[root@nginx-01 ~]# yum install -y gcc gcc-c++ autoconf automake zlib zlib-devel openssl openssl-devel pcre pcre-devel
6.3.3、 预编译
添加www组,创建nginx运行账户www并加入到www组,不允许www用户直接登录系统。
[root@nginx-01 ~]# groupadd www
[root@nginx-01 ~]# useradd -g www -s /sbin/nologin www
注:
结合proxy和upstream模块实现后端web负载均衡,使用proxy模块实现静态文件缓存。
结合nginx的ngx_http_proxy_module模块和ngx_http_upstream_module模块实现后端服务器的健康检查。
使用nginx-sticky-module扩展模块实现会话黏贴(保持会话)
使用ngx_cache_purge [pɜːrdʒ]实现更强大的缓存清除功能
上面提到的2个模块都属于第三方扩展模块,需要提前下好源码,然后编译时通过--add-moudle=src_path一起安装。
[root@nginx-01 ~]# tar zxf ngx_cache_purge-2.3.tar.gz -C /usr/local/src/
[root@nginx-01 ~]# tar zxf master.tar.gz -C /usr/local/src/
[root@nginx-01 ~]# cd /usr/local/src/nginx-1.10.3/
[root@nginx-01 nginx-1.10.3]# ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_realip_module --with-http_ssl_module --with-http_gzip_static_module --http-client-body-temp-path=/var/tmp/nginx/client --http-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fcgi --with-http_dav_module --with-http_stub_status_module --with-http_addition_module --with-http_sub_module --with-http_flv_module --with-http_mp4_module --with-pcre --with-http_flv_module --add-module=../ngx_cache_purge-2.3 --add-module=../nginx-goodies-nginx-sticky-module-ng-08a395c66e42
6.3.4、 编译安装
[root@nginx-01 nginx-1.10.3]# make && make install
6.3.5、 启动nginx
[root@nginx-01 nginx-1.10.3]# mkdir -p /var/tmp/nginx/{client,proxy,fcgi}
[root@nginx-01 nginx-1.10.3]# chown -R www:www /var/tmp/nginx/
[root@nginx-01 nginx-1.10.3]# /usr/local/nginx/sbin/nginx
6.3.6、 查看端口号
[root@nginx-01 nginx-1.10.3]# netstat -antup | grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 54315/nginx: master
6.3.7、 网站测试
http://172.16.16.172/
6.3.8、 添加path变量
[root@nginx-01 nginx-1.10.3]# ln -s /usr/local/nginx/sbin/* /usr/local/bin/
6.3.9、 生成服务启动脚本
[root@nginx-01 nginx-1.10.3]# vim /etc/init.d/nginx
#!/bin/bash
# chkconfig: - 99 2
# description: Nginx Service Control Script
PROG="/usr/local/nginx/sbin/nginx"
PIDF="/usr/local/nginx/logs/nginx.pid"
case "$1" in
start)
$PROG
;;
stop)
kill -3 $(cat $PIDF)
;;
restart)
$0 stop &> /dev/null
if [ $? -ne 0 ] ; then continue ; fi
$0 start
;;
reload)
kill -1 $(cat $PIDF)
;;
*)
echo "Userage: $0 { start | stop | restart | reload }"
exit 1
esac
exit 0
6.3.10、 配置服务开机自动启动
[root@nginx-01 ~]# chmod +x /etc/init.d/nginx #给脚本添加可执行权限
[root@nginx-01 ~]# chkconfig --add nginx #把nginx添加为系统服务
[root@nginx-01 ~]# chkconfig nginx on #把nginx添加开机自启动
[root@nginx-01 ~]# chkconfig --list nginx #查看nginx开机启动项
nginx-02主机按同样的方法安装nginx,过程略
nginx-01和nginx-02配置反向代理,过程参考“nginx-tomcat”文档
6.4、 在nginx-01和nginx-02两台主机上安装keepalived
6.4.1、 在nginx-01和nginx-02安装keepalived
6.4.1.1、 解决依赖:
[root@nginx-01 ~]# yum -y install gcc openssl-devel pcre-devel libnl-devel
6.4.1.2、 安装keepalived
[root@nginx-01 ~]# tar zxf keepalived-2.0.18.tar.gz
[root@nginx-01 ~]# cd keepalived-2.0.18/
[root@nginx-01 keepalived-2.0.18]# ./configure --prefix=/usr/local/keepalived
[root@nginx-01 keepalived-2.0.18]# make && make install
6.4.1.3、 了解keepalived的文件
[root@nginx-01 keepalived-2.0.18]# cd /usr/local/keepalived/
[root@nginx-01 keepalived]# ls
bin etc sbin share
#etc下有配置文件etc/keepalived/keepalived.conf
在nginx-02上用同样的方法安装keepalived(过程略)
6.4.2、 修改keepalived.conf配置文件
6.4.2.1、 nginx-01主机上的keepalived.conf文件的修改
[root@nginx-01 ~]# ln -s /usr/local/keepalived/sbin/keepalived /usr/sbin/
[root@nginx-01 ~]# mkdir /etc/keepalived/
[root@nginx-01 ~]# cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
[root@nginx-01 ~]# vim /etc/keepalived/keepalived.conf
keepalived.conf配置文件完整内容如下所示:
! Configuration File for keepalived
global_defs {
router_id nginx-01
}
vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh"
interval 2 #每2秒检测一次nginx的运行状态
weight -20 #失败一次,将自己的优先级-20
}
vrrp_instance VI-1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
!nopreempt #不抢占模式,如果使用抢占模式,只需将其注释即可
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.16.16.172
}
track_script {
chk_nginx # nginx存活状态检测脚本
}
}
6.4.2.2、 nginx-02主机上的keepalived.conf文件的修改
nginx-02的keepalived.conf文件配置与主节点基本相同,只是router_id,state,priority三处不同,其他配置都相同
[root@nginx-02 ~]# ln -s /usr/local/keepalived/sbin/keepalived /usr/sbin/
[root@nginx-02 ~]# mkdir /etc/keepalived/
[root@nginx-02 ~]# scp root@172.16.16.173:/etc/keepalived/keepalived.conf /etc/keepalived/
复制过来之后,还要做一定的修改:
[root@nginx-02 ~]# vim /etc/keepalived/keepalived.conf
keepalived.conf配置文件完整内容如下所示:(标红色部分)
! Configuration File for keepalived
global_defs {
router_id nginx-02
}
vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh"
interval 2
weight -20
}
vrrp_instance VI-1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 90
advert_int 1
!nopreempt
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.16.16.172
}
track_script {
chk_nginx
}
}
6.4.2.3、 创建nginx服务检测脚本
分别在nginx-01和nginx-02服务器的/etc/keepalived目录下创建nginx_check.sh脚本,并为其添加执行权限。用于keepalived定时检测nginx的服务状态,如果nginx停止了,会尝试重新启动nginx,如果启动失败,会将keepalived进程杀死,将vip漂移到备用机器上。
[root@nginx-01 ~]# vim /etc/keepalived/nginx_check.sh
#!/bin/bash
num=$(ps -C nginx --no-header | wc -l)
if [ $num -eq 0 ];then
/usr/local/nginx/sbin/nginx #尝试重新启动nginx
sleep 1 #睡眠1秒
if [ $(ps -C nginx --no-header | wc -l) -eq 0 ];then
killall keepalived #若nginx启动失败,将keepalived服务杀死。将vip漂移到其它备份节点
fi
fi
说明:
ps -C nginx --no-header | wc -l一般用于shell脚步编写用
-C <指令名称> 选项用来指定程序的名称
--no-header选项去掉头部
killall命令由软件包psmisc提供,确保两台主机要安装psmisc
[root@nginx-01 ~]# chmod +x /etc/keepalived/nginx_check.sh
6.4.2.4、 启动keepalived服务
nginx-01主机:
[root@nginx-01 ~]# systemctl enable keepalived.service
[root@nginx-01 ~]# systemctl start keepalived.service
[root@nginx-01 ~]# ps -ef | grep keepalived
root 54735 1 0 23:32 ? 00:00:00 /usr/local/keepalived/sbin/keepalived -D
root 54736 54735 0 23:32 ? 00:00:00 /usr/local/keepalived/sbin/keepalived -D
nginx-02主机:
[root@nginx-02 ~]# systemctl enable keepalived.service
[root@nginx-03 ~]# systemctl start keepalived.service
[root@nginx-02 ~]# ps -ef | grep keepalived
root 54465 1 0 23:32 ? 00:00:00 /usr/local/keepalived/sbin/keepalived -D
root 54466 54465 0 23:32 ? 00:00:00 /usr/local/keepalived/sbin/keepalived -D
如果看到如上进程信息,表示keepalived已经启动成功。下面用ip addr命令查看vip绑定的情况,如下所示:
[root@nginx-01 ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:17:92:f3 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.173/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 172.16.16.172/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::784:4bfa:defc:4233/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@nginx-02 ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:94:34:09 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.174/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::e411:893e:5322:6160/64 scope link noprefixroute
valid_lft forever preferred_lft forever
从上面可以看出,vip地址172.16.16.172绑定在nginx-01的ens33网卡上。
6.4.2.5、 测试故障转移
6.4.2.6、 抢占模式
将nginx-01的keepalived服务和nginx服务停掉,查看vip是否漂移到nginx-02
[root@nginx-01 ~]# systemctl stop keepalived
[root@nginx-01 ~]# nginx -s stop
注:本环境中,在抢占模式下,请思考为什么要将keepalived服务停掉?
下面用ip addr命令查看vip绑定的情况,如下所示:
[root@nginx-01 ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:17:92:f3 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.173/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::784:4bfa:defc:4233/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@nginx-02 ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:94:34:09 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.174/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 172.16.16.172/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::e411:893e:5322:6160/64 scope link noprefixroute
valid_lft forever preferred_lft forever
从上面显示可以看出,vip已经成功从nginx-01漂移到了nginx-02。
将nginx-01的nginx服务和keepalived服务启动,查看抢占模式的效果。
[root@nginx-01 ~]# nginx
[root@nginx-01 ~]# systemctl start keepalived
[root@nginx-01 ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:17:92:f3 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.173/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 172.16.16.172/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::784:4bfa:defc:4233/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@nginx-02 ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:94:34:09 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.174/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::e411:893e:5322:6160/64 scope link noprefixroute
valid_lft forever preferred_lft forever
此时再将nginx-01的nginx服务和keepalived服务启动后,由于nginx-01是MASTER且优先级高,所以会将nginx-02的VIP抢占过来。从上面的显示结果可以看到,VIP又漂移到了nginx-01主机。
6.4.2.7、 非抢占模式
和抢占模式的配置相比,只改了两个地方:
l在vrrp_instance块下,两个节点各增加了nopreempt指令,表示不争抢vip。
l两个节点的state都为BACKUP。
在非抢占模式下,两个keepalived节点都启动后,默认都是BACKUP状态,双方在发送组播信息后,会根据优先级来选举一个MASTER出来。由于两者都配置了nopreempt,所以MASTER从故障中恢复后,不会抢占vip。这样会避免VIP切换可能造成的服务延迟。
nginx-01和nginx-02的keepalived.conf内容(标红色部分):
[root@nginx-01 ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id nginx-01
}
vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh"
interval 2
weight -20
}
vrrp_instance VI-1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 100
advert_int 1
nopreempt
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.16.16.172
}
track_script {
chk_nginx
}
}
[root@nginx-02 ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id nginx-02
}
vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh"
interval 2
weight -20
}
vrrp_instance VI-1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 90
advert_int 1
nopreempt
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.16.16.172
}
track_script {
chk_nginx
}
}
重启nginx-01和nginx-02的keepalived服务
[root@nginx-01 ~]# systemctl restart keepalived.service
[root@nginx-02 ~]# systemctl restart keepalived.service
用ip addr命令查看vip绑定的情况,如下所示:
[root@nginx-01 ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:17:92:f3 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.173/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 172.16.16.172/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::784:4bfa:defc:4233/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@nginx-02 ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:94:34:09 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.174/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::e411:893e:5322:6160/64 scope link noprefixroute
valid_lft forever preferred_lft forever
从上面的显示结果可以看到VIP在nginx-01上
将nginx-01的keepalived服务停掉
[root@nginx-01 ~]# systemctl stop keepalived
[root@nginx-01 ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:17:92:f3 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.173/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::784:4bfa:defc:4233/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@nginx-02 ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:94:34:09 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.174/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 172.16.16.172/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::e411:893e:5322:6160/64 scope link noprefixroute
valid_lft forever preferred_lft forever
VIP地址漂移到了nginx-02上
再将nginx-01的keepalived服务启动,查看是否抢占VIP
[root@nginx-01 ~]# systemctl start keepalived
[root@nginx-01 ~]# ps -ef | grep keepalived | grep -v "grep"
root 82535 1 0 11:37 ? 00:00:00 /usr/local/keepalived/sbin/keepalived -D
root 82536 82535 0 11:37 ? 00:00:00 /usr/local/keepalived/sbin/keepalived -D
用ip addr命令查看vip绑定的情况,如下所示:
[root@nginx-01 ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:17:92:f3 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.173/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::784:4bfa:defc:4233/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@nginx-02 ~]# ip addr show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:94:34:09 brd ff:ff:ff:ff:ff:ff
inet 172.16.16.174/24 brd 172.16.16.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 172.16.16.172/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::e411:893e:5322:6160/64 scope link noprefixroute
valid_lft forever preferred_lft forever