Nginx+Keepalived高可用集群应用实践

Nginx+Keepalived高可用集群应用实践

1.Keepalived高可用软件

1.1 Keepalived服务的三个重要功能

1.1.1管理LVS负载均衡软件

早期的LVS软件,需要通过命令行或脚本实现管理,并且没有针对LVS节点的健康检查功能。为了解决LVS的这些使用不便问题,Keepalived诞生了,可以说,Keepalived软件起初是专为解决LVS的问题而诞生的。因此,Keepalived和LVS的感情很深,他们的关系如同夫妻一样,可以紧密地结合,愉快地工作。Keepalived可以通过读取自身的配置文件,实现通过更底层的接口直接管理LVS的配置以及控制服务的启动,停止功能,这使得LVS的应用更加简单方便了。

1.1.2实现对LVS集群节点健康检查功能(healthcheck)

前文已讲过,Keepalived可以通过在自身的Keepalived.conf文件里配置LVS的节点IP和相关参数实现对LVS的直接管理;除此之外,当LVS集群中的某一个甚至是几个节点服务器同时发生故障无法提供服务时,Keepalived服务会自动将失效的节点服务器从LVS的正常转发队列中清除出去,并将请求调度到别的正常节点服务器上,从而保证最终用户的访问不受影响;当故障的节点服务器被修复以后,Keepalived服务又会自动地把它们加入到正常转发队列中,对客户提供服务。

1.1.3作为系统网络服务的高可用功能(failover)

  • Keepalived可以实现任意两台主机之间,例如Master和Backup主机之间的故障转移和自动切换,这个主机可以是普通的不能停机的业务服务器,也可以是LVS负载均衡,Nginx反向代理这样的服务器。
  • Keepalived高可用功能实现的简单原理为,两台主机同时安装好Keepalived软件并启动服务,开始正常工作时,由角色为Master的主机获得所有资源并对用户提供服务,角色为Backup的主机作为Master主机的热备;当角色为Master的主机失效或出现故障时,角色为Backup的主机将自动接管Master主机的所有工作,包括接管VIP资源及相应资源服务;而当角色为Master的主机故障修复后,又会自动接管回它原来处理的工作,角色为Backup的主机则同时释放Master主机失效时它接管的工作,此时,两台主机将恢复到最初启动时各自的原始角色及工作状态。

1.2解答Keepalived的工作原理

Keepalived高可用之间是通过VRRP通信的

  • VRRP也就是虚拟路由冗余协议,它的出现就是为了解决静态路由的单点故障。
  • VRRP是通过一种竞选协议机制来将路由任务交给某台VRRP路由器的。
  • VRRP用IP多播的方式(默认多播地址(224.0.0.18))实现高可用之间通信。
  • 工作时主节点发包,备节点接包,当备节点接收不到主节点发的数据包的时候,就启动接管程序接管主节点的资源。备节点可以有多个,通过优先级竞选,但一般Keepalived系统运维工作中都是一对。
  • VRRP使用了加密协议加密数据,但Keepalived官方目前还是推荐用明文的方式配置认证类型和密码

1.3 Keepalived服务的工作原理:

  • Keepalived高可用之间是通过VRRP进行通信的,VRRP是通过竞选机制来确定主备的,主的优先级高于备,因此,工作时主会优先获得所有的资源,备节点处于等待状态,当主挂了的时候,备节点就会接管主节点的资源,然后顶替主节点对外提供服务。
  • 在Keepalived服务之间,只有作为主的服务器会一直发送VRRP广播包,告诉备它还活着,此时备不会抢占主,当主不可用时,即备监听不到主发送的广播包时,就会启动相关服务接管资源,保证业务的连续性。接管速度最快可以小于1秒。

2.Keepalived高可用服务搭建准备

2.1安装Keepalived环境说明

2.1.1硬件环境准备

准备4台物理服务器或4台VM虚拟机,两台用来做Keepalived服务,两台做测试的Web节点如下表所示:

HOSTNAME IP 说明
lb01 192.168.200.64 Keepalived主服务器(Nginx主负载均衡器)
lb02 192.168.200.66 Keepalived备服务器(Nginx备负载均衡器)
web01 192.168.200.63 web01服务器
web02 192.168.200.60 web02服务器

2.1.2CentOS系统及Nginx代理环境

[root@lb01 /]# cat /etc/redhat-release
CentOS release 6.5 (Final)
[root@lb01 /]# uname -r
2.6.32-431.el6.x86_64
[root@lb01 /]# uname -m
x86_64

