Heartbeat<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

运行于备用主机上的Heartbeat可以通过以太网连接检测主服务器的运行状态,一旦其无法检测到主服务器的“心跳”则自动接管主服务器的资源。通常情况下,主、备服务器间的心跳连接是一个独立的物理连接,这个连接可以是串行线缆、一个由“交叉线”实现的以太网连接。Heartbeat甚至可同时通过多个物理连接检测主服务器的工作状态,而其只要能通过其中一个连接收到主服务器处于活动状态的信息,就会认为主服务器处于正常状态。从实践经验的角度来说,建议为Heartbeat配置多条独立的物理连接,以避免Heartbeat通信线路本身存在单点故障。

1、串行电缆:被认为是比以太网连接安全性稍好些的连接方式,因为hacker无法通过串行连接运行诸如telnetsshrsh类的程序,从而可以降低其通过已劫持的服务器再次侵入备份服务器的几率。但串行线缆受限于可用长度,因此主、备服务器的距离必须非常短。

2、以太网连接:使用此方式可以消除串行线缆的在长度方面限制,并且可以通过此连接在主备服务器间同步文件系统,从而减少了从正常通信连接带宽的占用。

基于冗余的角度考虑,应该在主、备服务器使用两个物理连接传输heartbeat的控制信息;这样可以避免在一个网络或线缆故障时导致两个节点同时认为自已是唯一处于活动状态的服务器从而出现争用资源的情况,这种争用资源的场景即是所谓的“脑裂”(split-brain)或“partitioned cluster”。在两个节点共享同一个物理设备资源的情况下,脑裂会产生相当可怕的后果。

为了避免出现脑裂,可采用下面的预防措施:

1、如前所述,在主、备节点间建立一个冗余的、可靠的物理连接来同时传送控制信息;

2、如前所述,在主、备节点间建立一个冗余的、可靠的物理连接来同时传送控制信息;

3、一旦发生脑裂时,借助额外设备强制性地关闭其中一个节点;

第二种方式即是俗称的“将其它节点‘爆头’(shoot the other node in the head)”,简称为STONITH。基于能够通过软件指令关闭某节点特殊的硬件设备,Heartbeat即可实现可配置的Stonith。但当主、备服务器是基于WAN进行通信时,则很难避免“脑裂”情景的出现。因此,当构建异地“容灾”的应用时,应尽量避免主、备节点共享物理资源。

Heartbeat的控制信息:

“心跳”信息(也称为状态信息)仅150 bytes大小的广播、组播或多播数据包。可为以每个节点配置其向其它节点通报“心跳”信息的频率,以及其它节点上的heartbeat进程为了确认主节点出节点出现了运行等错误之前的等待时间。

集群变动事务(transition)信息:ip-requestip-request-rest是相对较常见的两种集群变动信息,它们在节点间需要进行资源迁移时为不同节点上heartbeat进程间会话传递信息。比如,当修复了主节点并且使其重新“上线”后,主节点会使用ip-request要求备用节点释放其此前从因主节点故障而从主节点那里接管的资源。此时,备用节点则关闭服务并使用ip-request-resp通知主节点其已经不再占用此前接管的资源。主接点收到ip-request-resp后就会重新启动服务。

重传请求:在某集群节点发现其从其它节点接收到的heartbeat控制信息“失序”(heartbeat进程使用序列号来确保数据包在传输过程中没有被丢弃或出现错误)时,会要求对方重新传送此控制信息。 Heartbeat一般每一秒发送一次重传请求,以避免洪泛。

上面三种控制信息均基于UDP协议进行传送,可以在/etc/ha.d/ha.cf中指定其使用的UDP端口或者多播地址(使用以太网连接的情况下)。

此外,除了使用“序列号/确认”机制来确保控制信息的可靠传输外,Heartbeat还会使用MD5SHA1为每个数据包进行签名以确保传输中的控制信息的安全性。

