一、XAPI对资源池的管理
作为XenServer的管理工具集,XAPI管理XenServer的主机,网络和存储。不管是OpenStack还是CloudStack,如果使用XenServer作为虚拟化底层,其对XenServer的调用必然使用XAPI。真正意义上的XAPI在XenServer中主要提供XenCenter以及资源池中各个XenServer主机的通信的接口。
首先,资源池中的所有XenServer主机的操作请求都是通过XAPI传递给Dom0的,同时在池中的所有XenServer主机间的通信也是通过XPAI进行传递。例如:资源池中数据库(XenServer配置数据库)会通过XAPI在所有的XenServer主机之间进行同步,以便在资源池Master宕机之后,其他XenServer主机能够正确而迅速的取代Master,并维持资源池的功能和服务。其简要示意图如下所示:
如上图所示,在创建XenServer资源池的时候,默认会选定一台XenServer主机作为Master,即所谓的资源池主。Master的作用是协调和锁定资源池内的各种资源。默认情况下在创建资源池的时候,加入资源池的第一台XenServer主机被默认推选为Master。当资源池的Master主机出现故障不在可用时,Master是可以进行角色转移的。其转移的情况有两种:一是进行手动转移,二是在开启资源池高可用的情况下进行自动转移。
在一个资源池中虽然所所有的XenServer主机都有XAPI,并在XML / RPC接口上运行了HTTP 80端口和TLS / SSL的443端口,但控制操作只会在Master主机上进行处理。如果将一个控制操作指令发送给资源池的Slave主机,Slave主机上的XAPI将会将该控制指令重定向到Master主机,并且Slave主机上的XAPI将会产生一个XAPI重定向的错误消息并将其存储在日志中。为了提高效率以下操作被允许在Slave主机进行:
- 查询性能计数器(以及主机的历史)
- 连接到VNC控制台
- 导入/导出(特别是本地存储上的磁盘时)
由于Master主机充当协调和锁管理器,其他主机在需要调用资源的时候就会经常和Master产生大量的交互。当然Slave主机之间也会进行彼此的交互,比如说:
- 转移VM的内存映像(虚拟机迁移)
- 镜像磁盘(存储迁移)
其次,XenCenter通过XAPI来读取XenServer主机的配置、管理、License信息、数据库信息等,同时XAPI也通过和上篇文章我们所讲述的XenServer核心运行的toolstack系列工具,包括如Xenopsd、Xcp-rrdd、Xcp-networkd、SM、perfmon、mpathalert、snapwatchd、stunnel、xenconsoled和xenstored等所有的组件进行交互,这些组件通过和XAPI进行通信并监控XAPI的命令接口,根据XAPI发送过来的命令执行相应的功能控制。
下图显示了一台XenServer主机上运行的软件。所有的主机上运行相同的软件。我们可以看到XAPI和其他的Toolstack所处的一个关系。
二、XAPI架构及运行机制解析
下面的关系图显示了xapi内部运行关系及架构:
图的顶部显示连接XenAPI客户端:XenCenter、XenOrchestra、OpenStack以及CloudStack。这些客户端都是通过XenAPI(XenAPI的XMLRPC通过HTTP POST)和HTTP GET/PUT在端口80和443与XAPI建立通讯。并且双方之间建立互信是通过使用PAM认证(默认情况下使用本地passwd和group文件)或通过Active Directory进行认证。
其中XAPI中的Xen API又细分为三类:
* master-only:这是最重要的API也是最常用的API类型,顾名思义,这种类型的API只有Master能够接受并进行执行。
* normally-local:这些API是为了提高性能的前提下,允许Slave主机执行的特殊API,其往往和主机以及虚拟机的性能相关。如磁盘输入/输出和虚拟机控制台连接这些接口控制的API,这些API直接有Slave主机在本地就进行控制执行,不需要再有Master记下来转发,提高了访问速度和性能。
* emergency:这些API归类为紧急情况下的API处理方案,例如当Master主机脱机的情况下,对资源池的紧急修复等。
对于API的执行,在资源池正常的情况下,XAPI会首先判断API的类型。如果用户在XenCenter中对Slave的操作是需要通过Master来执行的API,那么Slave主机的XAPI就会将该API重定向到Master主机,交由Master主机进行执行控制。在确认了API类型之后,即通过了初步检查,API调用就会进入“消息转发”层—控制、锁定资源(通过current_operations机制) - 决定哪些主机应该执行该请求。如果请求是在本地执行,主机直接调用函数或者进程使用功能即可;否则消息转发层就会将该请求同步给其他需要一同执行的主机上。
注:XAPI目前使用“每个请求一个独立线程”的模式,导致将为每个请求创建一个完整的POSIX线程。甚至当这个请求在这台主机上创建后被转发给其他的主机,这个创建的线程仍然存在在第一次被创建的主机上,毫无疑问,这种模式的弊端必然是在请求数量较多时,导致XenServer主机的处理阻塞,影响虚拟机的性能。
接下来API具体如何执行调用呢?如果XenAPI的调用是关于VM生命周期操作,那么它将会通过JSON-RPC(类似Unix域套接字)转换成具体的负责VM生命周期管理的组件Xenopsd 的API调用。XAPI和Xenopsd组件之间,对于每一个调用采用类似异步消息队列的概念,XAPI的每一个调用不需要Xenopsd立即返回执行结果。所以目前XAPI将每一个任务(所有操作在任务的上下文中运行)都绑定到Xenopsd任务上,XAPI在接受到调用时将其所对应的任务扔给对应绑定的Xenopsd之后就不在过问了。具体有无执行成功需要等待Xenopsd给它的反馈,所以我们在XenCenter中执行一个命令之后看见任务的进度条在走,但是什么时候走完进度条需要底层的执行组件给XAPI反聩,XAPI再其状态更新在状态数据库中,XenCenter会与XAPI进行不断的通讯以收取状态更新。如果Xenopsd组件执行命令出错,会返回相应的错误信息并存储在日志中。
如果XenAPI的调用是存储操作,那么“存储访问”层 -- 验证存储对象处于正确的状态(SR连接/分离;VDI连接/活动状态、只读/读写),然后调用存储管理API(SMAPI)V2接口中的相关操作;同时其中还存在着一个SMAPIv2到SMAPIv1转换器,可以生成必要的命令去跟SMAPIv1插件(EXT,NFS,LVM等)并执行它这些插件支持的存储类型。
在对存储进行API调用的时候,其都是属于Master类型的API调用,其Slave主机是没有权限对磁盘进行执行操作的。因此在内部,SMAPIv1插件使用特权访问XAPI的数据库,会将被视为只读权限的客户端直接设置只读字段属性(例如VDI.virtual_size)。同时由于共享的存储同时在资源池内被多个主机进行访问,为了保证数据的安全性,只能允许同一时刻只有一台主机对其进行对其进行访问。因此该SMAPIv1插件还协同XAPI对存储的访问进行控制,其采用共享存储常用的锁机制来对多台访问共享存储的主机进行控制。
XAPI的数据库包含主机和虚拟机元数据和资源池信息。该数据库被资源池的Master主机将其副本加载到内存中,与资源池的其他所有Slave进行共享,其他Slave主机通过远程的方式访问该数据库,同时将其同步到本地主机。数据库将每个API对象所实现的event.next和event.from的存储在数据库中。在接收到数据后是以XML格式并且是异步刷新的方式存储到磁盘中的。如果“重做日志”被启用,那么所有数据库的写入数据会被同步以增量的方式存储到给出的共享的块设备中。如果没有启用重做日志,那么XAPI在重启之后,就可能会丢失最近的更新。
同时XAPI还在资源池内实现主机的高可用。高可用性是在资源池内当其中的一台主机发生故障时,还能保证资源池内的正常运行意以外,还保证出现故障的主机上运行的虚拟机在其他主机上重启。 XAPI和名为xhad的组件进行紧密集成,实现XenServer资源池的高可用。Xhad是一个主机活跃度监视器。当xhad确认主机发生故障时(其通过监视超时时间和主机与存储等该设备的连接状态来判断),那么XAPI将重新启动出现故障并且已被HA标记为 “受保护”的虚拟机。 XAPI还可以限制资源利用,以防止资源池变得过于超载,以应对有多个主机故障时没有资源运行HA。
最后XAPI还承载了实现XE CLI的任务,其XE执行效率和XAPI直接关联。XE程序远程控制访问XAPI命令行,XAPI则根据返回一Shell界面,显示系列简单的命令(提示输入;打印屏幕;取文件;退出等等)。