2.2为服务器新开一个网卡eth1

[root@lb01 extar]# cd /etc/sysconfig/network-scripts/
[root@lb01 network-scripts]# cp ifcfg-eth0 ifcfg-eth1
[root@lb01 network-scripts]# cat ifcfg-eth1
DEVICE=eth1
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=dhcp

[root@lb01 network-scripts]# ifup eth1
[root@lb01 network-scripts]# ifconfig eth1
eth1      Link encap:Ethernet  HWaddr 00:0C:29:BC:3F:E9  
          inet6 addr: fe80::20c:29ff:febc:3fe9/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:504 errors:0 dropped:0 overruns:0 frame:0
          TX packets:241 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:66191 (64.6 KiB)  TX bytes:19038 (18.5 KiB)

提示:上述安装过程需要在lb01和lb02两台服务器上同时安装。

2.3开始安装Keepalived软件

说明:下面有关Keepalived安装,启动服务的操作都是同时处理lb01,lb02两台机器

[root@lb01 /]# yum -y install keepalived
[root@lb01 /]# rpm -qa keepalived
keepalived-1.2.7-3.el6.x86_64

提示:

  • 上述安装过程需要在lb01和lb02两台服务器上同时安装。
  • epalived版本为2.7版

2.4启动及检查Keepalived服务的命令如下:

[root@lb01 /]# /etc/init.d/keepalived start
Starting keepalived:                                       [  OK  ]
[root@lb01 /]# ps -ef | grep keep | grep -v grep
root     1479     1   0 00:42 ?   00:00:00  /usr/sbin/keepalived -D
root     1481   1479  0 00:42 ?   00:00:00  /usr/sbin/keepalived -D
root     1482   1479  0 00:42 ?   00:00:00  /usr/sbin/keepalived -D
#提示:启动后有3个Keepalived进程表示安装正确

[root@lb01 /]# ip add | grep 192.168
    inet 192.168.200.64/24 brd 192.168.200.255 scope global eth0
    inet 192.168.200.16/32 scope global eth0
    inet 192.168.200.17/32 scope global eth0
    inet 192.168.200.18/32 scope global eth0
    #提示:默认情况会启动三个VIP地址
    
[root@lb01 ~]# /etc/init.d/keepalived stop
Stopping keepalived:                                       [  OK  ]
#提示:测试完毕后关闭服务,上述测试需要同时在lb01和lb02两台服务器上进行

2.5 Keepalived配置文件说明

2.5.1全局定义(Global Definitions)部分

这部分主要用来设置Keepalived的故障通知机制和Router ID标识。示例代码如下:

[root@lb01 ~]# head -13 /etc/keepalived/keepalived.conf | cat -n 
     1  ! Configuration File for keepalived
     2  
     3  global_defs {
     4     notification_email {
     5       acassen@firewall.loc
     6       failover@firewall.loc
     7       sysadmin@firewall.loc
     8     }
     9     notification_email_from Alexandre.Cassen@firewall.loc
    10     smtp_server 192.168.200.1
    11     smtp_connect_timeout 30
    12     router_id LVS_DEVEL
    13  }

基础参数说明:

  • 第1行是注释,!开头和#号开发一样,都是注释。
  • 第2行是空行。
  • 第3~8行是定义服务故障报警的Email地址。作用是当服务发生切换或RS节点等有故障时,发报警邮件。这几行是可选配置,notification_email指定在Keepalived发生事件时,需要发送的Email地址,可以有多个,每行一个.
  • 第9行是指定发送邮件的发送人,即发件人地址,也是可选的配置。
  • 第10行smtp_server指定发送邮件的smtp服务器,如果本机开启了sendmail或postfix,就可以使用上面默认配置实现邮件发送,也是可选配置。
  • 第11行smtp_connect_timeout是连接smtp的超时时间,也是可选配置。

注意:

  • 第4~11行所有和邮件报警相关的参数均可以不配,在实际工作中会将监控的任务交给更加擅长监控报警的Nagios或Zabbix软件。
  • 第12行是Keepalived服务器的路由标识(router_id).在一个局域网内,这个标识(router_id)应该是唯一的。
    大括号“{}”。用来分隔区块,要成对出现。如果漏写了半个大括号,Keepalived运行时,不会报错,但也不会得到预期的结果。另外,由于区块间存在多层嵌套关系,因此很容易遗漏区块结尾处的大括号,要特别注意。

2.5.2 VRRP实例定义区块(VRRP instance(s))部分

