基于APIServer的CMDB架构设计和实现

摘要

本文从外卖CMDB的实际业务场景出发,介绍机器相关资源的生命周期以及如何在生命周期的各个阶段对资源进行管理;同时介绍了APIServer,并将其作为核心组件之一应用到CMDB中,通过修改主机名的业务流程介绍APIServer在CMDB中的应用。

1.背景

传统CMDB(Configuration Management Database)即配置管理数据库,是与IT系统所有组件相关的信息库,它包含IT基础架构配置项的详细信息[1]。CMDB是外卖运维的基础核心系统,旨在实现对机器相关资源的有效管理,机器相关资源又可以分为物理资源(如机器、交换机等)和逻辑资源(如域名、IP等),而对所有资源的管理都是围绕着机器资源的生命周期在进行;机器资源的生命周期可以划分成五个阶段:机器同步、机器分配、机器初始化、机器变更以及机器报修,CMDB通过实现对机器生命周期的管理来实现对资源的管理。

传统CMDB是将一切对象配置化,外卖CMDB为了实现对机器资源的有效管理,在技术选型上我们采用了APIServer作为CMDB的核心组件;Kubernetes是Google开源的容器编排引擎(简称K8s),而APIServer作为k8s的三大核心组件之一,APIServer将一切资源都抽象成对象进行管理,并提供资源对象的唯一操作入口,其他所有的组件都必须通过它提供的API来操作资源对象。基于APIServer的这一设计规范将机器资源的对象化管理,利用其提供的对资源操作的接口完成机器生命周期中的其它业务操作。

2.APIServer

本节介绍APIServer资源即对象的设计理念以及Watch机制。正是因为这些优点所以将APIServer从Kubernetes中借鉴过来应用到CMDB中。

2.1资源即对象

APIServer的设计理念是资源即对象,一切资源都可以抽象为对象的管理,将资源对象存储在ETCD中,提供统一的操作API入口来操作资源对象。它以RESTful风格的API对外提供了增删改查盯接口,盯即Watch操作,所有对K8s资源对象的生命周期维护都是通过调用APIServer的这些接口来完成。例如,用户通过kubectl创建一个Pod,即是通过调用APIServer的接口创建一个Pod对象,并储存在ETCD中;CMDB中,从公有云同步机器到CMDB就是通过调用APIServer的接口创建一个Machine对象进行存储[2][3]。关于APIServer对于对象结构的定义可以参考API Conventions,设计原则可以参考Design Principles

2.2Watch机制

List-watch是k8s中统一的异步消息传递方式,对系统的性能、数据一致性起到关键性的作用,在CMDB中这一消息传递方式也得到了广泛的应用。List是一个简单的列表操作,Watch是一个典型的发布-订阅模式,组件向APIServer而不是etcd发起watch请求,在组件启动时就进行订阅,告诉apiserver需要知道什么数据发生变化,有变化时推送给Watch客户端。APIServer Watch的实现是在ETCD Watch的基础上进行了封装,增加过滤功能来满足组件的有条件订阅[4]。Watch机制依赖于Etcd,同时也是ETCD的性能也是Watch的瓶颈,使用Etcd V2仅能支撑上千个客户端的Watch连接,使用Etcd V3 Watch上限可以达到1W+,足以满足当前的业务需求。Watch机制的详细代码实现可以参考apiserver的list-watch代码解读

2.3小结

下表总结了基于APIServer的CMDB和传统CMDB的对比:

对比项 基于APIServer 传统CMDB
资源定义 资源即对象,对象结构定义清晰,易扩展 基于配置项,不易扩展
资源订阅 基于Watch的异步消息传递机制,实时性高
API 提供统一Restful风格API作为资源操作唯一入口,清晰 基于业务需求定制API
任务模式 任务入库后根据状态触发动作,不同对象的操作相互无影响 直接下发任务并入库,任务多需排队
业务理解 基于状态比较难理解 流程化任务较容易理解
异常处理 基于状态,方便定位问题,可通过恢复断点继续任务 任务流程化,问题定位和任务恢复较困难
存储DB 分布式非关系型数据库etcd 传统关系型数据库

3.CMDB

3.1业务场景

CMDB实现的是对机器相关资源的管理,利用APIServer将机器作为对象存储在Etcd中,并通过提供的API对机器进行增删改查操作,尤其是Watch机制,方便的组件间消息传递也使得相关操作的业务流程更为清晰、简单。APIServer是CMDB的核心组件之一,CMDB对机器资源生命周期的管理都通过APIServer提供的增删改查盯API来完成,CMDB的工作方式如下图1所示:

图1 CMDB工作方式

