+-----------------------+
| Data Collectors |
+-----------------------+
|
v
+-----------------------+
| Time Series DB |
+-----------------------+
|
v
+-----------------------+ +-------------------+
| Analytics Engine | <------> | User Interface |
+-----------------------+ +-------------------+
|
v
+-----------------------+
| Alerting System |
+-----------------------+从上往下看,采集器是负责采集监控数据的,采集到数据之后传输给服务端,通常是直接写入时序库。然后就是对时序库的数据进行分析和可视化,分析部分最典型的就是告警规则判断(复杂一些的会引入统计算法和机器学习的能力做预判),即图上的告警引擎,告警引擎产生告警事件之后交给告警发送模块做不同媒介的通知。可视化比较简单,就是图上的数据展示,通过各种图表来合理地渲染各类监控数据,便于用户查看比较、日常巡检。
采集器负责采集监控数据,有两种典型的部署方式:
跟随监控对象部署:比如所有的机器上都部署一个采集器,采集机器的 CPU、内存、硬盘、IO、网络相关的指标
远程探针式:比如选取一个中心机器做探针,同时探测很多个机器的 PING 连通性,或者连到很多 MySQL 实例上去,执行命令采集数据
在监控系统(特别是 IT 监控和工业控制系统)中,时序数据库(Time Series Database, TSDB)扮演着最重要角色。时序数据库接收和存储时间序列数据,提供高效的数据写入和查询能力。
分析引擎从时序数据库中提取数据进行处理和分析,支持复杂的计算和数据处理任务。
用户界面提供数据可视化和用户交互功能,允许用户实时查看和分析数据,生成报告和仪表盘。
告警系统根据分析引擎的结果触发警报,通知相关人员采取行动。
部署组件少:Prometheus 将时序库、分析引擎、数据展示三大块,整合成了一个进程,组件的数量大幅减少。
使用 Pull 模型:Prometheus 使用拉取(Pull)模型,通过 HTTP 来定期抓取被监控的服务数据。相比于推送(Push)模型,这种方式更加灵活,便于动态发现和删除实例,减少监控配置和管理的复杂性。
本地存储:Prometheus 提供高效的本地存储解决方案,支持大规模数据存储和快速查询。同时,它也支持远程存储接口,可以将数据存储到外部的持久化存储系统中。
丰富的 Exporters(即 Prometheus 的采集器):Prometheus 社区提供了大量的 exporters,用于采集各种应用和服务的数据,包括数据库、操作系统、容器、云服务等。这使得 Prometheus 可以轻松集成到各种环境中。
Alertmanager:Prometheus 自带强大的告警管理组件 Alertmanager,支持复杂的告警规则配置,告警抑制和分组,灵活的告警路由,集成邮件、Slack、PagerDuty 等多种通知方式。
Grafana:Prometheus 与 Grafana 等可视化工具紧密集成,能够通过直观的仪表盘展示监控数据和告警信息。
官网下载链接:Prometheus
# 因为俺用的是 arm 的机器,所以下的是 arm 的包
wget https://github.com/prometheus/prometheus/releases/download/v2.53.0-rc.0/prometheus-2.53.0-rc.0.linux-arm64.tar.gz
# 建个 Prometheus 的程序目录
mkdir -p /opt/prometheus
# 先解压
tar xf prometheus-2.53.0-rc.0.linux-arm64.tar.gz
# 把东西都复制过去
cp -far prometheus-2.53.0-rc.0.linux-arm64/ /opt/prometheus/
# 创建 systemd 托管服务
vi /etc/systemd/system/prometheus.servicesystemd 配置文件如下:
[Unit]
# 服务的简单描述
Description="Prometheus Monitoring System"
# 指向 Prometheus 文档的 URL
Documentation=https://prometheus.io/docs/introduction/overview/
# 定义服务的依赖和启动顺序,却包网络服务可用后启动 Prometheus
Wants=network-online.target
After=network-online.target
[Service]
# user 和 group 为运行 Prometheus 的用户和用户组
# User=prometheus
# Group=prometheus
# 服务类型,这里使用 simple 表示系统认为启动进程会继续运行
Type=simple
# 启动 Prometheus 的命令和参数
# --config.file 指定 Prometheus 的配置文件路径
# --storage.tsdb.path 指定 Prometheus 时序数据的硬盘存储路径
# --web.enable-lifecycle 启用生命周期管理相关的 API,比如调用 /-/reload 接口就需要启用该项
# --enable-feature=remote-write-receiver 启用 remote write 接收数据的接口,启用该项之后,categraf、grafana-agent 等 agent 就可以通过 /api/v1/write 接口推送数据给 Prometheus
# --query.lookback-delta=2m 查询回溯时间,默认是 5 分钟,这里设置为 2 分钟
# --web.enable-admin-api 启用管理性 API,比如删除时间序列数据的 /api/v1/admin/tsdb/delete_series 接口
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 \
--web.enable-admin-api
# 设置重启策略,这里是 on-failure,表示在服务崩溃或失败后自动重启。
Restart=on-failure
# 设置服务的成功退出状态码,这里是 0。
SuccessExitStatus=0
# 设置文件描述符限制,这里设置为 65536,以便处理大量并发连接。
LimitNOFILE=65536
# 将标准输出重定向到 syslog
StandardOutput=syslog
# 将标准错误重定向到 syslog
StandardError=syslog
# 设置 syslog 记录的标识符,这里是 prometheus,便于日志管理和查找。
SyslogIdentifier=prometheus
[Install]
# 定义服务在多用户目标下启动,这表示服务将在系统启动时自动启动。
WantedBy=multi-user.target如果正常启动,Prometheus 默认会在 9090 端口监听,访问这个端口就可以看到 Prometheus 的 Web 页面,输入下面的 PromQL 可以查到一些监控数据。
{instance="localhost:9090",__name__=~"go_gc_.*"}这个数据是从哪里来的呢?其实是 Prometheus 自己抓取自己的,Prometheus 会在 /metrics 接口暴露监控数据,你可以访问这个接口看一下输出。同时 Prometheus 在配置文件里配置了抓取规则,打开 prometheus.yml 就可以看到了。
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']localhost:9090 是暴露监控数据的地址,没有指定接口路径,默认使用 /metrics,没有指定 scheme,默认使用 HTTP,所以实际请求的是 http://localhost:9090/metrics。了解了 Prometheus 自监控的方式,下面我们来看一下机器监控。
Prometheus 生态的机器监控比较简单,就是在所有的目标机器上部署 Node-Exporter,然后在抓取规则中给出所有 Node-Exporter 的地址就可以了。
# 因为俺用的是 arm 的机器,所以下的是 arm 的包
wget https://github.com/prometheus/node_exporter/releases/download/v1.8.1/node_exporter-1.8.1.linux-arm64.tar.gz
# 建个 node_exporter 的程序目录
mkdir -p /opt/node_exporter
# 先解压
tar xf node_exporter-1.8.1.linux-arm64.tar.gz
# 把东西都复制过去
cp -far node_exporter-1.8.1.linux-arm64/ /opt/node_exporter/
# 创建 systemd 托管服务
vi /etc/systemd/system/node_exporter.servicesystemd 配置文件可以参考 Prometheus 的
[Unit]
Description="Prometheus Node Exporter"
Documentation=https://github.com/prometheus/node_exporter
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
ExecStart=/opt/node_exporter/node_exporter
Restart=on-failure
SuccessExitStatus=0
LimitNOFILE=65536
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=node_exporter
[Install]
WantedBy=multi-user.targetNode-Exporter 默认的监听端口是 9100,我们可以通过下面的命令看到 Node-Exporter 采集的指标。
curl -s localhost:9100/metrics然后把 Node-Exporter 的地址配置到 prometheus.yml 中即可。修改了配置之后,记得给 Prometheus 发个 HUP 信号,让 Prometheus 重新读取配置:kill -HUP <prometheus pid>。最终 scrape_configs 部分变成下面这段内容。
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node_exporter'
static_configs:
- targets: ['localhost:9100']其中 targets 是个数组,如果要监控更多机器,就在 targets 中写上多个 Node-Exporter 的地址,用逗号隔开。之后在 Prometheus 的 Web 上(菜单位置 Status -> Targets),就可以看到相关的 Targets 信息了。
在查询监控数据的框里输入 node,就会自动提示很多 node 打头的指标。这些指标都是 Node-Exporter 采集的,选择其中某一个就可以查到对应的监控数据,比如查看不同硬盘分区的余量大小。
Node-Exporter 默认内置了很多 collector,比如 cpu、loadavg、filesystem 等,可以通过命令行启动参数来控制这些 collector,比如要关掉某个 collector,使用 --no-collector.<name>,如果要开启某个 collector,使用 --collector.<name>。具体可以参考 Node-Exporter 的 README。Node-Exporter 默认采集几百个指标,有了这些数据,我们就可以演示告警规则的配置了。
Prometheus 进程内置了告警判断引擎,prometheus.yml 中可以指定告警规则配置文件,默认配置中有个例子。
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"我们可以把不同类型的告警规则拆分到不同的配置文件中,然后在 prometheus.yml 中引用。比如 Node-Exporter 相关的规则,我们命名为 node_exporter.yml,最终这个 rule_files 就变成了如下配置。
rule_files:
- "node_exporter.yml"我设计了一个例子,监控 Node-Exporter 挂掉以及内存使用率超过 1% 这两种情况。这里我故意设置了一个很小的阈值,确保能够触发告警。文件路径为 /opt/prometheus
groups:
- name: node_exporter
rules:
# 报警规则 HostDown
- alert: HostDown
# 表达式,表示 node_exporter 任务的某个实例不在线
expr: up{job="node_exporter"} == 0
# 持续时间,如果表达式在 1 分钟内一直为真,则触发报警
for: 1m
# 报警标签,severity 设置为 critical,表示这是一个严重报警
labels:
severity: critical
# 报警的附加信息,summary 提供简短描述,{{ $labels.instance }} 用于动态插入报警触发的实例信息
annotations:
summary: Host down {{ $labels.instance }}
# 报警规则 MemUtil
- alert: MemUtil
# 当内存使用率大于 1% 时报警
expr: 100 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100 > 1
# 持续时间,如果表达式在 1 分钟内一直为真,则触发报警
for: 1m
# 报警标签,severity 设置为 warn,表示这是一个警告级别的报警
labels:
severity: warn
# 报警的附加信息,summary 提供简短描述,{{ $labels.instance }} 用于动态插入报警触发的实例信息
annotations:
summary: Mem usage larger than 1%, instance:{{ $labels.instance }}之后,我们就可以去 Prometheus 的 Web 上(Alerts 菜单)查看告警规则的判定结果了。
我们从图中可以看出,告警分成 3 个状态,Inactive、Pending、Firing。HostDown 这个规则当前是 Inactive 状态,表示没有触发相关的告警事件,MemUtil 这个规则触发了一个事件,处于 Firing 状态。那什么是 Pending 状态呢?触发过阈值但是还没有满足持续时长( for 关键字后面指定的时间段)的要求,就是 Pending 状态。比如 for 1m,就表示触发阈值的时间持续 1 分钟才算满足条件,如果规则判定执行频率是 10 秒,就相当于连续 6 次都触发阈值才可以。
在页面上我们看到告警了,就是一个巨大的进步,如果我们还希望在告警的时候收到消息通知,比如邮件、短信等,就需要引入 AlertManager 组件了。
老规矩,继续下载
# 因为俺用的是 arm 的机器,所以下的是 arm 的包
wget https://github.com/prometheus/alertmanager/releases/download/v0.27.0/alertmanager-0.27.0.linux-arm64.tar.gz
# 建个 alertmanager 的程序目录
mkdir -p /opt/alertmanager
# 先解压
tar xf alertmanager-0.27.0.linux-arm64.tar.gz
# 把东西都复制过去
cp -far alertmanager-0.27.0.linux-arm64/ /opt/alertmanager/
# 创建 systemd 托管服务
vi /etc/systemd/system/alertmanager.servicesystemd 配置文件可以参考 Prometheus 的
[Unit]
Description="Prometheus Alertmanager"
Documentation=https://github.com/prometheus/alertmanager
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
ExecStart=/opt/alertmanager/alertmanager
WorkingDirectory=/opt/alertmanager
Restart=on-failure
SuccessExitStatus=0
LimitNOFILE=65536
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=alertmanager
[Install]
WantedBy=multi-user.targetAlertmanager 会读取二进制同级目录下的 alertmanager.yml 配置文件。修改下具体的报警配置文件
global:
# 发件人邮件地址
smtp_from: 'username@163.com'
# SMTP 服务器地址和端口号,这里使用的是 163 邮箱的 SMTP 服务器
smtp_smarthost: 'smtp.163.com:465'
# SMTP 服务器的用户名
smtp_auth_username: 'username@163.com'
# SMTP 服务器的密码,这里填写的是 163 邮箱的授权码
smtp_auth_password: 'password'
# 指定是否需要 TLS 加密,这里设置为 false,表示不要求使用 TLS
smtp_require_tls: false
route:
# 定义报警分组的依据,这里按照 alertname 分组
group_by: ['alertname']
# 在发送第一个报警前等待的时间,这里是 30 秒
group_wait: 30s
# 每组报警之间的最小间隔时间,这里是 1 分钟
group_interval: 1m
# 重复发送同一报警的间隔时间,这里是 1 小时
repeat_interval: 1h
# 默认接收报警的接收器,这里是 email
receiver: 'email'
receivers:
- name: 'web.hook'
# 配置 Webhook,报警会发送到这个地址
webhook_configs:
- url: 'http://127.0.0.1:5001/'
- name: 'email'
# 配置邮件接收器,报警会发送到 alarmUser@163.cn
email_configs:
- to: 'alarmUser@163.cn'
# 定义抑制规则
inhibit_rules:
# 匹配源报警的标签,这里是 severity: 'critical'
- source_match:
severity: 'critical'
# 匹配目标报警的标签,这里是 severity: 'warning'
target_match:
severity: 'warning'
# 定义标签匹配条件,这里要求 alertname、dev 和 instance 标签相同
equal: ['alertname', 'dev', 'instance']
# 规则的含义是:如果存在一个严重程度为 critical 的报警,那么将抑制所有相同 alertname、dev 和 instance 标签的 warning 级别报警。这样可以避免重复报警。首先配置一个全局 SMTP,然后修改 receivers。receivers 是个数组,默认例子里有个 web.hook,我又加了一个 email 的 receiver,然后配置 route.receiver 字段的值为 email。email_configs 中的 to 表示收件人,多个人用逗号分隔,比如 to: 'user1@163.com, user2@163.com'。然后修改 Prometheus 配置文件,添加 alertmanager 告警的并重启 Prometheus
默认为:
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093
修改为:
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
- localhost:9093最后收到的邮件内容大概是这样的。
收到告警邮件,就说明这整个告警链路走通了。最后我们再看一下数据可视化的问题。Prometheus 自带的看图工具,是给专家用的,需要对指标体系非常了解,经验没法沉淀,而且绘图工具单一,只有折线图。如果你希望有一个更好用的 UI 工具,可以试试 Grafana。
老规矩,继续下载
# 因为俺用的是 arm 的机器,所以下的是 arm 的包
wget https://dl.grafana.com/oss/release/grafana-11.0.0.linux-arm64.tar.gz
# 建个 grafana 的程序目录
mkdir -p /opt/grafana
# 先解压
tar xf grafana-11.0.0.linux-arm64.tar.gz
# 把东西都复制过去
cp -far grafana-v11.0.0/ /opt/grafana/
# 创建 systemd 托管服务
vi /etc/systemd/system/grafana.servicesystemd 配置文件可以参考 Prometheus 的
[Unit]
Description="Grafana - Data visualization & Monitoring"
Documentation=http://docs.grafana.org
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
ExecStart=/opt/grafana/bin/grafana-server \
--config=/opt/grafana/conf/defaults.ini \
--homepath=/opt/grafana
WorkingDirectory=/opt/alertmanager
Restart=on-failure
SuccessExitStatus=0
LimitNOFILE=65536
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=grafana
[Install]
WantedBy=multi-user.targetGrafana 默认的监听端口是 3000,访问后就可以看到登录页面了,默认的用户名和密码都是 admin。
要看图首先要配置数据源,在菜单位置:Connections -> Data sources,点击 Add data source 就能进入数据源类型选择页面,选择 Prometheus,填写 Prometheus 的链接信息,主要是 URL,点击 Save & test 完成数据源配置。 Grafana 提供了和 Prometheus 看图页面类似的功能,叫做 Explore,我们可以在这个页面点选指标看图。
但 Explore 功能不是最核心的,我们使用 Grafana,主要是使用 Dashboard 看图。Grafana 社区有很多人制作了各式各样的大盘,以 JSON 格式上传保存在了 grafana.com,我们想要某个 Dashboard,可以先去这个网站搜索一下,看看是否有人分享过,特别方便。因为我们已经部署了 Node-Exporter,那这里就可以直接导入 Node-Exporter 的大盘,大盘 ID 是 1860,写到图中对应的位置,点击 Load,然后数据源选择 Prometheus 后点击 Import 即可。
本讲的核心内容就是演示 Prometheus 生态相关组件的部署。如果你在课程中是一步一步跟我操作下来的,相信你对 Prometheus 这套生态就有了入门级的认识。学完这些内容我们再来看一下 Prometheus 的架构图,和监控系统通用架构图相互做一个印证,加深理解。
图上有两个部分我们没有讲到,一个是 Pushgateway 组件,另一个是 Service discovery 部分。这里我再做一个简单的补充。
Pushgateway:用于接收短生命周期任务的指标上报,是 PUSH 的接收方式。因为 Prometheus 主要是 PULL 的方式拉取监控数据,这就要求在拉取的时刻,监控对象得活着,但是很多短周期任务,比如 cronjob,可能半秒就运行结束了,就没法拉取了。为了应对这种情况,才单独做了 Pushgateway 组件作为整个生态的补充。
Service discovery:我们演示抓取数据时,是直接在 prometheus.yml 中配置的多个 Targets。这种方式虽然简单直观,但是也有弊端,典型的问题就是如果 Targets 是动态变化的,而且变化得比较频繁,那就会造成管理上的灾难。所以 Prometheus 提供了多种服务发现机制,可以动态获取要监控的目标,比如 Kubernetes 的服务发现,可以通过调用 kube-apiserver 动态获取到需要监控的目标对象,大幅降低了抓取目标的管理成本。