要充分利用公有云的弹性扩展和高可用, 首先要在应用系统层面支持横向扩展(scale out),这个说起来很容易,或者说对新开发的应用系统而言已经成为标配。但是对已有的、老旧的应用系统来说,这就比较困难了,不是每个应用系统都能实现/支持横向扩展的。从客户的角度来说,基本上很难接受为了把应用系统迁移到公有云上而去额外投入修改应用系统代码。虽然我们都心知肚明,本质上这是在“偿还技术债”,修改应用系统代码也是为了更好地利用公有云的优势...
对于应用系统的横向扩展而言,“状态”是最大的拦路虎,要支持横向扩展,首先要实现stateless。最常见的“状态”就是web应用中的session。此外还有一些tcp通讯,socket通讯之类的应用也是需要“有状态”的。还有一些商业软件这样那样的限制,总是就是不允许、也不能通过同时运行多个应用程序实例来实现横向扩展和高可用。
上述现状直接导致的后果就是:客户将应用系统迁移到公有云上之后,却完全体验不到公有云应有的优势,和本地部署没有任何区别,甚至还不如本地部署方便、划算。
在传统的IT环境(on-premises)中,Linux Server有很多成熟的高可用方案,例如:LVS,Heartbeat,Keepalived...但这些方案都需要一个虚拟的IP地址来对外提供服务。在公有云上,无论是公网IP地址还是内网IP地址,都是被统一管理和分配的,凭空冒出来的一个IP地址是不会被识别和使用的。所以用户千万不要在虚拟机里面随便修改网卡的IP地址,以免造成虚拟机无法连接。
Azure的Loadbalancer有一个“Direct Server Return”选项,新版的Portal中改名为:“EnableFloatingIP”。
一直以来,官方文档中只是说这个选项只有在做SQL Server Always-on集群的时候才需要。其实DSR并非是Azure Loadbalancer专属的一个属性,这个概念在硬件负载均衡设备中很常见。我们来看一段关于DSR的介绍:
Direct Routing aka. Direct Server Return (DSR) is a great load balancing method, the idea being that incoming traffic comes into the Virtual IP (VIP) on the load balancer.
Then all the load balancer does is change the destination MAC address of the packet (to one of the destination real servers in the pool) and flips it back to the switch which duefully delivers the packets to the selected real server.
这个DSR就可以支持我们需要的虚拟IP地址!无论是自动还是手工分配给启用了DSR的Loadbalancer的IP地址,都相当于设置了一个虚拟IP地址,这个IP地址可以根据需要附加到位于Loadbalancer之后的虚拟机上。通过这个虚拟IP地址过来的请求会直接到达在Loadbalancer后面的、绑定了虚拟IP地址的虚拟机。
基本原理就是这样了,原来我们一直都忽略了Azure的一个独门秘笈,目前我暂时还没有发现其他的公有云提供DSR支持!
下面我们使用CentOS 6.7镜像创建两个虚拟机,在Azure中国版上配置一个Linux Server故障转移集群。
前置准备工作:
1、把两个虚拟机放在同一个云服务中,而且必须使用standard类型的虚拟机。
2、为虚拟机分配固定的内网IP地址(DIP)和公网IP地址(Reserved VIP)。
3、创建一个新的负载均衡端点并启用DSR。
安装keepalived:
不要直接使用yum里面的Keepalived,那个版本太低,不能支持单播。还有就是一定要彻底关闭SELINUX(这个家伙到哪都不讨人喜欢)。
wget http://www.keepalived.org/software/keepalived-1.2.20.tar.gz sudo yum install make gcc openssl-devel tar xvf keepalived-1.2.20.tar.gz cd keepalived-1.2.20 ./configure --prefix=/usr/local/keepalived sudo make install sudo cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/rc.d/init.d/ sudo cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/ sudo cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
配置Keepalived:
#创建配置文件目录 mkdir /etc/keepalived #创建配置文件 sudo vim keepalived.conf #创建动作脚本 sudo vim keepalived-action.sh #创建服务检查脚本 sudo vim keepalived-check-appsvc.sh #给上述三个文件添加读取权限(chmod +r)
配置文件内容: keepalived-check-appsvc.sh -------------------------------- #!/bin/bash exit 0 #这个脚本用于检查本机的服务或者进程的运行状态。为了简化演示过程,我们临时让这个文件返回状态码“0”,即代表本地服务或者进程的运行状态是正常的。 #在生产环境中,必须根据实际的业务需求对服务或进程的健康状态进行检查。 #返回非“0”表示检查失败,会触发故障转移。 #如果主机(MASTER)重启或者操作系统崩溃,也会触发故障转移,即:BACKUP提升为MASTER。 #因此,这里我们直接返回“0”,若主机(MASTER)重启或者操作系统崩溃,依然可以触发故障转移动作。 keepalived-action.sh -------------------------------- #!/bin/bash TYPE=$1 NAME=$2 STATE=$3 case $STATE in "MASTER") service httpd start exit 0 ;; "BACKUP"|"STOP") exit 0 ;; "FAULT") exit 0 ;; *) exit 1 ;; esac #当某个服务器成为MASTER的时候,启动httpd服务。(本例中我们用Apache服务进行演示) keepalived.conf -- 主机(MASTER) ------------------------------- vrrp_script chk_appsvc { script /etc/keepalived/keepalived-check-appsvc.sh interval 1 fall 2 rise 2 } vrrp_instance VI_1 { interface eth0 authentication { auth_type PASS auth_pass secr3t } virtual_router_id 51 virtual_ipaddress { 42.159.241.126 #Azure Loadbalancer的公网IP地址(VIP) } track_script { chk_appsvc } state MASTER priority 101 unicast_src_ip 10.11.12.4 #本机地址,Azure虚拟机的内网IP地址(DIP) unicast_peer { 10.11.12.5 #对端地址,Azure虚拟机的内网IP地址(DIP) } notify /etc/keepalived/keepalived-action.sh }
keepalived.conf -- 备机(BACKUP) ------------------------------- vrrp_script chk_appsvc { script /etc/keepalived/keepalived-check-appsvc.sh interval 1 fall 2 rise 2 } vrrp_instance VI_1 { interface eth0 authentication { auth_type PASS auth_pass secr3t } virtual_router_id 51 virtual_ipaddress { 42.159.241.126 #Azure Loadbalancer的公网IP地址(VIP) } track_script { chk_appsvc } state BACKUP priority 100 unicast_src_ip 10.11.12.5 #本机地址,Azure虚拟机的内网IP地址(DIP) unicast_peer { 10.11.12.4 #对端地址,Azure虚拟机的内网IP地址(DIP) } notify /etc/keepalived/keepalived-action.sh }
除了keepalived.conf文件之外,其他的操作和配置文件在两个服务器上(MASTER和BACKUP)都是一样的。
最后一项设置是修改Linux操作系统的一个网络配置
vim /etc/sysctl.conf #在末尾追加一行:net.ipv4.ip_nonlocal_bind=1 #保存后使更改生效 sudo sysctl -p
因为本例中使用Apache来作为故障转移演示,因此我们需要同时在两个服务器上安装Apache服务,并修改Apache的Listen端口与Azure Loadbalancer端口保持一致。
sudo yum install httpd sudo vim /etc/httpd/conf/httpd.conf
Apache安装配置完成后,先不要启动服务,因为即便启动Apache服务,也没法通过Azure Loadbalancer访问到,原因就是Azure Loadbalancer已经启用了DSR,而在Azure Loadbalancer之后的虚拟机上却没有绑定相应的虚拟机IP地址。
至此,所有的配置都已经完成了。我们来测试一下效果:
在MASTER上启动Keepalived服务,随后使用:"ps -el | grep httpd"命令可以看到Apache服务已经启动了。这时通过Azure Loadbalancer的公网IP地址就能访问到MASTER上的web界面了。虚拟IP地址已经成功的绑定到MASTER上,并且已经生效。
sudo service keepalived start
在MASTER上执行重启命令:“sudo reboot”,模拟MASTER故障。然后到BACKUP上执行"ps -el | grep httpd",可以看到BACKUP上的Apache已经被启动了。这时依然可以通过Azure Loadbalancer的公网IP地址访问到web页面,但此时访问到的web页面已经是由BACKUP在提供服务了。因为MASTER重启后,位于MASTER上的Apache并没有被随之启动。
在Azure上使用Keepalived创建Linux Server故障转移集群已经成功!
不过这仅仅是一个开始,在正式的生产环境中,还有很多需要调整和优化的配置。特别是服务状态检测脚本(track script)和故障转移动作脚本(notify script),有很大的发挥和想象空间,例如:我们可以在脚本中通过调用Azure CLI来动态创建或者销毁Azure资源...
BTW:Windows Server Failover Cluster其实也是通过虚拟IP对外提供服务的,因此在Azure上也同样可以部署WSFC,这样在Azure上部署类似SAP ECC的应用就可以实现高可用了。