专栏:手把手构建生产级监控系统

秦晓辉 2024年1月1日

笔者去年在极客时间发布了一个专栏《运维监控系统实战笔记》,很多朋友借此梳理了较为体系化的运维监控系统知识,但是限于专栏篇幅,有些手把手实操类的内容没有办法展开,另外时隔一年,监控系统的技术栈也有了一些变化,所以笔者决定在这里把这些内容补充完整。

监控系统的典型架构

对于一些前置背景知识、名词解释、行业黑话,请大家自行阅读之前的专栏,这里不再赘述。这个新的专栏更多是偏向实操,不过在开始之前,还是要先回顾一下监控系统的典型架构,如下图:

20240102073028

对于上图中的每个模块,都有开源和商业的解决方案,具体如何选型,可以参考之前的专栏,在当下时点,2024.1.1,笔者的建议是:

  • 采集器:如果仅限于开源,那么推荐 Otel Collector + Cprobe,如果有预算,那么推荐 Categraf,可以有商业支持,省心不少。理由:Otel Collector 是个巨型缝合怪,内置了很多采集插件,可以作为单机上的 Daemonset 采集器,采集日志和机器维度的指标,虽然 Otel Collector 也集成了中间件、数据库的指标,但是集成的比较生硬,没有很好的目标实例发现机制;Cprobe 可以看做是 vmagent 和各类 exporter 的缝合怪,支持目标实例服务发现,用于采集各类中间件、数据库的指标,小巧好用。如果你觉得 Otel Collector 太重了,就用 Cprobe + Node-Exporter 也可以满足指标监控的需求。
  • 时序库:毫无疑问会推荐 VictoriaMetrics,一般公司使用单机版就够了,每秒承载 100 多万指标的上报,稳定可靠。如果公司有多个数据中心,可以每个数据中心部署一个 VictoriaMetrics,让机房内部的监控能力自闭环,避免机房网络割裂时,监控系统不可用。
  • 数据展示分析:毫无疑问是 Grafana,虽然我们团队开源了 Nightingale 可以作为国产替代,但是 Grafana 确实更为强大,支持的数据源类型也更多,毕竟人家做了很多年了。
  • 告警判定引擎:比如 Prometheus,是内置告警引擎的,但就需要维护配置文件,如果很多个团队一起使用,协作上会比较费劲。另外就是通常一个公司会有多套时序库,一套规则可能要同时应用到多个时序库,管理起来比较麻烦。所以我们才开源了 Nightingale,主打告警管理。
  • 告警事件分发:这块没有很好的开源方案,只有 Prometheus 生态的 alertmanager 算是有那么点意思。商业方案比较多,国外是 PagerdutyOpsgenie,国内是睿象云Flashduty。最新版本的 Flashduty 不但支持告警事件降噪、分发、排班、认领、升级等告警事件层面的功能,还直接内置了告警引擎,相当于不再需要部署 Nightingale 了,对用户而言那是大大的省心。

于是乎,当下时点,笔者建议的监控系统架构选型如下:

20240102081306

快速安装体验

这是专栏第一篇,我们先快速安装起来,体验一下,后面再逐步深入。我手头有一台虚拟机,Arm 架构的,我们就在这个机器上安装。从依赖关系来看,时序库是最底层的,所以我们先安装 VictoriaMetrics。

安装 VictoriaMetrics

监控系统通常是 P0 级的系统,即所有系统都挂了,监控也不能挂,要不然就是两眼一抹黑,VictoriaMetrics 个人建议使用二进制部署,不要部署到 Kubernetes 中,以防 Kubernetes 挂了监控也没法用。VictoriaMetrics 在 github 提供二进制,地址如下:

我下载最新版本的 linux arm64 的包:victoria-metrics-linux-arm64-v1.96.0.tar.gz,完事解压缩,里边只有一个二进制 victoria-metrics-prod,启动即可:

nohup ./victoria-metrics-prod &> stdout.log &

我这里为了演示方便,姑且使用 nohup 启动的,实际生产环境,可以使用 systemd 或者 supervisord 等工具来管理,并设置开机自启动。启动之后,通过 ss -tlnp|grep 8428 可以检查端口是否在监听,正常来讲, VictoriaMetrics 会监听 8428 端口,同时会在当前目录下创建 victoria-metrics-data 目录用于存放数据。来,浏览器访问 8428 看一眼庐山真面目(如果启动失败或浏览器无法访问,检查 selinux 和 firewalld 是否关闭):

20240102090120

点击 vmui 可以进入 Web UI,不过现在还没有采集数据,所以看不到什么东西。下面我们把采集器安装起来。

安装 Cprobe

Cprobe 的发布包也是在 github releases 上,地址如下:

根据你自己的环境选择下载最新的发布包即可。解压缩,里边的内容就比较丰富了,有 cprobe 二进制以及 conf.d 配置目录,conf.d 下有不同的子目录,每个子目录就是一个采集插件,其中 writer.yaml 是配置 remote write 地址的,Cprobe 采集了数据之后要推给远端时序库,就是在 writer.yaml 中配置远端时序库的地址,这里我们配置的是 VictoriaMetrics 的地址:

