论文阅读之Comparing Containers versus Virtual Machines for Achieving High Availability

初步了解

程序分为有状态和无状态的程序,无状态的程序能够保存自己的状态,当节点失败时,可以使用负载均衡将请求转发至其他健康副本
而有状态的程序需要维护网络和程序的状态,因此需要采用不同的策略。

在虚拟机环境达到高可用性,需要有如下能力

  • 能够遍历和保存虚拟机的状态;
  • 能够实现虚拟机热迁移的能力;
  • 在节点失败后转向备用节点的恢复机制。 虚拟机提供商提供了不同的HA/FT(Fault Tolerance)方案给他们的客户。在这些方案中,高可用性一般是通过松散耦合的自我包含的服务器池和不间断的监控来实现。而对容错来说,负载均衡是不够的,为了保证服务的连续性,需要提供一个与主要节点一致的副本,这样就可以保在服务不中断、数据不丢失的情况下,一直有服务器来接手下面的工作。

管理平台的高可用性

高可用性概览

VMWare
Citrix XenServer
Marathon everRun MX
所有的这些供应商都提供了高可用性的方案,一般都是通过故障转移策略来实现的。

VMware和XenServer分别通过vMtoion和XenMotion来支持虚拟机的热迁移了。但是CPU的兼容性是保证虚拟机在目标机器上正常运转的保证。目标机器的CPU最好能够提供一样的特性给虚拟机,这样随之而来的应用程序不会崩溃。同时,它们也支持检查点及恢复功能,从而允许虚拟机快照的功能。

容错:检查点vs 记录和重放,与高可用性支持采用故障转移集群来实现不同,虚拟化平台中虚拟机的高效同步容错是一件更具有挑战的事情,因为第二台虚拟机与主虚拟机之间高效同步是一件非常复杂的任务。目前主要有两种方式来进行解决。

  • 记录与重放,首先记录主虚拟机上面所有的输入数据,并通过专用通道发送至第二个副本,并进行重放。在只有一个内核的CPU上面实现这种策略是一件比较简单的事情,但是由于现代的CPU有事觉又多个内核,硬件制作厂商为了提高CPU的性能,采取了分支预测、猜测和乱序执行的策略,这样导致了程序执行的不确定性,这些不确定性增加了副本与主机之间同步的复杂性。这种挑战一般称之为对称多处理器容错。Pereira等人提出,解决这种问题需要有硬件的支持,VMware目前提供的策略只支持单核CPU,在本文章写作时,只有Marathon everRun MX宣布他们解决了这个问题。但是具体的信息公布的很少。

  • 相比记录与重放机制,另外一种策略是检查点机制,检查点机制是记录下虚拟机在输入数据之后的状态,并将状态发送到副本中。从而保持副本虚拟机与主虚拟机之间的持续同步。与记录与重放策略相比,检查点具有简单和对称多处理器支持的优势。然而检查点机制的表现性能依赖于检查频率以及需要检查以及传输到副本的数据量。Remus和Kemari是这种方式的两种实现但是都没有开始商业化使用。

VMware中的高可用性。

VMware平台采用VMware分布式资源调度器(DRS),VMware HA,VMware FT以及vMotion来保证虚拟机环境的高可用性。
VMware HA:High-Level Architecture
图中可以看出VMware HA是建立在故障转移集群上面的,所有的磁盘镜像需要存储在共享存储中。HA代理负责维护主机之间的心跳以及虚拟机虚拟中心服务器之间的心跳,以及应用程序与虚拟中心服务器之间的心跳。

VMware高可用性可以处理Host failure,Guest OS failure,Application failure这三种失败。
关于虚拟机迁移以及在新的主机上面启动虚拟机来说,分布式资源调度器根据集群主机的状态、虚拟机资源的消耗情况,以及一些附加规则等来选择虚拟机移植到的新主机的位置。
图二展示的是目前VMware容错的实现版本,通过vLockStep协议,将所有的输入数据通过一个专用通道发送到备份机,并进行重放。vLockStep技术需要物理处理器的支持,目前已经与Intelli和AMD进行了合作。目前所有的x86服务器处理器都兼容vLockStep。要使用vLockStep,需要一条主机和备份机之间高速的网络,至少1Gbit。
VMware FT:vLockStep overview
VMWare基于目前实现的容错机制只能支持基于单个逻辑内核的虚拟机,为了保护多核虚拟机,VMware开发了对称多核处理器容错协议,该协议需要更高的网络带宽,最少10Gbit。

