夜莺 v7 业务组使用的最佳实践
夜莺 v7 中有个管理概念,是业务组,业务组是一个很宽泛的概念,可大可小,所以在具体实践时,很多朋友比较懵,本文来解释一下业务组的划分颗粒度和最佳实践。
业务组的设计初衷
业务组主要服务于权限和过滤筛选两个原始需求。比如一个公司机器很多,放到一张大表格里呈现,所有人可以看到所有机器,大家都可以互相操作,这显然不是我们期望的,告警规则、订阅规则、仪表盘、自愈脚本等,也都是类似的,都需要一个权限管控的机制,以及一个过滤筛选的机制。
那我们可以把这些资源直接归给某个团队么?
归给某个人显然不合适,人一旦离职就没法搞了。那把这些资源归给某个团队行吗?比如创业某个告警规则的时候,指定这个告警规则归属某个团队,只有这个团队的人可以管理这个告警规则,还有仪表盘、机器等,也都直接归给某个团队行么?
是可以 work 的,但是会有不便。比如 DBA 是一个团队,里边有 10 个人,这 10 个人负责所有的数据库,包括 mysql、redis、mongo 等,DBA 肯定希望不同的库不同的告警规则分别进行管理,所以,团队这个颗粒度有点大。
这个场景典型的解法是把团队拆小,比如把 DBA 拆成 mysql、redis、mongo 三个团队。但是这样拆还是不够细,比如 redis 相关的机器,有些可能部署的 redis 进程,有些可能部署的 proxy,其职能不同,所以从机器的分类需求来讲,只是 mysql、redis、mongo 这三个团队还是不够细。
为什么会出现这种问题?是因为 redis 进程、proxy 进程,这个分法的维度是根据部署的服务,而团队更多的是面向权限。
虽然机器按照团队来划分不太合适,因为机器的归类需要更细颗粒度的划分维度,对应的告警规则也是,需要比团队更细颗粒度的划分维度。但是像仪表盘、自愈脚本,本来就不多,可以直接归给团队,这样就不需要再细分了。
既然团队不能解决所有的归类需求,那就必须要引入一个新概念
这个新概念可以解决机器、告警规则等比团队更细颗粒度的划分需求。借鉴业内实现的话,就类似 Zabbix 中的 HostGroup 概念。本质上,HostGroup 就是一个容器,关联了一些有权限的人,HostGroup 里放机器,这些人可以操作这些机器,这样就解决了权限问题。
比如可以创建 dba-mysql、dba-redis、dba-mongo 这三个 HostGroup,分别放 mysql、redis、mongo 机器和相关的告警规则,这三个 HostGroup 关联的团队都是 dba 团队。
HostGroup 不但放机器,还放告警规则,所以叫 HostGroup 总感觉不太合适,就叫业务组吧。
后来想想,对于仪表盘、订阅规则、资源脚本等,其实也是类似的管理逻辑,所以都可以和业务组关联起来。所以,现在的夜莺 v7 里,各种实体都是归属某个业务组,使用业务组来管理权限,同时起到一定的分类过滤的作用。
业务组的问题
业务组也有很明显的问题。比如机器的划分,需要划分的很细,但是仪表盘不需要划分的那么细,所以,业务组到底是按照怎么一个颗粒度来划分呢?用机器的颗粒度来划分也不合适,用仪表盘的颗粒度来划分也不合适。
最好的方式,是分开划分。比如创建一个 dba 的业务组,放置仪表盘、自愈脚本等,再创建 dba-redis-instances 放置 redis 机器,创建 dba-redis-proxy 放置 proxy 机器。甚至,为了更清晰,你也可以把实体名称作为前缀,比如创建 仪表盘-dba
业务组放置 DBA 的仪表盘,自愈脚本-dba
业务组放置 DBA 的自愈脚本。
如果有机会重新设计,我不会让业务组在全局范围内复用,而很可能是:机器的划分机制称为 HostGroup,仪表盘直接没有划分机制(仅仅支持打标签),或者仪表盘的划分机制叫 DashboardGroup,告警规则的划分机制叫 RuleGroup,告警规则的划分机制甚至会改成 Tree。
不同实体真实的划分需求
简单粗暴使用业务组划分各类实体,实际是考虑不周的。那我们回归原始需求,看看各类实体真实的划分需求。
整体上来看,机器的划分需求最为特殊,咱们待会再说。其他的实体,包括仪表盘、自愈脚本、告警规则、订阅规则、屏蔽规则等,本质上只有两个需求,一个是权限,一个是筛选,最好的方式是:
- 实体本身支持打标签,支持根据名称、标签搜索
- 实体归属 Tree 节点,如果不需要很深的层级,就搞一层也可以,这是灵活的,用户自由控制
- 不同的实体所用的 Tree 相互隔离,不使用全局统一的 Tree
机器的划分需求,如下:
- 权限管控,控制哪些人可以对哪些机器有操作权限
- 附加标签,使用标签筛选机器,同时附加标签也一并打到机器的 metrics 上
- 资产归属管理,用于资产统计之类的,实际这个分类需求最好是在 CMDB 里搞定,如果 CMDB 没有搞定,用监控来搞也凑合可以
- 描述机器部署了哪些服务,后面需要根据这个信息配置采集规则、告警规则等
从产品设计角度,咱们应该如何抽象呢?
首先,标签肯定必须要有的,虽说最佳实践其实不是在页面上给机器打标签,而是在 agent 侧直接配置标签,但是不同的公司情况各异,有的公司甚至很难上去操作 agent,所以,通过页面给机器打标签从产品角度是必须的,尽管不是我心目中的最佳实践。
比如给机器打上标签:region=bj
、env=prod
、app=redis
,这样就可以根据标签筛选机器了。
权限需求可以复用标签么?比如打有 app=redis
的机器,授权给 redis-sre 团队来管理。抱歉不行,除非 app=redis
这个标签不是谁都可以打的,是很特殊的标签,否则,假设我是 redis-sre 团队一员,只要随意把某个机器打上 app=redis
标签,就可以管理这个机器了,这显然不合适。
所以权限需求,需要有另外一种机制。这可以是一个 Tree,也可以是一个 HostGroup,只有管理员可以把机器划分到某个 Tree 或 HostGroup 里,然后 Tree 或 HostGroup 关联的团队才能对这些机器进行后续操作。
资产归属,是多对一的,即多个机器归属某个组织,对于某一台特定的机器而言,只能归属一个组织。资产归属本质应该在 CMDB 之类的其他平台里管理,如果要把这个信息映射到监控系统中,可以通过标签实现。
最后说说机器部署了哪些服务,应该如何建模,使用标签显然是不行了,因为标签也作为时序数据的附加标签,在 Prometheus 生态里,标签 key 是不能重复的。所以对于混部的场景,需要另外的机制,这里可以有三种办法:
- 直接把机器挂到不同的组里,比如 dba-redis-instances、dba-redis-proxy
- 给机器搞一个特定的属性,比如叫 apps,值是一个数组,比如
["redis", "proxy"]
- 把这个信息放到机器的备注里,比如某个机器的备注是
app_redis app_proxy
不管是哪种方式,在告警规则或者仪表盘里,能够根据这些信息做筛选即可。如果硬要推荐一个最佳实践,我认为是第二种方式。因为这种方式,其数据更结构化。另外两种方式也凑合能用,但是使用这类数据的时候,必须要用户手工指定搜索条件才有意义,要想从全局做一些统计,几无可能。比如第一种方式,我不知道哪些组代表 app,第三种方式的话,我不知道哪些前缀作为 app,上例中我使用的 app,另一个公司可能就想叫 application 或者 service 呢。
结构化的数据,对自动化也更友好,比如 agent 根据采集规则,自动生成混部的服务列表,自动填充到服务端的机器信息里,结构化的数据显然更容易操作。
夜莺里的最佳实践
上面说的比较零散,实际是一些很关键的思考。落到实处,以现在夜莺的实现来看,这些需求应该怎么做是最佳实践呢?
- 仪表盘、自愈脚本、订阅规则、屏蔽规则,这类数量不多的实体,可以直接归类到一个相对高层的业务组里,比如 dba
- 告警规则,数量相对多,和机器的划分颗粒度不同,可以搞一个顶层节点叫
dbarules
,然后下面分门别类放置各类告警规则 - 机器,划分颗粒度最细,可以在 dba 下面创建各类子节点,放置机器,比如 dba-redis-instances、dba-redis-proxy
总结
本文主要讲了夜莺 v7 中的业务组的设计初衷,以及业务组的划分颗粒度和最佳实践。业务组是一个很宽泛的概念,可大可小,所以在具体实践时,很多朋友比较懵,本文希望能够帮助大家更好地理解业务组的设计初衷和最佳实践。