资源脚本(resource scripts)即Heartbeat控制下的脚本。这些脚本可以添加或移除IP别名(IP alias)或从属IP地址(secondary IP address),或者包含了可以启动/停止服务能力之外数据包的处理功能等。通常,Heartbeat会到/etc/init.d//etc/ha.d/resource.d/目录中读取脚本文件。Heartbeat需要一直明确了解“资源”归哪个节点拥有或由哪个节点提供。在编写一个脚本来启动或停止某个资源时,一定在要脚本中明确判断出相关服务是否由当前系统所提供。

Heartbeat的配置文件:

/etc/ha.d/ha.cf

定义位于不同节点上的heartbeat进程间如何进行通信;

/etc/ha.d/haresources

定义对某个资源来说哪个服务器是主节点,以及哪个节点应该拥有客户端访问资源时的目标IP地址。

/etc/ha.d/authkeys

定义Heartbeat包在通信过程中如何进行加密。

ha.cfauthkeys文件发生改变时,需要重新加载它们就可以使用之生效;而如果haresource文件发生了改变,则只能重启heartbeat服务方可使之生效。

尽管Heartbeat并不要求主从节点间进行时钟同步,但它们彼此间的时间差距不能超过1分钟,否则一些配置为高可用的服务可能会出异常。

Heartbeat当前也不监控其所控制的资源的状态,比如它们是否正在运行,是否运行良好以及是否可供客户端访问等。要想监控这些资源,仍要使用额外的Mon软件包来实现。

所需软件包:

# yum -y --nogpgcheck localinstall libnet-1.1.4-3.el5.i386.rpm  

# yum -y --nogpgcheck localinstall perl-MailTools-1.77-1.el5.noarch.rpm 

# yum -y --nogpgcheck localinstall heartbeat-pils-2.1.4-10.el5.i386.rpm  

# yum -y --nogpgcheck localinstall heartbeat-stonith-2.1.4-10.el5.i386.rpm 

# yum -y --nogpgcheck localinstall heartbeat-gui-2.1.4-10.el5.i386.rpm

# yum -y --nogpgcheck localinstall heartbeat-ldirectord-2.1.4-10.el5.i386.rpm

# yum -y --nogpgcheck localinstall heartbeat-devel-2.1.4-10.el5.i386.rpm

# yum -y --nogpgcheck localinstall heartbeat-2.1.4-10.el5.i386.rpm

复制到此目录下:

# cp -v /usr/share/doc/heartbeat-2.1.4/{ha.cf,authkeys,haresources} /etc/ha.d/

# cp /usr/share/doc/heartbeat-ldirectord-2.1.4/ldirectord.cf /etc/ha.d/

heartbeat服务加入到自动启动队列:

# chkconfig --add heartbeat

# chkconfig heartbeat on

Heartbeat工作图:

组建一个heartbeat步骤简单如下:

安装heartbeat

配置/etc/ha.d/ha.ccf    /etc/ha.d/haresources    /etc/ha.d/authkets

安装heartbeatbackup服务器上

设置系统时钟,能保证它们之间的时间一致性

启动heartbeat

###############################################################################

具体实现步骤:

实验环境:浮动IP地址为192.168.0.123

Heartbeat外网卡地址

192.168.0.121

Heartbeat内网卡地址

192.168.10.11

辅助Heartbeat外网卡地址

192.168.0.122

辅助Heartbeat内网卡地址

192.168.10.12

设置网络环境:

配置网卡地址在主Heartbeat

# vim /etc/hosts

192.168.0.121   node1.example.com      node1

192.168.0.122   node2.example.com      node2

# vim /etc/sysconfig/network (设置主机名一定要与uname  -n显示的主机名一致)

# hostname node1.example.com

# hostname

注销重新登录后已生效

为了测试这里我们安装httpd包,并编辑一个简单的网页

# yum install httpd

# vim /var/www/html/index.html

######This is node1.example.com######

可以先启动httpd服务来测试网页是否成功,但测试后一定要把httpd服务关闭

# service httpd start

# elinks 192.168.0.121

# service httpd stop

# chkconfig httpd off

这里我已经把所需的所有Heartbeatrpm软件包全部放在Heartbeat目录下了,这里可直接在本地安装了

# cd Heartbeat/

# yum --nogpgcheck localinstall ./*.rpm(一次安装这些软件包)

有可能要用到net-snmp包,所以这里我们也安装此包# yum install net-snmp