从图中可以发现,CMDB中机器的入库/出库都是通过APIServer的API创建/移除;用户对机器的操作都是通过APIServer的API来实现的,通过API修改机器的status或其它信息,Agent或CMDB根据Watch到的机器变化进行相应操作。

3.2机器相关资源生命周期的管理

我们根据机器资源的生命周期进行划分,通过机器生命周期的管理来实现对所有资源的管理,可以分成五个阶段:机器同步、机器分配、机器初始化、机器变更以及机器报修。每个阶段处理的业务可以概括为:

  • 机器同步:包括新机器入库、信息完善和机器出库;入库是同步公有云信息并创建机器对象实例到Etcd中存储并同步添加DNS记录,同时部署Agent进行信息采集并通过Update API更新完善机器信息;公有云下线机器后,CMDB通过Delete接口将机器从etcd中同步移除,并移除DNS记录。
  • 机器分配:新入库机器处于待分配状态,根据申请记录,通过APIServer API更新Status为运行状态,完成待分配机器的分配操作;
  • 机器初始化:新机器分配后需要进行初始化,如puppet初始化;
  • 机器变更:常见的变更有修改主机名、BNS绑定、域名绑定等;其中以修改主机名的流程最为复杂,交互的组件最多,下文中会详细介绍其业务流程;
  • 机器报修:报修分为自动和人工报修,自动报修通过Agent周期性检测发现故障并提交到CMDB进行人工检查是否故障,若故障则进入报修流程,并通过APIServer API更新机器Status为维修状态,维修状态的机器不能进行变更等操作;

CMDB V2机器相关资源生命周期管理架构图如图2所示。CMDB的资源从业务上又可以分为公有云资源Noah资源,公有云资源包括BLB(VIP)、EIP(公网IP)、BCC(虚拟机)、BBC(物理机)和DNS等,Noah资源包括BNS(机器Group)、监控等;交互的组件有Etcd、Agent、网络故障检测平台、机器故障检测平台、Local DNS、Puppet、Workflow、keytab分发、权限系统等。其中图中橙色部分是已经对接完成或者开发完成的功能,绿色部分是待开发或对接的功能组件。

图2 CMDB V2机器相关资源生命周期管理

3.3修改主机名

修改主机名是CMDB中较为复杂的一个变更流程,交互的组件比较多,对于Watch的应用也最有代表性。修改主机名过程的主线是机器状态的变化,根据状态的变化相应组件进行变更操作并记录事件Event,修改过程可以简要概述为以下几个阶段:

  • 提交订单:对修改主机名订单进行输入检查,通过后提交Workflow进行审批;机器状态由Running变为NameReview,非Running状态的机器禁止进行其它变更操作;
  • 审批通过:周期性轮询订单状态,审批打回的订单进行状态回滚,通过的则修改状态为UpdateDNS,进入更新Etcd实例信息和DNS阶段;
  • 更新DNS和ETCD:Watch主机状态,发现机器状态为UpdateDNS的记录时,对该机器对应的DNS进行修改,同时修改Etcd中的该主机信息,操作完成后,将机器状态变更为UpdateHostName,机器本地进行相应更新操作;
  • 本地更新主机名:机器的Agent客户端Watch到当前主机状态为UpdateHostName的记录时,进行修改本地配置文件、执行主机名生效命令以及Ketab清理和分发等操作,完成后将主机状态更新为Running,该机器的修改主机名完成;
  • 订单完成:周期性轮询订单中机器状态,当所有机器状态为Running时表示订单完成,关闭订单。

在进行修改主机名操作时,Watch不仅能检测到状态的变化,同时可以根据需要传递必要的信息,每个阶段的操作除了判断状态之外还会进行其它条件的判断来共同完成变更的判断。修改主机名是CMDB机器变更中比较复杂的一个流程,组件和环节比较多,为了保证修改的准确性,不仅增加了各种判断和回滚操作,同时还在每个小的变更操作时记录事件Event,便于追踪流程进度来保证信息一致性。

CMDB修改主机名的详细流程图如图3所示:

图3 CMDB修改主机名流程

4.总结

CMDB的实现依赖于APIServer这一核心组件,其提供的统一的API为CMDB对资源的管理提供了便捷入口,尤其是Watch机制的使用使得组件之间的消息传递更加简便。目前CMDB已经上线的功能有机器同步、机器报修、机器信息查询、机器故障检测、修改主机名等功能,对接了Workflow、网络故障检测平台、DNS、Puppet等组件;未来开发工作的重心放在机器变更部分,规范和简化机器分配、回收、BLB、BNS、EIP等操作。

参考文献