XenServer平台的高可用性

XenServer平台仅仅提供了主机级别的高可用性,但是可以通过增加第三方产品,如HA-Lizard来解决虚拟机以及应用程序级别的失败从而实现高可用的能力。一个有潜力的方向是讲Remus集成到XenServer中来实现容错,Remus目前已经是Xen管理器中的一部分了。

Remus采用Active-Passive结合的配置,虚拟机状态被持续从主机复制到备份机。Remus允许推测执行活动虚拟机,使其状态稍微先于备份机系统,这将允许虚拟机状态的的异步复制,从而提高了主虚拟机的性能。同时,主虚拟机的所有输出数据被缓存,直到检测点被认可之后,才将结果同步到备份机。

基于容器平台的高可用性

与基于管理器的虚拟化不一样,基于容器的虚拟化(操作系统级虚拟化)主要不是为了模拟一整套硬件环境,而是为了允许现在的虚拟机内核实现应用程序之间的隔离。有了操作系统级虚拟化,在一台主机上就可以运行多个隔离的Linux操作系统(容器),每个容器都有自己的进程和网络空间,操作系统,例如LXC,Docker,OpenVZ都是基于这种的实现。

实际上,容器就是一些列与其他容器完全隔离的进程。为了保证容器的高可靠性,进程检查点和回复的能力是必须的。目前有很多为了解决这个问题的研究工作,包括BLCR,DMTCP,ZAP,但是这些是系统都不是专门为容器设计的。它们不是缺少这个特性就是缺少那个特性,或者是经常只支持一部分应用程序,然而,由于实现的复杂性,它们都没有能够成为主流Linux内核的一部分。

通过在LXC(LinuX Container)上添加一些诸如版本和共享特性的Docker正在成为一个具有吸引力的提供容器的平台。然而高可用性的特性在Docker或LXC编写时并没有考虑。例如,Docker的检查点机制依赖于lxc-checkpoint,但是它至今还没有实现。作为一个备选方案,可以使用commit命令来对运行中的容器进行快照,然而,仅仅保存容器的文件变化以及放入新的镜像,但是没有考虑正在运行的进程中的状态。当另一个基于快照保存的镜像的容器在另外一个主机上启动时,在之前的容器上运行的进程的状态却没有保存下来。

表3-Docker和OpenVZ中高可用性特性的对比
相反,正如表3所示。进程迁移和检查点/回复的特性在OpenVZ是完整的,而且可以使用。这些特性是通过可以加载的内核模块机上一些用户空间功能来实现的。然而,和之前提到的一些已有工作一样,这种方式的主要缺点是,OpenVZ缺乏官方的与主流Linux内核的集成。于此同时,OpenVZ的这些特性是在2006年4月份提出的,它们至今没有被主流的Linux内核所接受。目前仅有定制的2.6.32内核上面具有OpenVZ的全部特性。使用老的内核会存在很多问题,注入安全和兼容性等。为了解决这个问题,一个新的研究方向被提出了,就是将检查点复杂性的大部分从老得内核去掉,将其加入到用户控件,这样可以减少内核修改的工作量。在书写这篇文章的时候,超过150个来自于CRIU的补丁已经加入到了内核的主线用于实现检查点/还原功能以及有与LXC集成的可能。同时注意到,目前没有其他容器平台支持主从之间失败检测、自动状态同步以及故障转移管理的特性。

CRIU中的检查点/还原和热迁移

图4描述容器迁移的时间序列,OpenVZ和CRIU目前的实现和这些序列是一致的。
容器迁移的序列图

这种是实现的一个优势就是在传输内存或者文件系统同时过程中出现连接失败时,迁移进程可以回滚至源机器,在源机器上恢复容器。

