简介
老版本的夜莺监控有树形结构,不同机器可以挂在不同节点。从 v5 版本开始,夜莺取消了树形机器分组,转而使用一维业务组和标签。社区经常会问:为什么不继续使用树?树形结构以后是否还会重新引入?
这篇文章回答一个核心问题:夜莺为什么把“权限归属”和“机器筛选”拆开设计。简要说,业务组用于管理权限和配置对象,标签用于表达机器的多维属性,并且标签会进入时序数据,方便告警规则、监控大盘和 Grafana 等工具复用。
核心结论如下:
- 只用一维 HostGroup,简单但维度固定,跨维度筛选困难。
- 只用树形结构,可以表达归属层级,但业务语义与时序数据分离,告警和看图都要绕一层元信息查询。
- 只用标签,筛选最灵活,但权限治理会变复杂,也不够直观。
- 夜莺选择业务组 + 标签:业务组承载权限和配置归属,标签承载机器分类和时序过滤。
机器分组机制
机器分组机制常见有 3 种:扁平一维 HostGroup、树形结构、标签。它们都能完成“把机器组织起来”的任务,但解决的问题不同,代价也不同。
| 分组方式 | 适合解决的问题 | 主要不足 |
|---|---|---|
| HostGroup | 快速把一批机器绑定到采集规则、告警规则 | 维度单一,机器变更时可能要维护多个组 |
| 树形结构 | 表达组织、业务线、服务模块等层级关系 | 层级固定,元信息不在时序数据中,跨工具复用困难 |
| 标签 | 用多个维度描述同一台机器,便于灵活过滤 | 标签体系不直观,权限治理成本高 |
扁平一维的 HostGroup
Zabbix、Open-Falcon 都采用过类似 HostGroup 的设计:在 HostGroup 上绑定采集规则、告警规则,让规则对组内所有机器生效。这种方式简单直观,但灵活性不够。
假设创建了三个分组:
cloud.sre - 放置所有的 sre 的机器
cloud.sre.n9e - 放置所有的 n9e 的机器,因为 n9e 是 sre 团队搞的,所以用了一个 cloud.sre 的前缀
cloud.sre.n9e.mysql - 放置所有的 n9e 用到的 mysql 的机器
这里有两个问题:
- 添加或替换机器时要同时维护多个分组。比如
cloud.sre.n9e.mysql下更换一台机器,除了维护这个分组,还要维护cloud.sre和cloud.sre.n9e。 - 分组维度比较固化。如果想查询所有 MySQL 机器,不只包括 n9e 使用的 MySQL,也包括其他服务使用的 MySQL,单靠这种层级命名很难完成。
树形结构
树形结构相比 HostGroup 有明显优势,至少可以解决“同一台机器要重复维护多个分组”的问题。上面的三个分组转换成树形结构,大概是这样:
cloud
|- sre
|- n9e
|- mysql
mysql 节点下面的机器如果有调整,只调整这个节点即可。未来按树节点查询,比如查询 cloud.sre 下面的机器,自然也能把 mysql 下的机器查到。
但树形结构仍然有两个典型问题:
- 层级仍然比较固化,无法天然解决其他维度的过滤需求。你当然可以再创建一个
mysql节点,专门放所有 MySQL 机器,但节点越多,维护成本越高。 - 树节点带有业务语义,后续写告警规则、配置监控大盘时很可能要使用这些节点做过滤。问题在于:时序数据在时序库里,机器元信息在树形结构里。比如要对所有 n9e 机器配置
cpu.idle < 10%的告警,就需要先查树形结构得到机器列表,再拿机器列表去时序库里查数据。Grafana 等工具直接查时序库时,也无法复用这些树节点元信息,因为时序库里没有这些元信息。
标签的方式
标签方式是对机器打多个 key=value 标签。比如某台机器打上这些标签:
dept=cloud team=sre product=n9e service=mysql
这些标签表达了机器来自 cloud 部门、sre 团队,用于部署 n9e 产品和 mysql 服务模块。相比 HostGroup,标签相当于让一台机器同时属于多个分组,并且每个分组都有明确维度。标签 Key 就是维度信息。换个角度看,树形结构可以理解为固定标签 Key 顺序的一种组织方式。
标签最灵活,但也有一个核心问题:不直观。比如公司有 1 万台机器,每台机器有七八个标签。虽然标签可以做灵活筛选,但不了解标签体系的人,可能根本不知道有哪些标签,也就无从筛选。
夜莺的方式
夜莺的方式,是综合 HostGroup 和标签:用业务组解决权限和配置归属,用标签解决机器的多维分类。
最初设计时,我甚至不想要业务组,只想让机器直接打标签。标签不直观的问题,可以通过 UI 解决一部分,比如在筛选区展示常见标签,让用户点击筛选。
真正改变设计的是权限问题。夜莺希望把故障自愈、批量执行脚本的能力开放出来,而这类能力必须有强权限控制,不能让用户随便在机器上执行命令。因此系统必须回答:哪些人可以对哪些机器做操作?
最简单的办法是给每台机器配置操作权限,但这显然太麻烦。仍然需要一个分组能力,用来一次性配置一批机器的权限。继续用标签行不行?比如给 dept=cloud 的所有机器配置权限。看起来可以,但会引出新的治理问题:谁能给机器打上 dept=cloud?谁能把机器从这个标签下移除?如果任何人都能改,权限就会失控。
为标签设置管理员似乎能缓解问题,但仍然不自然。标签本应是轻量、灵活的维度分组机制,如果把标签和管理人员、权限边界强绑定,标签体系会越来越重。权限是管理范畴,标签是分类范畴,二者紧密耦合并不合适。
因此,夜莺的设计思路变成了:用分组管理权限,用标签管理机器分类。
还有一个相关问题:告警规则、监控大盘、订阅规则、屏蔽规则等配置对象也需要分组。公司里如果有几千条告警规则,全部放在一个表格里会很混乱,同时也需要权限控制:我们团队的规则,其他团队不能乱改。
机器权限管理和告警规则权限管理,本质上可以用同一个概念解决,这就是夜莺里的业务组。一个业务组下可以有很多机器;业务组里的机器如果需要更细粒度划分,就继续使用标签。有些业务组也可以没有机器,只用来管理告警规则、监控大盘等配置对象。
业务组和标签如何分工
在夜莺里,业务组和标签不是互相替代,而是各司其职。
| 对象 | 主要职责 | 典型场景 |
|---|---|---|
| 业务组 | 权限边界、配置归属、机器归属 | 管理机器权限、告警规则、屏蔽规则、订阅规则、自愈脚本、监控大盘 |
| 标签 | 多维筛选、时序数据过滤、细粒度分类 | 按 service=mysql、team=sre、product=n9e 查询指标或配置规则 |
如果你的问题是“谁有权限操作这批机器或规则”,优先考虑业务组。如果你的问题是“如何在同一批机器里按服务、团队、产品继续筛选”,优先使用标签。
总结
- 业务组既可以管理机器,也可以管理告警规则、屏蔽规则、订阅规则、自愈脚本、监控大盘。
- 业务组下可以有机器,也可以完全没有机器。
- 用于管理机器的业务组,可以按照资产归属范围划分。比如机器归属于各个业务线,就按业务线划分。
- 用于管理规则、大盘的业务组,不必按照资产归属划分,可以按照产品、服务等维度划分。
- 业务组虽然是一维的,但命名时建议用前缀表达关联关系。比如管理 n9e 基础告警规则的业务组可以叫
n9e-rules,管理 n9e.mysql 告警规则的业务组可以叫n9e-mysql-rules。
夜莺取消树形结构,不是因为树形结构没有价值,而是因为监控系统里的机器归属、权限治理、告警配置和时序数据过滤混在一起后,树形结构很难同时解决这些问题。业务组 + 标签的组合,把管理边界和数据维度拆开,才更适合监控告警系统长期维护。
