xiufeigo™
Home
运维
如何快速搭建 Prometheus 系统

一、监控系统的典型架构

                +-----------------------+
                |    Data Collectors    |
                +-----------------------+
                           |
                           v
                +-----------------------+
                |    Time Series DB     |
                +-----------------------+
                           |
                           v
                +-----------------------+          +-------------------+
                |    Analytics Engine   | <------> |   User Interface  |
                +-----------------------+          +-------------------+
                           |
                           v
                +-----------------------+
                |    Alerting System    |
                +-----------------------+

从上往下看,采集器是负责采集监控数据的,采集到数据之后传输给服务端,通常是直接写入时序库。然后就是对时序库的数据进行分析和可视化,分析部分最典型的就是告警规则判断(复杂一些的会引入统计算法和机器学习的能力做预判),即图上的告警引擎,告警引擎产生告警事件之后交给告警发送模块做不同媒介的通知。可视化比较简单,就是图上的数据展示,通过各种图表来合理地渲染各类监控数据,便于用户查看比较、日常巡检。

1)采集器(Data Collectors)

采集器负责采集监控数据,有两种典型的部署方式:

  • 跟随监控对象部署:比如所有的机器上都部署一个采集器,采集机器的 CPU、内存、硬盘、IO、网络相关的指标

  • 远程探针式:比如选取一个中心机器做探针,同时探测很多个机器的 PING 连通性,或者连到很多 MySQL 实例上去,执行命令采集数据

2)时序库(Time Series DB)

在监控系统(特别是 IT 监控和工业控制系统)中,时序数据库(Time Series Database, TSDB)扮演着最重要角色时序数据库接收和存储时间序列数据,提供高效的数据写入和查询能力。

3)分析引擎(Analytics Engine)

分析引擎从时序数据库中提取数据进行处理和分析,支持复杂的计算和数据处理任务。

3.x)用户界面

用户界面提供数据可视化和用户交互功能,允许用户实时查看和分析数据,生成报告和仪表盘。

4)告警系统(Alerting System)

告警系统根据分析引擎的结果触发警报,通知相关人员采取行动。

二、Prometheus 的优势

  1. 部署组件少:Prometheus 将时序库、分析引擎、数据展示三大块,整合成了一个进程,组件的数量大幅减少。

  2. 使用 Pull 模型:Prometheus 使用拉取(Pull)模型,通过 HTTP 来定期抓取被监控的服务数据。相比于推送(Push)模型,这种方式更加灵活,便于动态发现和删除实例,减少监控配置和管理的复杂性。

  3. 本地存储:Prometheus 提供高效的本地存储解决方案,支持大规模数据存储和快速查询。同时,它也支持远程存储接口,可以将数据存储到外部的持久化存储系统中。

  4. 丰富的 Exporters(即 Prometheus 的采集器):Prometheus 社区提供了大量的 exporters,用于采集各种应用和服务的数据,包括数据库、操作系统、容器、云服务等。这使得 Prometheus 可以轻松集成到各种环境中。

  5. Alertmanager:Prometheus 自带强大的告警管理组件 Alertmanager,支持复杂的告警规则配置,告警抑制和分组,灵活的告警路由,集成邮件、Slack、PagerDuty 等多种通知方式。

  6. Grafana:Prometheus 与 Grafana 等可视化工具紧密集成,能够通过直观的仪表盘展示监控数据和告警信息。

三、部署 Prometheus

官网下载链接: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.service

systemd 配置文件如下:

[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 自监控的方式,下面我们来看一下机器监控。

四、部署 Node-Exporter

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.service

systemd 配置文件可以参考 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.target

Node-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 默认采集几百个指标,有了这些数据,我们就可以演示告警规则的配置了。

1)配置告警规则

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 组件了。

五、部署 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.service

systemd 配置文件可以参考 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.target

Alertmanager 会读取二进制同级目录下的 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。

六、 部署 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.service

systemd 配置文件可以参考 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.target

Grafana 默认的监听端口是 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 动态获取到需要监控的目标对象,大幅降低了抓取目标的管理成本。

粤ICP备2022009857号-1