一、高可用集群的架构
从微观上讲,高可用集群可分为4个层次
1、第一层是信息和基础架构层,主要用于节点之间传心跳信息。节点之间通过UDP传递心跳信息,可以通过广播,组播,单播等方式。
2、第二层是成员关系层,作用是主节点通过cluster consensus menbership service(CCM)这种服务由第一层提供的信息,来生产一个完整的成员关系。这层主要是实现承上启下的作用,承上是将下层产生的信息生成成员关系图传递给上层以通知各个节点的工作状态;启下是将上层对于隔离某一设备进行实施。
3、第三层为资源分配层,真正实现集群服务的层。在该层中每个节点都运行一个集群资源管理器(CRM,cluster Resource Manager),它能为实现高可用提供核心组件,包括资源定义,属性等。在每一个节点上CRM都维护有一个集群信息机库(cluster information base,CIB,XML文档)和本地资源管理器(local resource manager,LRM)组件。只有指定协调员(DC, 主节点)上的CIB文档可以修改,其他节点的CIB都是从主节点上复制而来的。对于LRM,是执行CRM传递过来的在本地执行某个资源的执行和停止的具体执行人。CRM最著名的是pacemaker软件。
当某个节点发生故障之后,是由DC通过PE(policy engine)和TE(transition engine)来决定是否抢夺资源。TE通知从节点的LRM,由LRM对这个从节点做出具体的动作。
4、第四层为资源层,资源层包括一个或多个resource agent(RA),RA是一个程序,通常是一个能够管理本节点上的属于集群资源的某一资源的启动,停止和状态信息的脚本,在任何一个节点上RA只能由本地的LRM控制。
RA的种类:
linux standard base(LSB):即在/etc/init.d/目录下的脚本
Open Clustering Framework(OCF):有stop、start和Monitor功能的脚本,比LSB功能强大
STONITH:第三方的脚本
二、corosync和pacemaker简介
Coreosync是集群管理套件的一部分,它在传递信息的时候可以通过一个简单的配置文件来定义信息传递的方式和协议等。它是一个新兴的软件,2008年推出,但其实它并不是一个真正意义上的新软件,在2002年的时候有一个项目Openais , 它由于过大,分裂为两个子项目,其中可以实现HA心跳信息传输的功能就是Corosync ,它的代码60%左右来源于Openais。Corosync可以提供一个完整的HA功能,但是要实现更多,更复杂的功能,那就需要使用Openais了。
Pacemaker是一个集群管理器。它利用首选集群基础设施(OpenAIS 或heartbeat)提供的消息和成员能力,由辅助节点和系统进行故障检测和回收,实现性群集服务(亦称资源)的高可用性。
三、基本概念
资源类型:
1)primitive(native): 基本资源,同一时刻只能运行在一个节点,如服务的IP地址
2)group: 资源组
3)clone: 克隆资源(可同时运行在多个节点上),要先定义为primitive后才能进行clone。
4)master/slave: 只能运行2个节点,一主一从
资源粘性stickiness: 表示资源是否倾向于留在当前节点
>0: 倾向于留在当前节点
<0: 倾向于离开此节点
=0: 由HA来决定去留
INFINITY: 正无穷大
-INFINITY: 负无穷大
资源约束: 资源的启动是要有先后次序的,这时就需要对资源进行约束。资源约束是用以指定在哪些群集节点上运行资源,以何种顺序装载资源,以及特定资源依赖于哪些其它资源。pacemaker共给我们提供了三种资源约束方法:
1)Location(位置): 定义资源可以、不可以或尽可能在哪些节点上运行
2)Collocation(排列): 排列约束用以定义集群资源可以或不可以在某个节点上同时运行
3)Order(顺序): 顺序约束定义集群资源在节点上启动的顺序
法定票数quorum:
集群服务中的每个node都有自己的票数,票数是由DC负责统计,然后形成CIB(集群信息库),然后同步集群信息库到各个节点上,只有quorum大于总票数的二分之一,集群服务才可以继续运行,当quorum小于总票数的二分之一时,会有一下动作:
ignore(忽略): 当集群服务只有两个节点时,无论谁挂了,都需要切换node,所以要忽略法定票数
freeze(冻结): 已经启动的资源继续运行,不允许新的资源启动
stop(停止): 停止集群服务,这是默认值
suicide(自杀): 将所有节点全部隔离
隔离Fence:
多台node在共享存储写同一个文件时,文件系统就会崩溃,所以资源转移之前需要先完成其他节点的隔离,隔离有2个级别:
1)资源隔离: 让被隔离主机不能能再使用这个资源。如让隔离的主机不能访问共享存储。
2)主机隔离: 直接让改主机关机。如通过STONITH让主机断电,强行关闭。
四、安装配置
环境:
node1: 172.16.1.1
node2: 172.16.1.2
VIP: 172.16.1.10
集群资源: VIP、httpd
集群代理(RA): OCF的IPaddr、LSB的httpd
1. node1、node2的准备工作
[root@node1 ~]# vim /etc/hosts 172.16.1.1 node1.tcnet.com node1 172.16.1.2 node2.tcnet.com node2 #这个主机名需要和hostname命令显示的相同 [root@node1 ~]# ssh-keygen -t rsa [root@node1 ~]# ssh-copy-id -i .ssh/id_rsa.pub root@node2 #设定两个节点可以基于密钥进行ssh通信
[root@node1 ~]# service iptables stop #关闭防火墙 iptables: Flushing firewall rules: [ OK ] iptables: Setting chains to policy ACCEPT: filter [ OK ] iptables: Unloading modules: [ OK ] You have new mail in /var/spool/mail/root [root@node1 ~]# getenforce #关闭selinux Disabled
2. node1、node2安装httpd服务作为测试的服务
[root@node1 ~]# yum install httpd -y [root@node1 ~]# echo "node1.tcnet.com" > /var/www/html/index.html [root@node1 ~]# service httpd start [root@node1 ~]# service httpd stop #测试服务是否正常运行 [root@node1 ~]# chkconfig --list httpd #必须不能开机自动启动 httpd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
2. node1、node2上安装软件
[root@node1 ~]# yum install openaislib libesmtp cluster-glue corosync pacemaker
3. node1上配置corosync
[root@node1 ~]# cd /etc/corosync/ [root@node1 corosync]# cp corosync.conf.example corosync.conf [root@node1 corosync]# vim corosync.conf compatibility: whitetank totem { #指定心跳信息传递的参数 version: 2 secauth: off #是否开启安全认证 threads: 0 #开启线程的个数 interface { ringnumber: 0 #标识一个通信接口 bindnetaddr: 172.16.0.0 #指定心跳报文传输的网段 mcastaddr: 226.94.1.1 #指定心跳报文发送的组播地址 mcastport: 5405 #指定端口 ttl: 1 #生命周期,跨3层的话需要加大一点,不然对方接收不到,最大255 } } logging { fileline: off to_stderr: no #是否发送标准错误输出 to_logfile: yes #是否记录到日志文件中 to_syslog: no #是否记录到syslog,二者选其一即可 logfile: /var/log/cluster/corosync.log #日志文件的路径 debug: off #是否开启调试信息 timestamp: on #日志中是否协商时间戳 logger_subsys { subsys: AMF #是否记录AMF debug: off #是否开启AMF的调试信息 } } amf { mode: disabled #AMF的状态 } service { #corosync启动时也将pacemaker启动 ver: 0 name: pacemaker } aisexec { #指定ais的用户和组的身份 user: root group: root }
4. node1上生成节点间通信时用到的认证密钥文件
[root@node1 ~]# corosync-keygen Corosync Cluster Engine Authentication key generator. Gathering 1024 bits for key from /dev/random. Press keys on your keyboard to generate entropy. Press keys on your keyboard to generate entropy (bits = 128). Press keys on your keyboard to generate entropy (bits = 192). Press keys on your keyboard to generate entropy (bits = 264). Press keys on your keyboard to generate entropy (bits = 328). Press keys on your keyboard to generate entropy (bits = 392). Press keys on your keyboard to generate entropy (bits = 464). Press keys on your keyboard to generate entropy (bits = 528). Press keys on your keyboard to generate entropy (bits = 600). Press keys on your keyboard to generate entropy (bits = 672). Press keys on your keyboard to generate entropy (bits = 736). Press keys on your keyboard to generate entropy (bits = 800). Press keys on your keyboard to generate entropy (bits = 864). Press keys on your keyboard to generate entropy (bits = 928). Press keys on your keyboard to generate entropy (bits = 992). Writing corosync key to /etc/corosync/authkey. #系统刚开机,/dev/random中的随机数不足,阻塞了当前的程序,直 #到根据熵池产生新的随机字节之后才返回。可以一直等,系统运行也 #会产生随机数,也可以随便敲一些键值。 [root@node1 ~]# cd /etc/corosync/ [root@node1 corosync]# ll total 24 -r--------. 1 root root 128 Mar 9 22:43 authkey #权限为400 -rw-r--r--. 1 root root 520 Mar 9 21:57 corosync.conf -rw-r--r--. 1 root root 445 Feb 22 2013 corosync.conf.example -rw-r--r--. 1 root root 1084 Feb 22 2013 corosync.conf.example.udpu drwxr-xr-x. 2 root root 4096 Feb 22 2013 service.d [root@node1 corosync]# scp -p authkey corosync.conf node2:/etc/corosync/ authkey 100% 128 0.1KB/s 00:00 corosync.conf 100% 520 0.5KB/s 00:00 #拷贝一份到node2上
5. node1、node2上启动集群服务
[root@node1 ~]# /etc/init.d/corosync start Starting Corosync Cluster Engine (corosync): [ OK ] [root@node1 ~]# grep -e "Corosync Cluster Engine" -e "configuration file" /var/log/cluster/corosync.log #查看corosync引擎是否正常启动 [root@node1 ~]# grep TOTEM !$ #查看初始化成员节点通知是否正常发出 [root@node1 ~]# grep pcmk_startup !$ #查看pacemaker是否正常启动 [root@node1 ~]# grep ERROR: !$ #检查启动过程中是否有错误产生 [root@node1 ~]# ssh node2 '/etc/init.d/corosync start' Starting Corosync Cluster Engine (corosync): [ OK ] #在node2上启动服务并查看日志信息
6. 查看集群状态
[root@node1 ~]# crm_mon Attempting connection to the cluster... Last updated: Sun Mar 9 23:33:37 2014 Last change: Sun Mar 9 23:28:22 2014 via crmd on node2.tcnet.com Stack: classic openais (with plugin) Current DC: node2.tcnet.com - partition with quorum Version: 1.1.8-7.el6-394e906 2 Nodes configured, 2 expected votes 0 Resources configured. Online: [ node1.tcnet.com node2.tcnet.com ]
7. node1上安装crmsh,因为crmsh依赖于pssh,所以直接用yum安装
[root@node1 ~]# yum --nogpgcheck localinstall crmsh-1.2.6-6.1.x86_64.rpm pssh-2.3.1-3.2.x86_64.rpm
8. 开始配置资源
[root@node1 ~]# crm crm(live)# configure #进入配置模式 crm(live)configure# verify #查看错误信息 error: unpack_resources: Resource start-up disabled since no STONITH resources have been defined error: unpack_resources: Either configure some or disable STONITH with the stonith-enabled option error: unpack_resources: NOTE: Clusters with shared data need STONITH to ensure data integrity Errors found during check: config not valid -V may provide more details crm(live)configure# property stonith-enabled=false #关闭stonith,因为实验环境没有stonish设备 crm(live)configure# commint crm(live)configure# verify crm(live)configure# primitive Myip ocf:IPaddr params ip=172.16.1.10 #定义IP资源 crm(live)configure# primitive Myservice lsb:httpd #定义服务资源 crm(live)configure# commit crm(live)configure# group MYSERVER Myip Myservice #定义资源组 crm(live)configure# commit crm(live)configure# property no-quorum-policy=ignore #法定票权不到一半时的策略 crm(live)configure# commit
9. 测试
[root@node2 ~]# ssh node1 '/etc/init.d/corosync stop' Signaling Corosync Cluster Engine (corosync) to terminate: [ OK ] Waiting for corosync services to unload:...[ OK ] #在node2上停止node1的服务 [root@node2 ~]# crm_mon Attempting connection to the cluster... Last updated: Mon Mar 10 01:31:18 2014 Last change: Mon Mar 10 01:03:43 2014 via cibadmin on node1.tcnet.com Stack: classic openais (with plugin) Current DC: node2.tcnet.com - partition WITHOUT quorum Version: 1.1.8-7.el6-394e906 2 Nodes configured, 2 expected votes 2 Resources configured. Online: [ node2.tcnet.com ] OFFLINE: [ node1.tcnet.com ] Resource Group: MYSERVER Myip (ocf::heartbeat:IPaddr): Started node2.tcnet.com Myservice (lsb:httpd): Started node2.tcnet.com #可以看到服务到node2上了