[root@lb01 ~]# sed -n '15,30{=;p}' /etc/keepalived/keepalived.conf | xargs -L2
15 vrrp_instance VI_1 {
16 state MASTER
17 interface eth0
18 virtual_router_id 51
19 priority 100
20 advert_int 1
21 authentication {
22 auth_type PASS
23 auth_pass 1111
24 }
25 virtual_ipaddress {
26 192.168.200.16
27 192.168.200.17
28 192.168.200.18
29 }
30 }

参数说明:

  • 第15行表示定义一个vrrp_instance实例,名字是VI_1,每个vrrp_instance实例可以认为是Keepalived服务的一个实例或者作为一个业务服务,在Keepalived服务配置中,这样的vrrp_instance实例可以有多个。注意,存在于主节点中的vrrp_instance实例在备节点中也要存在,这样才能实现故障切换接管。
  • 第16行state MASTER表示当前实例VI_1的角色状态,当前角色为MASTER,这个状态只能有MASTER和BACKUP两种状态,并且需要大写这些字符。其中MASTER为正式工作的状态,BACKUP为备用的状态。当MASTER所在的服务器故障或失效时,BACKUP所在的服务器会接管故障的MASTER继续提供服务。
  • 第17行interface为网络通信接口。为对外提供服务的网络接口,如eth0,eth1。当前主流的服务器都有2~4个网络接口,在选择服务接口时,要搞清楚了。
  • 第18行virtual_router_id为虚拟路由ID标识,这个标识最好是一个数字,并且要在一个keepalived.conf配置中是唯一的。但是MASTER和BACKUP配置中相同实例的virtual_router_id又必须是一致的,否则将出现脑裂问题。
  • 第19行priority为优先级,其后面的数值也是一个数字,数字越大,表示实例优先级越高。在同一个vrrp_instance实例里,MASTER的优先级配置要高于BACKUP的。若MASTER的priority值为150,那么BACKUP的priority必须小于150,一般建议间隔50以上为佳,例如:设置BACKUP的priority为100或更小的数值。
  • 第20行advert_int为同步通知间隔。MASTER与BACKUP之间通信检查的时间间隔,单位为秒,默认为1.
  • 第21~24行authentication为权限认证配置。包含认证类型(auth_type)和认证密码(auth_pass)。认证类型有PASS(Simple Passwd(suggested)),AH(IPSEC(not recommended))两种,官方推荐使用的类型为PASS。验证密码为明文方式,最好长度不要超过8个字符,建议用4位数字,同一vrrp实例的MASTER与BACKUP使用相同的密码才能正常通信。
  • 第25 ~ 29 行virtual_ipaddress为虚拟IP地址。可以配置多个IP地址,每个地址占一行,配置时最好明确指定子网掩码以及虚拟IP绑定的网络接口。否则,子网掩码默认是32位,绑定的接口和前面的interface参数配置的一致。注意,这里的虚拟IP就是在工作中需要和域名绑定的IP,即和配置的高可用服务监听的IP要保持一致!

3.Keepalived高可用服务单实例实战

3.1实战配置Keepalived主服务器lb01 MASTER

[root@lb01 keepalived]# pwd
/etc/keepalived
[root@lb01 keepalived]# cat keepalived.conf 
! Configuration File for keepalived

global_defs {
   notification_email {
    1773464408@qq.com       #邮箱随便写
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1    #邮件服务器IP
}
   smtp_connect_timeout 30
   router_id yang1    #id为yang1,不能和其他Keepalived节点相同(全局唯一)
}

vrrp_instance VI_1 {        #实例名字为VI_1,相同实例的备节点名字要和这个相同
state MASTER                #状态为MASTER,备节点状态需要为BACKUP
    interface eth1          #通信(心跳)接口为eth1,此参数备节点设置和主节点相同
    virtual_router_id 55    #实例ID为55,要和备节点相同
    priority 150            #优先级为150,备节点的优先级必须比此数字低
    advert_int 1            #通信检查间隔时间1秒
    authentication { 
        auth_type PASS      #PASS认证类型,此参数备节点设置和主节点相同
        auth_pass 1111      #密码1111,此参数备节点设置和主节点相同
    }
    virtual_ipaddress {
        192.168.200.123/24 dev eth0 label eth0:1
  #虚拟IP,即VIP为192.168.200.123,子网掩码为24位,绑定接口为eth0,别名为eth0:1,此参数备节点设置和主节点相同
   }
}

3.2启动Keepalived服务

