夜莺介绍
夜莺监控( Nightingale )是一款国产、开源云原生监控分析系统,采用 All-In-One 的设计,集数据采集、可视化、监控告警、数据分析于一体。于 2020 年 3 月 20 日,在 github 上发布 v1 版本,已累计迭代 60 多个版本。从 v5 版本开始与 Prometheus、VictoriaMetrics、Grafana、Telegraf、Datadog 等生态紧密协同集成,提供开箱即用的企业级监控分析和告警能力,已有众多企业选择将 Prometheus + AlertManager + Grafana 的组合方案升级为使用夜莺监控。夜莺监控,由滴滴开发和开源,并于 2022 年 5 月 11 日,捐赠予中国计算机学会开源发展委员会(CCF ODC),为 CCF ODC 成立后接受捐赠的第一个开源项目。夜莺监控的核心开发团队,也是Open-Falcon项目原核心研发人员。
Nightingale 可以接收各种采集器上报的监控数据,转存到时序库(可以支持Prometheus、M3DB、VictoriaMetrics、Thanos等),并提供告警规则、屏蔽规则、订阅规则的配置能力,提供监控数据的查看能力,提供告警自愈机制(告警触发之后自动回调某个webhook地址或者执行某个脚本),提供历史告警事件的存储管理、分组查看的能力。
系统架构
夜莺 v5 的设计非常简单,核心是 server 和 webapi 两个模块,webapi 无状态,放到中心端,承接前端请求,将用户配置写入数据库;server 是告警引擎和数据转发模块,一般随着时序库走,一个时序库就对应一套 server,每套 server 可以只用一个实例,也可以多个实例组成集群,server 可以接收 Categraf、Telegraf、Grafana-Agent、Datadog-Agent、Falcon-Plugins 上报的数据,写入后端时序库,周期性从数据库同步告警规则,然后查询时序库做告警判断。每套 server 依赖一个 redis。
安装部署
服务端组件部署
首先我们来看下面的架构图,夜莺的服务端有两个模块:n9e-webapi 和 n9e-server,n9e-webapi 用于提供 API 给前端 JavaScript 使用,n9e-server 的职责是告警引擎和数据转发器。依赖的组件有 MySQL、Redis、时序库,时序库我们这里使用 Prometheus。
组件安装
mysql、redis、prometheus,这三个组件都是开源软件,请大家自行安装,其中 prometheus 在启动的时候要注意开启 –enable-feature=remote-write-receiver ,如果之前贵司已经有 Prometheus 了,也可以直接使用,无需再次部署。这里也提供一个小脚本来安装这3个组件,大家可以参考:
# install prometheus
mkdir -p /opt/prometheus
wget https://s3-gz01.didistatic.com/n9e-pub/prome/prometheus-2.28.0.linux-amd64.tar.gz -O prometheus-2.28.0.linux-amd64.tar.gz
tar xf prometheus-2.28.0.linux-amd64.tar.gz
cp -far prometheus-2.28.0.linux-amd64/* /opt/prometheus/
# service
cat <<EOF >/etc/systemd/system/prometheus.service
[Unit]
Description="prometheus"
Documentation=https://prometheus.io/
After=network.target
[Service]
Type=simple
ExecStart=/opt/prometheus/prometheus --config.file=/opt/prometheus/prometheus.yml --storage.tsdb.path=/opt/prometheus/data --web.enable-lifecycle --enable-feature=remote-write-receiver --query.lookback-delta=2m
Restart=on-failure
SuccessExitStatus=0
LimitNOFILE=65536
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=prometheus
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable prometheus
systemctl restart prometheus
systemctl status prometheus
# install mysql
yum -y install mariadb*
systemctl enable mariadb
systemctl restart mariadb
mysql -e "SET PASSWORD FOR 'root'@'localhost' = PASSWORD('1234');"
# install redis
yum install -y redis
systemctl enable redis
systemctl restart redis
安装夜莺
mkdir -p /opt/n9e && cd /opt/n9e
# 去 https://github.com/didi/nightingale/releases 找最新版本的包,文档里的包地址可能已经不是最新的了
tarball=n9e-5.8.0.tar.gz
urlpath=https://github.com/didi/nightingale/releases/download/v5.8.0/${tarball}
wget $urlpath || exit 1
tar zxvf ${tarball}
mysql -uroot -p1234 < docker/initsql/a-n9e.sql
nohup ./n9e server &> server.log &
nohup ./n9e webapi &> webapi.log &
# check logs
# check port
如果启动成功,server 默认会监听在 19000 端口,webapi 会监听在 18000 端口,且日志没有报错。上面使用 nohup 简单演示,生产环境建议用 systemd 托管。
配置文件etc/server.conf和etc/webapi.conf中都含有 mysql 的连接地址配置,检查一下用户名和密码,prometheus 如果使用上面的脚本安装,默认会监听本机 9090 端口,server.conf 和 webapi.conf 中的 prometheus 相关地址都不用修改就是对的,如果使用贵司之前已有的 Prometheus,就要检查这俩配置文件中的时序库的配置了,把 127.0.0.1:9090 改成你的 Prometheus。
好了,浏览器访问 webapi 的端口(默认是18000)就可以体验相关功能了,默认用户是root,密码是root.2020。
夜莺服务端部署好了,默认情况下时序库中只有少量 Prometheus 自身的数据,大家可以简单测试。接下来要考虑监控数据采集的问题,如果是 Prometheus 重度用户,可以继续使用各类 Exporter 来采集,只要数据进了时序库了,夜莺就能够消费(判断告警、展示图表等)了。如果是新用户,我们建议使用 Categraf 来采集,当然,也可以使用 Telegraf、Grafana-agent、Datadog-agent,这些监控采集器都可以和夜莺无缝集成。
部署集群
如果担心容量问题,或高可用问题,可以部署夜莺集群,除了夜莺的两个组件,还有依赖的 MySQL、Redis、时序库,都需要部署集群版。
MySQL
MySQL 全局就部署一个主从集群就可以了,n9e-webapi、n9e-server都要连到 MySQL 的主库。建议使用公有云提供的 RDS 服务。
Redis
夜莺 5.8.0(含)之前的版本,都只支持 standalone 的 Redis,为了高可用,建议使用公有云提供的 Redis 服务。从 5.9.0 开始,夜莺依赖的 Redis 支持 cluster 版本和 sentinel 版本。为了简单起见,全局就使用一套 Redis 即可。如果 n9e-webapi 和 n9e-server 根据地域做了拆分,物理距离较远,比如一个在国内,一个在美东,此时 Redis 就建议拆开,n9e-webapi 依赖一套 Redis,n9e-server 依赖另一套 Redis,如果 n9e-server 有多套,也可以为每套 n9e-server 部署单独的 Redis。
时序库
时序库的高可用,有不同的方案,我们建议使用 VictoriaMetrics 或 Thanos,VictoriaMetrics 如何部署集群版本,后面的章节会有介绍,当然大家也可以查看 VictoriaMetrics 的官方文档,Thanos 的话请大家自行查看 Thanos 的官方文档。
n9e-webapi
高可用就是部署多个实例即可,各个n9e-webapi的实例的配置完全相同。前面架设 nginx 或 lvs,某个 n9e-webapi 挂掉了,会被 nginx、lvs 自动摘掉,用户无感
n9e-server
首先,n9e-server 是随着时序库走的,贵司有几套时序库,就要部署几套 n9e-server,每套 n9e-server 要取个名字,在 server.conf 中有个 ClusterName 的配置来标识 n9e-server 集群的名字,每套 n9e-server 可以只有一个实例,可以有多个实例组成集群,一套 n9e-server 集群内的多个实例,其 ClusterName 要保持一致。不同的 n9e-server 集群,ClusterName 要不同。
如果有多套时序库,其连接信息都要配置到 n9e-webapi 的配置文件 webapi.conf 中,即配置多个 [[Clusters]] ,每个 Cluster 有个 Name 的配置,要和 server.conf 中的 ClusterName 保持一致。
采集器
Categraf
Categraf 是一款 all-in-one 的采集器,由 快猫团队 开源,代码托管在:
github: https://github.com/flashcatcloud/categraf
Categraf 不但可以采集 OS、MySQL、Redis、Oracle 等常见的监控对象,也准备提供日志采集能力和 trace 接收能力,这是夜莺主推的采集器,相关信息请查阅项目 README
Categraf 采集到数据之后,通过 remote write 协议推给远端存储,Nightingale 恰恰提供了 remote write 协议的数据接收接口,所以二者可以整合在一起,重点是配置 Categraf 的 conf/config.toml 中的 writer 部分,其中 url 部分配置为 n9e-server 的 remote write 接口:
[writer_opt]
# default: 2000
batch = 2000
# channel(as queue) size
chan_size = 10000
[[writers]]
url = "http://N9E-SERVER:19000/prometheus/v1/write"
# Basic auth username
basic_auth_user = ""
# Basic auth password
basic_auth_pass = ""
# timeout settings, unit: ms
timeout = 5000
dial_timeout = 2500
max_idle_conns_per_host = 100
采集插件
Categraf 每个采集器,都有一个配置目录,在 conf 下面,以 input. 打头,如果某个插件不想启用,就把插件配置目录改个名字,别让它是 input. 打头即可,比如 docker 不想采集,可以 mv input.docker bak.input.docker 就可以了。当然了,也并不是说只要有 input.xx 目录,就会采集对应的内容,比如 MySQL 监控插件,如果想采集其数据,至少要在 conf/input.mysql/mysql.toml 中配置要采集的数据库实例的连接地址。
每个采集插件的配置文件,都给了很详尽的注释,阅读这些注释,基本就了解如何去配置各个插件了。另外,有些采集插件还会同步提供夜莺监控大盘JSON和告警规则JSON,大家可以直接导入使用,在
代码的 inputs 目录
,机器的监控大盘比较特殊,放到了 system 目录,没有分散在 cpu、mem、disk 等目录。
很多采集插件的配置文件中,都有 [[instances]] 配置段,这个 [[]] 在 toml 配置中表示数组,即 instances 配置段可以配置多份,比如 oracle 的配置文件:
# collect interval, unit: second
interval = 15
[[instances]]
address = "10.1.2.3:1521/orcl"
username = "monitor"
password = "123456"
is_sys_dba = false
is_sys_oper = false
disable_connection_pool = false
max_open_connections = 5
# interval = global.interval * interval_times
interval_times = 1
labels = { region="cloud" }
[[instances]]
address = "192.168.10.10:1521/orcl"
username = "monitor"
password = "123456"
is_sys_dba = false
is_sys_oper = false
disable_connection_pool = false
max_open_connections = 5
labels = { region="local" }
address 可以指定连接地址,如果想监控多个 oracle 实例,一个 address 显然不行了,就要把 instances 部分拷贝多份,即可做到监控多个 oracle 实例的效果。
Telegraf
Telegraf 是 InfluxData 公司开源的一款采集器,内置非常多的采集插件,不过 Telegraf 是面向 InfluxDB 生态的,采集的监控数据推给 InfluxDB 非常合适,推给 Prometheus、Victoriametrics、Thanos 这些时序库,可能会带来问题。主要是两点:
- 有些数据是 string 类型的,Prometheus、VM、M3、Thanos 等都不支持 string 类型的数据
- 有些采集器设计的标签是非稳态的设计,比如经常会看到 result=success 和 result=failed 的标签,需要手工配置采集器 drop 掉,但是对于新手确实有些难度
另外一个问题是,Telegraf 采集的数据存到 Prometheus 中,这种做法在业界实践的比较少,导致 Grafana 大盘很少,需要我们付出较大精力手工制作大盘。
Telegraf 是如何与 Nightingale 整合的呢?Telegraf 有不同的 output plugin,可以把采集的数据推给 OpenTSDB、推给 Datadog,Nightingale 实现了 OpenTSDB 和 Datadog 这两种消息接收接口,所以,可以通过任一 output plugin 和 Nightingale 对接。下面提供一个简单的 Telegraf 配置供大家参考,使用 OpenTSDB 的 output plugin 和 Nightingale 对接,即 [[outputs.opentsdb]] 配置段,host 部分配置为 n9e-server 的地址:
#!/bin/sh
version=1.20.4
tarball=telegraf-${version}_linux_amd64.tar.gz
wget https://dl.influxdata.com/telegraf/releases/$tarball
tar xzvf $tarball
mkdir -p /opt/telegraf
cp -far telegraf-${version}/usr/bin/telegraf /opt/telegraf
cat <<EOF > /opt/telegraf/telegraf.conf
[global_tags]
[agent]
interval = "10s"
round_interval = true
metric_batch_size = 1000
metric_buffer_limit = 10000
collection_jitter = "0s"
flush_interval = "10s"
flush_jitter = "0s"
precision = ""
hostname = ""
omit_hostname = false
[[outputs.opentsdb]]
host = "http://127.0.0.1"
port = 19000
http_batch_size = 50
http_path = "/opentsdb/put"
debug = false
separator = "_"
[[inputs.cpu]]
percpu = true
totalcpu = true
collect_cpu_time = false
report_active = true
[[inputs.disk]]
ignore_fs = ["tmpfs", "devtmpfs", "devfs", "iso9660", "overlay", "aufs", "squashfs"]
[[inputs.diskio]]
[[inputs.kernel]]
[[inputs.mem]]
[[inputs.processes]]
[[inputs.system]]
fielddrop = ["uptime_format"]
[[inputs.net]]
ignore_protocol_stats = true
EOF
cat <<EOF > /etc/systemd/system/telegraf.service
[Unit]
Description="telegraf"
After=network.target
[Service]
Type=simple
ExecStart=/opt/telegraf/telegraf --config telegraf.conf
WorkingDirectory=/opt/telegraf
SuccessExitStatus=0
LimitNOFILE=65535
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=telegraf
KillMode=process
KillSignal=SIGQUIT
TimeoutStopSec=5
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable telegraf
systemctl restart telegraf
systemctl status telegraf
Datadog-Agent
Datadog 是专门提供监控和分析服务的 SaaS 服务商,市值几百亿,成立了10多年了,他们做的客户端采集器,理论上应该是比较完备的,夜莺实现了几个 Datadog 特定的接口,可以接收Datadog-Agent 推送上来的数据,即:我们可以拿 Datadog-Agent 作为客户端采集器采集监控数据,然后上报给夜莺。
Grafana-Agent
Grafana-agent 是 Grafana 开源的一款 Agent,专门用于和自己的 Cloud 做数据采集集成,通过 remote write 协议推数据给后端,和 Categraf 的数据推送方式一样,所以,也是可以作为 Nightingale 的采集器的。Grafana-Agent 的具体使用请查阅 Grafana 官方文档,下面给出 v0.23.0 版本的 Grafana-Agent 的简要安装方式,如果各位看官使用了其他版本的 Grafana-Agent,下面的教程可能就不适用了,毕竟,Grafana-Agent 也在快速迭代,请大家注意。
Falcon-Plugin
Nightingale 实现了 Open-Falcon 的 HTTP 数据接收接口,所以,Open-Falcon 社区很多采集插件也是可以直接使用的。但是 Falcon-Agent 不行,因为 Falcon-Agent 推送监控数据给服务端,走的是 RPC 接口。
如果你发现某个 Falcon-Plugin 是用 CRON 的方式驱动的,推送数据走的是 Falcon-Agent 的 HTTP 接口,那这个插件就可以推数据给夜莺。