ZStack中的标签不只帮助用户汇集资源,也帮助控制软件行为。ZStack有一套完整的规范,用以定义标签的类别、形式和用法。除了用户外,插件也能够建立本身的标签,以记录元数据和拓展示有的资源属性;经过这些手段,标签能够帮助插件引入新的特性,而不改变ZStack的数据库结构,消除了在软件升级对数据库迁移的需求。web
动机算法
随着云中资源的不断增加,用户可能会想要有一种方式,使用人类可读的标签,去分组类似的资源。举个例子,全部Web服务器的虚拟机均可以有一个标签'web-tier-vm',这样能够从UI和CLI把它们做为一个组来获取。对于IaaS自己,预先定义的业务逻辑也许历来都不能知足用户的需求。以建立虚拟机为例,默认的选择目标主机的算法是,从主机池中随机选择一个,但用户可能须要各类各样的算法来知足它们的使用情景。好比说选择内存超过8G的主机,选择拥有SR-IOV硬件的主机,或选择一个有当前用户的运行中虚拟机的主机。IaaS软件几乎不能为全部无止境的、不可预知的需求提供单独的API,必须有一种机制容许基础API(如APICreateVmInstanceMsg)携带额外信息。数据库
根据各自的业务逻辑,插件能够选择是否建立数据库表。好比,Open vSwitch L2 Network插件,因为须要建立一种新的类型的资源,可能须要添加一张新表;然而,一个容许主机保留内存的插件可能不须要添加一张新表,而仅需在主机上附加一点数据。若是IaaS软件没有为插件提供一种附加数据,它们将开始创造新的、琐碎的模式或添加现有模式的列从而修改现有的模式,致使软件升级时数据库迁移的难处理的状况。apache
最后,对于创建在ZStack上的第三方软件,容许它们将信息存储到ZStack的数据库能够避免数据完整性问题,并使得它们可使用ZStack的所有查询API(详见“查询API”)。编程
问题后端
大多数IaaS软件都有着标签的概念。然而,它们并非都为不一样场景定义了一个详尽的标签规范。例如,一些IaaS使用标签是为了用户聚合资源,一些IaaS是为了内部业务逻辑。ZStack则为不一样场景的标签的每个层面都精心设计了标签规范。服务器
标签系统架构
在ZStack中,标签本质上是携带了少许资源相关信息的字符串。一个标签一般由如下几个字段组成:工具
FIELDui |
DESCRIPTION |
uuid |
标签的UUID |
resourceUuid |
标签所关联的资源的UUID |
resourceType |
标签所关联的资源的类型 |
Tag |
一个包含了有意义信息的字符串 |
Type |
标签类型:System 或者 User |
在标签方面,ZStack和其余IaaS软件的本质区别是ZStack将标签分为两类:用户(User)和系统(System)。
1.用户标签
用户标签,顾名思义,是用户为资源分组而建立的标签。例如,经过标签'apache2-http'将安装了Apache2 HTTP服务器的虚拟机分组,这样用户就能够经过查询API获取这些虚拟机,使用标签'apache2-http'做为查询条件便可:
QueryVmInstance __userTag__=apache2-http
备注:详见“查询API”
这是最多见的标签使用方法,一个资源能够和多个标签相关联,而且被不一样的逻辑组划分。
用户标签也能够经过和系统的标签一块儿使用来控制ZStack的行为。例如,若是一个用户标签SSD
已经在主存储系统上建立好,那么一个系统标签能够指导ZStack在有用户标签SSD的主存储上去建立VM的根目录。在这种状况下,用户标签更像是用户输入的资源元数据。咱们很快就会看到,插件也可使用系统标签建立资源元数据。
2.系统标签
不像用户标签能够被用户在任意时间、以任意值建立,系统标签有固定的格式,而且是被ZStack的业务服务和插件提早定义好的,能够在如下场景被使用:
2.1元数据
插件可使用系统标签来记录资源的元数据。例如,主机的数据库表中没有列去记录如hypervisor版本,hypervisor SDK版本这样的元数据;然而,衍生的主机插件,例如,KVM主机插件,可能须要这些元数据来肯定当前虚拟机管理程序是否有某些特征;例如,是否能对KVM在线快照是由libvirt和QEMU版本决定的。在ZStack中,当链接到后端主机时,KVM主机插件将OS的版本,libvirt版本,QEMU的版本和qemu-img工具的版本做为系统标签保存。
QuerySystemTag fields=tag resourceUuid=d07066c4de02404a948772e131139eb4
{
"inventories": [
{
"tag": "capability:liveSnapshot"
},
{
"tag": "qemu-img::version::2.0.0"
},
{
"tag": "os::version::14.04"
},
{
"tag": "libvirt::version::1.2.2"
},
{
"tag": "os::release::trusty"
},
{
"tag": "os::distribution::Ubuntu"
}
],
"success": true
}
2.2资源属性
插件也可使用系统标签将新属性添加到资源中。例如,虚拟机的数据库模式中没有列来记录该使用什么IP分配算法,何时分配虚拟机网卡。这种额外的属性能够用系统标签实现。插件能够建立的系统标签的数量没有限制,附加的插件能够利用这点,并避免干扰数据库模式。
数据库表和系统标签:由于数据库表和系统标签均可以定义资源属性,有时会难以决定属性是应该为数据库模式中的一列,仍是应该为一个单独的表中的系统标签。添加新列来修改一个现有的数据库模式,一般须要进行数据库迁移,这是IaaS软件升级的一个主要痛点。因此开发者可能更倾向使用系统标签来表明新属性。然而,滥用系统标签是一种错误的编程方式。按照ZStack的约定,只应该使用系统标签形式引入非固有的资源属性;系统的标签并不能拯救设计的很烂的数据库表。例如,若是VM的数据库表缺失集群UUID(虽然不会),即便须要进行数据库迁移也必须补充回来;但为了私人使用而被用户建立的插件引入的部门ID应该做为一个系统标签实现。这种权衡有时候并不容易,咱们会严格控制任何数据库结构的变化。
2.3元编程
系统标签也能够标注资源以影响ZStack的执行流,它在某种程度上相似于Metaprogramming(https://en.wikipedia.org/wiki/Metaprogramming)。
例如,管理员能够在KVM主机上建立一个系统标签reservedMemory::1G,提示ZStack主机分配器从主机的可用内存保留1G内存;若是管理员改变心意,他能够经过删除标签来回收这1G内存。有不少相似的系统标签。
例如,在用户标签这一节中,咱们提到了同时使用用户标签SSD和系统标签来为VM的根云盘指定主存储。系统标签叫primaryStorage::allocator::userTag::{tag}::required,若是一个虚拟机实例规格上有primaryStorage::allocator::userTag::SSD::required,从该虚拟机实例规格上建立的虚拟机根云盘的任务,将只被分配到拥有用户标签为SSD的主存储上。有许多称之为解释点interpreting points的代码,将在执行过程当中寻找特定的系统标签,能够改变代码的默认行为。
2.4第三方软件集成
创建在ZStack上的第三方软件可使用系统标签在ZStack的数据库中存储和资源关联的信息,这能有效避免第三方软件数据库和ZStack数据库的数据不一致性。
例如,一个私有软件可能须要记录虚拟机的部门ID来审计每一个部门IT资源的使用状况,这个功能一般由一个私有的数据库完成,并迫使私有软件跟踪虚拟机的生命周期,由于它须要在数据库建立或销毁时,去更新本身的数据库。不然,数据将不会正确反映真实状况。
有了系统标签的帮助,私有软件可使用系统标签,例如audit::departmentId::{id}将信息存储在ZStack的数据库,将管理部门ID生命周期的责任转移给ZStack。当一个虚拟机被销毁,它的部门ID(例如audit::departmentId::1)将在删除该虚拟机记录的数据库事务中被自动删除。此外,私有软件能够用它们的部门ID调用常规查询API检索虚拟机:
QueryVmInstance fields=uuid __sysTag__=audit::departmentId::1
注:在ZStack版本(0.6)中,咱们还没开放容许定义任意系统标签的接口,全部的系统标签都是预先定义的。咱们计划在下一个版本中开放这个接口,用户定义的系统标签能够在建立的时候添加一些系统容许的前缀,例如,3rd::
。
和其余组件的关系
标签系统是ZStack核心组件之一;它不只具备单独的API和服务,并且还和其余核心组件无缝集成。用户能够在资源建立时或在资源建立后建立标签。ZStack全部创造型的API支持两个固有参数:userTags
和systemTags,经过它们传递的标签将随着资源一块儿建立。例如:
CreateVmInstance name=testTag systemTags=hostname::web-server-1 l3NetworkUuids=6572ce44c3f6422d8063b0fb262cbc62
instanceOfferingUuid=04b5419ca3134885be90a48e372d3895 imageUuid=f1205825ec405cd3f2d259730d47d1d8
若是资源已经存在,用户可使用标签API来建立或删除标签:
CreateUserTag resourceType=VmInstanceVO resourceUuid=613af3fe005914c1643a15c36fd578c6 tag=web
DeleteTag uuid=596070a6276746edbf0f54ef721f654e
资源被删除时,与资源相关联的标签将被自动删除。
资源能够经过使用两个特殊的查询条件进行查询:__userTag__
and__systemTag__标签:
QueryVmInstance __userTag__=web zoneUuid=04b5419ca3134885be90a48e372d3895
QueryHost __systemTag__=capability:liveSnapshot
也有查询API专门用于分类:
QueryUserTag resourceUuid=0cd1ef8c9b9e0ba82e0cc9cc17226a26 tag~=web-server-%
QuerySystemTag resourceUuid=50fcc61947f7494db69436ebbbefda34
总结
在这篇文章中,咱们展现了ZStack的标签系统。经过这个系统,用户、插件和第三方软件能够经过各类各样的方式使用标签,而不用改变代码和数据库表结构。这是又一个基本点,激发了一种潜力,使得ZStack在快速进化为一个成熟的、完整的云计算解决方案的同时,又能保持核心架构强壮稳定。