[root@lb01 keepalived]# /etc/init.d/keepalived start
Starting keepalived:                                       [  OK  ]

3.3检查配置结果,查看是否有虚拟IP 192.168.200.123

[root@lb01 keepalived]# ip a | grep 192.168.200.123
    inet 192.168.81.123/24 scope global eth0:1
    #出现上述带有vip:192.168.200.123行的结果表示lb01的Keepalived服务单实例配置成功

3.4实战配置Keepalived备服务器lb02 BACKUP

[root@lb02 keepalived]# pwd
/etc/keepalived
[root@lb02 keepalived]# cat keepalived.conf 
! Configuration File for keepalived

global_defs {
   notification_email {
    1773464408@qq.com
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
}
   smtp_connect_timeout 30
   router_id yang2         #此参数和lb01 MASTER不同
}

vrrp_instance VI_1 {       #和lb01 MASTER相同
    state BACKUP           #此参数和lb01 MASTER不同
    interface eth1         #和lb01 MASTER相同
    virtual_router_id 55   #和lb01 MASTER相同
    priority 100           #此参数和lb01 MASTER不同
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.200.123/24 dev eth0 label eth0:1
   }
}

3.5启动Keepalived服务

[root@lb02 keepalived]# /etc/init.d/keepalived start
Starting keepalived:                                       [  OK  ]

3.6检查配置结果,查看是否有虚拟IP 192.168.200.123

[root@lb02 keepalived]# ip a | grep 192.168.200.123
[root@lb02 keepalived]# 
    #这里没有返回任何结果就对了,因为lb02为BACKUP,当主节点活着的时候,它不会接管VIP 192.168.200.123
  • 出现上述无任何结果的现象,表示lb02的Keepalived服务单实例配置成功。如果配置过滤后有192.168.200.123的IP,则表示Keepalived工作不正常,同一个IP地址同一时刻应该只能出现一台服务器。
  • 如果查看BACKUP备节点VIP有如下信息,说明高可用裂脑了,裂脑是两台服务器争抢同一资源导致的,例如:两边都配置了同一个VIP地址。
  • 出现上述两台服务器争抢同一IP资源问题,一般要先考虑排查两个地方:
    1)主备两台服务器对应的Keepalived.conf配置文件是否有错误?例如,是否同一实例的virtual_router_id配置不一致。

3.7进行高可用主备服务器切换实验

[root@lb01 keepalived]# ip a | grep 192.168.200.123   #虚拟VIP在lb01服务器上
    inet 192.168.200.123/24 scope global eth0:1
[root@lb01 keepalived]# /etc/init.d/keepalived stop  #停掉服务
Stopping keepalived:                                       [  OK  ]
[root@lb01 keepalived]# ip a | grep 192.168.200.123   #虚拟VIP消失了
[root@lb01 keepalived]# 

#再检查lb02服务器
[root@lb02 keepalived]# ip a | grep 192.168.200.123   #虚拟VIP出现在了lb02上
    inet 192.168.200.123/24 scope global eth0:1
  • 我们可以发现,备节点lb02已经接管绑定了192.168.200.123这个VIP,这期间备节点还会发送ARP广播,让所有的客户端更新本地的ARP表,以便客户端访问新接管VIP服务的节点。
  • 此时如果再启动主服务器的Keepalived服务,主服务器就会接管回VIP 192.168.200.123,启动后可以观察下主备的IP漂移情况,备服务器是否释放了IP?主服务器是否又接管了IP?

3.8主节点启动Keepalived服务后,发现很快就又接管了VIP192.168.200.123,操作及检查步骤如下

[root@lb01 keepalived]# ip a | grep 192.168.200.123
[root@lb01 keepalived]# /etc/init.d/keepalived start
Starting keepalived:                                       [  OK  ]
[root@lb01 keepalived]# ip a | grep 192.168.200.123
    inet 192.168.200.123/24 scope global eth0:1

#与此同时,备节点上的VIP 192.168.200.123则被释放了,如下:
[root@lb02 keepalived]# ip a | grep 192.168.200.123
#这样就实现了单实例Keepalived服务IP自动漂移接管了,VIP飘逸到了新机器新服务上,用户的访问请求自然就会找新机器新服务了

说明:

这里仅实现了VIP的自动漂移切换,因此,仅适合两台服务器提供的服务均保持开启的应用场景,这也是工作中常用的高可用解决方案。

3.9单实例主备模式Keepalived配置文件对比(只有三项不同)

