首页 > 代码库 > 基于Keepalived构建高可用集群配置实例(HA Cluster)

基于Keepalived构建高可用集群配置实例(HA Cluster)

什么是集群

简单的讲集群(cluster)就是一组计算机,它们作为一个整体向用户提供一组网络资源。这些单个的计算机系统就是集群的节点(node)。一个理想的集群是,用户从来不会意识到集群系统底层的节点,在他/她们看来,集群是一个系统,而非多个计算机系统。并且集群系统的管理员可以随意增加和删改集群系统的节点。 
关于更详细的高可用集群我们在后面再做详解,先来说说Keepalived

Keepalived是什么

Keepalived是集群管理中保证集群高可用的一个服务软件,其功能类似于heartbeat,用来防止单点故障。可以说就是为了高可用集群而生…

keepalived工作原理

Keepalived是以VRRP协议为实现基础的,VRRP全称Virtual Router Redundancy Protocol,即虚拟路由冗余协议。 
虚拟路由冗余协议,可以认为是实现路由器高可用的协议,即将N台提供相同功能的路由器组成一个路由器组,这个组里面有一个master和多个backup,master上面有一个对外提供服务的VIP(该路由器所在局域网内其他机器的默认路由为该VIP),Master会发组播,当Backup收不到VRRP包时就认为Master宕掉了,这时就需要根据VRRP的优先级来选举一个Backup当Master。这样的话就可以保证路由器的高可用了。 
Keepalived主要有三个模块,分别是core、check和vrrp。core模块为keepalived的核心,负责主进程的启动、维护以及全局配置文件的加载和解析。check负责健康检查,包括常见的各种检查方式。VRRP模块是来实现VRRP协议的。

keepalived延伸之VRRP协议原理

1、 一个VRRP路由器有唯一的标识:VRID范围为0-255是该路由器对外表现为唯一的虚拟MAC地址,地址的格式为00-00-5E- 00-01-[VRID]主控路由器负责对ARP请求用该MAC地址做应答这样,无论如何切换,保证给终端设备的是唯一一致的IP和MAC地址,减少了切换对终端设备的影响。 
2、VRRP控制报文只有一种:VRRP通告(advertisement)它使用IP多播数据包进行封装,组地址为224.0.0.18,发布范围只限于同一局域网内这保证了VRID在不同网络中可以重复使用为了减少网络带宽消耗只有主控路由器才可以周期性的发送VRRP通告报文备份路由器在连续三个通告间隔内收不到VRRP或收到优先级为0的通告后启动新的一轮VRRP选举。 
3、上面我们讲过在VRRP路由器组中,按优先级选举主控路由器,VRRP协议中优先级范围是0-255若VRRP路由器的IP地址和虚拟路由器的接口IP地址相同,则称该虚拟路由器作VRRP组中的IP地址所有者;IP地址所有者自动具有最高优先级:255优先级0一般用在IP地址所有者主动放弃主控者角色时使用可配置的优先级范围为1-254优先级的配置原则可以依据链路的速度和成本路由器性能和可靠性以及其它管理策略设定主控路由器的选举中,高优先级的虚拟路由器获胜,因此,如果在VRRP组中有IP地址所有者,则它总是作为主控路由的角色出现对于相同优先级的候选路由器,按照IP地址大小顺序选举VRRP还提供了优先级抢占策略,如果配置了该策略,高优先级的备份路由器便会剥夺当前低优先级的主控路由器而成为新的主控路由器。 
4、为了保证VRRP协议的安全性,提供了两种安全认证措施:明文认证和IP头认证。 
明文认证方式要求:在加入一个VRRP路由器组时,必须同时提供相同的VRID和明文密码适合于避免在局域网内的配置错误,但不能防止通过网络监听方式获得密码IP头认证的方式提供了更高的安全性,能够防止报文重放和修改等攻击 
好了基于以上了解内容,我们大致对Keepalived基于VRRP协议怎么实现高可用集群有了概念性理解,下面我们就简单配置个示例来加深印象

keepalived核心组件

vrrp stack 
ipvs wrapper 
checkers 
控制组件:配置文件分析器 
IO复用器 
内存管理组件 
我们来看张图吧

技术分享

测试实验环境

实验平台:Windows10_64 
虚拟环境:基于Win系统搭建的VMware虚拟主机实现 
所需要的虚拟主机:两台,CentOS 7.2或者是CentOS 6.8,偏移CentOS 7.2 
虚拟主机的IP地址是:node1地址,10.1.15.43, node2地址,10.1.15.44

配置基于Keepalived HA Cluster的前提

(1) 各节点时间必须同步;使用ntp, 或者chrony同步主机时间 
(2) 确保iptables及selinux不会成为阻碍; 
(3) 各节点之间可通过主机名互相通信(对KA可选)建议使用/etc/hosts文件实现 
(4) 各节点之间的root用户可以基于密钥认证的ssh服务完成互相通信;(可选)

使用ntp去同步你的主机时间,多同步几次
ntpdate 10.1.0.1
或者是编辑以下文件加入server内容重启chrony服务
vim /etc/chrony.conf
server 10.1.0.1 iburst
chronyc sources//去验证下服务时间是否同步过来
或者你可以直接通过date命令手动修改
date XXXXXX//参考date命令
[root@localhost ~]# getenforce
Enforcing
[root@localhost ~]# setenforce 0
[root@localhost ~]# getenforce
Permissive
[root@localhost ~]# iptables -F
[root@localhost ~]#
各节点直接的互相通信可以是基于主机的也可以是ip,这里我们就不嗷述(非必须)
各节点基于密钥认证的互相通信:不是必须,但为了拷贝文件方便,所以就做了
先在node1节点上生成字符串10.1.253.43
[root@localhost ~]# ssh-keygen -t rsa -P ‘‘ //也可以在后面自定义
把文件拷贝到另一台主机上
ssh-copy-id -i .ssh/id_rsa.pub root@10.1.253.43
测试是否不需要密码直接登录
[root@localhost ~]# ssh root@10.1.253.44
Last login: Mon Oct 31 13:34:38 2016 from 10.1.15.85
[root@localhost ~]#
成功......

Keepalived的配置

Keepalived从Centos6以后是收集到base仓库中的,所以我们可以直接yum安装

yum install keepalived //直接yum安装就行

Keepalived程序环境: 
配置文件是:/etc/keepalived/keepalived.conf 
主程序文件:/usr/sbin/keepalived 
Unit File服务文件:keepalived.service

Keepalived配置文件组成部分

先备份keepalived配置文件 
cp /etc/keepalived/keepalived.conf{,.back}

GLOBAL CONFIGURATION //全局配置段
   Global definitions //全局定义
   Static routes/addresses //静态路由配置
VRRPD CONFIGURATION //VRRP实力,其实就是定义虚拟路由器
   VRRP synchronization group(s)// VRRP同步组
   VRRP instance(s) //VRRP实力
LVS CONFIGURATION// 集群配置段
   Virtual server group(s)//组
   Virtual server(s)//

配置一个单主模型(主节点IP:10.1.15.43)

如果出现单点故障,另一个备节点会立马接管这台主机,并启用vip备用地址
编辑etc目录下keepalived目录keepalived.conf文件填入以下内容
vim /etc/keepalived/keepalived.conf
打开文件扩展模式下在virtual_ipaddress处光标移动此处输入:.,$d,删除其它

! Configuration File for keepalived //keepalived全局配置文件

global_defs {
  notification_email { //接收邮箱地址,目标地址
   root@localhost //配置为直接发给主机管理员  
}
  notification_email_from keepalived@localhost //谁发送的,源地址
  smtp_server 127.0.0.1//只在本机测试,所有只发给自己
  smtp_connect_timeout 30 //smtp服务连接超时时长,30秒
  router_id node1 //当前路由器物理标识符,直接配置当前节点就可以
  vrrp_mcast_group4 224.15.15.15 //多播地址接口
} //使用多播地址确保MULTICAST服务启动,网卡要支持

vrrp_instance VI_1 { //VI_1就是VRRP名称,就是定义一个虚拟路由器
   state MASTER //当前节点在此虚拟路由器上的初始状态,主的且只有一个
   interface eno16777736 //绑定为当前虚拟路由器物理接口
   virtual_router_id 20 //当前虚拟路由器的惟一标识,范围是0-255
   priority 100 //当前主机在此虚拟路径器中的优先级;范围1-254
   advert_int 1 //vrrp通告的时间间隔
   authentication { //认证信息
       auth_type PASS //不动
       auth_pass 6b8a916c // 生成一串字符串贴到此处
   } //字符串生成方法:openssl rand -hex 4
   virtual_ipaddress { //定义的转移ip地址,这是最主要的,由它来决定哪个节点断了下面配置的地址直接顶上去,这里有个优先级和抢占模式,可以自己去了解
   10.1.15.50/16
}
}
配置完用scp命令拷贝到备节点,只修改优先级priority 与 state状态。
scp keepalived.conf root@10.1.15.44:/etc/keepalived/

