Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

项目整体设计思路 #1

Open
UlricQin opened this issue Nov 22, 2023 · 16 comments
Open

项目整体设计思路 #1

UlricQin opened this issue Nov 22, 2023 · 16 comments
Labels

Comments

@UlricQin
Copy link
Contributor

UlricQin commented Nov 22, 2023

背景

背景信息见这篇文章:《招贤令:一起来搞一个新的开源项目

整体逻辑

相当于是 Prometheus 的 Service Discovery 部分(简称 SD) + 各类 Exporter + Remote Write。即:通过 SD 找到要监控的目标,通过 Exporter 的逻辑来抓取指标,通过 Remote Write 发送数据到时序库。没错,这是一个缝合怪。

希望达成的效果

  • 使用一个进程,即可监控各类目标,比如 MySQL、Redis、ElasticSearch、网络设备等。/metrics 暴露的数据暂不提供抓取能力,因为 Prometheus agent mode 或者 vmagent 已经可以很好的解决这个问题
  • 具备方便的服务发现机制,比如 HTTP SD 来跟 CMDB 等打通,Network SD 来发现网络设备,File SD 来读取本机配置文件。以 MySQL 监控举例,原本 SD 机制发现的是 mysqld_exporter 的 /metrics 地址,现在直接发现 MySQL 实例的地址,直接连到这些实例上采集数据
  • 各类 Exporter 只有一个规范,就是暴露 /metrics 接口数据,至于如何管理配置,Exporter 和目标实例之间是一对一关系还是一对多关系,都没有规范,导致不同的 Exporter 设计各异,没有一致性的体验。这个项目来解决这些一致性的体验和规范问题
  • 尽量复用 Prometheus 的 scrape 配置,降低学习成本,并对 scrape 配置做扩展,比如监控网络设备要配置各类 OID,监控 Postgres 要配置一些 SQL 语句,这类配置姑且称为采集规则:scrape_rules,scrape_configs 中要引用这些 scrape_rules,并对这些 rules 进行切文件管理

举例

以 MySQL 监控举例,大概需要这么配置 scrape_configs:

scrape_configs:
- job_name: mysql-prod
  scrape_rules:
  - /etc/prometheus/mysql.rules/common.toml
  - /etc/prometheus/mysql.rules/schema_size.toml
  - /etc/prometheus/mysql.rules/biz.toml
  static_configs:
  - targets:
    - 10.1.2.3:3306
    - 10.1.2.5:3306
    labels:
      group: "mysql_from_static"

MySQL 有一些通用的采集规则,放到 common.toml 中,比如采集 global status、global variables,有一些不太通用的采集规则则放在其他规则文件中,比如采集 schema 大小的配置放到 schema_size.toml,业务自定义的监控 SQL 放到 biz.toml 中。之所以用 toml 举例,是因为多个 toml rule 直接 merge 成一个大配置即可,如果是 json 或者 yaml 就不太好 merge 处理了。

各类 SD 发现的 target 列表,格式如下(使用 json 举例):

[
    {
        "targets": ["10.1.2.3:3306"],
        "labels": {
            "project": "foo",
            "region": "beijing"
        }
    },
    {
        "targets": ["10.1.2.4:3306"],
        "labels": {
            "project": "bar",
            "region": "beijing"
        }
    }
]

labels 部分是个 map,我也有在考虑是否引入一个 path 的概念来表示树路径,很多 CMDB 在维护 target 的时候,都是挂到树形结构下。一个 target 可能会挂在多个节点下,导致没法使用 map 来描述这个关系。引入 path 之后,结构举例:

[
    {
        "targets": ["10.1.2.3:3306"],
        "labels": {
            "project": "foo",
            "region": "beijing"
        },
        "paths": [
            "dba.cloud",
            "dba.shop"
        ]
    },
    {
        "targets": ["10.1.2.4:3306"],
        "labels": {
            "project": "bar",
            "region": "beijing"
        },
        "paths": [
            "dba.cloud"
        ]
    }
]

之后在 scrape_configs 中可以基于 paths 信息做过滤,不过这个设计尚未想清楚。

对于 Prometheus 而言,只需要发现 HTTP 抓取地址即可,但现在我们想直接抓目标 target,比如要抓网络设备,这个时候就需要额外的 SD 机制,比如 snmp_sd_configs,举例:

- job_name: network-x
  snmp_sd_configs:
  - refresh_interval: 1m
    cidr:
    - "10.1.2.0/24"
    - "10.1.3.0/24"
    range:
    - "10.2.3.2-254"
    - "10.2.3.3-254"
    port: 3306
    community: public
    version: 2

其他改造和重难点

关于认证,原本 Prometheus 只需要处理 HTTP 相关的认证,现在要直连监控目标,可能要处理不同的认证方式,比如网络设备有 SNMP 专属认证机制,MySQL 则走 TCP,不同的 scrape job 就需要不同的认证机制。

Prometheus 有多种不同的 SD 机制,现在要直连监控目标,SD 相关的代码需要想办法复用,如果每类监控目标都要拷贝一坨 SD 代码就非常麻烦了。后面再具体考虑。

任何问题或建议,欢迎留言。

@kuluce
Copy link

kuluce commented Nov 22, 2023

期望的效果是一个进程应对各种的监控场景,拷贝一坨SD代码好像没办法避免

@UlricQin
Copy link
Contributor Author

期望的效果是一个进程应对各种的监控场景,拷贝一坨SD代码好像没办法避免

对于终端用户是没法避免的,我的本意不是指用户的SD配置,是说代码实现的时候,如何抹除各个插件的差异,让SD代码是一份哈:)

@robotneo
Copy link

robotneo commented Nov 22, 2023

网络设备扫描发现建议新的自动发现 同时保留file sd 扫描阶段最好可以基于不同网段配置不同团体名 在同一个snmp_sd_configs中,比如:

scrape_configs:  
  snmp_sd_configs:
  - refresh_interval: 1m
    cidr:
    - "192.168.1.0/24"
    range:
    - "192.168.1.1-253"
    port: 161  # 端口参数不写 就默认161
    auth: 
      - community: public456
      - version: 2`
    cidr:
    - "172.16.1.0/24"
    range:
    - "172.16.1.1-253"
    port: 161  # 端口参数不写 就默认161
    auth: 
      - community: public123
      - version: 2

@UlricQin
Copy link
Contributor Author

@robotneo 你的意思是网络设备采集的job要同时支持file_sd和snmp_sd是么?如果是这个问题的话是会的,基础的file_sd、http_sd 之类的所有监控类别都是具备的。另一个问题也是支持的,不同的job可以配置不同的认证信息

@songtao98
Copy link

不懂就问:

原本 SD 机制发现的是 mysqld_exporter 的 /metrics 地址,现在直接发现 MySQL 实例的地址,直接连到这些实例上采集数据

所谓的直连实例采集数据,具体想要实现的是什么效果,是不仅要完成SD,还要替代各种exporter自身采集指标的逻辑吗?倘若该项目应用在大规模的云集群中,这样的方式会不会需要考虑各类权限相关的问题的设计?

@huyouba1
Copy link

huyouba1 commented Nov 22, 2023

感觉可以参考一下zabbix agent的SD机制,以及他对黑盒场景的探测,还有就是利用不同的监控模板来监控不同的服务的方式,尽量保留这方面的监控采集开关

@Brant-lzh
Copy link
Contributor

/metrics 暴露的数据暂不提供抓取能力
是用过remote_write的方式吗?

@joker-bai
Copy link
Contributor

通过自动发现获取目标实例,通过HTTP方式获取目标的原始指标,然后构建成prometheus指标?

@UlricQin
Copy link
Contributor Author

不懂就问:

原本 SD 机制发现的是 mysqld_exporter 的 /metrics 地址,现在直接发现 MySQL 实例的地址,直接连到这些实例上采集数据

所谓的直连实例采集数据,具体想要实现的是什么效果,是不仅要完成SD,还要替代各种exporter自身采集指标的逻辑吗?倘若该项目应用在大规模的云集群中,这样的方式会不会需要考虑各类权限相关的问题的设计?

核心就是要整合exporter,所以是会替代exporter自身采集逻辑。权限跟散的exporter是一样的,原本需要给exporter授权的现在就要给这个新组件授权。

@UlricQin
Copy link
Contributor Author

感觉可以参考一下zabbix agent的SD机制,以及他对黑盒场景的探测,还有就是利用不同的监控模板来监控不同的服务的方式,尽量保留这方面的监控采集开关

scrape_rules 就相当于模板了,这个东西可以沉淀。

@UlricQin
Copy link
Contributor Author

UlricQin commented Nov 22, 2023

/metrics 暴露的数据暂不提供抓取能力 是用过remote_write的方式吗?

这个数据可以用 vmagent 来抓,也可以用 Prometheus 来抓,当前这个组件暂未考虑抓这类数据,不过也保不齐,具体写代码的时候再看要不要挪过来。总之是这部分社区是有能力的,重复做意义不太大,如果顺手就做了,也可以做。

@UlricQin
Copy link
Contributor Author

通过自动发现获取目标实例,通过HTTP方式获取目标的原始指标,然后构建成prometheus指标?

通过服务发现找到要监控的目标地址,比如mysql的 10.1.2.3:3306 这个地址,然后直连上去执行 show global status 之类的命令获取数据,转换成 Prometheus 协议的指标发给时序库

@songtao98
Copy link

不懂就问:

原本 SD 机制发现的是 mysqld_exporter 的 /metrics 地址,现在直接发现 MySQL 实例的地址,直接连到这些实例上采集数据

所谓的直连实例采集数据,具体想要实现的是什么效果,是不仅要完成SD,还要替代各种exporter自身采集指标的逻辑吗?倘若该项目应用在大规模的云集群中,这样的方式会不会需要考虑各类权限相关的问题的设计?

核心就是要整合exporter,所以是会替代exporter自身采集逻辑。权限跟散的exporter是一样的,原本需要给exporter授权的现在就要给这个新组件授权。

假如一个cprobe进程可以替代(整合)所有的exporter,是否在性能开销上可能会有一定的劣势?——cprobe既要完成exporter的采集任务,又要负责网络层面上的服务发现

@UlricQin
Copy link
Contributor Author

不懂就问:

原本 SD 机制发现的是 mysqld_exporter 的 /metrics 地址,现在直接发现 MySQL 实例的地址,直接连到这些实例上采集数据

所谓的直连实例采集数据,具体想要实现的是什么效果,是不仅要完成SD,还要替代各种exporter自身采集指标的逻辑吗?倘若该项目应用在大规模的云集群中,这样的方式会不会需要考虑各类权限相关的问题的设计?

核心就是要整合exporter,所以是会替代exporter自身采集逻辑。权限跟散的exporter是一样的,原本需要给exporter授权的现在就要给这个新组件授权。

假如一个cprobe进程可以替代(整合)所有的exporter,是否在性能开销上可能会有一定的劣势?——cprobe既要完成exporter的采集任务,又要负责网络层面上的服务发现

如果体量很大,就需要做切片,通过类似 hashmod 的方式或者垂直业务切分,比如一个 cprobe 负责几百个 mysql 实例的采集,另一个 cprobe 负责几百个 redis 的采集。但是配置体验经过统一化改造设计,会更加一致

UlricQin pushed a commit that referenced this issue Nov 30, 2023
@Sniper91
Copy link

Sniper91 commented Jan 2, 2024

我们之前也有想做过类似事情,但是依赖各种 exporter,更新会变的非常麻烦。

  • 一个 exporter 的更新就要更新整个 agent
  • exporter 和监控目标的版本适配不好做,比如有些老版本的k8s 就只能用老版本的 exporter
  • 插件机制怎么隔离啥的,不知道这边有啥想法没有?

@UlricQin
Copy link
Contributor Author

UlricQin commented Jan 3, 2024

我们之前也有想做过类似事情,但是依赖各种 exporter,更新会变的非常麻烦。

  • 一个 exporter 的更新就要更新整个 agent
  • exporter 和监控目标的版本适配不好做,比如有些老版本的k8s 就只能用老版本的 exporter
  • 插件机制怎么隔离啥的,不知道这边有啥想法没有?
  1. 是有这个问题的,不过很多exporter其实已经基本不更新了,即便有改动,改动也不大,而且,最后拼的是生态拼的用户,如果某个采集逻辑不合适,cprobe如果被大量使用,就一定有用户会反馈,改起来其实也蛮快,如果大家都不反馈,可能那个升级逻辑也没有太关键。换句话说,这个问题确实有,不过没有想的那么大。
  2. 一般都是只采纳应用最广泛的那个
  3. 配置层面就是 conf.d 下面拆分目录,运行层面就是拆分不同的 goroutine,相互不影响

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants