一、Keepalived 简介

          Keepalived 是一个用 C 语言编写的路由软件。它最初是专门为 LVS 负载均衡软件设计的,用来管理并监控 LVS 集群系统中各个服务节点的状态,后来又加入了可以实现高可用的 VRRP 功能。

          VRRP:虚拟冗余路由协议,它是 IETF 的公共标准,就好像 HSRP(热备份路由协议,思科私有,只可在思科自己的设备上使用。)一样实现高可用。

          由于 VRRP 功能的加入,使得 LVS 和 LVS 集群中的其他服务节点解决了可能出现的单点故障的问题。他能够使集群中个别节点宕机的情况下,整个集群网络不受影响,可以无间断的运行,因此,Keepalived 对于 LVS 负载均衡以及 LVS 负载均衡集群中的其他节点提供了高可用功能。

二、Keepalived 高可用故障转移实现的原理

          Keepalived 高可用服务对节点之间的故障进行切换转移,是通过VRRP来实现的。在 Keepalived 服务工作时,主 Master 节点会不断地向备节点发送心跳(heartbeat)包,用来告诉备 Backup 节点自己还活着。当主节点发生故障时,就无法发送心跳包了,因此,备节点无法继续检测到来自主节点的心跳了。于是就会调用自身的接管程序,接管主节点的IP资源池和服务。当主节点恢复时,备节点又会释放主节点故障时自身接管的IP资源池和服务,恢复到原来的备用角色。

三、高可用负载均衡集群拓扑

         Keepalived + LVS + LAMP 高可用负载均衡集群实现_第1张图片

    由上图可知

    1、LVS-A、LVS-B、Web-A 和 Web-B 共用一个 VIP。

    2、Web-A 和 Web-B 的 VIP 需要绑定在本机的 loopback 网络接口上,具体绑定方式参见小弟的另一篇博文 VIP 地址绑定 loopback 接口

    3、LVS-A 和 LVS-B 的 VIP 是浮动的,由 Keepalived 动态分配,不需要手动绑定。

    4、MySQL-A 和 MySQL-B 的 VIP 也是是浮动的,由 Keepalived 动态分配,不需要手动绑定。

    5、MySQL-A 和 MySQL-B 之间互为主从。

四、高可用负载均衡集群环境准备

    image

    如上表:

    我们准备 6 台服务器,分别为 2 台 MySQL 服务器、2 台 Web 服务器和 2 台 LVS 服务器,地址分配如上表所示。

    说明:LVS 、WEB 的 RIP 和 VIP 均可使用公网 IP ,MySQL 的 RIP 和 VIP 使用私有 IP ,至于原因,大佬们都是懂得,在实验环境中为了方便,我就统一使用一个网段的 IP 地址。

    至于说服务器环境的安装配置,我这里就不再啰嗦,有疑问,可以参照小弟的前几篇博文。

五、LVS 安装

    分别在 LVS-A 和 LVS-B 服务器中安装 ipvsadm 服务

    LVS-A:

    [root@lvsa ~]# yum -y install ipvsadm

    LVS-B:

    [root@lvsb ~]# yum -y install ipvsadm

    说明:这里只需要安装即可,不需要进行配置。

六、Keepalived 安装

    分别在 LVS-A 、 LVS-B 、MySQL-A 和 MySQL-B 服务器中安装 Keepalived 服务

    LVS-A:

    [root@lvsa ~]# yum -y install keepalived

    LVS-B:

    [root@lvsb ~]# yum -y install keepalived

    MySQL-A:

    [root@mysqla ~]# yum -y install keepalived

    MySQL-B:

    [root@mysqlb ~]# yum -y install keepalived