Keepalived配置参数 MASTER节点特殊参数 BACKUP节点特殊参数
router_id(唯一标识) router_id yang1 router_id yang2
state(角色状态) state MASTER state BACKUP
priority(竞选优先级) priority 150 priority 100

4.Keepalived高可用服务器的“裂脑”问题

4.1什么是裂脑

由于某些原因,导致两台高可用服务器对在指定时间内,无法检测到对方的心跳消息,各自取得资源及服务的所有权,而此时的两台高可用服务器对都还活着并在正常运行,这样就会导致同一个IP或服务在两端同时存在而发生冲突,最严重的是两台主机占用同一个VIP地址,当用户写入数据时可能会分别写入到两端,这可能会导致服务器两端的数据不一致或造成数据丢失,这种情况就被称为裂脑。

4.2导致裂脑发生的原因

  • 高可用服务器对之间心跳线链路发生故障,导致无法正常通信。
  • 心跳线坏了(包括断了,老化)
  • 网卡及相关驱动坏了,IP配置及冲突问题(网卡直连)。
  • 心跳线间连接的设备故障(网卡及交换机)
  • 仲裁的机器出问题(采用仲裁的方案)
  • 高可用服务器上开启了iptables防火墙阻挡了心跳消息传输
  • 高可用服务器上心跳网卡地址等信息配置不正确,导致发送心跳失败。
  • 其他服务配置不当等原因,如心跳方式不同,心跳广播冲突,软件BUG等

提示:

  • Keepalived配置里同一VRRP实例如果virtual_router_id两端参数配置不一致,也会导致裂脑问题发生.

4.3在实际生产环境中,我们可以从以下几个方面来防止裂脑问题的发生:

  • 同时使用串行电缆和以太网电缆连接,同时用两条心跳线路,这样一条线路坏了,另一个还是好的,依然能传送心跳消息。
  • 当检测到裂脑时强行关闭一个心跳节点(这个功能需特殊设备支持,如Stonith,fence)。相当于备节点接收不到心跳消息,通过单独的线路发送关机命令关闭主节点的电源。
  • 做好对裂脑的监控报警(如邮件及手机短信等或值班),在问题发生时人为第一时间介入仲裁,降低损失。例如,百度的监控报警短信就有上行和下行的区别。报警信息发送到管理员手机上,管理员可以通过手机回复对应数字或简单的字符串操作返回给服务器,让服务器根据指令自动处理相应故障,这样解决故障的时间更短。
  • 当然,在实施高可用方案时,要根据业务实际需求确定是否能容忍这样的损失。对于一般的网站常规业务,这个损失是可容忍的。

4.4解决Keepalived裂脑的常见方案

作为互联网应用服务器的高可用,特别是前端Web负载均衡器的高可用,裂脑的问题对普通业务的影响是可以忍受的,如果是数据库或者存储的业务,一般出现裂脑问题就非常严重了。因此,可以通过增加冗余心跳线路来避免裂脑问题的发生,同时加强对系统的监控,以便裂脑发生时人为快速介入解决问题。

  • 如果开启防火墙,一定要让心跳消息通过,一般通过允许IP段的形式解决。
  • 可以拉一条以太网网线或者串口线作为主被节点心跳线路的冗余。
  • 开发检测程序通过监控软件(例如Nagios)检测裂脑。

4.5生产场景检测裂脑故障的一些思路

  • 简单判断的思想:只要备节点出现VIP就报警,这个报警有两种情况,一是主机宕机了备机接管了;二是主机没宕,裂脑了。不管属于哪个情况,都进行报警,然后由人工查看判断及解决。
  • 比较严谨的判断:备节点出现对应VIP,并且主节点及对应服务(如果能远程连接主节点看是否有VIP就更好了)还活着,就说明发生裂脑了。

5.Keepalived双实例双主模式配置实战

5.1下图为Keepalived双实例双主模式IP及VIP规划表

HOSTNAME IP 说明
lb01 192.168.200.64 VIP:192.168.81.123(用于绑定A服务www.yunjisuan.com域名)
lb02 192.168.200.66 VIP:192.168.81.124(用于绑定B服务bbs.yunjisuan.com域名)

5.2配置lb01的Keepalived.conf,在单实例的基础上增加一个vrrp_instance VI_2实例

[root@lb01 keepalived]# pwd
/etc/keepalived
[root@lb01 keepalived]# cat keepalived.conf 
! Configuration File for keepalived

global_defs {
   notification_email {
    1773464408@qq.com
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
}
   smtp_connect_timeout 30
   router_id yang1
}