global:
  extra_labels:
    colld: cprobe

writers:
- url: http://127.0.0.1:8428/api/v1/write
  concurrency: 1

注意,默认 url 配置是 9090 端口,这里我们使用 VictoriaMetrics,所以端口改成 8428。之后,我们启用其中一个插件来验证效果,姑且启用 Blackbox 插件,这个比较简单,我们就对 www.baidu.com 和 flashcat.cloud 两个域名做一下黑盒监控。进入 conf.d/blackbox 目录下,修改 main.yaml,内容如下:

global:
  scrape_interval: 15s
  external_labels:
    cplugin: 'blackbox'

scrape_configs:
- job_name: 'blackbox_http_external'
  static_configs:
  - targets:
    - 'https://www.baidu.com'
    - 'https://flashcat.cloud'
  scrape_rule_files:
  - 'rule.d/http_2xx_get.yaml'

完成配置修改,我们先测试一下是否能抓到数据,执行下面的命令:

./cprobe --no-writer --no-httpd --plugins blackbox

这个命令给 cprobe 传了三个参数,含义是:

  • --no-writer:不推送数据到远端时序库,仅仅是把采集到的数据打印到控制台
  • --no-httpd:不启动 httpd 服务,cprobe 实际内置了一个 http 服务,用于做健康检查,测试时不启动
  • --plugins blackbox:仅启动 blackbox 插件

执行之后,会在控制台看到输出很多指标,就表示采集成功了。接下来我们正式启动 cprobe 进程。

# install 参数用于安装,如果是支持 systemd 的系统,install 会自动生成 systemd 的 service 文件
./cprobe --install

# start 参数用于启动 cprobe 进程,如果是支持 systemd 的系统,start 相当于 systemctl start cprobe
./cprobe --start

# 通过 status 查看 cprobe 进程状态
./cprobe --status

之后,再次访问 vmui 就可以看到采集到的数据了:

20240102092903

上面我是测试的 probe_dns_lookup_time_seconds 指标,其他指标你可以自行尝试。Cprobe 定位是中心式探针,采集比如 MySQL、Redis、Postgres、ElasticSearch 等中间件、数据库的指标,那如果要采集机器维度的指标,比如 CPU、内存、磁盘、网络等,就需要使用 Node-Exporter 了。

安装 Node-Exporter

Node-Exporter 下载地址在 Prometheus 官网可以找到:

下载最新版本的 node_exporter,解压缩,启动即可:

nohup ./node_exporter &> stdout.log &

启动之后,通过 ss -tlnp|grep 9100 可以检查端口是否在监听,正常来讲, Node-Exporter 会监听 9100 端口。通过下面的命令可以获取到 Node-Exporter 相关的指标:

curl -s http://10.211.55.3:9100/metrics

10.211.55.3 是我的机器的 IP,你要换成你的机器的 IP。如果正常的话,你会看到很多指标。接下来我们通过 cprobe 来抓取 Node-Exporter 的指标,然后推给 VictoriaMetrics。配置也很简单,进入 cprobe 的 conf.d/prometheus 目录,修改 main.yaml,内容如下:

global:
  scrape_interval: 15s
  external_labels:
    cplugin: 'prometheus'

scrape_configs:
- job_name: 'node_exporter'
  static_configs:
  - targets:
    - 'http://127.0.0.1:9100/metrics'
  scrape_rule_files:
  - 'rule.toml'

完成配置修改,我们先测试一下是否能抓到数据,执行下面的命令:

./cprobe --no-writer --no-httpd --plugins prometheus

正常来讲,会输出很多指标,表示采集成功了。接下来我们给 cprobe 发个 HUP 信号,让 cprobe 重载配置文件,然后就可以去 VictoriaMetrics 查看采集的数据了:

kill -HUP `pidof cprobe`

20240102100502

数据都采集成功了,接下来我们就可以在 Grafana 中展示这些数据了。

安装 Grafana

Grafana 我这里采用 9.5 的版本,从 grafana.com 官网直接下载即可:

wget https://dl.grafana.com/oss/release/grafana-9.5.15.linux-arm64.tar.gz
tar -zxvf grafana-9.5.15.linux-arm64.tar.gz
cd grafana-v9.5.15
nohup ./bin/grafana-server &> stdout.log &

Grafana 监听在 3000 端口,访问 3000 端口,输入 admin/admin 登录即可。在 Administration -> Data Sources 中添加 VictoriaMetrics 数据源(选择 Prometheus 数据源类型,VictoriaMetrics 和 Prometheus 接口兼容,所以,就把 VictoriaMetrics 当做 Prometheus 来看待即可),如下图是添加成功之后的列表页面:

20240102101452

之后可以导入仪表盘,我们先导入 Node-Exporter 的仪表盘,仪表盘地址:

可以直接复制仪表盘 ID 1860,然后在 Grafana 中导入即可。导入之后,就可以看到 Node-Exporter 的数据了:

20240102101805

Blackbox 的指标中,原本 Blackbox Exporter 中的 probe_duration_seconds 在 cprobe 下 rename 成了 blackbox_cprobe_duration_seconds,可以导入这个仪表盘:

