1.部署架构
比较典型的SAP应用是搭建在小型机UNIX系统上的,小型机都有厂家提供的HA软件,比如IBM的PowerHA。这样的方案也是被SAP认证通过的。目前,SUSE LINUX也是被SAP认证通过的,但是在云上,尤其是HA的方案,还没有完全成型,本文档重点探索的就是如何在阿里云ECS Linux环境搭建一套可行的HA方案提供给SAP系统使用。
我们以SAP AFS(Apprarel and Footwear Solution),即SAP在服装鞋帽行业的解决方案为例,来搭建在阿里云ECS上的HA。
上图中是SAP实例的官方部署建议图,基础软件环境的安装和部署情况:
阿里云SUSE Linux 11 SP3 + SAP ECC 6.0 EHP6 + SAP NetWeaver 7.3.1 + Sybase 15.7。
上面的架构图中没有体现DB,我们必须把DB也考虑进来。同时,根据SAP应用的特点,我们在部署上也做了一些改变,最重要的就是将SAPSID部署在了一个能多节点同时挂载和读写的存储上,避免了在两个节点做切换的过程,提升系统的可用性。
节点A部署的有:阿里云SUSE Linux + ASCS + SAP primary Application Server;
节点B部署的有:阿里云SUSE Linux + DB + SAP Secondary Application Server。
在这个架构中,application Server在ASCS后端,ASCS提供客户端的统一访问,然后分发到后端的application Server。所以,我们发现整个架构存在2个单点,一个是DB,一个是ASCS。HA的目标就是解决这两个单点,在发生故障时能够进行切换,保证系统整体的高可用性。
2. 方案评估
我们在两个方案上做了评估和选择,一个方案是与SUSE Linux配合紧密的HAE(High Availability Extension),另一个是开源的keepalived。
2.1 HAE介绍
HAE的层次结构主要有:信息交换/基础结构、资源分配和资源层。第一层和第二层基本是HAE自己控制和管理的,主要用来协调基础信息,集群配置,控制上层资源等。对用户来说,可以配置最多的一层在最上层,即资源代理(resource agent)。资源代理是已写入的用来启动、停止和监视某种服务(资源)的程序(通常是外壳脚本)。资源代理仅由 LRM 调用。第三方可将他们自己的代理放在文件系统中定义的位置,这样就为各自的软件提供了现成群集集成。目前,HAE已经集成了适用于市面上大多数主流应用和软件的资源代理,包括mysql、lvm、oracle等,包括SAPDatabase和SAPInstance也是已经包装好的资源代理。
经测试,SAPDatabase可以正常管理本测试中用到的sybase 15.7,但是SAPInstance代理由于我们的部署架构将一个实例在两个节点进行了拆分,所以无法被管理。在尝试完全重写对ASCS的资源代理时,由于对ASCS的原理理解不够深入,在规定的时间内没能调整好脚本到预期的状态,所以最终暂时放弃了HAE方案。
理论上说,HAE是比较成熟的商业软件,提供图形化的配置运维管理界面,降低了对客户的技术要求,而且还有软件厂家的售后服务。如果可能,还是会建议客户首选HAE。
2.2 Keepalived介绍
Keepalived 是一个基于VRRP协议来实现的LVS服务高可用方案,可以利用其来避免单点故障。一个LVS服务会有多台服务器运行Keepalived,一台为主服务器(MASTER),其他为备份服务器(BACKUP),这些服务器是通过优先级来选举出来最高优先级的那个节点为主服务器的。这些节点对外表现为一个虚拟IP,主服务器会发送特定的消息给备份服务器,当备份服务器收不到这个消息的时候,即主服务器宕机的时候, 备份服务器就会接管虚拟IP,继续提供服务,从而保证了高可用性。
在实际测试过程中,发现keepalived的配置,尤其是对脚本的控制比较简单直接,容易理解,也好上手,最终也及时地完成了测试和客户需求。所以我们以keepalived为例来说明在阿里云上如何配置对SAP的HA。
3. 实施过程
所有的HA都要满足以下几点,在阿里云上实现也不能例外:
n VIP:为需要做高可用保证的应用服务提供统一的对外IP,能在集群中节点进行漂移和切换;
n 共享存储,上面部署共享的数据,提供在主节点down掉后,备节点可以挂载的可能性;
n 异常/故障状态下的处理机制实现。
我们在下面的实施步骤中重点说明和解决这几个问题,我们会创建两个VRRP_INSTANCE,分别管理DB和ASCS。
3.1 VIP的创建
阿里云提供一款叫HaVIP的产品,可以帮助客户在指定的VPC网络内创建最多5个能够在该CIDR网段内没有被占用的VIP。客户可以通过提工单的形式申请HAVIP,申请成功后,在VPC的配置界面将出来一个新的菜单:“高可用虚拟IP”。
根据提示选择交换机,创建2个IP,一个IP是172.16.32.30,这个是DB的VIP;一个IP是172.16.32.40,这是ASCS的VIP。这两个IP创建出来先预留,不要使用。
如果您很不幸没有申请到havip,也不要沮丧,还有一款开源软件:n2n VPN可以解决云上的虚拟网卡和多IP的问题。可以移步这个地址来参考实现:http://blog.csdn.net/yetyongjin/article/details/7419894。
3.2 共享存储
阿里云在2017年4月即将推出共享的块存储,即SSD云盘。在正式推出前,我们在阿里云上暂时只能使用开源的iscsi来实现共享。在安装配置共享存储前,我们需要熟悉一下iscsi的相关概念,比如iscsi-target和iscsi-initiator,在我们的规划中,我们使用了4台target,每台target上挂载一个800GB的SSD云盘。配置HA的2个节点自然就是iscsi-initiator了。
目前主流的linux发行版都已经自带了iscsi,阿里云上的suse linux、centOS也不例外,安装一下就好了。
在SUSE Linux 11SP3的版本中,配置iscsi-target的步骤:
(1) 打开yast,选择Network-Service-iSCSI Target,系统会提示没有安装,选择安装,稍等一会儿就安装好了;
(2) 安装完后,就可以退出yast了,如果继续用yast来做配置,会发现后面共享出去的磁盘是没有办法被识别的;
(3) 此时,需要编辑一下/etc/ietd.conf文件,这个文件的格式大约是:
Target iqn.2017-03.com.example:05261bd3-258a-4baa-935f-1700be499e44 Lun 0 Path=/dev/vdb,Type=blockio |
这里的关键是第二行的Path和Type,Path定义了我们要共享的本地磁盘路径,Type定义了共享磁盘的类型。
(4) 然后就可以执行#service iscsitarget start启动iscsi-target了;
(5) 每个iscsi-target上都做一番这样的配置;
(6) 在两个HA节点上,打开yast,选择Network-Service-iSCSI Initiator,按照提示安装;
(7) 安装完毕,在Conneted Targets界面选择Add添加
(8) 填上iscsi-target的IP地址去发现共享出来的磁盘,参照下图
(9) 然后NEXT,然后再添加,直到把所有的target都添加进来。此时fdisk -l和lsscsi都能看到新挂载的磁盘,保证2个节点都能看到;
(10) 在任意一个节点,使用lvm可以创建vg/lv/fs,将这些资源分配和挂载给需要的节点使用。这里我们创建了两个vg:sapvg和datavg。sapvg存放ASCS数据,挂载了3个目录:/export/sapmnt、/export/usr/sap/trans和/usr/sap/TST/ASCS10,默认在节点1;datavg存放数据库数据,挂载了1个目录:/sybase,默认在节点2。
3.3 NAS
NAS还要求能给两个节点提供一个可以同时挂载并发读写的2个文件系统,最初使用的NFS,将一个节点的本地目录共享给另一个节点,在实际使用中发现当服务节点异常时,使用NFS共享目录的节点会受到很大的影响。比如NFS Server已经挂掉了,那么client节点因为无法正常umount NFS目录会导致涉及到NFS目录的所有操作都长时间hang住。
于是,我们更换了一个方案,将阿里云的NAS引入了方案中。实践发现,NAS作为性能要求不高的共享文件系统是十分合适的,也非常稳定。
所以,两个节点都挂载了2个NAS文件系统:
112f4483d9-byb70.cn-beijing.nas.aliyuncs.com:/ /sapmnt
1f8dc4b72a-yaq0.cn-beijing.nas.aliyuncs.com:/ /usr/sap/trans
3.4 部署SAP
这部分不是本文的重点,按照第一章的设计将SAP AFS部署好即可。前提是先把HAVIP对应的存储资源、NAS共享文件系统都准备好。
3.5 部署HA
(1)下载keepalived
我们希望尽可能下载使用最新版本,但是在实际中发现SUSE 11 SP3和keepalived的兼容性还是存在比较严重的问题的。经过反复测试,我们选用了1.2.20版本。
下载地址:http://www.keepalived.org/download.html
(2)安装keepalived前的准备
zypper -n install gcc gcc-c++ kernel-source make glib* |
可能还需要升级openssl,依然是去网上找openssl 1.1.0e的包,自己make和make install安装。这里可能还有其他的包需要安装,在安装keepalived时会进行检查,如果不通过,就回到这一步来补齐。
(3)安装keepalived
#tar zxvf keepalived-1.2.20.tar.gz #cd keepalived-1.2.20 #./configure --prefix=/usr/local/keepalived #make #make install |
(4)配置keepalived
请注意,keepalived安装完后,会自动生成一个配置文件:/usr/local/keepalived/etc/keepalived/keepalived.conf。修改这个文件是没有意义的,因为keepalived认可的配置文件是:/etc/keepalived/keepalived.conf!!!
在正式进行配置之前,请务必先保证手工执行脚本能完美实现对vrrp实例资源的完整管理和切换,如果手工执行都无法正常运行,那么加上HA自动化后将会有更多不可预知的情况发生!!!
当你已经确定手工执行脚本已经没有任何问题,就可以配置keepalived了。2个节点(afsdev01和afsdev02)都得配置,修改完成后,我们的节点1配置文件长这样子:
! Configuration File for keepalived
global_defs { notification_email { huiyan.hq@alibaba-inc.com } notification_email_from huiyan.hq@alibaba-inc.com smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id afsdev }
vrrp_instance ascs { state MASTER interface eth0 virtual_router_id 20 priority 100 advert_int 1
authentication { auth_type PASS auth_pass 1111 }
virtual_ipaddress { 172.16.32.40/24 dev eth0 label eth0:1 }
# track_script { # check_service_down # }
unicast_src_ip 172.16.32.17 unicast_peer { 172.16.32.18 }
notify_master /root/init_master.sh notify_backup /root/init_backup.sh }
vrrp_instance db { state BACKUP interface eth0 virtual_router_id 30 priority 40 advert_int 1
authentication { auth_type PASS auth_pass 1111 }
virtual_ipaddress { 172.16.32.30/24 dev eth0 label eth0:0 }
# track_script { # check_service_down # }
unicast_src_ip 172.16.32.17 unicast_peer { 172.16.32.18 }
notify_master /root/init_db_master.sh notify_backup /root/init_db_backup.sh } |
节点2配置文件长这样子:
! Configuration File for keepalived
global_defs { notification_email { huiyan.hq@alibaba-inc.com } notification_email_from huiyan.hq@alibaba-inc.com smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id afsdev }
vrrp_instance ascs { state BACKUP interface eth0 virtual_router_id 20 priority 40 advert_int 1
authentication { auth_type PASS auth_pass 1111 }
virtual_ipaddress { 172.16.32.40/24 dev eth0 label eth0:1 }
# track_script { # check_service_down # }
unicast_src_ip 172.16.32.18 unicast_peer { 172.16.32.17 }
notify_master /root/init_master.sh notify_backup /root/init_backup.sh }
vrrp_instance db { state MASTER interface eth0 virtual_router_id 30 priority 100 advert_int 1
authentication { auth_type PASS auth_pass 1111 }
virtual_ipaddress { 172.16.32.30/24 dev eth0 label eth0:0 }
# track_script { # check_service_down # }
unicast_src_ip 172.16.32.18 unicast_peer { 172.16.32.17 }
notify_master /root/init_db_master.sh notify_backup /root/init_db_backup.sh } |
这两个配置文件定义了两个vrrp实例,实例中的节点优先级,VIP资源,实例在成为master时执行的脚本,在成为backup时执行的脚本。
特别提醒一点,正常VRRP协议是要通过组播来实现的,阿里云对ECS网络禁用了组播,所以我们需要使用点对点的模式,即“unicast”方式。
这里我们定义希望master节点选举出来后,就远程到对端把服务下掉,然后在自己的节点启动服务。相应的脚本:
init_master.sh
echo "Now is " `date` >> /tmp/master.log echo "I'm afsdev02, I am the master node now" >> /tmp/master.log timeout 10 ssh afsdev01 /root/sap_stop.sh >> /tmp/master.log timeout 5 ssh afsdev01 umount -f /usr/sap/TST/ASCS10 >> /tmp/master.log timeout 3 ssh afsdev01 umount -f /export/sapmnt >> /tmp/master.log timeout 3 ssh afsdev01 umount -f /export/usr/sap/trans >> /tmp/master.log timeout 3 ssh afsdev01 vgchange -a n sapvg >> /tmp/master.log vgchange -a y sapvg >> /tmp/master.log mount /dev/mapper/sapvg-lvsapmnt /export/sapmnt mount /dev/mapper/sapvg-lvtrans /export/usr/sap/trans mount /dev/mapper/sapvg-lvascs /usr/sap/TST/ASCS10 /root/sap_start.sh >> /tmp/master.log echo "`date` Master is ready!!!" >> /tmp/master.log |
init_db_master.sh
echo "`date`: Receiving command to being master, stop resources on the other node..." timeout 3 ssh afsdev01 ifconfig eth0:0 172.16.32.30/24 up timeout 3 ssh afsdev01 /root/db_stop.sh >> /tmp/master_db.log timeout 3 ssh afsdev01 ifconfig eth0:0 down timeout 3 ssh afsdev01 umount -f /sybase timeout 3 ssh afsdev01 vgchange -a n datavg >> /tmp/master_db.log echo "`date`: I'm master DB node, starting resources..." >> /tmp/master_db.log vgchange -a y datavg >> /tmp/master_db.log mount /dev/mapper/datavg-lv_sybase /sybase /root/db_start.sh >> /tmp/master_db.log echo "`date`: Master DB is online now" >> /tmp/master_db.log |
sap_start.sh
su - tstadm -c "startsap R3 ASCS10 afsdev" |
sap_stop.sh
su - tstadm -c "stopsap R3 ASCS10 afsdev"
kill_process(){ pid=`ps axu | grep -w START_ASCS10_afsdev | grep -v grep | awk '{print $2}'` for i in $pid do kill $i done }
kill_process |
db_start.sh
su - sybtst << EOF cd /sybase/TST/ASE-15_0/install nohup ./startserver -f /sybase/TST/ASE-15_0/install/RUN_TST & nohup ./startserver -f /sybase/TST/ASE-15_0/install/RUN_TST_BS & EOF |
db_stop.sh
su - tstadm -c "stopdb" |
如果希望HA的管理更精细,我们还可以加入track_script,定义一段状态判断的脚本,比如定义每个几秒判断某个进程是否存在,如果存在就返回正常,不存在就返回异常,异常时将该节点的优先级调低多少点,从而导致主节点的优先级低于其他备节点,重新选举出一个新的主节点来,最终实现了instance的切换。
3.6 其他的配合工作
为了能让系统在重启后也能支持SAP实例的正常工作,我们还需要增加一些启动项,比如自动挂载NAS目录,修改一些目录和文件的权限,以免在vg的切换过程中发生异常。
#vi /etc/init.d/after.local,内容:
mount -t nfs -o vers=3,nolock,proto=tcp 112f4483d9-byb70.cn-beijing.nas.aliyuncs.com:/ /sapmnt mount -t nfs -o vers=3,nolock,proto=tcp 1f8dc4b72a-yaq0.cn-beijing.nas.aliyuncs.com:/ /usr/sap/trans chown -R tstadm:sapsys /sapmnt/TST chown -R tstadm:sapsys /usr/sap/trans/EPS chown -R tstadm:sapsys /usr/sap/trans/bin chown -R tstadm:sapsys /usr/sap/trans/buffer chown -R tstadm:sapsys /usr/sap/trans/cofiles chown -R tstadm:sapsys /usr/sap/trans/data chown -R tstadm:sapsys /usr/sap/trans/etc chown -R tstadm:sapsys /usr/sap/trans/log chown -R tstadm:sapsys /usr/sap/trans/sapnames chown -R tstadm:sapsys /usr/sap/trans/storage chown -R tstadm:sapsys /usr/sap/trans/tmp |
3.7 启动keepalived
当确认配置和脚本都没有问题,就可以在两个节点分别启动keepalived了。
执行:# /usr/local/keepalived/sbin/keepalived
会看到有几个进程启动:
#ps -fe|grep keepalived root 4768 1 0 10:18 ? 00:00:00 /usr/local/keepalived/sbin/keepalived root 4769 4768 0 10:18 ? 00:00:00 /usr/local/keepalived/sbin/keepalived root 4770 4768 0 10:18 ? 00:00:01 /usr/local/keepalived/sbin/keepalived root 11411 9870 0 21:00 pts/1 00:00:00 grep keepalived |
然后观察keepalived的日志文件,默认为:/var/log/messages,能看到这样的记录,代表这keepalived启动。
紧接着能看到的提示,这意味着对于VRRP_Instance(db)来说,本节点被选举为主节点,并执行主节点定义的脚本:
然后,需要去脚本定义的日志文件查看,我们所执行的动作是否执行成功。
3.8 测试keepalived
在我们配置的keepalived中,支持两类失败的资源切换:keepalived高可用程序失败和ECS节点失败。
测试过程:
(1) 确认该节点的资源和keepalived运行正常;
(2) 强制shutdown该节点或杀掉keepalived进程;
(3) 观察另外一个节点该原来运行在对端节点的一系列资源接管过来,恢复在短暂中断后自动恢复,切换时间在15秒到120秒不等。这个切换速度与小型机的环境相当;
(4) 重新启动被关闭的节点,重新运行keepalived;
(5) 观察重新启动的节点在数秒内接管回来自己的资源。
如果我们定义了对异常状态的检测,我们可以再加入异常状态的场景测试内容。
同时,由于阿里云ECS底层物理网卡做了bond,加上物理机NC的自动化运维和故障热迁移等都由阿里云负责,所以在云下要考虑的一种场景,即网络或网卡故障的情形是可以不用考虑的。当然,有一种例外,即有人执行了#fconfig eth0 down,这会造成脑裂(brain-split),要解决这种异常,也需要在keepalived的配置中加入另一种track_script,即每隔一段时间ping一下网关地址,如果连续多次没有正常返回,那么就认为自己已经异常,执行一个脚本把自己的keepalived服务和系统的SAP服务一起杀掉,避免脑裂的发生。这些配置都与云下使用keepalived是相同的,不再单独做实现和测试了。