前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >高可用篇之Heartbeat(Heartbeat+HAProxy搭建高可用负载均衡集群)

高可用篇之Heartbeat(Heartbeat+HAProxy搭建高可用负载均衡集群)

作者头像
小土豆Yuki
发布2020-06-15 16:58:38
2.3K0
发布2020-06-15 16:58:38
举报
文章被收录于专栏:洁癖是一只狗洁癖是一只狗

上一篇我们介绍了keepalived, 以及使用keepalived+haproxy搭建高可用负载均衡集群。那么今天我们介绍另外一种实现高可用的开源软件heartbeat,并实现搭建一个heartbeat+proxy的高可用负载均衡集群。因为在现实环境中, 一台HAProxy很容易出现单点故障,为了提升服务可用性, 我们建议搭建高可用集群避免单点故障造成的业务中断。

一、heartbeat 简介

Heartbeat是Linux-HA项目中的一个组件,Linux-HA的全称是High-Availability Linux,这个开源项目的目标是:通过社区开发者的共同努力,提供一个增强linux可靠性(reliability)、可用性 (availability)和可服务性(serviceability)(RAS)的群集解决方案。

Heartbeat提供了所有 HA 软件所需要的基本功能比如心跳检测和资源接管、监测群集中的系统服务、在群集中的节点间转移共享IP等。自1999年开始到现在,发布了众多版本,是目前开源Linux-HA项目最成功的一个例子,在行业内得到了广泛的应用。

Linux-HA的官方网站:http://www.linux-ha.org

二、heartbeat基本原理

通过修改heartbeat的配置文件,可以指定一台heartbeat服务器作为主服务器,另一台自动成为热备服务器。在热备服务器上面配置heartbeat守护程序来监听来自主服务器的心跳信息如果在规定时间内,无法监听到心跳信息,那么就启动故障转移,取得主服务器上的相关资源的所有权接替主服务器继续不间断的提供服务,从而达到资源以及服务高可用的目的。

所以,在Heartbeat集群中,最核心的是heartbeat模块的心跳监测部分和集群资源管理模块的资源接管部分。

Heartbeat仅仅是个HA软件,它仅能完成心跳监控和资源接管,不会监视它控制的资源或应用程序,要监控资源和应用程序是否运行正常,必须使用第三方的插件,例如ipfail、Mon、Ldirector等。Heartbeat自身包含了几个插件,分别是ipfail、Stonith和Ldirectord。

注意:

heartbeat高可用是服务器级别的,不是服务级别的。

切换的条件:

1.服务器宕机

2.heartbeat服务本身故障

3.心跳连接故障

三、heartbeat+haproxy高可用负载均衡集群构建

环境:至少要准备四台机器,IP配置如下

(我们只创建两台web 机器,你可以根据需要创建多台web 机器实现动静分离;你也可以创建NFS机器做web服务器的后端存储等。)

注意: heartbeat中的VIP不需要像keepalived一样手动配置,直接把需要的VIP写到heartbeat的配置文件haresources里面, heartbeat会自动生成VIP。

主haproxy+heartbeat: 192.168.1.102 网卡接口:ens33

备haproxy+heartbeat: 192.168.1.103 网卡接口:ens33

Web server1: 192.168.1.105 网卡接口:ens33

Web server2: 192.168.1.106 网卡接口:ens33

VIP: 192.168.1.200 网卡接口:ens33:0 (自动生成)

heartbeat+haProxy 高可用负载均衡集群构建拓扑图:

heartbeat配置文件(主要有3个)

1.密钥文件authkeys,权限600:实现主机和备机之间的认证

2.heartbeat服务配置ha.cf

3.资源管理配置文件haresources:可以实现VIP创建以及调用脚本管控服务。

今天我们只演示heartbeat的配置, 至于Haproxy搭建负载均衡集群的配置我们之前已经说过了,请参考之前的文章:HAProxy负载均衡器用法详解

具体配置步骤如下:

1. 使用yum安装依赖包(HA主备两个节点都要同样操作)

代码语言:javascript
复制
yum -y install source-highlight
yum -y install asciidoc
yum -y install gcc gcc-c++ make glibc kernel-devel kernel-headers autoconf automake libtool glib2-devel libxml2 libxml2-devel libxslt-devel libtool-ltdl-devel wget asciidoc libuuid-devel bzip2 bzip2-devel e2fsprogs-devel net-snmp net-tools