服务可用性主要取决于3-5阶段消耗的时间。文件系统改变追踪、延迟迁移以及迭代迁移这三个优化被引入来减少服务拓机时间。

  • 文件系统变化追踪:基本动机是为了减少图4中第4阶段文件系统同步的时间。这是通过不断追踪文件系统的变化并只同步变化的部分来实现的。目前CRIU的优化是基于ploop,一个类似于Linux loop设备但是专门为容器设计的块设备。ploop的一个主要特性是写追踪,它允许讷河记录下一些列被修改的数据块的清单。这个清单能够用于在最少的容器拓机时间内高效地将一个ploop设置迁移至另外一个宿主机。ploop拷贝工具已经在用户空间实现了这个功能并且用于vzmigrate工具。
  • 延迟迁移:如图5中高亮部分所示,延迟加载的基本思想是仅仅传输内存页的少数子集至目标机器,并在目标宿主机上还原空气,并根据具体的需求从源机器上把剩下的页拉过来。有了延迟加载之后,容器可以不需要等待所有的内存也拷贝完,就可以在机器上重启。如果出现内存页缺失的情况,容器发送一个请求给源宿主机上的缺页守护进程来拉取缺失的内存页。通过这种方式来实现内存页的传输。最后,容器在任何空闲间隙,交换行为被强制执行,所有剩下的内存页将会从源宿主机上面传输过来。
    Lazy Migration
    延迟迁移的一个主要的难点在于无论是源还是目的宿主机需要保持容器的完整状态,这意味着在整个虚拟机迁移的过程中,源和目的宿主机之间的网络连接需要可靠。特别地,在目的
    宿主机上面还原的容器由于网络故障导致的不完整内存页而产生故障,然而回滚在这种情况下也没有多大的作用。

  • 迭代迁移
    另外一种优化(迭代迁移)就是在冻结容器之前进行内存页和文件系统的同步,这样可以大量减少容器在冻结之后需要迁移的数据的数量。然而,在数据传输过程中,内存页以及文件系统都有可能会被修改,因此,整个过程需要迭代执行。采用这种方式时,文件系统将会被同步迭代,与此同时,内存中的脏页也会在迭代过程中不断产生。
    Iterative Migration
    如图六所示,迭代进行在没有任何改变或达到设置的阈值时才会停止。

容器的集群

Docker目前还处于尚未成熟的阶段,但是其真正的潜力在于使用一些列容器来构建服务。目前有两种Docker集群级别的管理工具。Docker Swarm是Docker原生的集群挂历系统,旨在使用一个Docker集群来提供一个单一的虚拟主机。Kubernetes是另外一个有潜力的Docker集群管理工具,它将若干个松散耦合的容器使用label编入Pod。标签在其中为认为是多个Pod组成的代表服务意义的元数据。Kubernetes中副本控制器是用来保证随时都有一定数量的给定的Pod在运行,如果Pod失败,它能够启动另外一个可用的主机。尽管这种方式对于无状态的服务可行,但是它还是缺乏保证服务连续性的状态保存机制。

总结与展望

本文从高可用的角度比较了虚拟化技术。表四对这些技术进行了总结,我们可以得出以下结论。高可用性与容错已经在基于管理程序的平台上面进行了实现,大部分都是采用集群故障转移机制来实现的。但是这些方案都具有局限性,例如在对称多处理器的支持或者是客户机系统方面。另一方面,基于容器的平台缺少的特性更多,特别地,基于容器的检查点恢复机制还远不成熟,然而,尽管在容器集群方面做了努力,但是还没有成熟的方案来持续监测容器的失败以及作为一个完整高可用性方案必须的自动故障转移管理,。总而言之,从高可用性的角度来讲,容器技术有待继续研究。

基于容器平台高可用性方面的优化,研究使用gzip、bzip2以及rar技术来减少从源主机至目标主机之间的数据容量从而加速热迁移的进程,另外,目前没有通过记录与重放在容器上面实现容错的相关工作。

ZHANGCHI wechat
关注微信号进一步交流