高可用性是指提供在本地系统单个组件故障情况下,能继续访问应用的能力,无论这个故障是业务流程、物理设施、IT软/硬件的故障。最好的可用性, 就是你的一台机器宕机了,但是使用你的服务的用户完全感觉不到。你的机器宕机了,在该机器上运行的服务肯定得做故障切换(failover),切换有两个维度的成本:RTO (Recovery Time Objective)和 RPO(Recovery Point Objective)。RTO 是服务恢复的时间,最佳的情况是 0,这意味着服务立即恢复;最坏是无穷大意味着服务永远恢复不了;RPO 是切换时向前恢复的数据的时间长度,0 意味着使用同步的数据,大于 0 意味着有数据丢失,比如 ” RPO = 1 天“ 意味着恢复时使用一天前的数据,那么一天之内的数据就丢失了。因此,恢复的最佳结果是 RTO = RPO = 0,但是这个太理想,或者要实现的话成本太高,全球估计 Visa 等少数几个公司能实现,或者几乎实现。
对 HA 来说,往往使用共享存储,这样的话,RPO =0 ;同时往往使用 Active/Active (双活集群) HA 模式来使得 RTO 几乎0,如果使用 Active/Passive 模式的 HA 的话,则需要将 RTO 减少到最小限度。HA 的计算公式是[ 1 - (宕机时间)/(宕机时间 + 运行时间)],我们常常用几个 9 表示可用性:
1.1.1 服务的分类
HA 将服务分为两类:
1.1.2 HA 的种类
HA 需要使用冗余的服务器组成集群来运行负载,包括应用和服务。这种冗余性也可以将 HA 分为两类:
1.1.3 云环境的 HA
云环境包括一个广泛的系统,包括硬件基础设施、IaaS层、虚机和应用。以 OpenStack 云为例:
云环境的 HA 将包括:
本文的重点是讨论 OpenStack 作为 IaaS 的 HA。
几个概念:
大体上讲,容灾可以分为3个级别:数据级别、应用级别以及业务级别。
级别 | 定义 | RTO | CTO |
数据级 | 指通过建立异地容灾中心,做数据的远程备份,在灾难发生之后要确保原有的数据不会丢失或者遭到破坏。但在数据级容灾这个级别,发生灾难时应用是会中断的。 在数据级容灾方式下,所建立的异地容灾中心可以简单地把它理解成一个远程的数据备份中心。数据级容灾的恢复时间比较长,但是相比其他容灾级别来讲它的费用比较低,而且构建实施也相对简单。 但是,“数据源是一切关键性业务系统的生命源泉”,因此数据级容灾必不可少。 |
RTO 最长(若干天) ,因为灾难发生时,需要重新部署机器,利用备份数据恢复业务。 | 最低 |
应用级 | 在数据级容灾的基础之上,在备份站点同样构建一套相同的应用系统,通过同步或异步复制技术,这样可以保证关键应用在允许的时间范围内恢复运行,尽可能减少灾难带来的损失,让用户基本感受不到灾难的发生,这样就使系统所提供的服务是完整的、可靠的和安全的。 | RTO 中等(若干小时) | 中等。异地可以搭建一样的系统,或者小些的系统。 |
业务级 | 全业务的灾备,除了必要的 IT 相关技术,还要求具备全部的基础设施。其大部分内容是非IT系统(如电话、办公地点等),当大灾难发生后,原有的办公场所都会受到破坏,除了数据和应用的恢复,更需要一个备份的工作场所能够正常的开展业务。 | RTO 最小(若干分钟或者秒) | 最高 |
两者相互关联,互相补充,互有交叉,同时又有显著的区别:
也可以从别的角度上看待两者的区别:
Master SQL Server 发生故障时,切换到 Standby SQL Server,继续提供数据库服务:
在主机房中心发生灾难时,切换到备份机房(总公司机房中心)上,恢复应用和服务:
OpenStack 部署环境中,各节点可以分为几类:
要实现 OpenStack HA,一个最基本的要求是这些节点都是冗余的。根据每个节点上部署的软件特点和要求,每个节点可以采用不同的 HA 模式。但是,选择 HA 模式有个基本的原则:
OpenStack 官方认为,在满足其 HA 要求的情况下,可以实现 IaaS 的 99.99% HA,但是,这不包括单个客户机的 HA。
云控制节点上运行的服务中,API 服务和内部工作组件都是无状态的,因此很容易就可以实现 A/A HA;这样就要求 Mysql 和 RabbitMQ 也实现 A/A HA,而它们各自都有 A/A 方案。但是,Mysql Gelera 方案要求三台服务器。如果只想用两台服务器的话,则只能实现 A/P HA,或者引入一个 Arbiter 来做 A/A HA。
2.1.1 云控制节点的 A/A HA 方案
该方案至少需要三台服务器。以 RDO 提供的案例为例,它由三台机器搭建成一个 Pacemaker A/A集群,在该集群的每个节点上运行:
从每个 API 服务来看:
关于共享 DB 的几个说明 (主要来自 这篇文章):
(1)根据该文章中的一个调查,被调查的 220 多个用户中,200 个在用 Mysql Galera,20 多个在用单 Mysql,只有一个用 PostgreSQL。
(2)以 Nova 为例,Mysql 使用 Write-intent locks 机制来保证多个连接同时访问数据库中的同一条记录时的互斥。以给新建虚机分配 IP 地址为例,该锁机制保证了一个 IP 不会分给两个用户。
(3)使用 Mysql Galera 时,所有节点都是 Master 节点,都可以接受服务,但是这里有个问题,Mysql Galera 不会复制 Write-intent locks。两个用户可以在不同节点上获取到同一条记录,但是只有一个能够修改成功,另一个会得到一个 Deadlock 错误。对于这种情况,Nova 使用 retry_on_deadlock 机制来重试,比如@oslo_db_api.wrap_db_retry(max_retries=5, retry_on_deadlock=True)。默认都是重试 5 次。但是,这种机制效率不高。
该 HA 方案具有以下优点:
由于这些优点,该方案被大量采用。具体配置请参考 OpenStack High Availability Guide。
2.1.2 云控制节点的 A/P HA方案
需要的话,可以使用 Pacemaker + Corosync 搭建两节点集群实现 A/P HA 方案。由主服务器实际提供服务,在其故障时由 Pacemaker 将服务切换到被服务器。OpenStack 给其组件提供了各种Pacemaker RA。对 Mysql 和 RabbitMQ 来说,可以使用 Pacemaker + Corosync + DRBD 实现 A/P HA。具体配置请参考 OpenStack High Availability Guide。
该 HA 方案的问题是:
因此,可以看到实际部署中,这种方案用得较少,只看到 Oracel 在使用这种方案。
Neutron 包括很多的组件,比如 L3 Agent,L2 Agent,LBaas,VPNaas,FWaas,Metadata Agent 等 Neutron 组件,其中部分组件提供了原生的HA 支持。这些组件之间的联系和区别:
2.2.1 原生 HA 方案
Neutron 提供了多种原生的 HA 方案:
(1)L2 Agent HA: L2 agent 只在所在的网络或者计算节点上提供服务,因此它是不需要HA的。
(2)L3 Agent HA
L3 Agent 比较特殊,因为它是所有 openstack (core)services 中唯一一个有状态的,因此,不能使用传统的在多个节点上部署多个实例使用LB来做HA。Neutron 本身的调度器(scheduler)支持在多个网络节点上部署多个L3 Agent,但是,由 L3 Agent 管理的 Virtual Router 自身需要有HA的实现。它的HA的Neutron 原生实现包括如下几种方式:
(a)Juno 中引入的 Automatic L3 Agent Failover (当 VR 所在的 L3 Agent 失效的时候,Neutron 自动将它 failover 到其它某个 L3 Agent 上)
该方案增加了一个配置项 allow_automatic_l3agent_failover。当它的值为 True 时,L3 plugin 去周期性地检查所有有管理 Virtual Router 的 L3 Agent 的状态。如果某 L3 Agent 死了,受它管理的 Router 会重新被 schedule 到别的 L3 Agent 上。 Neutron L3 Plugin 通过判断该 L3 Agent 是否在规定时间(agent_down_time)内有发回心跳消息来判断它是否活着。存在多种 L3 Agent 未能及时上报心跳但是 router 依然在转发网络包的可能。因此这种实现可能会存在 L3 Agent 被认为死了但是其 router namespace 依然在转发网络包和响应 ARP 请求而导致的问题。如果网络后端不阻止死掉了的 agent 使用 route 的 IP 地址,那新老 namespace 就可能存在冲突。这种冲突不会断掉 E-W 网络,因为新老 namespace 中的一个都可以承担无状态网络包的转发任务。然后,南-北网络可能会受影响,因为 NAT 只存在于一个router 上。而且,reschedule 后,浮动 IP 也会无法工作,因为它们与 router 的 外部端口的绑定关系不会被设置到新的router 上。
这种方案要求使用多个网络控制节点,每个节点上运行一个 L3 Agent。在某个 Agent 死了时,Router 会被部署到别的 Agent 上。这种方案,除了上述的问题外,切换时间过长是其主要问题。
(b)Juno 中引入的 VRRP (Virtual Router Redundancy Protocol)方案 (由 VRRP/Keepalived 控制 VR 的 VIP 和 VMAC 的 failover)
该方案使用多余一个的网络控制节点,提供 A/P HA。其主要特点为:
(c)Juno 引入的 DVR
该方案将 NAT 和 L3 Agent 部署到虚机所在的计算节点,在网络控制节点上只部署 DHCP 和 SNAT。该方案解决了 L3 Agent 和 Metadata Agent 的 H/A 问题。目前,将 DHCP Agent 改成分布式,VPNaas 以及 FWaas 的修改工作已经在进行中。用户需要使用第三方软件提供 SNAT 的 HA 方案。
(3)DHCP Agent 的 HA
DHCP 协议自身就支持多个 DHCP 服务器,因此,只需要在多个网卡控制节点上,通过修改配置,为每个租户网络创建多个 DHCP Agent,就能实现 DHCP 的 HA 了。
(4)Metadata agent 和 proxy 的 HA
跟 metadata service 相关的组件包括:
从 HA 角度来讲:
(注意,因为虚机在启动过程中需要访问 qrouter,这也就是说,要求虚机所在的子网必须已经添加到了一个 Virtual router 上,否则,它是无法通过 qrouter 走的,除非走 qdhcp)
或者更详细地看出完整的路径(图中红色线条,从VM开始,到 NOVA-API Metadata 结束):
(5)LBaas Agent HA
目前 Neutron LBaaS 代理服务是无法通过其自带的 HAProxy 插件 实现高可用的。实现 HAProxy 高可用常见的方案是使用 VRRP (Virtual Router Redundancy Protocol ,虚拟路由冗余协议),不过 LBaaS HAProxy 插件目前还不支持该协议。因此,只能使用 Pacemaker + 共享存储(放置 /var/lib/neutron/lbaas/ 目录) 的方式来部署 A/P 方式的 LBaas Agent HA,具体请参考 这篇文章 中描述的方法。
2.2.2 使用 Pacemaker 实现 A/P HA
使用 Pacemaker + Corosync 搭建两节点(或者多节点) A/P 集群。在主节点上,由 Pacemaker 启动 Neutron 的各种服务。
2.2.3 小结
从上面可以看出,除了 DHCP Agent 天生就通过配置可以实现 A/A HA 以及 L3 HA 以外,其它的组件的 HA 都是 A/P 的,而且实现的技术可以是原生的,也可以使用 Pacemaker,也可以结合起来使用。比如 RDO 的方案:
这里只讨论 cinder-volume。
(1)在使用非共享存储时,cinder-volume 进程受 Pacemaker 监控,在其停止的时候重启。这种方案下,存储控制节点宕机的话,上面的所有卷都会损失掉。因此,在生产环境中,必须使用下一种方案。
(2)在使用共享存储时,考虑到目前代码中存在的资源竞争(参考这里),该服务只能实现为 A/P HA 方式,也就是说在某个时刻,只有主节点上的 cinder-volume 在运行。RedHat 这个 ticket 中有具体的分析。目前,cinder-volume 还没有内在的 HA 实现,只能借助第三方软件比如 Pacemaker。A/A 的实现在 Liberty 中正在进行,请 参见 这个和 这个。
在测试环境中,我们常常将虚机创建在本地磁盘上,那么,在机器宕机的话,这些虚机将永远也回不来了。因此,在生产环境中,需要将虚机部署在 cinder-volume 或者共享的存储比如 RDB 或者 NFS 上。这样的话,在虚机损坏时,可以从共享存储上将其恢复(使用 nova evacuate 功能)。 使用 Pacemaker 部署 A/P 方案(类似 2.3 中 cinder-volume A/P HA)的话,生产环境中计算节点的数据往往远远超过 Corosync 集群中节点数目的限制。
业界有几个解决方案:
(1)Controller 节点通过管理网 Ping 所有 Compute 节点,Controller 节点检查nova service-list,对出问题的节点 Evacuate
特征:太简单粗暴,容易引起误杀和数据损坏
(2)Pacemaker-remote: 突破Corosync的集群规模限制,
特征:启用多个心跳网时,处理策略单一,引起用户业务不必要的中断
(3)集中式检查
(4)分布式健康检查
OpenStack 的各提供商中,就该需求,RadHat 使用的是上述的第二种方案,具体方案在 计算节点HA 方案:
部署方式如下:
HA 实现细节:
当一个节点失效时,恢复(recovery)过程会被触发,Pacemaker 会依次:
其中:
其余一些前提条件:
小结: OpenStack 云/网络/存储 控制节点 HA 集群
作者信息:刘世民(Sammy Liu),IBM 云架构师,十余年IT行业从业经历,在电信、企业软件、存储以及云计算等领域做过研发、管理和架构设计等工作。从 2012 年开始学习 OpenStack,对其核心模块有较深入的了解;带领过团队开发OpenStack模块。
责编:陈晨 联系请添加微信:violace95 备注公司 职位 姓名。寻求报道或投稿,请请发送至邮箱:[email protected]