HA(High Avaliablity,高可用)集群的出现是为了使集群的整体服务尽可能可用,从而减少由计算机硬件和软件易错性所带来的损 失。如果某个节点失效,它的备援节点将在几秒钟的时间内接管它的职责。
一、高可用原理简述
我们在要做高可用的节点上安装好实现高可用功能的程序,这些程序最核心的包括两个部分:心跳监测部分和资源管理部分;通过资源管理器的配置接口定义资源,并将配置文件同步到其它节点,节点之间在心跳监测层通过相互发送报文来告诉对方自己当前的状态,如果在指定的时间内未收到对方发送的报文,那么就认为对方失效,这时会启动资源管理模块来接管运行在对方主机上的资源或者服务。
二、HA的框架和要点
1、Messaging与Membership层:Messaging层主要用于节点之间传递心跳和集群事务信息,可以使用广播、组播、单播、串行链路等方式,集群节点之间的心跳信息也要做认证。成员关系(Membership)层最重要的作用是主节点通过Cluster Consensus Menbership Service(CCM或者CCS)这种服务由Messaging层提供的信息,来产生一个完整的成员关系。
解决方案:heartbeat, corosync, cman(openais)
注:有时候,接收不到节点的心跳信息可能并非是节点出现故障,也有可能是节点很繁忙,因此建议节点上至少配两张网卡,一张网卡专门用来传递心跳信息,另外一张网卡即用于对外提供服务,也可作为传递心跳信息的备用网卡
2、CRM:cluster resource manager,集群资源管理器,工作在Messaging Layer之上。资源管理器的主要工作是根据messaging Layer传递的健康信息来决定服务的启动、停止和资源的定义、转移、分配。每一个节点上都包含一个CRM,在CRM中还包含LRM和DC等组件。
解决方案:
haresources(heartbeat v1):
配置接口:配置文件,文件名也叫haresources,在一个节点完成配置后,再手动将配置文件同步到其它节点;
crm(heartbeat v2):
运行为守护进程mdmtd,监听在指定的端口;配置文件cib(cluster information base),为xml格式;配置接口:命令行客户端crmsh,GUI客户端hb-gui,在一个节点完成配置后,配置文件会自动同步到其它节点;
pacemaker(heartbeat v3):
守护进程crmd;配置文件cib.xml;配置接口:CLI(crm,pcs), GUI(hawk,LCMC,pacemaker-mgmt);
rgmanager:守护进程,配置文件为/etc/cluster/cluster.xml,配置接口:clustat, cman_tool, Conga(Web GUI):控制端luci+被控制端ricci(运行于各节点)
3、LRM:local resource manager,它是CRM的一个子组件,用来获取某个资源的状态,并且管理本地资源
4、RA:resource agent,是实际负责操纵(启动、停止、监控等)资源的,LRM用来管理本地资源的,但是不能操纵资源,当需要操纵资源时会调用RA来执行,RA通常是脚本文件,在一个节点上可能有多个RA。
RA的类型:
heartbeat legacy:heartbeat的传统类型,通常是/etc/ha.d/haresources.d/目录下的脚本
LSB:/etc/init.d/*
OCF(open cluster framework):比LSB更强大的一种脚本,支持更多的参数
STONITH:一种特殊的RA,主要作用是使出现问题的节点从集群环境中脱离,进而释放集群资源,避免两个节点争用一个资源的情形发生。保证共享数据的安全性和完整性。
5、DC:可以理解为事务协调员,这个是当多个节点之间彼此收不到对方的心跳信息时,这样各个节点都会认为对方发生故障了,于是就会产尘分裂状况(分组)。并且都运行着相关服务,因此就会发生资源争夺的状况。因此,事务协调员在这种情况下应运而生。事务协调员会根据每个组的法定票数来决定哪些节点启动服务,哪些节点停止服务。例如高可用集群有3个节点,其中2个节点可以正常传递心跳信息,与另一个节点不能相互传递心跳信息,因此,这样3个节点就被分成了2组,其中每一个组都会推选一个DC,用来收集每个组中集群的事务信息,并形成CIB,且同步到每一个集群节点上。同时DC还会统计每个组的法定票数(quorum),当该组的法定票数大于总票数二分之一时,则表示启动该组节点上的服务,否则放弃该节点上的服务。对于某些性能比较强的节点来说,它可以投多张票,因此每个节点的法定票数并不是只有一票,需要根据服务器的性能来确定,DC位于主节点上。
PE和TE也是DC的子组件,其中:
PE(Policy Engine):策略引擎,用来定义资源转移的一整套转移方式,但只是做策略者,并不亲自来参加资源转移的过程,而是让TE来执行自己的策略。
TE(Transition Engine):执行PE做出的策略。
6、仲裁设备:偶数个集群节点分裂时可能出现两组票数相同的情况,这时候就需要借助仲裁设备(ping node, ping group)来决定服务该在哪个节点上启动。
7、集群分裂场景中,without quorum之时,如何采取对资源管控的策略:
stopped
ignore:仅在只有两个节点,又没有仲裁节点时才可考虑
freeze:继续处理未完成的请求,但不再接受新请求
suicide
8、资源:启动一个服务需要的子项目。例如启动一个web服务,需要ip、服务程序、文件系统(用来存储数据),这些都可以统称为资源。
9、资源隔离机制:
节点级别:STONITH,这种方式直接操作电源开关,当一个节点发生故障时,另一个节点如果能侦测到,就会通过网络发出命令,控制故障节点的电源开关,通过暂时断电,而又上电的方式使故障节点被重启动或者直接断电, 这种方式需要硬件支持
电源交换机
服务硬件管理模块
资源级别:例如:使用FC SAN switch可以实现在存储资源级别拒绝某节点的访问
应用场景:集群分裂
10、资源类型:
primitive, native:主资源,其仅能运行于某一节点
group:组资源,可用于实现限制多个资源运行于同一节点及对此些资源统一进行管理
clone:克隆资源,一个资源可以运行于多个节点;
应该指定:最大克隆的份数,每个节点最多可以运行的克隆;
master/slave: 主从资源,特殊的克隆资源;
11、资源运行的倾向性(资源转移倾向性):
rgmanager:
failover domain, node priority
pacemaker:
资源黏性:资源倾向于留在当前节点的分数;通常使用score来定义,当score为正数表示乐意留在当前节点,负数表示不乐意留在当前节点
资源约束:
位置约束:资源对某节点运行的倾向性
inf:正无穷, -inf:负无穷
n, -n
排列约束:定义资源彼此间的倾向性
inf, -inf
n, -n
顺序约束:属于同一服务的多个资源运行在同一节点时,其启动及关闭的次序约束;
启动:A→B→C
关闭:C→B→A
例如:定义高可用的mysql服务,需要三个资源vip、mysqld、nfs,合理的启动次序应该是vip→nfs→mysqld
要定义资源同进同退,有两种方式:排列约束和组资源,常用后者。
12、HA集群的工作模型:
A/P:两节点,active/passive,主备模型;
A/A:两节点,active/active,双主模型,两个节点各自运行一个集群服务,彼此把对方当作备用节点
N-M:N>M, N个节点,M个服务;活动节点数为N,备用节点数为N-M
N-N
13、根据messagin层程序和CRM层程序的不同组合,CentOS或RHEL系统高可用集群的解决方案有:
CentOS 5:
RHCS:cman+rgmanager
选用第三方方案:corosync+pacemaker, heartbeat(v1或v2), keepalived
CentOS 6:
RHCS:cman+rgmanager
corosync + rgmanager
cman + pacemaker
heartbeat v1(自带haresources), v2(自带crm), v3(自带pacemaker)
keepalived
三、配置高可用集群
1、配置高可用集群的前提:(以两节点的heartbeat为例)
⑴时间必须保持同步
⑵节点之间必须用名称互相通信
建议使用/etc/hosts 而不要用DNS
集群中使用的主机名为`uname -n`表示的主机名;
⑶ping node(仅偶数节点才需要)
⑷ssh密钥认证进行无障碍通信;
2、heartbeat v1的配置
程序主配置文件:ha.cf
认证密钥:authkeys, 其权限必须为组和其它无权访问;
用于资源的文件:haresources
3、案例:基于heartbeat v1配置mysql和httpd的双主高可用模型,二者使用nfs共享数据
⑴实验环境:
node4:192.168.30.14,mysqld主节点,httpd备节点
node5:192.168.30.15, httpd主节点,mysql备节点
node3:192.168.30.20,nfs
配置mysql所需的资源:ip, mysqld, nfs
配置httpd所需的资源:ip, httpd, nfs
⑵准备工作
①让节点之间的时间同步,并能使用名称进行无障碍通信
ntpdate 202.120.2.101
vim /etc/hosts
ssh-keygen -t rsa
ssh-copy-id -i .ssh/id_rsa.pub root@node5
[root@node4 ~]# ntpdate 202.120.2.101 13 Apr 23:08:47 ntpdate[2613]: the NTP socket is in use, exiting [root@node4 ~]# date Wed Apr 13 23:09:25 CST 2016 [root@node4 ~]# crontab -e */10 * * * * /usr/sbin/ntpdate 202.120.2.101 [root@node4 ~]# vim /etc/hosts #编辑本地hosts文件 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.30.10 node1 192.168.30.20 node2 192.168.30.13 node3 192.168.30.14 node4 192.168.30.15 node5 [root@node4 ~]# scp /etc/hosts root@node5:/etc/ The authenticity of host ‘node5 (192.168.30.15)‘ can‘t be established. RSA key fingerprint is a3:d3:a0:9d:f0:3b:3e:53:4e:ee:61:87:b9:3a:1c:8c. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added ‘node5,192.168.30.15‘ (RSA) to the list of known hosts. root@node5‘s password: hosts 100% 262 0.3KB/s 00:00 [root@node4 ~]# ping node5 PING node5 (192.168.30.15) 56(84) bytes of data. 64 bytes from node5 (192.168.30.15): icmp_seq=1 ttl=64 time=0.419 ms 64 bytes from node5 (192.168.30.15): icmp_seq=2 ttl=64 time=0.706 ms ^C --- node5 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1888ms rtt min/avg/max/mdev = 0.419/0.562/0.706/0.145 ms [root@node4 ~]# ssh-keygen -t rsa #生成密码对 Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: bc:b8:e6:78:6d:51:91:30:4d:d4:dd:50:c0:18:f1:28 root@node4 The key‘s randomart image is: +--[ RSA 2048]----+ | o=ooo*o=.| | .+ ooo .| | E.. . | | . .. | | S. | | ... | | .... | | .o.o | | .+o. | +-----------------+ [root@node4 ~]# ssh-copy-id -i .ssh/id_rsa.pub root@node5 #将公钥信息导入对方节点的认证文件中 The authenticity of host ‘node5 (192.168.30.15)‘ can‘t be established. RSA key fingerprint is a3:d3:a0:9d:f0:3b:3e:53:4e:ee:61:87:b9:3a:1c:8c. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added ‘node5,192.168.30.15‘ (RSA) to the list of known hosts. root@node5‘s password: Now try logging into the machine, with "ssh ‘root@node5‘", and check in: .ssh/authorized_keys to make sure we haven‘t added extra keys that you weren‘t expecting. [root@node4 ~]# ssh root@node5 hostname #连接对方节点不需要输入密码了 node5
#在另一个节点上执行同样的步骤 [root@node4 ~]# ntpdate 202.120.2.101 ... [root@node4 ~]# crontab -e */10 * * * * /usr/sbin/ntpdate 202.120.2.101 [root@node5 ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.30.10 node1 192.168.30.20 node2 192.168.30.13 node3 192.168.30.14 node4 192.168.30.15 node5 [root@node5 ~]# ssh-keygen -t rsa ... [root@node5 ~]# ssh-copy-id -i .ssh/id_rsa.pub root@node4 ... [root@node5 ~]# ssh root@node4 hostname node4
②提供一个nfs服务器
[root@node3 ~]# mkdir -p /mydata/{data,binlogs} /web [root@node3 ~]# vim /web/index.html hello [root@node3 ~]# ls /mydata binlogs data [root@node3 ~]# useradd -r mysql [root@node3 ~]# id mysql uid=27(mysql) gid=27(mysql) groups=27(mysql) [root@node3 ~]# useradd -r apache [root@node3 ~]# id apache uid=48(apache) gid=48(apache) groups=48(apache) [root@node3 ~]# chown -R mysql.mysql /mydata [root@node3 ~]# setfacl -R -m u:apache:rw- /web [root@node3 ~]# vim /etc/exports /mydata 192.168.30.0/24(rw,no_root_squash) /web 192.168.30.0/24(rw) [root@node3 ~]# service rpcbind status rpcbind (pid 1337) is running... [root@node3 ~]# service nfs start Starting NFS services: [ OK ] Starting NFS quotas: [ OK ] Starting NFS mountd: [ OK ] Starting NFS daemon: [ OK ] Starting RPC idmapd: [ OK ]
③在两个节点上都准备好要做高可用的服务程序
[root@node4 ~]# useradd -u 27 -r mysql [root@node4 ~]# useradd -u 48 -r apache [root@node4 ~]# yum -y install mysql-server httpd ... [root@node4 ~]# chkconfig mysqld off [root@node4 ~]# chkconfig httpd off [root@node4 ~]# vim /etc/my.cnf [mysqld] datadir=/mydata/data socket=/var/lib/mysql/mysql.sock user=mysql log-bin=/mydata/binlogs/mysql-bin innodb_file_per_table=ON # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid [root@node4 ~]# scp /etc/my.cnf root@node5:/etc/ my.cnf 100% 308 0.3KB/s [root@node4 ~]# mkdir /mydata [root@node4 ~]# showmount -e 192.168.30.13 Export list for 192.168.30.13: /web 192.168.30.0/24 /mydata 192.168.30.0/24 [root@node4 ~]# mount -t nfs 192.168.30.13:/mydata /mydata [root@node4 ~]# service mysqld start Initializing MySQL database: Installing MySQL system tables... OK Filling help tables... OK [root@node4 ~]# cd /mydata [root@node4 mydata]# ls binlogs data [root@node4 mydata]# ls data ibdata1 ib_logfile0 ib_logfile1 mysql test [root@node4 mydata]# ls binlogs mysql-bin.000001 mysql-bin.000002 mysql-bin.000003 mysql-bin.index [root@node4 mydata]# cd [root@node4 ~]# service mysqld stop Stopping mysqld: [ OK ] [root@node4 ~]# umount /mydata
另一节点执行类似步骤,只是不需要再次执行mysql初始化
⑶在每个节点上安装实现高可用功能的程序
本例中安装heartbeat v2,v2兼容v1,可使用haresources作为配置接口。
说明:heartbeat-pils不要使用yum安装,否则会被自动更新成cluter-glue,而cluster-glue跟heartbeat v2不兼容
原文地址:http://9124573.blog.51cto.com/9114573/1763636