2. 下载Heartbeat 3.0.6 ,Cluster Glue 1.0.12 和 resource-agents-3.9.6 源码包(HA主备两个节点都要同样操作)

我下载到了/root 下, 你可以自定义下载位置

这些安装包都可以从官网:

http://www.linux-ha.org/wiki/Downloads下载得到:

代码语言:javascript
复制
wget  http://hg.linux-ha.org/heartbeat-STABLE_3_0/archive/958e11be8686.tar.bz2  ##下载Heartbeat 3.0.6源码包
wget http://hg.linux-ha.org/glue/archive/0a7add1d9996.tar.bz2      ##下载Cluster Glue 1.0.12源码包
wget https://github.com/ClusterLabs/resource-agents/archive/v3.9.6.tar.gz  ##下载resource-agents3.9.6源码包

3. 安装Cluster Glue 1.0.12(HA主备两个节点都要操作)

代码语言:javascript
复制
[root@haproxy-master ~]# groupadd haclient  #创建组
[root@haproxy-master ~]# useradd -g haclient hacluster   #创建用户,并加到刚才创建的组里面

#下面开始安装Cluster Glue 1.0.12
[root@haproxy-master ~]# tar -jxvf 0a7add1d9996.tar.bz2   
[root@haproxy-master ~]# mv Reusable-Cluster-Components-glue--0a7add1d9996 cluster_glue
[root@haproxy-master ~]# cd cluster_glue/
[root@haproxy-master cluster_glue]# ./autogen.sh
[root@haproxy-master cluster_glue]#./configure --prefix=/usr/local/heartbeat --with-daemon-user=hacluster --with-daemon-group=haclient --enable-fatal-warnings=no LIBS='/lib64/libuuid.so.1'
[root@haproxy-master cluster_glue]#make    #编译
[root@haproxy-master cluster_glue]#make install   #安装

4. 安装resource-agents-3.9.6(HA主备两个节点都要操作)

代码语言:javascript
复制
#resource-ahent一定要安装,否则VIP不能漂移
[root@haproxy-master ~]# cd resource-agents-3.9.6/
[root@haproxy-master resource-agents-3.9.6]# ./autogen.sh
[root@haproxy-master resource-agents-3.9.6]# ./configure --prefix=/usr/local/heartbeat --with-daemon-user=hacluster --with-daemon-group=haclient --enable-fatal-warnings=no LIBS='/lib64/libuuid.so.1'
[root@haproxy-master ~resource-agents-3.9.6]# make && make instal

5. 安装Heartbeat 3.0.6(HA主备两个节点都要操作)