# cd /etc/ha.d/

# cp /usr/share/doc/heartbeat-2.1.4/{ha.cf,haresources,authkeys} ./

生成authkeys

# echo -ne "auth 1\n1 sha1 " >> /etc/ha.d/authkeys

# dd if=/dev/urandom bs=512 count=1 | openssl md5  >> /etc/ha.d/authkeys

# chmod 0600 /etc/ha.d/authkeys(修改authkeys权限为0600

# vim authkeys (再次查看生成的信息)

auth 1

1 sha1 fe43939eefd2a517e761d84069c95e0f

# vim ha.cf 

debugfile /var/log/ha-debug

logfacility     local0

keepalive 2

deadtime 30

warntime 10

initdead 120

udpport 694

bcast   eth1

auto_failback on

node    node1.example.com

node    node2.example.com

# vim haresources 

node1.example.com 192.168.0.123 httpd

# ln -sv /etc/init.d/httpd /etc/ha.d/resource.d/

# cd resource.d/

# ll已出现httpd链接了)

在辅助Heartbeat上首先去配置网卡

# vim /etc//hosts

192.168.0.121    node1.example.com      node1

192.168.0.122    node2.example.com      node2

# vim /etc/sysconfig/network配置主机名要和uname  -n显示的名字一致)

# hostname node2.example.com(加速生效)

# hostname

注销重新登录主机名字已改变

httpd服务:

# yum install httpd

编辑测试页面:

# vim /var/www/html/index.html

This is a test page from node1.example.com

# service httpd start(先启动服务查看测试页面是否成功)

# elinks 192.168.0.122

# service httpd stop(关闭httpd服务)

# chkconfig httpd off(一定不能开机后随即自启动)

在辅助Heartbeat上部骤和主Heartbeat基本一致,并且/etc/ha.d/{ha.cf,authkeys,haresources}三个文件配置全部一样,所以这里直接从主Heartbeat上拷贝了

# scp root@192.168.0.121:/etc/ha.d/{ha.cf,authkeys,resources} /etc/ha.d/

# ln -sv /etc/init.d/httpd /etc/ha.d/resource.d/

# cd resource.d/

# ll(已经出现httpd连接了)

先启动作为主heartbeat的主机,在起动辅助的heartbeat主机

node1.example.com上启动heartbeat

# service heartbeat start

用客户端访问:

如图一看到node1.example.com在工作

若我们停掉node1.example.com上的heartbeat,看node2.example.com能否接替主heartbeat的资源共享管理功能,在客户端上再次访问

# cd /usr/lib/heartbeat

# ./hb_standby

如图看到此时node2.example.com已经接替了node1.example.com

因为我们把auto_failback on设置为on表明如果node1.exampel.com恢复正常时他会重新接管他自己的工作的

node1.example.com上再次开启heartbeat,在客户端上再次访问:

# service heartbeat restart

看到node1.example.com此时又恢复工作了

# tcpdump -i eth1 udp port 694(抓包查看信息)

01:50:54.382673 IP 192.168.10.11.40665 > 192.168.10.255.ha-cluster: UDP, length 220

01:50:54.893989 IP 192.168.10.12.51335 > 192.168.10.255.ha-cluster: UDP, length 221

01:50:56.973833 IP 192.168.10.11.40665 > 192.168.10.255.ha-cluster: UDP, length 220

01:50:57.699547 IP 192.168.10.12.51335 > 192.168.10.255.ha-cluster: UDP, length 221

haresources配置文件介绍:

主从节点上的/etc/ra.d/raresource文件必须完全相同。文件每行通常包含以下组成部分:

1、服务器名字:指正常情况下资源运行的那个节点(即主节点),后跟一个空格或tab;这里指定的名字必须跟某个节点上的命令"uname -n"的返回值相同;

2IP别名(即额外的IP地址,可选):在启动资源之前添加至系统的附加IP地址,后跟空格或tabIP地址后面通常会跟一个子网掩码和广播地址,彼此间用“/”隔开;