配置一个单主模型(备节点IP:10.1.15.44)

编辑etc目录下keepalived目录keepalived.conf文件填入以下内容
vim /etc/keepalived/keepalived.conf
打开文件扩展模式下在virtual_ipaddress处光标移动此处输入:.,$d,删除其它

! Configuration File for keepalived

global_defs {
  notification_email {
   root@localhost  
}
  notification_email_from keepalived@localhost
  smtp_server 127.0.0.1
  smtp_connect_timeout 30
  router_id node1
  vrrp_mcast_group4 224.15.15.15
}

vrrp_instance VI_1 {
   state BACKUP
   interface eno16777736
   virtual_router_id 20
   priority 98
   advert_int 1
   authentication {
       auth_type PASS
       auth_pass 6b8a916c
   }
   virtual_ipaddress {
   10.1.15.50/16
}
}
测试模拟故障:
   在两个节点43,44启动关闭keepalived服务,并观察日志状态,是否如我们配置文件所要求,单个节点故障后另一个节点马上切换为master状态,反之亦然。
[root@node1 ~]# systemctl start|stop| keepalived.service
[root@node1 ~]# tail -f /var/log/messages  

配置一个双主模型(主备,备主模型)

主节点ip:10.1.15.43 备节点:10.1.15.44
编辑etc目录下keepalived目录keepalived.conf文件填入以下内容
vim keepalived.conf增加 vrrp_instance VI_2 { 配置段
配置完用scp命令拷贝到双主模型的备节点,只修改优先级priority 与 state状态。
scp keepalived.conf root@10.1.15.44:/etc/keepalived/
相关文字描述参考上面的就可以
! Configuration File for keepalived

global_defs {
  notification_email {
   root@localhost  
}
  notification_email_from keepalived@localhost
  smtp_server 127.0.0.1
  smtp_connect_timeout 30
  router_id node1
  vrrp_mcast_group4 224.15.15.15
}

vrrp_instance VI_1 {
   state MASTER
   interface eno16777736
   virtual_router_id 20
   priority 100
   advert_int 1
   authentication {
       auth_type PASS
       auth_pass 6b8a916c
   }
   virtual_ipaddress {
   10.1.15.50/16
}
}
vrrp_instance VI_2 {
   state BACKUP
   interface eno16777736
   virtual_router_id 30
   priority 98
   advert_int 1
   authentication {
       auth_type PASS
       auth_pass 6b9a916c
   }
   virtual_ipaddress {
   10.1.15.60/16
}
}
   notify_master "/etc/keepalived/notify.sh master"
   notify_backup "/etc/keepalived/notify.sh backup"
   notify_fault "/etc/keepalived/notify.sh fault"
最后测试模拟故障,监控两台双主备节点服务启动各个地址切换状态
[root@node1 ~]# systemctl start|stop| keepalived.service
[root@node1 ~]# tail -f /var/log/messages
如果成功,则双主模型配置成功,处于监控状态

写一个脚本来触发三种状态检测(master,backup,fault状态)

配置个脚本叫notify.sh 放在etc/keepalived/目录下,通过配置文件直接调用
调用方法是:./notify.sh master/BACKUP/fault,观察各节点ip切换信息
#!/bin/bash
#
#只在本机测试,只发给本机就可以
contact=‘root@localhost‘
#定义一个函数notify,在后面调用
notify()
{
#定义一个local变量,邮件标题,命令替换获取当前主机,并且vip发生了转移
mailsubject="$(hostname) to be $1, vip floating"
#邮件正文,命令调用,完整日期格式,在这个时刻vrrp发生了转移,转移到主或者备的
mailbody="$(date +‘%F %T‘): vrrp transition, $(hostname) changed to be $1"
#发邮件,mailbody通过管道送给主题,联系人是,都是命令调用
echo "$mailbody" | mail -s "$mailsubject" $contact

}
#可接收的参数
case $1 in
#如果传递参数是master
   master)
   notify master
#转给函数notify调用,往下见名之意
;;
   backup)
   notify backup
;;
   fault)
   notify fault
;;
#如果其它,脚本用错了,所发送的内容
   *)
   echo "Usage: $(basename $0) {master|backup|fault}"
   exit 1
;;

esac
给执行权限或者直接bash运行 chmod +x notify.sh,应该邮件已发送
测试:
./notify.sh 给传递的参数是master或者BACKUP或者fault
这样我们就实现了通过脚本来接管三种状态,并可以通过mail命令来监控服务状态

以上测试完成我们接下来配置基于Keepalived的高可用集群

以httpd服务为测试目标

测试的环境和主机我们都用上面的 
使用LVS的DR模型结合Keepalived配置高可用集群,实现服务调度 
配置的拓扑再细化下: 
两台Director server当VIP,两台Real server当检测机,每个节点都接在交换机上 
IP地址:10.1.15.43,10.1.15.44作为Real server1与 Real server2 
两台Real server的80端口分别向外提供服务 
IP地址:10.1.15.45,10.1.15.46作为Director server 当VIP 
VIP server的轮转地址为10.1.15.50 80端口向外提供web服务

配置vip的内核参数在lo:0上加入轮询的ip地址

我们通过脚本来实现
!#/bin/bash
#
vip=‘10.1.15.50
vport=‘80
netmask=‘255.255.255.255
iface=‘lo:0

case $1 in
start)
   echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
   echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
   echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
   echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
   ifconfig $iface $vip netmask $netmask broadcast $vip up
   route add -host $vip dev $iface
esac
也可以手动测试下

在Real server1和2主机上用keepalived来轮询10.1.15.50地址

编辑keepalived.conf其它全删除,填入以下内容
Real server1和2都要修改,确保配置都一样
   ! Configuration File for keepalived
   global_defs {
      notification_email {
       root@localhost  
   }
      notification_email_from keepalived@localhost
      smtp_server 127.0.0.1
      smtp_connect_timeout 30
      router_id node1
      vrrp_mcast_group4 224.15.15.15
   }

   vrrp_instance VI_1 {
       state BACKUP
       interface eno16777736
       virtual_router_id 20
       priority 98
       advert_int 1
       authentication
{
           auth_type PASS
           auth_pass 6b8a916c
       }
       virtual_ipaddress {
       10.1.15.50/16 //这个是我们要轮询的地址
   }
   }
       notify_master "/etc/keepalived/notify.sh master"
       notify_backup "/etc/keepalived/notify.sh backup"
       notify_fault "/etc/keepalived/notify.sh fault"
#### 我们要轮询的地址是50而轮询的服务是Director server上的web服务
> 我们接下来要在real server上去使用ipvsadm命令,使用10.1.15.50轮询地址去配置把Director server上的web服务集群给测试出来,并且是成功的
> 在real server配置以下命令,real server1与2都要配置,然后再删除,只是为了测试轮询与集群web服务是工作正常的。

   [root@node1 keepalived]# ipvsadm -A -t 10.1.15.50:80 -s rr
   [root@node1 keepalived]# ipvsadm -a -t 10.1.15.50:80 -r 10.1.15.45 -g -w 1
   [root@node1 keepalived]# ipvsadm -a -t 10.1.15.50:80 -r 10.1.15.46 -g -w 1

> 在客户端用curl 命令确认real server上的集群配置是否成功且Director server的web服务是可正常提供服务的
> 注意:我们是用real server 的keepalived去轮询50地址做的,目的就是这个

       curl http://10.1.15.50
       [root@Centos6 ~]# curl 10.1.15.50
       <h1>RS 1 </h1>  
       [root@Centos6 ~]# curl 10.1.15.50
       <h1> RS 2 </h1>
       [root@Centos6 ~]#
       测试成功,只要能轮询我们指定的Director server上的web服务就可以    
#### 在Real server 1上的keepalived.con配置文件
   配置完毕后记得把Real server 1 上的配置文件拷贝一份到Real server 2
   scp keepalived.conf root@10.1.15.44:/etc/keepalived/
! Configuration File for keepalived

global_defs {
  notification_email {
   root@localhost  
}
  notification_email_from keepalived@localhost
  smtp_server 127.0.0.1
  smtp_connect_timeout 30
  router_id node1
  vrrp_mcast_group4 224.15.15.15
}
vrrp_script chk_down { //keepalived调用外部的辅助脚本
   script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"
   interval 1
   weight -5
   }

vrrp_instance VI_1 {
   state BACKUP
   interface eno16777736
   virtual_router_id 20
   priority 98
   advert_int 1
   authentication
{
       auth_type PASS
       auth_pass 6b8a916c
   }
   virtual_ipaddress {
   10.1.15.50/16  dev eno16777736

}
   track_script { //检测这个脚本,只要存在down文件就地址轮询
   chk_down
}

   notify_master "/etc/keepalived/notify.sh master"
   notify_backup "/etc/keepalived/notify.sh backup"
   notify_fault "/etc/keepalived/notify.sh fault"
}

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

   sorry_server 127.0.0.1 80

   real_server 10.1.15.45 80 {
       weight 1
       HTTP_GET {
           url {
             path /
       status_code 200
           }
          connect_timeout 1
     nb_get_retry 3
     delay_before_retry 1
}
}

  real_server 10.1.15.46 80 {
   weight 1
   HTTP_GET {
       url {
       path /
          status_code 200
       }
       connect_timeout 1
       nb_get_retry 3
       delay_before_retry 1
   }  
   }
}

在任意客户端上模拟故障并测试是否单点故障,另一个可正常工作

测试模拟故障,看Real server 上是否自动加入了LVS集群服务地址
[root@node1 ~]# systemctl start|stop| keepalived.service
[root@node1 ~]# ipvsadm -L -n
[root@node2 keepalived]# ipvsadm -L -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
->
RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP  10.1.15.50:80 rr
 ->
10.1.15.45:80                Route   1      0          0        
 ->
10.1.15.46:80                Route   1      0          0        
任意客户端执行curl请求
[root@Centos6 ~]# curl http://10.1.15.50
<h1> Sorry Server 2 </h1>
[root@Centos6 ~]# curl http://10.1.15.50
<h1> RS 2 </h1>
[root@Centos6 ~]# curl http://10.1.15.50
<h1>RS 1 </h1>  
[root@Centos6 ~]#
注意:使用keepalived做集群检测web服务,四台主机80端口都必须是监听状态,但请求的服务是Director server主机上的web服务的80端口,
也可向上面的步骤做个脚本,调用脚本来监控keepalived服务的运行状态

keepalived调用外部的辅助脚本进行资源监控,并根据监控的结果状态能实现优先动态调整实行健康检测; 
分两步:(1) 先定义一个脚本;(2) 调用此脚本; 
在keepalived目录创建down文件地址会自动轮询 
参考Real Server 1 的配置文件,脚本已经在上面定义

配置高可用nginx集群反向代理

在Real Server1和2的主机上安装nginx

[root@node1 ~]# rpm -ivh nginx-1.10.0-1.el7.ngx.x86_64.rpm

配置nginx反代功能

编辑nginx.conf文件
vim /etc/nginx/nginx.conf 加入以下内容,
   access_log  /var/log/nginx/access.log  main; //定义到此处加入
       upstream websrvs { //这是我们要加入的集群节点
           server 10.1.15.45;
           server 10.1.15.46;
       }
编辑conf.d目录下default.conf文件,加入以下内容
vim /etc/nginx/conf.d/default.conf
   location / {
   root   /usr/share/nginx/html;
   index  index.html index.htm;
   proxy_pass http://websrvs; //这个是我们需要加入的反代web站点
       }
启动服务 systemctl start nginx.service
模拟故障随随便启动一台测试反代是否响应
   systemctl start keepalived.service
在客户端请求
curl 10.1.15.50,如果能请求到集群节点则反代功能配置成功!!!到此结束

如有不足的请多多指点,一直在学习中……,其它的功能我也在慢慢练习 
通过上面的三种状态脚本加入systemctl restart nginx.service, 
然后通过这个脚本定义的触发机制,来监控如果nginx服务故障,实现自动重启 
算了我还是贴上来吧,以后忘了怎么办(我自己留着!!!)


本文出自 “51eA” 博客,请务必保留此出处http://51eat.blog.51cto.com/11892702/1891636

基于Keepalived构建高可用集群配置实例(HA Cluster)