Linux高可用解决方案
高可用(High Availability)是Linux集群三个概念中的其中一个,其他两个分别是高性能(High Performance)和负载均衡(Load Balancing)。简单来说,高可用的目的是为了让企业能够提供持续稳定的服务。
高可用的原理是多个节点之间(通常是2个)互相发送检测信号,一旦任意一方发现对端已经离线,则自动接管对方来提供服务。
HA包含两个关键的内容:
- 一个是集群成员管理,成员一般指的是系统节点,例如一台服务器
- 另一个是集群中的资源管理,资源通常是对外提供的服务,例如web服务(httpd),数据库服务(mysql)等。
针对不同的概念,每一种系统都会提供不同的软件对它们进行配置管理。对于成员管理,Corosync是通用平台解决方案;而基于RHEL平台的还可以使用Cman,Cman在其他非RHEL系的系统不太常用。对于资源管理,有我们熟知的heartbeat,尽管heartbeat如今有种廉颇老矣的感觉,但是它的使用率依然非常高。值得一提的是,centos7中的yum源已经不再提供heartbeat,即只能够通过源码或二进制包安装。作为heartbeat的替代,现在都会使用Pacemaker,它提供了比heartbeat更多的功能。在RHEL6之前,rgmanager(resource group manager)也是一种管理集群资源的手段,不过在RHEL6或之后的系统之中,基本上都被Pacemaker取代。
Linux集群种的相关概念
高可用需要解决的问题基本上有以下几个:
- 是否应该使用共享存储
- 共享存储的多路径访问
- 如何确保集群的网络稳定
- 如何防止split brain(裂脑)
共享存储
资源管理中的重点是数据存储,多台服务器中的数据必须保持一致性,否则,对某些服务来说将是灾难性的后果,问题是,应该采取什么方式去确保数据一致呢?在回答这个问题之前,需要明确我们的数据类型。
基本上来说,可以把这些数据分为三类:
- 静态文件
- 配置文件
- 数据文件(数据库)
静态文件的储存是最简单的,因为它们发布之后就不会被改变,因此静态文件不需要解决一致性问题,我们只需要保证这些文件的安全性即可,例如对静态文件做定期备份。
配置文件在某种程度来说也是动态文件,例如httpd或nginx,mysql等配置文件。当集群中的其中一个节点宕机之后,在节点切换的时候就必须保证程序的行为是一致的,因此,多台集群节点的配置文件必须一致。
数据文件就不用说了,如何实现数据库一致性的相关讨论在网络上已经有太多了,因此数据库的一致性是重中之重。
NAS还是SAN?大多数情况下,我们选择SAN,虽然前者搭建简单,维护方便,但是SAN比NAS更加灵活可靠,而且SAN性能更好。不过在使用SAN之前,我们还是有个问题需要考虑的,SAN可以通过两种方式传输数据,分别是Fibre Channel和iSCSI,前者通过光纤通道进行传输,提供高速的传输性能,但缺点是价格昂贵;后者通过网络协议传输,因此,我们可以通过Linux系统创建自己SAN,使得成本更加低,而且,配合高速以太网,它的传输速度也可以得到保证。
共享存储的多路冗余
传统的本地硬盘或者是基于fibre channel的SAN都是一条线缆对应一个存储设备(硬盘),但基于网络的SAN情况稍微有点不一样,服务器一般都会有多个网卡,那么一个LUN设备就可以通过不同的IP地址访问,当集群节点挂载SAN的时候,通过不同的IP地址,即使是相同的LUN都会被认为是不同的存储设备,因此,我们需要通过multipath解决这个问题。
另外,多路径技术还提供一些优势:
- 故障的切换和恢复
-
流量的负载均衡
集群网络布局
由于活性检测是通过互相发送心跳包来完成的,因此,心跳包发送的线路最好独立出来,避免和对外提供的服务的网络混合使用,使得活性检测更加准确。另外,心跳线最好通过串口线连接,其次是网线,而且网线最好是直接连接在两台节点的网卡上面,可以避免其他设备的影响。
除此之外,集群网络最好连接多个网络,其中一个好处是负载均衡,另一个好处是在其中一条线路失效的情况下依然可以正常提供服务。
防止集群裂脑
一旦集群出现split brain,数据的一致性就很难得到保证,因此必须尽最大努力去防止这种情况出现。
一般可以通过两种手段防止裂脑
- Fencing/STONITH(shoot the other node in the head)
- Quorum
手段1比较直接,就是把集群中无响应的一个节点隔离,可以是关机,也可以是断网,反正就是使它无法向外提供服务。STONITH通常由特定的硬件提供支持,例如HP ILO,DELL DRAC和IBM的RSA等。
手段2也叫做仲裁,也就是通过投票决定哪一个节点提供服务,票数多者胜出。
高可用软件(software stack)
常见的高可用软件有heartbeat、corosync、pacemaker等,heartbeat和corosync都属于Messaging Layer,负责集群节点的通讯管理。而pacemaker则用于管理集群节点中的资源。在较早前的版本中,pacemaker是heartbeat的一部分,后来从这个项目中被分离出来。pacemaker可以配合heartbeat或corosync一起使用。
heartbeat简介
heartbeat主要负责检测节点间的通讯是否正常,一旦任何一方认为对端已经离线,那么就会马上接管对方提供服务。需要注意的是,heartbeat只监控是硬件级别的,即只要节点没有掉线,即使软件服务(http,mysql等)已经停止,heartbeat都认为节点正常。如果需要监控软件的状态,则需要介入其他手段。
可以通过以下4中方式发送心跳包
- 单播
- 组播/多播
- 广播
- 串口
为了避免其他设备的干扰,例如交换机,路由器等,节点间的连接最好采用网卡直连的方式。一般来说,heartbeat的结构如下:
正常情况下,左边的节点提供服务,右边的节点处于待命状态,如果节点1掉线或者宕机了,那么节点2就会启动相关的服务并接管节点1的工作,整个过程外界不会察觉,始终认为是同一台服务器提供服务。
heartbeat通常都会把管理ip和提供服务的ip区分开,这样管理起来会更加方便。上图使用了虚拟网卡eth1:0
作为服务网卡。
安装heartbeat
实验环境为vmware安装centos6,两个节点ip分别是192.168.88.237
和192.168.88.238
。由于是虚拟机,我们只使用eth0和eth0:0作为管理ip和服务ip。首先两个节点都安装好heartbeat。
1 2 |
[root@centos6-host1 ~]# yum install -y heartbeat |
heartbeat需要3个配置文件,它们是:
- authkeys
- ha.cf
- haresources
需要把它们放到/etc/ha.d/
目录中,这三个文件可以在/usr/share/doc/heartbeat-3.0.4/
目录中找到。authkeys用于配置节点的授权方式,它的权限必须是600。ha.cf是heartbeat的配置文件,haresources则是资源配置文件。
配置heartbeat
- 配置hostname和hosts文件
两个节点都要配置ip域名映射和hostname,首先配置hosts文件
1234## vim /etc/hosts192.168.88.237 centos6-host1192.168.88.238 centos6-host2然后就要设置节点hostname,主节点是centos6-host1,备节点是centos6-host2
1234## vim /etc/sysconfig/networkNETWORKING=yesHOSTNAME=centos6-host1配置好后可以使用
hostname
命令或者uname -n
命令查看。 -
配置authkeys
authkeys里面的内容最少,也是最简单的,根据自己的需要选择授权方式即可,这里选择使用crc方式。
1234567### vim /etc/ha.d/authkeysauth 11 crc#2 sha1 HI!#3 md5 Hello!由于默认authkeys的权限不是600,因此记得更正文件的权限
1234[root@centos6-host1 ha.d]# chmod 0600 authkeys[root@centos6-host1 ha.d]# ls -l authkeys-rw-------. 1 root root 643 Jul 3 06:30 authkeys - 配置ha.cf
这个配置文件虽然看上去内容很多,但其实大部分都是注释,只需要简单的配置就可以让heartbeat工作。
1234567891011121314[root@centos6-host1 ha.d]# grep -v ^# ha.cfdebugfile /var/log/ha-debug #调试输出信息文件logfile /var/log/ha-log #日志文件logfacility local0keepalive 2 #心跳包发送间隔deadtime 30 #30秒检测不到对端认为对端已离线warntime 10 #当对端离线10秒后发出警告initdead 60 #系统重启过度时间udpport 694bcast eth0 #心跳包发送方式和路径auto_failback on #主节点恢复正常自动重新接管node centos6-host1 #添加集群节点node centos6-host2 #添加集群节点 - 配置haresources
haresources用于配置集群资源,这些资源通常是可执行脚本,在
/etc/ha.d/resource.d
目录中可以找到,用于管理节点提供的服务。1234[root@centos6-host1 ha.d]# ls resource.d/apache db2 drbddisk Filesystem ICP IPaddr IPsrcaddr LinuxSCSI MailTo portblock SendArp WAS XinetdAudibleAlarm Delay drbdupper hto-mapfuncs ids IPaddr2 IPv6addr LVM OCF Raid1 ServeRAID WinPopupharesources中的资源格式如下:
12345##节点域名 节点对外的服务ip 节点对外提供的服务centos6-host1 IPaddr::192.168.88.111/24/eth0:0 nginx#也可以把IPaddr去掉,简单写为centos6-host1 192.168.88.111/24/eth0:0 nginx这里的节点域名是centos6-host1,表示centos6-host1为集群的主节点,当客户端访问192.168.88.111的时候,访问的节点都是centos6-host1。
节点1配置好后,需要把这三个文件文件复制到节点2上面可以使用scp命令复制过去
12[root@centos6-host1 ha.d]# scp authkeys ha.cf haresources root@centos6-host2:/etc/ha.d/
启动heartbeat
在启动之前,有两件事要做
- 安装nginx用于测试效果,两个节点的nginx设置不同的首页,这样方便观察。
- 关闭iptables,防止裂脑。如果不希望关闭iptables,则可以把udp 694添加到防火墙白名单
一切准备就绪后,就可以启动heartbeat。当heartbeat启动后,可以看到eth0:0虚拟网卡被启动了,这个网卡并不是我们手动添加的,而是在haresources文件配置,由heartbeat创建。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
[root@centos6-host1 ha.d]# ifconfig eth0 Link encap:Ethernet HWaddr 00:0C:29:30:65:42 inet addr:192.168.88.237 Bcast:192.168.88.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:fe30:6542/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:807939 errors:0 dropped:0 overruns:0 frame:0 TX packets:5482676 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:141174815 (134.6 MiB) TX bytes:8214096402 (7.6 GiB) eth0:0 Link encap:Ethernet HWaddr 00:0C:29:30:65:42 inet addr:192.168.88.111 Bcast:192.168.88.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 b) TX bytes:0 (0.0 b) |
如果eth0:0正常创建出来,那么说明heartbeat开始工作了,但并没有说明两台节点没有出现裂脑,因此需要到节点2检查是否有eth0:0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
[root@centos6-host2 ~]# ifconfig eth0 Link encap:Ethernet HWaddr 00:0C:29:FF:2F:E9 inet addr:192.168.88.238 Bcast:192.168.88.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:feff:2fe9/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:5490217 errors:0 dropped:0 overruns:0 frame:0 TX packets:787508 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:8244783549 (7.6 GiB) TX bytes:109860373 (104.7 MiB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 b) TX bytes:0 (0.0 b) |
当节点1出现故障,节点2就会主动创建eth0:0并设置它的ip地址为192.168.88.111,这些都是根据配置文件haresources来处理的,节点切换的同时,备节点没有启动的服务也会一起被启动,这里是nginx。
DRBD简介
DRBD类似于raid 1,不同的是,raid 1是数据双向同步写入,而DRBD是先写入一个磁盘,然后通过网络把数据传输到网络另一端的DRBD磁盘,因此DRBD的实时性比raid 1略差。简单来说,DRBD用于同步网络上两个磁盘的数据,也可以说是数据的复制(replication)。比起SAN解决方案,DRBD显得既廉价,但也可以保证数据安全。
DRBD处于文件系统以下的工作层,因此它是和文件系统无关的,以block的方式复制数据。
DRBD的工作模式
DRBD的数据复制模式有三种,分别是A、B、和C模式
- A 异步复制 当数据写入到本地磁盘后就认为工作流程已经完成
- B 半同步复制 数据写入到本地磁盘和数据发送到对端就认为工作已完成,但对端数据未被写入磁盘
- C 同步复制 当两端数据都被写入磁盘才认为工作完成
通常都是采用同步复制的工作模式
DRBD存储设备
DRBD支持(但不限于)以下几种设备的数据复制
- 硬盘分区或整个硬盘
- 软件RAID设备
- LVM设备
DRBD meta-data
meta-data即元数据,用于保存DRBD磁盘的一些数据资料,例如
- DRBD设备的大小
- 设备ID
- 活动日志
- 同步状态图(quick-sync bitmap),用于追踪设备的同步状态
可以通过两种方式保存元数据
- internal方式,即和普通数据使用同一个磁盘
好处是当有磁盘失效,元数据可以和普通数据一起被还原,不需要额外的工作
坏处是会影响性能,因为普通数据写入后,接着就会更新元数据,也就是说,会造成两次磁盘写操作
-
external方式,配置的时候指定一个额外的设备保存元数据
好处是普通数据和元数据分开保存,元数据的写入不会影响数据盘的性能
坏处是管理麻烦
安装DRBD
centos默认仓库不提供DRBD,因此我们要先添加ELREPO仓库。
其他域名配置等不再描述,和前面配置heartbeat一样。
1 2 3 4 5 6 7 |
## 先导入public key rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org ## 针对centos6的仓库 rpm -Uvh http://www.elrepo.org/elrepo-release-6-8.el6.elrepo.noarch.rpm ## 针对centos7的仓库 rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm |
仓库安装完后就可以安装DRBD
1 2 3 4 5 6 7 8 9 10 11 12 |
[root@centos6-host1 ~]# yum search drbd Loaded plugins: fastestmirror, security Loading mirror speeds from cached hostfile ................. ................. ============================================================ N/S Matched: drbd ================================ drbd83-utils.x86_64 : Management utilities for DRBD drbd84-utils.x86_64 : Management utilities for DRBD drbdlinks.noarch : Program for managing links into a DRBD shared partition kmod-drbd83.x86_64 : drbd83 kernel module(s) kmod-drbd84.x86_64 : drbd84 kernel module(s) |
根据需要选择版本安装,我们选择的是drbd84,因此需要安装drbd84-utils
和kmod-drbd84
两个包
1 2 |
[root@centos6-host1 ~]# yum install -y drbd84-utils kmod-drbd84 |
配置DRBD
drbd提供了两个配置文件,分别是drbd.conf
和global_common.conf
,drbd.conf的内容如下:
1 2 3 |
include "drbd.d/global_common.conf"; include "drbd.d/*.res"; |
可以看到,它的作用就是导入/etc/drbd.d/
目录下面的global_common.conf
文件和扩展名为res
的文件。当然我们可以把所有配置都写入到drbd.conf文件中,但这样做以后管理起来会比较麻烦。
drbd.conf文件格式
drbd.conf由一个或多个section组成,每一个section可以包括多个参数,这些参数包含在或括号{}
里面,例如
1 2 3 4 5 |
section [name] { parameter1 value1; parameter2 value2; } |
section也可以嵌套另一个section。
常用的section
- global 用于配置一些全局参数,目前只有4个参数可用,详细参考
man drbd.conf
- common common中的参数可被子section继承
- resource 用于定义drbd资源
- on 定义指定主机资源
- disk 用于对drbd储存设备进行微调
常用的parameter
- protocol 指定复制模式
- device 指定drbd的逻辑设备
- disk 指定drbd的实际储存设备
- address 资源的主机地址
- meta-disk 元数据保存类型(internal/external)
逻辑设备
drbd的所有操作基本上都是针对/dev/drbd*设备,逻辑设备会和物理设备进行关联,例如最终挂载的设备也是逻辑设备
1 2 |
# mount /dev/sdb1 /data |
准备测试环境
- 两个虚拟机分别是centos6-host1和centos6-host2
- 虚拟机IP地址分别是:192.168.88.237和192.168.88.238
- 两个虚拟机的数据盘都是/dev/sdb1
- 使用逻辑磁盘/dev/drbd1进行通讯
DRBD规定逻辑设备名称必须以drbd开头,即只能是/dev/drbd*。
注意以下步骤如果没有特别提出,则表示两个节点都需要操作
创建/dev/sdb1分区
两个节点上都需要这个步骤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
[root@centos6-host1 ~]# fdisk /dev/sdb WARNING: DOS-compatible mode is deprecated. It's strongly recommended to switch off the mode (command 'c') and change display units to sectors (command 'u'). Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 1 First cylinder (1-261, default 1): Using default value 1 Last cylinder, +cylinders or +size{K,M,G} (1-261, default 261): Using default value 261 Command (m for help): w |
编写资源文件
资源文件以res扩展名结尾,位于/etc/drbd.d/
目录下面,资源文件需要我们自己创建,会被drbd.conf自动包含。
r0.res文件内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
resource r0{ #r0是资源名称 protocol C; #实时同步 on centos6-host1 { #centos6-host1上的资源 device /dev/drbd1; #逻辑设备,必须以drbd开头,由drbd创建 disk /dev/sdb1; #实际数据储存设备 address 192.168.88.237:7789; #本机IP地址 meta-disk internal; #元数据和普通数据保存在同一设备 } on centos6-host2 { device /dev/drbd1; disk /dev/sdb1; address 192.168.88.238:7789; meta-disk internal; } } |
一个可以让drbd正常工作的资源文件就准备好了,global_common.conf
目前还没有修改任何东西。
写入元数据到设备
sdb1设备和资源文件准备好后, 接下来就是把元数据(meta-data)写入到磁盘中去,可以通过drbdadm命令操作
1 2 3 4 5 6 |
[root@centos6-host1 ~]# drbdadm create-md r0 initializing activity log NOT initializing bitmap Writing meta data... New drbd meta data block successfully created. |
看到successfully created 就表示元数据写入成功。
启动资源
同样使用drbdadm命令启动资源
1 2 |
[root@centos6-host1 ~]# drbdadm up r0 |
没有错误表示资源已经启动。但这个时候两个节点都是从节点,在初始状态,两个从节点是不会进行数据同步的
1 2 3 |
[root@centos6-host1 ~]# drbdadm role r0 #查询节点状态 Secondary/Secondary #两个都是从节点 |
设置主节点
使用drbdadm设置其中一个为主(primary)节点
1 2 |
[root@centos6-host1 ~]# drbdadm primary --force r0 |
没有错误则表示设置成功,可以通过下面的命令看到数据开始同步
1 2 3 4 5 6 7 8 9 |
[root@centos6-host1 ~]# watch cat /proc/drbd version: 8.4.9-1 (api:1/proto:86-101) GIT-hash: 9976da086367a2476503ef7f6b13d4567327a280 build by mockbuild@Build64R6, 2016-12-13 18:38:15 1: cs:SyncTarget ro:Primary/Secondary ds:Inconsistent/UpToDate C r----- ns:0 nr:1120 dw:1120 dr:0 al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:2095228 [>....................] sync'ed: 0.2% (2095228/2096348)K finish: 0:29:06 speed: 1,120 (1,120) want: 1,280 K/sec |
创建文件系统
只有创建完文件系统之后,我们才能使用这些硬盘空间,文件系统的创建在主节点进行,从节点不需要这个步骤
1 2 3 |
[root@centos6-host1 ~]# mkfs.ext4 /dev/sdb1 [root@centos6-host1 ~]# mount /dev/sdb1 /mnt #挂载设备到/mnt目录 |
故障处理
这里的故障指的是任意一个节点由于硬盘损坏或其他问题需要更换的情况。
处理起来也是非常简单
- 更换硬盘后重新创建分区
- 重新写入元数据
- 启动资源
下面假设primary硬盘损坏
1 2 3 4 |
#省略新硬盘创建分区过程,假设已经重新建立sdb1分区 drbdadm create-md r0 drbdadm up r0 |
通过这些步骤之后,drbd会自动识别设备的大小,把数据从数据多的硬盘复制到数据小的硬盘。
heartbeat配合drbd实现高可用
drbd提供了一些脚本来配合heartbeat实现高可用,例如drbddisk
脚本,该脚本在/etc/ha.d/resource.d/
目录下面。
在haresources文件中添加drbd资源
1 2 3 |
centos6-host1 IPaddr::192.168.88.111/24/eth0:0 nginx \ drbddisk::r0 Filesystem::/dev/drbd1::/mnt::ext4 |
haresources添加了两个资源,分别是nginx和drbd,当主节点宕机,从节点就会自动提供服务,从节点的drbd就会被提升为primary节点(由drbddisk脚本实现);并且把/dev/drbd1挂载到/mnt目录下面(由Filesystem脚本实现)。
转载请注明:Pure nonsense » Heartbeat和drbd实现高可用