七、Keepalived 配置

    首先,我们配置 MySQL-A 和 MySQL-B 中的 Keepalived  。

    MySQL-A 配置:

    Keepalived + LVS + LAMP 高可用负载均衡集群实现_第2张图片

    如上图,配置文件解释:

    global                                                       #为全局配置

    script_user                                              #脚本执行用户,该参数是我们根据官方说明手动添加的,默认没有,如果不添加,会报错 WARNING - default user 'keepalived_script' for script execution does not exist - please create.

    enable_script_security                         #设置脚本的可运行性,该参数是我们根据官方说明手动添加的,默认没有,如果不添加,会报错 WARNING - default user 'keepalived_script' for script execution does not exist - please create.

    notification_email                                 #为通知邮件,这里配置报警邮件接收人的邮箱

    notification_email_from                      #为发件人邮箱

    smtp_server                                           #为发件服务器

    smtp_connect_timeout                       #smtp服务器连接超时时间

    route_id                                                  #为路由器 id ,可以自定义修改

    vrrp_static                                              #需要注释,要不然服务一启动,会自动配置 iptables 防火墙,会引起 VIP 问题

    vrrp_skip_check_adv_addr、vrrp_garp_interval、 vrrp_gna_interval                                           #这三项不用管,保持默认就行。


    vrrp_instance                                         #创建一个 vrrp 的实例 VI_1 就是 vrrp_instance 的缩写

    state MASTER                                         #状态为 MASTER ,备份路由器需要写 BACKUP,不能写 SLAVE ,7.2之前的版本是 SLAVE ,之后的版本是 BACKUP

    interface                                                  #配置网络接口卡

    virrual_route_id                                     #虚拟路由 id 号,这个需要在同类型集群服务器中的 Keepalived 中保持一致,否则无法正常路由,所以,一般不需要修改,注意,我们这里 MySQL 集群和 LVS 集群中的 id 号不能相同,否则会报错。

    priority                                                     #优先级,这个可以自定义更改,这个数越大,优先级越高

    advert_int                                                #心跳消息发送间隔,通知时间,即 心跳(heartbeat)包 的发送时间,用来检查路由是否处于活跃状态

    authentication                                        #集群成员共享密码

    auth_type                                                #认证类型,这里为password

    auth_pass                                                #认证密码,集群中的路由器中这个密码必须保持一致

    virtual_ipaddress                                   #虚拟 ip 地址(VIP),注意不要冲突就行


    virtual_server                                         #虚拟服务器,后跟 VIP + 空格 + 端口
     delay_loop 6                                           #每个 6 秒检查 RealServer 状态
     lb_algo rr                                                 #LVS 算法,这里为轮询
     lb_kind DR                                               #LVS 工作模式,默认为 NAT,这里改为 DR(路由模式 ),还有 TUN 模式
     persistence_timeout 50                        #连接保持时间,也就是说,在这段时间内,同一个客户端的请求会被分配到同一个后端服务器
     protocol TCP                                           #协议,这里为TCP,还可以为 UDP 和 SCTP

    real_server                                              #后端真实服务器,后跟 RIP + 空格 + 端口
     weight 1                                                   #权重
     notify_down /wdata/scripts/shutdown.sh                               #服务宕掉后执行的脚本
     TCP_CHECK                                              #TCP检查,这里还可以为 HTTP_GET 、SSL_GET 、SMTP_CHECK 、DNS_CHECK 、MISC_CHECK
     connect_timeout 3                                #连接超时时间
     nb_get_retry 3                                       #重连次数
     delay_before_retry 3                            #重连间隔时间

    MySQL-B 配置:

    Keepalived + LVS + LAMP 高可用负载均衡集群实现_第3张图片

    MySQL-B的配置和 MySQL-A 的配置差不多,个别参数酌情修改即可。

    shutdown.sh 脚本内容:

[root@mysqlb scripts]# cat shutdown.sh
#!/bin/bash
systemctl stop keepalived

    LVS-A 配置:

    Keepalived + LVS + LAMP 高可用负载均衡集群实现_第4张图片

    字段意思同 MySQL-A,只是增加了一条 RealServer 的服务器,这里就不多做解释。

    LVS-B 配置:

    Keepalived + LVS + LAMP 高可用负载均衡集群实现_第5张图片

    跟 LVS-A 的配置,基本相同,除了状态和优先级之外,LVS-A 的状态为 MASTER ,这里为 BACKUP ,LVS-A 的优先级为 200 ,这里为 100 。

    注意:LVS 的路由器 id 为 51(可自定义),而 MySQL 的路由器 id 为 60 。

八、MySQL 服务器的主主结构配置

    关于 MySQL 服务器的主主结构配置请参考小弟的另外一篇博文 MySQL 主主结构配置

    这里就不再多做阐述。

九、Keepalived 高可用集群验证

    1、Keepalived + MySQL 高可用集群验证

     我们在 Keepalived + MySQL 高可用集群中设置了 VIP 地址 192.168.20.150,首先,我们来验证一下联通性,在另外的主机或者服务器中用 VIP 进行连接,看能否登陆 MySQL 数据库。

     [root@client ~]# mysql -h192.168.20.150 -uroot –p123456

     Keepalived + LVS + LAMP 高可用负载均衡集群实现_第6张图片

     如图所示,说明可以正常连接

     其次,我们再停止 MySQL-A 的 MySQL 服务,查看 MySQL-A 中 Keepalived 服务是否有自动停止,是否还可以通过 VIP 地址 192.168.20.150 连接到 MySQL 数据库。

     [root@mysqla ~]# service mysqld stop

     [root@mysqla ~]# systemctl status keepalived

     Keepalived + LVS + LAMP 高可用负载均衡集群实现_第7张图片

     如上图所示,MySQL-A 的 MySQL 服务停止,随之 MySQL-A 中 Keepalived 服务自动停止,下面再通过 VIP 地址 192.168.20.150 连接 MySQL 数据库。

     [root@client ~]# mysql -h192.168.20.150 -uroot –p123456

     Keepalived + LVS + LAMP 高可用负载均衡集群实现_第8张图片

     如上图所示,可以正常连接。

     最后,我们开启 MySQL-A 的 MySQL 服务和 Keepalived 服务,并关闭 MySQL-B 的 MySQL 服务,查看 MySQL-B 中 Keepalived 服务是否有自动停止,是否还可以通过 VIP 地址 192.168.20.150 连接到 MySQL 数据库。

     [root@mysqlb ~]# service mysqld stop

     [root@mysqlb ~]# systemctl status keepalived

     Keepalived + LVS + LAMP 高可用负载均衡集群实现_第9张图片

     如上图所示,MySQL-B 的 MySQL 服务停止,随之 MySQL-B 中 Keepalived 服务自动停止,下面再通过 VIP 地址 192.168.20.150 连接 MySQL 数据库。

     [root@client ~]# mysql -h192.168.20.150 -uroot –p123456

     Keepalived + LVS + LAMP 高可用负载均衡集群实现_第10张图片

     如上图所示,也可以正常连接,说明,我们的 MySQL 高可用集群配置是 OK 的。

     在验证过程中,我们还可以看一下 VIP 地址的切换情况,可以在 MySQL-A 和 MySQL-B 中使用命令 ip a s ens33 来查看,这里就不演示了,ens33 是网卡名称,当然大部分主机或者服务器的网卡名称可能是 eth0 。

     2、Keepalived + LVS 高可用负载均衡集群验证

      a、查看 LVS 集群状态是否正常或者是否有 LVS 集群存在,分别在 LVS-A 和 LVS-B 中执行 ipvsadm –Ln 命令

             LVS-A 结果:

             Keepalived + LVS + LAMP 高可用负载均衡集群实现_第11张图片

             LVS-B 结果:

             image

            如上图所示, LVS 集群存在且正常,说明 Keepalived 配置生效。

      b、验证 LVS 负载均衡及故障转移

      首先,我们在 Web-A 和 Web-B 中站点目录下编写 index.php 文件,内容如下:

[root@weba www]# cat index.php
echo "Real ServerA

";
$link=mysql_connect("192.168.20.150","root","123456");
if(!$link) echo "FAILD!连接错误,用户名密码不对";
else echo "OK ! MySQL 可以连接。";
?>

      其次,我们在浏览器中输入我们配置的 VIP 地址 192.168.20.135,查看结果。

      Keepalived + LVS + LAMP 高可用负载均衡集群实现_第12张图片Keepalived + LVS + LAMP 高可用负载均衡集群实现_第13张图片

      如上图所示,说明我们的负载均衡 OK ,接下来我们验证故障转移

      首先,我们关闭 Web-A 的 http 服务和 MySQL–A 的 MySQL 服务,刷新页面,查看网页结果返回和 LVS-A 和 LVS-B 中的 LVS 集群状态。

      Keepalived + LVS + LAMP 高可用负载均衡集群实现_第14张图片

      imageimage

     如上三图所示,MySQL 可以正常连接,Web 也可以正常连接到 Web-B 服务器,说明故障转移 OK 。而 LVS 负载均衡集群中已经自动删掉了 Web-A 的地址。

     其次,我们开启 Web-A 的 http 服务和 MySQL–A 的 MySQL 服务,查看 LVS-A 和 LVS-B 中的 LVS 集群状态。

     imageKeepalived + LVS + LAMP 高可用负载均衡集群实现_第15张图片

     如上两图所示,Web-A 的地址已自动添加到 LVS 负载均衡集群中。

     最后,我们关闭 Web-B 的 http 服务和 MySQL–B 的 MySQL 服务,再刷新页面,查看网页结果返回和 LVS-A 和 LVS-B 中的 LVS 集群状态。

     Keepalived + LVS + LAMP 高可用负载均衡集群实现_第16张图片

      imageimage

      如上三图所示,MySQL 可以正常连接,Web 也可以正常连接到 Web-A 服务器,说明故障转移 OK 。而 LVS 负载均衡集群中已经自动删掉了 Web-B 的地址。

      我们再开启 Web-B 的 http 服务和 MySQL–B 的 MySQL 服务,查看 LVS-A 和 LVS-B 中的 LVS 集群状态。

      imageimage

      如上两图所示,Web-B 的地址已自动添加到 LVS 负载均衡集群中。

      经过一番的验证,我们的负载均衡 OK ,故障转移也 OK ,说明我们的 Keepalived + LVS + LAMP 高可用集群部署是成功的。当然了,集群的其他一些性能调优,还需要根据线上实际情况来进行调整,这里也就不进行赘述 了。

十、查看我们在验证过程中是否有收到邮件

      我们再配置 Keepalived 的时候,配置告警邮件的接收邮箱,理论上,我们在验证过程中频繁的关闭和开启各个节点的服务,就应该能收到 Keepalived 的告警邮件,现在我们登陆我们配置的邮箱进行查看。

      Keepalived + LVS + LAMP 高可用负载均衡集群实现_第17张图片

     如上图所示,我们每次对节点服务的关闭和开启都会收到 DOWN 和 UP 的邮件,这表明,我们的邮箱配置是生效的。


到此为止,我们的 Keepalived + LVS + LAMP 高可用负载均衡集群部署完成,过程中有可能会遇到很多坑,但是做为运维,踩坑可以说是家常便饭了,最重要的总结经验,才知道哪里容易出问题。由于小弟我文笔拙劣,欢迎各位大佬留言指正。