3、资源脚本:即用来启动或停止资源的脚本,位于/etc/init.d//etc/ha.d/resourcd.d目录中;如果需要传递参数给资源脚本,脚本和参数之间需要用两个冒号分隔,多个参数时彼此间也需要用两个冒号分隔;如果有多个资源脚本,彼此间也需要使用空格隔开;

 格式如下:

 primary-server [IPaddress[/mask/interface/broadcast]]  resource1[::arg1::arg2]  resource2[::arg1::arg2]

 

 例如:

 primary-server 221.67.132.195 sendmail httpd

HALVS集群有两台Director,在启动时,主节点占有集群负载均衡资源(VIPLVS的转发及高度规则),备用节点监听主节点的“心跳”信息并在主节点出现异常时进行“故障转移”而取得资源使用权,这包括如下步骤:

1、添加VIP至其网络接口;

2、广播GARP信息,通知网络内的其它主机目前本Director其占有VIP

3、创建IPVS表以实现入站请求连接的负载均衡;

4Stonith

弃用resource脚本,改用ldirecotord来控制LVS

ldirectord用来实现LVS负载均衡资源的在主、备节点间的故障转移。在首次启动时,ldirectord可以自动创建IPVS表。此外,它还可以监控各Realserver的运行状态,一旦发现某Realserver运行异常时,还可以将其从IPVS表中移除。

ldirectord进程通过向RealserverRIP发送资源访问请求并通过由Realserver返回的响应信息来确定Realserver的运行状态。在Director上,每一个VIP需要一个单独的ldirector进程。如果Realserver不能正常响应Directordldirectord的请求,ldirectord进程将通过ipvsadm命令将此RealserverIPVS表中移除。而一旦Realserver再次上线,ldirectord会使用正确的ipvsadm命令将其信息重新添加至IPVS表中。

例如,为了监控一组提供web服务的Realserverldirectord进程使用HTTP协议请求访问每台Realserver上的某个特定网页。ldirectord进程根据自己的配置文件中事先定义了的Realserver的正常响应结果来判断当前的返回结果是否正常。比如,在每台web服务器的网站目录中存放一个页面".ldirector.html",其内容为"GOOD"ldirectord进程每隔一段时间就访问一次此网页,并根据获取到的响应信息来判断Realserver的运行状态是否正常。如果其返回的信息不是"GOOD",则表明服务不正常。

ldirectord需要从/etc/ha.d/目录中读取配置文件,文件名可以任意,但建议最好见名知义。

实现过程:

创建/etc/ha.d/ldirectord-192.168.0.219.cf,添加如下内容:

# Global Directives

checktimeout=20    

# ldirectord等待Realserver健康检查完成的时间,单位为秒;

任何原因的检查错误或超过此时间限制,ldirector将会将此RealserverIPVS表中移除;

checkinterval=5

每次检查的时间间隔,即检查的频率;

autoreload=yes

此项用来定义ldirectord是否定期每隔一段时间检查此配置文件是否发生改变并自动重新加载此文件;

logfile="/var/log/ldirectord.log"

定义日志文件存放位置;

quiescent=yes

当某台Realserver出现异常,此项可将其设置为静默状态(即其权重为“0”)从而不再响应客户端的访问请求;

# For an http virtual service

virtual=192.168.0.219:80

此项用来定义LVS服务及其使用的VIPPORT

        real=192.168.0.221:80 gate 100

        # 定义Realserver,语法:real=RIP:port gate|masq|ipip [weight]

        real=192.168.0.223:80 gate 300

        fallback=127.0.0.1:80 gate

        # IPVS表没有任何可用的Realserver时,此“地址:端口”作为最后响应的服务;

        # 一般指向127.0.0.1,并可以通过一个包含错误信息的页面通知用户服务发生了异常;

        service=http

        # 定义基于什么服务来测试Realserver

        request=".ldirectord.html"

        receive="GOOD"

        scheduler=wlc 

        #persistent=600

        #netmask=255.255.255.255

        protocol=tcp

        # 定义此虚拟服务用到的协议;

        checktype=negotiate

        # ldirectord进程用于监控Realserver的方法;{negotiate|connect|A number|off}

        checkport=80

        

/etc/hd.d/haresources中添加类似如下行:

 node1.example.com 192.168.0.219 ldirectord::ldirectord-192.168.0.219.cf