代码语言:javascript
复制
#安装heartbeat
[root@haproxy-master ~]# tar -xjvf 958e11be8686.tar.bz2
[root@haproxy-master ~]# cd Heartbeat-3-0-958e11be8686/
[root@haproxy-master Heartbeat-3-0-958e11be8686]#export CFLAGS="$CFLAGS -I/usr/local/heartbeat/include -L/usr/local/heartbeat/lib"
[root@haproxy-master Heartbeat-3-0-958e11be8686##./bootstrap
[root@haproxy-master Heartbeat-3-0-958e11be8686]#./configure --prefix=/usr/local/heartbeat --with-daemon-user=hacluster --with-daemon-group=haclient --enable-fatal-warnings=no LIBS='/lib64/libuuid.so.1'
[root@haproxy-master Heartbeat-3-0-958e11be8686]#make    #编译
[root@haproxy-master Heartbeat-3-0-958e11be8686]#make install   #安装

并配置如下:(HA主备两个节点都要操作)

代码语言:javascript
复制
[root@haproxy-master ~]# cp /root/Heartbeat-3-0-958e11be8686/doc/{ha.cf,haresources,authkeys} /usr/local/heartbeat/etc/ha.d/
[root@haproxy-master ~]# chmod 600 /usr/local/heartbeat/etc/ha.d/authkeys
[root@haproxy-master ~]# mkdir -pv /usr/local/heartbeat/usr/lib/ocf/lib/heartbeat/
mkdir: created directory ‘/usr/local/heartbeat/usr’
mkdir: created directory ‘/usr/local/heartbeat/usr/lib’
mkdir: created directory ‘/usr/local/heartbeat/usr/lib/ocf’
mkdir: created directory ‘/usr/local/heartbeat/usr/lib/ocf/lib’
mkdir: created directory ‘/usr/local/heartbeat/usr/lib/ocf/lib/heartbeat/’
[root@haproxy-master ~]# cp /usr/lib/ocf/lib/heartbeat/ocf-* /usr/local/heartbeat/usr/lib/ocf/lib/heartbeat/
[root@haproxy-master ~]# ln -svf /usr/local/heartbeat/lib64/heartbeat/plugins/RAExec/* /usr/local/heartbeat/lib/heartbeat/plugins/RAExec/
‘/usr/local/heartbeat/lib/heartbeat/plugins/RAExec/*’ -> ‘/usr/local/heartbeat/lib64/heartbeat/plugins/RAExec/*’
[root@haproxy-master ~]# ln -svf /usr/local/heartbeat/lib64/heartbeat/plugins/* /usr/local/heartbeat/lib/heartbeat/plugins/
‘/usr/local/heartbeat/lib/heartbeat/plugins/HBauth’ -> ‘/usr/local/heartbeat/lib64/heartbeat/plugins/HBauth’
‘/usr/local/heartbeat/lib/heartbeat/plugins/HBcomm’ -> ‘/usr/local/heartbeat/lib64/heartbeat/plugins/HBcomm’
‘/usr/local/heartbeat/lib/heartbeat/plugins/quorum’ -> ‘/usr/local/heartbeat/lib64/heartbeat/plugins/quorum’
‘/usr/local/heartbeat/lib/heartbeat/plugins/tiebreaker’ -> ‘/usr/local/heartbeat/lib64/heartbeat/plugins/tiebreaker’
[root@haproxy-master ~]# systemctl enable heartbeat.service

6. 配置authkeys(HA主备节点必须配置一致)

1)先随机成一个口令:

dd if=/dev/random bs=512 count=1 | openssl md5

代码语言:javascript
复制
[root@haproxy-master ~]# dd if=/dev/random bs=512 count=1 | openssl md5    #随机生成一串秘钥
0+1 records in
0+1 records out
115 bytes (115 B) copied, 9.5149e-05 s, 1.2 MB/s
(stdin)= 5445f79028687989625093ae3ba9e3c4

将生成的口令配置到文件:/usr/local/heartbeat/etc/ha.d/authkeys

代码语言:javascript
复制
[root@haproxy-master ~]# cat /usr/local/heartbeat/etc/ha.d/authkeys | tail -n 2
auth 1
1 md5  5445f79028687989625093ae3ba9e3c4

7.配置Haresources(HA主备节点必须配置一致)

配置文件:/usr/local/heartbeat/etc/ha.d/haresources

配置内容如下:(可以实现VIP创建以及调用haproxy脚本管控haproxy服务)

代码语言:javascript
复制
[root@haproxy-master ~]# cat /usr/local/heartbeat/etc/ha.d/haresources | tail -n 1
haproxy-master IPaddr::192.168.1.200/24/ens33:0  haproxy  ##192.168.1.200 为VIP, 相当于创建VIP 网卡, 启动时还会启动haproxy脚本,haproxy脚本位置在/usr/local/heartbeat/etc/ha.d/resource.d/
[root@haproxy-master ~]#

#haproxy-mater 为主节点的机器名
#192.168.1.200/24 为要创建的VIP地址和掩码
#ens33:0 为网卡名
#haproy 为/usr/local/heartbeat/etc/ha.d/resource.d/下面的haproxy启动脚本, 脚本名字就叫haproxy

haproxy 管控脚本内容:

(这个是我自定义的, 你也可以根据需要自定义脚本)

代码语言:javascript
复制
[root@haproxy-master init.d]# cat /usr/local/heartbeat/etc/ha.d/resource.d/haproxy
#!/bin/sh
#
# chkconfig: - 85 15
# description: HA-Proxy is a TCP/HTTP reverse proxy which is particularly suited \
#              for high availability environments.
# processname: haproxy
# config: /etc/haproxy/haproxy.cfg
# pidfile: /var/run/haproxy.pid
# Source function library.
if [ -f /etc/init.d/functions ]; then
  . /etc/init.d/functions
elif [ -f /etc/rc.d/init.d/functions ] ; then
  . /etc/rc.d/init.d/functions
else
exit 0
fi
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
#[ ${NETWORKING} = "no" ] && exit 0
# This is our service name
BASENAME=`basename $0`
if [ -L $0 ]; then
  BASENAME=`find $0 -name $BASENAME -printf %l`
  BASENAME=`basename $BASENAME`
fi
BIN=/usr/sbin/haproxy
CFG=/etc/haproxy/haproxy.cfg
[ -f $CFG ] || exit 1
PIDFILE=/var/run/$BASENAME.pid
LOCKFILE=/var/lock/subsys/$BASENAME
RETVAL=0
start() {
  quiet_check
if [ $? -ne 0 ]; then
echo "Errors found in configuration file, check it with '$BASENAME check'."
return 1
fi
echo -n "Starting $BASENAME: "
  daemon $BIN -D -f $CFG -p $PIDFILE
  RETVAL=$?
echo
  [ $RETVAL -eq 0 ] && touch $LOCKFILE
return $RETVAL
}
stop() {
echo -n "Shutting down $BASENAME: "
  killproc $BASENAME -USR1
  RETVAL=$?
echo
  [ $RETVAL -eq 0 ] && rm -f $LOCKFILE
  [ $RETVAL -eq 0 ] && rm -f $PIDFILE
return $RETVAL
}
restart() {
  quiet_check
if [ $? -ne 0 ]; then
echo "Errors found in configuration file, check it with '$BASENAME check'."
return 1
fi
  stop
  start
}
reload() {
if ! [ -s $PIDFILE ]; then
return 0
fi
  quiet_check
if [ $? -ne 0 ]; then
echo "Errors found in configuration file, check it with '$BASENAME check'."
return 1
fi
$BIN -D -f $CFG -p $PIDFILE -sf $(cat $PIDFILE)
}
check() {
$BIN -c -q -V -f $CFG
}
quiet_check() {
$BIN -c -q -f $CFG
}
rhstatus() {
  status $BASENAME
}
condrestart() {
  [ -e $LOCKFILE ] && restart || :
}
# See how we were called.
case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart)
    restart
    ;;
  reload)
    reload
    ;;
  condrestart)
    condrestart
    ;;
  status)
    rhstatus
    ;;
  check)
    check
    ;;
  *)
echo $"Usage: $BASENAME {start|stop|restart|reload|condrestart|status|check}"
exit 1
esac

exit $?

[root@haproxy-master init.d]#

注意:一定要copy 脚本到/usr/local/heartbeat/etc/ha.d/resource.d/ 目录,

否则haproxy服务不能被heartbeat带起来 ,同时heartbeat服务也不能正常使用。查看log 会有如下报错:

代码语言:javascript
复制
[root@haproxy-master init.d]# vim haproxy  #编辑haproxy启动脚本, 输入上面的脚本内容
[root@haproxy-master init.d]# chmod 755 haproxy #更改脚本权限
[root@haproxy-master init.d]# cp haproxy /usr/local/heartbeat/etc/ha.d/resource.d/   #copy到heartbeat的脚本目录
 
#测试脚本可用性
[root@haproxy-master init.d]# ./haproxy start
./haproxy: line 23: [: =: unary operator expected
Starting haproxy:                                          [  OK  ]
[root@haproxy-master init.d]# ./haproxy status
./haproxy: line 23: [: =: unary operator expected
haproxy (pid  46279) is running...
[root@haproxy-master init.d]# ./haproxy stop
./haproxy: line 23: [: =: unary operator expected
Shutting down haproxy:                                     [  OK  ]
[root@haproxy-master init.d]# ./haproxy status
./haproxy: line 23: [: =: unary operator expected
haproxy is stopped
[root@haproxy-master init.d]#

#当然, 也要copy脚本到备机, 主备要一致
[root@haproxy-master init.d]# scp haproxy root@192.168.1.103:/etc/init.d
[root@haproxy-master init.d]# scp haproxy root@192.168.1.103:/usr/local/heartbeat/etc/ha.d/resource.d/

脚本测试成功:

8.配置heartbeat的主配置文件ha.cf (主备节点都要配置) ####重点#####

HA备节点的ha.cf文件只需要将上面配置中的ucast一行内容改为"ucast ens33 192.168.1.102" 即可, 其他配置内容和上面HA主节点的ha.cf完全一样!

代码语言:javascript
复制
[root@haproxy-master ~]# vim /usr/local/heartbeat/etc/ha.d/ha.cf 
debugfile /var/log/ha-debug
logfile /var/log/ha-log         #日志存放位置
#crm yes                            #是否开启集群资源管理功能
logfacility        local0         #记录日志等级
keepalive 2                   #心跳的时间间隔,默认时间单位为秒
deadtime 5                    #超出该时间间隔未收到对方节点的心跳,则认为对方已经死亡。
warntime 3                    #超出该时间间隔未收到对方节点的心跳,则发出警告并记录到日志中,但此时不会切换
initdead 10          #在某些系统上,系统启动或重启之后需要经过一段时间网络才能正常工作,该选项用于解决这种情况产生的时间间隔。取值至少为deadtime的两倍。
udpport  694        #设置广播通信使用的端口,694为默认使用的端口号。
bcast        ens33               # Linux指定心跳使用以太网广播方式,并在ens33上进行广播。"#"后的要完全删除,要不然要出错。
ucast ens33 192.168.1.103      #采用网卡ens33的UDP多播来组织心跳,后面跟的IP地址应该为双机中对方的IP地址!!!!!
auto_failback on            #在该选项设为on的情况下,一旦主节点恢复运行,则自动获取资源并取代备用节点。off主节点恢复后变为备用节点,备用为主节点!!!!!
#stonith_host *     baytech 10.0.0.3 mylogin mysecretpassword
#stonith_host ken3  rps10 /dev/ttyS1 kathy 0
#stonith_host kathy rps10 /dev/ttyS1 ken3 0
#watchdog /dev/watchdog       
node   haproxy-master           #主机节点名,可通过"uname -n"查看,默认为主节点!!!!!
node   haproxy-slave              #备用机节点名,默认为次节点,要注意顺序!!!!
#ping 172.16.60.207         # 选择ping节点,选择固定路由作为节点。ping节点仅用来测试网络连接。一般选择这行ping测试就行, 下面一行注释掉.
ping_group group1 192.168.1.105  192.168.1.106     #这个地址并不是双机中的两个节点地址,而是仅仅用来测试网络的连通性. 当这两个IP 都不能ping通时,对方即开始接管资源。
respawn root /usr/local/heartbeat/libexec/heartbeat/ipfail        #选配项。其中root表示启动ipfail进程的身份。要确保这个路径正确(可以用find命令搜索出来), 否则heartbeat启动失败。一般是在/usr/lib64/heartbeat/ipfail。
apiauth ipfail gid=root uid=root

至此,全部配置完成, 我们可以测试heartbeat了。

9. 测试 1)先启动主节点的heartbeat服务

当HA主节点的heartbeat服务启动后, 会发现主节点的haproxy服务也会被自动启动起来的!这是因为在haresources文件里配置了haproxy服务的监控了,主节点此时占有vip资源,即接管服务!

代码语言:javascript
复制
[root@haproxy-master ~]# systemctl start heartbeat

主节点状态:

果然,当我们不断刷新haproxy服务的状态时,发现haproxy 也随着heartbeat的启动而启动了

查看进程:

查看IP可以看到当前VIP在主节点上:

2)启动备节点的heartbeat服务

但是HA备节点的heartbeat服务启动后, 备节点的haproxy服务并没有被自动启动!因为此时vip在HA主节点那边,备节点此时没有接管服务。

备节点状态:

下图证明了随着备节点heartbeat服务的启动, haporxy 并没有被启动,因为VIP在主节点上:

通过ip a 查看到备节点并没有VIP:

尝试打开网页http://192.168.1.200:90/haproxy?stats:

可见我们可以成功打开网页,并且是通过VIP 访问的, 意味着Heartbeat, Haproxy 和 web 服务目前都是正常的。

3)关闭主节点的heartbeat

关闭HA主节点的heartbeat服务,会发现主节点的haproxy服务也会被自动关闭,并且VIP资源也被转移到HA备节点上。HA备节点自动接管VIP资源,且haproxy服务也自动起来。

主节点状态:(主节点的haproxy服务被自动关闭)

备节点状态:(VIP漂移到备节点,且haproxy服务被启动)

查看网页, 可以看到haproxy, web都正常。

4)再次启动主节点的heartbeat

我们发现VIP又从备份节点漂移到主节点:

主节点状态:

备份节点看不到VIP且haproxy被自动停掉:

5)将主节点关机

查看备节点状态:

发现VIP成功漂移到备节点,且备节点上的haproxy启动。

访问haproxy网站,可以看到服务正常。

至此,我们成功验证了heartbeat+haproxy的高可用性;以及haproxy的负载均衡。集群搭建成功!

今天我们先介绍到这里, 以后也会继续介绍Linux 负载均衡和高可用的内容。可以持续关注!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 洁癖是一只狗 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档