vrrp_instance VI_1 {
    state MASTER
    interface eth1
    virtual_router_id 55
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.200.123/24 dev eth0 label eth0:1 
  
   }
}
vrrp_instance VI_2 {
    state BACKUP
    interface eth1
    virtual_router_id 56
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.200.124/24 dev eth0 label eth0:2 
  
   }
}

#提示:
以vrrp_instance VI_1在lb01 192.168.200.64服务器上的角色为主
以vrrp_instance VI_2在lb01 192.168.200.66服务器上的角色为备

5.3配置lb02的Keepalived.conf,在单实例的基础上增加一个vrrp_instance VI_2实例

[root@lb02 keepalived]# pwd
/etc/keepalived
[root@lb02 keepalived]# cat keepalived.conf 
! Configuration File for keepalived

global_defs {
   notification_email {
    1773464408@qq.com
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
}
   smtp_connect_timeout 30
   router_id yang2
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth1
    virtual_router_id 55
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.200.123/24 dev eth0 label eth0:1
  
   }
}
vrrp_instance VI_2 {
    state MASTER
    interface eth1
    virtual_router_id 56
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.200.124/24 dev eth0 label eth0:2
  
   }
}

#提示:
以vrrp_instance VI_1在lb01 192.168.200.66服务器上的角色为主
以vrrp_instance VI_2在lb01 192.168.200.64服务器上的角色为备

5.4实战演练

5.4.1在lb01上进行如下操作:

[root@lb01 keepalived]# /etc/init.d/keepalived start
Starting keepalived:                                       [  OK  ]
[root@lb01 keepalived]# ip a | egrep "192.168.200.123|192.168.200.124"
    inet 192.168.200.123/24 scope global secondary eth0:1
    inet 192.168.200.124/24 scope global secondary eth0:2

#由于lb02还没开服务,主备VIP都显示在lb01上

5.4.2在lb02上进行如下操作:

[root@lb02 keepalived]# /etc/init.d/keepalived start
Starting keepalived:                                       [  OK  ]
[root@lb02 keepalived]# ip a | egrep "192.168.200.123|192.168.200.124"
    inet 192.168.200.124/24 scope global secondary eth0:2

#lb01开启的情况下,lb02开启服务后,只显示了vrrp_instance VI_2实例lb02作为主模式的VIP 192.168.0.124
[root@lb01 keepalived]# ip a | egrep "192.168.200.123|192.168.200.124"
    inet 192.168.200.123/24 scope global secondary eth0:1

#lb01上只有192.168.0.123了

5.4.3宕掉lb01进行实验

[root@lb01 keepalived]# /etc/init.d/keepalived stop
Stopping keepalived:                                       [  OK  ]
[root@lb01 keepalived]# ip a | egrep "192.168.200.123|192.168.200.124"
[root@lb01 keepalived]#  #宕掉lb01后发现什么VIP都没有显示
[root@lb02 keepalived]# ip a | egrep "192.168.200.123|192.168.200.124"
    inet 192.168.200.124/24 scope global secondary eth0:2
    inet 192.168.200.123/24 scope global secondary eth0:1
    
#由于lb01宕掉之后,主备VIP都显示在lb02上了

特别提示

如果测试结果不符,请查看是否没有关闭iptables,eth1有没有掉线
到此为止,我们发现lb01,lb02主备节点已经实现了初始配置的VIP服务状态,当任意一端宕机,VIP可以实现互相切换接管。在实际工作中,可以把www.yunjisuan.com解析到192.168.200.123提供服务,把bbs.yunjisuan.com解析到192.168.200.124提供服务,当然了,lb01,lb02也要配置相应服务,例如:Nginx反向代理服务等。

5.5 双实例双主模式的配置文件对比

  • tate(状态)
  • priority(精选优先级)
    其中优先级决定VIP在哪个机器上初始运行

6.Nginx负载均衡配合Keepalived服务案例实战

注意:调整好主负载均衡器lb01,备用负载均衡器lb02服务器上Nginx负载均衡环境,两台服务器的安装基础环境一模一样
Nginx+Keepalived高可用集群应用实践

6.1在lb01和lb02上配置Nginx负载均衡

[root@lb01 /]# cat /usr/local/nginx/conf/nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    upstream www_server_pools {          
    server 192.168.200.63:80 weight=1;    
    server 192.168.200.60:80 weight=1;    
    }

    server {             
        listen       80;
        server_name  www.yunjisuan.com;
        location / {
        proxy_pass http://www_server_pools;
        include extar/proxy.conf;   
        }
    }
}

6.2在lb01和lb02上配置Keepalived服务(与上面实验配置一样)

6.3 用户访问准备

6.3.1准备工作

在客户端hosts文件里把www.yunjisuan.com域名解析到VIP 192.168.0.240上,正式场景需通过DNS解析

6.3.2下面模拟实际的访问过程

Nginx+Keepalived高可用集群应用实践

Nginx+Keepalived高可用集群应用实践

6.3.3现在模拟宕掉lb01

[root@lb01 /]# /etc/init.d/keepalived stop
Stopping keepalived:                                       [  OK  ]
[root@lb01 /]# ip a | grep 192.168.200.123
[root@lb02 /]#  ip a | grep 192.168.200.123
    inet 192.168.200.123/24 scope global secondary eth0:1
    
#观察lb02备节点是否接管了VIP 192.168.200.123/24

6.3.4再次在客户端浏览器输入www.yunjisuan.com测试访问

Nginx+Keepalived高可用集群应用实践

Nginx+Keepalived高可用集群应用实践

6.3.5重新开启lb01的Keepalived服务

[root@lb01 /]# /etc/init.d/keepalived start
Starting keepalived:                                       [  OK  ]
[root@lb01 /]# ip a | grep 192.168.200.123
    inet 192.168.200.123/24 scope global secondary eth0:1
    
#可以看到,VIP很快就接管回来了,此时浏览器访问结果依然正常
[root@lb02 /]# ip a | grep 192.168.200.123
[root@lb02 /]# 

7.解决高可用服务只针对物理服务器的问题

默认情况下Keepalived软件仅仅在对方机器宕机或Keepalived停掉的时候才会接管业务。但在实际工作中,有业务服务停止而Keepalived服务还在工作的情况,这就会导致用户访问的VIP无法找到对应的服务,那么,如何解决业务服务宕机可以将IP漂移到备节点使之接管提供服务呢?

7.1可以写守护进程脚本来处理。

当Nginx业务有问题时,就停掉本地的Keepalived服务,实现IP漂移到对端继续提供服务。

7.1.1实际工作中部署及开发的示例脚本如下:

[root@lb01 scripts]# cat check_nginx.sh
#!/bin/sh
while true
do
    if [ `netstat -antup | grep nginx | wc -l` -ne 1 ];then
        /etc/init.d/keepalived stop
    fi
    sleep 5
done

#此脚本的基本思想是若没有80端口存在,就停掉Keepalived服务实现释放本地的VIP

7.1.2在后台执行上述脚本并检查:

[root@lb01 scripts]# sh check_nginx.sh &
[1] 1521
[root@lb01 scripts]# ps -ef | grep check | grep -v grep
root       1521   1195  0 10:49 pts/0    00:00:00 sh check_nginx.sh
#确认Nginx以及Keepalived服务是正常的

[root@lb01 scripts]# netstat -antup | grep nginx
tcp        0      0 0.0.0.0:80                  0.0.0.0:*                   LISTEN      1492/nginx          
[root@lb01 scripts]# /etc/init.d/keepalived status
keepalived (pid  1512) is running...

#然后模拟Nginx服务挂掉,看IP是否发生切换。
[root@lb01 scripts]# /usr/local/nginx/sbin/nginx -s stop
[root@lb01 scripts]# Stopping keepalived:                  [  OK  ]
[root@lb01 scripts]# /etc/init.d/keepalived status
keepalived is stopped

[root@lb01 scripts]# netstat -antup | grep nginx
#此时,备节点已接管:
[root@lb02 ~]# ip a | grep 192.168.0.240
    inet 192.168.0.240/24 scope global secondary eth0:1

7.2可以使用Keepalived的配置文件参数触发写好的监测服务脚本。

7.2.1首先要开发检测服务脚本(注意这个脚本与上一个脚本的不同)

[root@lb01 scripts]# cat chk_nginx_proxy.sh 
#!/bin/bash
if [ `netstat -antup | grep nginx | wc -l` -ne 1 ];then
    /etc/init.d/keepalived stop
fi

7.2.2

[root@lb01 scripts]# chmod +x chk_nginx_proxy.sh 
[root@lb01 scripts]# ls -l chk_nginx_proxy.sh 
-rwxr-xr-x. 1 root root 102 Jul 31 10:59 chk_nginx_proxy.sh
此时,Keepalived服务的完整配置为:

[root@lb01 scripts]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
   notification_email {
    1773464408@qq.com
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id yang1
}
vrrp_script chk_nginx_proxy {       #定义vrrp脚本,检测HTTP端口
    script "/server/scripts/chk_nginx_proxy.sh"     #执行脚本,当Nginx服务有问题,就停掉Keepalived服务
    interval 2          #间隔2秒
    weight 2
}
vrrp_instance VI_1 {
    state MASTER
    interface eth1
    virtual_router_id 55
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
    192.168.200.123/24 dev eth0 label eth0:1
    }
    track_script {
    chk_nginx_proxy         #触发检查
    }
}

7.2.3下面测试接管结果

#先杀掉之前的后台进程脚本的运行,之后进行如下操作
[root@lb01 scripts]# /usr/local/nginx/sbin/nginx 
[root@lb01 scripts]# netstat -antup | grep nginx
tcp        0      0 0.0.0.0:80                  0.0.0.0:*                   LISTEN      3937/nginx          
[root@lb01 scripts]# /etc/init.d/keepalived start
Starting keepalived:                                       [  OK  ]
[root@lb01 scripts]# /etc/init.d/keepalived status
keepalived (pid  3949) is running...
[root@lb01 scripts]# ip a | grep 192.168.0.240
    inet 192.168.0.240/24 scope global secondary eth0:1
[root@lb01 scripts]# /usr/local/nginx/sbin/nginx -s stop
[root@lb01 scripts]# ip a | grep 192.168.0.240
[root@lb01 scripts]# /etc/init.d/keepalived status
keepalived is stopped
#当停掉Nginx的时候,Keepalived 2秒钟内会被自动停掉,VIP被释放,由对端接管,这样就实现了即使服务宕机也会进行IP漂移,业务切换。

8.解决多组Keepalived服务器在一个局域网的冲突问题

当在同一个局域网内部署了多组Keepalived服务器对,而又未使用专门的心跳线通信时,可能会发生高可用接管的严重故障问题。之前已经讲解过Keepalived高可用功能是通过VRRP协议实现的,VRRP协议默认通过IP多播的形式实现高可用对之间的通信,如果同一个局域网内存在多组Keepalived服务器对,就会造成IP多播地址冲突问题,导致接管错乱,不同组的Keepalived都会使用默认的224.0.0.18作为多播地址。此时的解决办法是,在同组的Keepalived服务器所有的配置文件里指定独一无二的多播地址,配置如下:

global_defs {

router_id LVS_19
vrrp_mcast_group4 224.0.0.19    #这个就是指定多播地址的配置

}

#提示:
1)不同实例的通信认证密码也最好不同,以确保接管正常。
2)另一款高可用软件Heartbeat,如果采用多播方式实现主备通信,同样会有多播地址冲突问题。

9.开发检测Keepalived裂脑的脚本

检测思路:在备节点上执行脚本,如果可以ping通主节点并且备节点有VIP就报警,让人员介入检查是否裂脑。

9.1在lb02备节点开发脚本并执行

[root@lb02 scripts]# cat check_split_brain.sh 
#!/bin/bash
lb01_vip=192.168.200.123
lb01_ip=192.168.200.64
while true
do
    ping -c 2 -W 3 $lb01_ip &>/dev/null
    if [ $? -eq 0 -a `ip a | grep "$lb01_vip" | wc -l` -eq 1 ];then
        echo "ha is split brain.warning."
    else
        echo "ha is OK"
    fi
    sleep 5
done
[root@lb02 scripts]# sh check_split_brain.sh 
ha is OK
ha is OK
ha is OK

#正常情况下,主节点活着,VIP 192.168.200.123在主节点,因此不会报警,提示“ha is OK” 

9.2关掉lb01服务器

[root@lb01 scripts]# /etc/init.d/keepalived stop
Stopping keepalived:                                       [  OK  ]
[root@lb01 scripts]# ip a | grep 192.168.200.123
[root@lb01 scripts]# 

9.3再观察lb02脚本的输出。

[root@lb02 scripts]# sh check_split_brain.sh 
ha is OK
ha is OK
ha is OK
ha is split brain.warning.
ha is split brain.warning.
ha is split brain.warning.
ha is OK
ha is OK
ha is OK
#裂脑报警恢复了。

9.4可以将此脚本整合到Nagios或Zabbix监控服务里,进行监控报警

注:Keepalived软件的官方文档地址:http://www.keepalived.org/documentation.html

上一篇:CentOS搭建BWAPP靶场并安装docker


下一篇:Keepalived、LVS