Ceph-Mgr之源码解析
导读
ceph luminous版本中新增加了一个组件: Ceph Manager Daemon,简称ceph-mgr。 该组件的主要作用是分担和扩展monitor的部分功能,减轻monitor的负担,让更好地管理ceph存储系统。
本文档基于luminous版本简单介绍ceph-mgr的源码实现。由于ceph-mgr还在开发完善,可能最新版与本文档部分内容有所出入,但是大体框架上应该是没什么变化的。
本文档不介绍ceph-mgr的安装部署与使用,具体请参照官网:Ceph Manager Daemon
本文档代码基于Luminous 12.2版本进行解析,由于社区存在代码变动,其它版本有可能对不上号,但是整体架构应该不会有太大的变化。
mgr的实现与用途
ceph-mgr是由C/C++、python以及Cpython等共同编写完成的,mgr的实现使用了大量的Extending Python with C or C++的语法,不熟悉这块的可以先在python官网中科普一下。
由ceph-mgr的实现其实大概可以猜到,其将ceph的部分C/C++实现的接口python化(即以前只能通过调用c/c++接口发送msg获取比如osdmap、monmap等集群状态,现通过mgr可以很方便地拿到。同时,ceph-mgr支持用户自定义的plugin(插件纯python开发,特别方便),用以实现特殊功能。
截至目前为止,ceph-mgr的官方plugins包括:
- Dashboard(WEB界面的管理)、
- Restful API(API方式获取ceph信息,应该与之前的ceph-rest-api功能一致)、
- Zabbix、Prometheus、Influx(这三个实现了ceph的数据收集、监控等功能)
mgr组件
ceph-mgr的重要类或模块包括:MgrStandy、Mgr、DaemonServer、PyModules、ClusterState、DaemonState等。其主要功能描述如下:
MgrStandby
所有mgr服务启动时身份都是standby,唯一作用是包含一个mgr的client端,获取mgrmap及相关msg。在获取了mgr-map发现自己为当前active时,才会初始化mgr主服务进程。当mgrmap中变为非active状态,则shutdown mgr主服务进程,释放资源。
Mgr
主要工作是初始化daemonserver、pymodules、clusterstate等主要功能类,并handle standby mgr client的非mgrmap的消息(osdmap、pgmap、fsmap等)。执行了monc->sub_want()函数,注册了定期获取数据操作。
DaemonServer
为mgr主要的服务进程,和osd、mds等类似,初始化了一个mgr类型的Messenger,监听有关mgr消息,主要是MSG_PGSTATS、MSG_MGR_REPORT、MSG_MGR_OPEN、MSG_COMMAND。比如执行‘ceph tell mgr {command}’时就被发送到daemonserver中handle_command函数进行处理(包括了native命令和plugin的commands)
PyModules
包含ActivePyModule、StandbyPyModules、ActivePyModules、BaseMgrModules、BaseMgrStandbyModules、PyModulesRegistry、PyModuleRunner等类,分别处理mgr处于active和standby时对plugins的处理,并在active时初始化python的运行环境,将plugin模块初始化并加载运行。该类大量使用了python的c++扩展接口。
ClusterState
保存了cluster的状态,部分状态在monc中,由mgr类定期更新状态(ms_dispatch)
DaemonState
保存了DaemonServer的状态信息
这些类之间的关系如下图所示:
Ceph-Mgr 启动过程
图片已经很详细了,文字就不多说了。
mgr基于Active-Standby模式,大体流程就是mgr进程启动时先以MgrStandby身份启动,即所有mgr启动时都是standby,然后通过map知道自己是Active的mgr后,才会启动实际处理程序初始化DaemonServer,监听有关mgr的消息,加载并运行modules(一部分为用户自定义plugins)。
Mgr的一些功能介绍
mgr提供了常用的几种函数接口,只要重载这些接口,就能开发plugin实现特定功能。以下是官方的介绍,即实现服务器、消息通知、自定义命令等功能:
serve: member function for server-type modules. This function should block forever.
notify: member function if your module needs to take action when new cluster data is available.
handle_command: member function if your module exposes CLI commands.
编写自定义plugin
下面以简单的自定义命令为例,描述如何编