https://github.com/cprobe/cprobe/blob/main/conf.d/blackbox/doc/dash/grafana_blackbox_01.json

效果如下,截个图给大家看看:

20240102105103

安装告警引擎

时序库有了,采集器有了,可视化工具有了,就差告警引擎和事件分发了,这块说实话比较琐碎,零散的点太多,有四个方案:

  • Prometheus 的话可以直接在 prometheus.yml 中配置告警规则,搭配 alertmanager 使用,需要折腾 yaml 文件
  • VictoriaMetrics 也提供了 vmalert 组件作为告警引擎,搭配 alertmanager 使用,也是需要折腾 yaml 文件
  • Nightingale 作为告警引擎,对接不同的时序库,也可以对接 Loki、TDEngine 等其他存储,可以通过 Web UI 来配置告警规则,也可以通过 API 管理
  • Flashduty 既提供告警事件分发,也提供告警引擎,可以直接在 Web UI 中配置告警规则,也可以通过 API 管理

前面三个方案都是开源方案,Flashduty 是 SaaS 商业产品,按量计费,无需运维。至于选择开源自己折腾,还是选择 SaaS 开箱即用,就看大家各自的需求了。笔者使用 Flashduty 来讲解告警体系的全流程。

20240102112745

Flashduty 主要干的事情包括:

  • 和各个监控系统(比如 Prometheus、Nightingale、Zabbix、云监控)对接,收集告警事件,放到中心统一化处理和响应
  • 做告警事件的降噪、分发、排班、认领、升级等,确保告警处理不遗漏的同时减少打扰,提升工程师幸福感
  • 告警事件的统计分析,建立处理效率多维分析指标,推动故障处理时间持续下降
  • 提供告警判定引擎,和时序库、日志库直接对接,提供灵活的告警方式,内置常用的告警规则模板,这个功能是新功能,目前正在公测

安装 monitedge

首先免费注册一个 Flashduty 账号,地址:https://console.flashcat.cloud/。注册之后,登录控制台,右上角有个监控管理的菜单,点击进入会提示你安装告警引擎,选择对应的安装方式,安装即可,我这里采用 Linux 安装方式:

20240102114613

一条命令即可完成安装。如果你想知道安装脚本里具体干了啥,可以把 curl 后面那个 shell 脚本下载下来看看。实际就是安装了 monitedge 进程,放到了 /opt/monitedge 目录下,自动生成了 systemd 所需的 monitedge.service 文件。安装之后,使用 ps 查看:

20240102114835

此时,在 Flashduty 控制台 中,也可以看到告警引擎的状态。

20240102115317

配置数据源

monitedge 要做监控数据异常判定,需要:

  • 从 Flashduty WEB 拉取告警规则,缓存到内存里,针对每条规则做周期性的判定
  • 能够连到时序库,要不然查不到数据没法做告警判定

一个公司可能有多个 Prometheus、VictoriaMetrics,怎么把数据源的连接地址告诉 monitedge 呢?直接在 https://console.flashcat.cloud/monit/datasource 页面配置数据源即可。monitedge 会自动从 WEB 把数据源的信息拉取下来。当然,也可以通过本地配置文件的方式来告诉 monitedge,但如果有多个 monitedge 实例组成集群,配置管理就不方便了,所以还是建议在 Flashduty WEB 上配置。下面是我的配置举例:

20240102120535

配置告警规则

每个业务一般都有挺多告警规则,比如机器的、MySQL的、Redis的、应用程序的,需要分门别类的管理,那这里我会创建一个树形分组,来放置不同的告警规则,对于 NodeExporter 采集的数据,Flashduty 已经内置了常见的告警规则,导入即可,如下图:

20240102121244

20240102121734

20240102121831

完活了。后面如果有指标异常,就会触发告警事件。为了尽快看到效果,我们克隆一个告警规则,故意把阈值改一改,让它必然会触发,比如:

20240102122401

稍等片刻,点击规则列表页面的刷新按钮,就可以看到刚才的告警规则已经是 Triggered 状态了。

20240102122520

点击 Triggered 这个小按钮,就能看到相关的告警事件了。此时,如果我们继续修改阈值,比如改成 $A > 999,稍等片刻,刷新,就会看到告警事件已经是 Ok 状态了。点击刚才那个规则的 Ok 按钮,侧拉板里会看到告警的详情,在关联事件那个 tab 下会看到一条告警事件,一条恢复事件:

20240102122755

安装告警事件分发

上面的例子可以看到,告警事件生成了,如果想要定义灵活的分派策略,可以进入【故障管理】-【协作空间】-【某个协作空间】,在里边配置分派策略。

20240102123329

我们可以定义不同的时段、不同的告警,发给不同的人或值班组,使用不同的通知媒介。如果长时间没有认领的故障,还可以配置升级策略,升级给二线人员,避免告警遗漏。这里就不展开了,大家可以自行尝试。

小结

工欲善其事必先利其器,本专栏作为第一篇,我们把监控系统的底座构建了起来,后续会逐步深入,把监控系统的各个方面都给大家讲解清楚,敬请期待。

开源版
Flashcat
Flashduty