一、Prometheus 介绍
1. 什么是Prometheus?
Prometheus 是一个开源的监控管理组件。同时,还涉及许多以“explore”命名的客户端数据采集工具以及pushgateway网关。
官网:https://prometheus.io/ 文献:https://prometheus.io/docs/introduction/overview/
2. 各监控系统对比
监控方案 | 数据收集 | 自动发现 | 侧重点 | 数据展示方案 | 贴合云原生 |
---|---|---|---|---|---|
Cacti | SNMP | 插件支持 | 数据展示 | RRDTOOL | 差 |
Nagios | 各种脚本插件 | 脚本插入 | 状态展示 | 阈值 | 差 |
Zabbix | zabbix-agent为主 | 主机地址自动发现 | 状态、数据展示 | PHP | 中等 |
Prometheus | Exporter为主 | 各种模式支持,最为完善 | 以时间序列保存数据 | 通过结合Grafana 进行结合展示 | 优秀 |
- 普罗米修斯与Zabbix的主要区别是什么?
- Prometheus主要依赖于export方式进行数据采集,同时支持自动发现功能,适合用于现代微服务架构的监控。而Zabbix以 Zabbix agent为主,也支持SNMP、GMI等接口,同样具备自动发现能力,但不如Prometheus灵活,Zabbix 适合用于监控传统的 IT 基础设施。此外Prometheus安装简便,只需启动即可开启数据拉取接口,无需额外配置服务器地址。它能自动发现并监控容器内的服务,像Kubernetes集群中的节点,动态调整监控范围,适应容器灵活启动、停止的特点。
- Prometheus的数据存储基于时间序列,采用带时间维度的哈希表或键值对形式存储,不依赖关系型数据库,而Zabbix的数据存储基于关系型数据库,对时间维度的数据处理压力较大。Prometheus的数据增长模式更有利于长期保存和检索,而Zabbix则需面对文本文件过大导致无法打开等问题。
- Prometheus server 端口 是9090 Prometheus export 端口 是9100 Prometheus alertmanager 端口是9093 grafana 端口是 3000 Zabbix server 端口 10051 zabbix agentd 的端口是10050
3. Prometheus的特性
- 由 metric 名称和 K/V 键值对标识的时间序列的多维数据模型
- 简单的查询语言 PromQL(TSDB数据库的查询语言)
- 不依赖分布式存储,单个服务节点自动治理
- 通过 http 的 pull 模型获取数据的时序集合
- 支持通过网关 push 时序数据
- 通过服务发现或者静态配置发现目标
- 支持多种图表和仪表盘模式
- export : 是用来为被监控服务器开放一个数据采集端口的软件,安装在被监控主机上后会启动一个服务,允许Prometheus server端通过该端口拉取数据。
- Prometheus具有自动加载配置文件的功能,无需重启整个服务程序。
4. Prometheus架构图和组件介绍
- Prometheus代理 : 负责采集和暂存数据,然后将数据转发给最终的Prometheus服务器
- service discovery 帮助自动发现存活的被监控主机
**Prometheus Server:**负责定时去目标抓取 metrics数据,每个被抓取对象需要开放一个http服务接口;pull下来的数据经过整理后写入到本地的时序数据库(TSDB)中。
**Client Library:**客户端类库(例如官方提供的:Go,Python,Java等),为需要监控的服务产生相应的 metrics数据并开放一个http服务接口给 Prometheus Server。目前很多软件原生就支持Prometheus,提供了metrics数据,可以直接使用 Prometheus pull。对于像操作系统不提供提供metrics数据的情况,可以使用exporter,或者自己开发exporter来提供metrics数据服务。
**Node Exporter:**泛指能向Prometheus提供监控数据(metrics数据)的都可以称为一个 exporter,是用来为被监控服务器开放一个数据采集端口的软件,安装在被监控主机上后会启动一个服务,允许Prometheus server端通过该端口拉取数据,主要用来支持其他数据源的metrics数据导入到 Prometheus,支持数据库、硬件、消息中间件、存储系统、HTTP服务器、jmx等。
PushGateway:==主要用于保存 short-lived job。==因为这类 jobs 存在时间较短,可能在 Prometheus 来 pull 之前就消失了。对此类 jobs 定时将 metrics数据 push 到 pushgateway 上,再由 Prometheus Server 从 Pushgateway 上 pull 到本地。这种方式主要用于服务层面的metrics,对于机器层面的metrices,需要使用node exporter。
**Promdash 和 Grafana:**Prometheus内置一个简单的Web控制台Promdash,可以查询metrics数据,查看配置信息或者Service Discovery等,实际工作中,查看指标或者创建仪表盘通常使用Grafana,Prometheus作为Grafana的数据源。
alertmanager:以实现对Prometheus产生的告警进行处理,如去重、取消重复告警,避免大量告警信息对管理员造成困扰,并能配置其他报警媒介
**PromQL:**是Prometheus TSDB的查询语言。是结合Grafana进行数据展示和告警规则的配置的关键部分。
5. Prometheus服务工作过程
- Prometheus Daemon负责定时去被监控目标上抓取metrics(指标)数据,每个抓取目标需要暴露一个http服务的接口给它定时抓取。Prometheus支持通过配置文件、文本文件、Zookeeper、Consul、DNS SRV Lookup等方式指定抓取目标。Prometheus采用PULL的方式进行监控,即服务器可以直接通过目标PULL数据或者间接地通过中间网关来Push数据。
- Prometheus 在本地处理抓取到的所有数据,并通过一定规则进行整理数据,并把得到的结果存储到新的时间序列中。
- Prometheus通过PromQL和其他API可视化地展示收集的数据。Prometheus支持很多方式的图表可视化,例如Grafana、自带的Promdash以及自身提供的模版引擎等等。Prometheus还提供HTTP API的查询方式,自定义所需要的输出。
- PushGateway支持Client主动推送metrics到PushGateway,而Prometheus只是定时去Gateway上抓取数据。
- Alertmanager是独立于Prometheus的一个组件,可以支持Prometheus的查询语句,提供十分灵活的报警方式。
6. 实验前准备
1. 由于使用单机模式部署,所有有些软件的安装或者配置的生效需要连接到互联网(通网)
2. 为了方便识别主机身份,可以给主机设置不同的主机名和域名解析(hosts)
3. 要保证服务器之间的时间同步
#时间同步服务器
yum -y install ntp
vim /etc/ntp.conf
#添加以下配置文件
restrict 192.168.90.0 mask 255.255.255.0 nomodify notrap
server 127.127.1.0
fudge 127.127.1.0 stratum 10
systemctl enable --now ntpd
#时间同步客户端
yum -y install ntp
vim /etc/ntp.conf
#添加以下配置文件
server 192.168.90.100 iburst #服务器IP
systemctl enable --now ntpd
ntpdate -u 192.168.90.100 #客户端同步时间命令
#如果有VMware可按照下面的方法
- 为何服务器间的时间同步非常重要?
时间同步对于服务器至关重要,因为许多数据管理任务会附带时间戳和时间指标。时间不一致可能导致数据同步延迟、命令无法执行等问题。
二、Prometheus - Prometheus Server部署
- 下载并安装Prometheus Server服务 Download | Prometheus
# 上传本地Prometheus及相关软件包
$ rz promethues.zip
$ unzip promethues.zip
$ ls -l promethues/
-rw-r--r-- 1 root root 23928771 12月 17 2019 alertmanager-0.20.0.linux-amd64.tar.gz
-rw-r--r-- 1 root root 61032119 12月 17 2019 grafana-6.5.2.linux-amd64.tar.gz
-rw-r--r-- 1 root root 8083296 12月 17 2019 node_exporter-0.18.1.linux-amd64.tar.gz
-rw-r--r-- 1 root root 58625125 12月 17 2019 prometheus-2.14.0.linux-amd64.tar.gz
# 单独解压缩Prometheus软件,完成安装
$ cd prometheus/
$ tar -xf prometheus-2.53.3.linux-amd64.tar.gz
$ tree ./
./
├── console_libraries
│ ├── menu.lib
│ └── prom.lib
├── consoles
│ ├── index.html.example
│ ├── node-cpu.html
│ ├── node-disk.html
│ ├── node.html
│ ├── node-overview.html
│ ├── prometheus.html
│ └── prometheus-overview.html
├── LICENSE
├── NOTICE
├── prometheus # 启动文件
├── prometheus.yml # 配置文件(启动时被调用)
├── promtool
└── tsdb
# Prometheus安装非常简单,解压缩复制到自定义目录下即可,约定成俗的习惯:/usr/local/prometheus
$ cp -r prometheus-2.53.3.linux-amd64 /usr/local/prometheus
- 编写Prometheus service启动脚本
$ cat>/usr/local/prometheus/prometheus.service<<EOF
[Unit]
Description=Prometheus
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/usr/local/prometheus
ExecStart=/usr/local/prometheus/prometheus --config.file=/usr/local/prometheus/prometheus.yml
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
- 添加启动脚本到systemd启动管理中
$ ln -s /usr/local/prometheus/prometheus.service /lib/systemd/system/
$ systemctl daemon-reload
$ systemctl enable --now prometheus
$ systemctl restart prometheus
$ netstat -antp | grep LISTEN | grep :9090
tcp6 0 0 :::9090 :::* LISTEN 37984/prometheus
- 配置文件讲解
# 配置文件(原版未改)
$ vim /usr/local/prometheus/prometheus.yml
# my global config
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['localhost:9090']
# -----------------------------------------------------------------------------------------------
# 配置文件关键词介绍(由于alertmanager、exporter等都未安装,相关配置后面详细讲)
global: # 全局配置 (如果有内部单独设定,会覆盖这个参数)
scrape_interval: 15s
# 全局默认的数据拉取间隔
evaluation_interval: 15s
# 全局默认的规则(主要是报警规则)拉取间隔
scrape_timeout: 10s
# 全局默认的单次数据拉取超时间,默认不开启,当报context deadline exceeded错误时需要在特定的job下配置该字段,注意:scrape_timeout时间不能大于scrape_interval,否则Prometheus将会报错。
alerting: # 告警插件定义,这里会设定alertmanager这个报警插件。
rule_files: # 告警规则,按照设定参数进行扫描加载,用于自定义报警规则(类似触发器trigger),其报警媒介由alertmanager插件实现。
scrape_configs: # 采集配置,配置数据源,包含分组job_name以及具体target,又分为静态配置和服务发现。
- 通过浏览器访问指标数据和图形化界面(效果见下图)
http://192.168.88.10:9090/metrics
http://192.168.88.10:9090/graph
三、Prometheus - Node Exporter部署(客户端和服务器都要装)
类似zabbix的agent可以在服务器和客户端都安装,若需监控操作系统级别的资源(如CPU、内存、磁盘等),则需安装如node exporter这样的专用采集工具,它能通过特定端口9100采集系统资源数据,而不仅仅局限于普罗米修斯软件自身的监控。
- 解压缩并安装Node Exporter
$ tar -xf node_exporter-1.8.2.linux-amd64.tar.gz
$ cp -r node_exporter-1.8.2.linux-amd64 /usr/local/node_exporter
- 编写Node Exporter启动脚本
$ cat>/usr/local/node_exporter/node_exporter.service<<EOF
[Unit]
Description=Node Exporter
After=network.target
Wants=network-online.target
[Service]
Type=simple
User=root
ExecStart=/usr/local/node_exporter/node_exporter
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
- 添加启动脚本到systemd启动管理中
$ ln -s /usr/local/node_exporter/node_exporter.service /lib/systemd/system/
$ systemctl daemon-reload
$ systemctl enable --now node_exporter
$ systemctl restart node_exporter
$ netstat -antp | grep LISTEN | grep :9100
tcp6 0 0 :::9100 :::* LISTEN 38150/node_exporter
注意:以上安装除了在Prometheus Server服务器端安装也可以单独安装在其他被监控节点上
- 配置文件修改(修改Prometheus配置文件实现metrics数据获取和监控开启)
$ vim /usr/local/prometheus/prometheus.yml
# alertmanager 监控区域
alerting:
alertmanagers:
# 指定监控类型为静态配置
- static_configs:
- targets: ['127.0.0.1:9093']
# 指定当前 alertmanager 服务器连接方式
scrape_configs:
# 当前任务名称
- job_name: "prometheus server"
# 当前配置为静态配置,指定 Node_exporter 服务连接方式
static_configs:
- targets: ["192.168.90.107:9090","192.168.90.107:9100"]
# 另一个任务名称
#注意这是在客户端安装node_exporter,才需要配置
- job_name: "linux server"
static_configs:
- targets: ["192.168.90.108:9100"]
$ systemctl restart prometheus
#重启prometheus,加载最新配置
- 效果展示
四、Prometheus - PromQL查询语言
PromQL(Prometheus Query Language)是 Prometheus 自己开发的表达式语言,语言表现力很丰富,内置函数也很多。使用它可以对时序数据进行筛选和聚合。
1. PromQL语法
数据类型
PromQL 表达式计算出来的值有以下几种类型:标量&向量:简单来比喻就是标量是一个数字,向量是一组数字!
瞬时向量 (Instant vector): 一组时序,每个时序只有一个采样值
区间向量 (Range vector): 一组时序,每个时序包含一段时间内的多个采样值
标量数据 (Scalar): 一个浮点数
字符串 (String): 一个字符串,暂时未用
时序选择器
2.1 **瞬时向量选择器:**瞬时向量选择器用来选择一组时序在某个采样点的采样值
# 最简单的情况就是指定一个度量指标,选择出所有属于该度量指标的时序的当前采样值。比如下面的表达式 http_requests_total 或 promhttp_metric_handler_requests_total # 可以通过在后面添加用大括号包围起来的一组标签键值对来对时序进行过滤。比如下面的表达式筛选出了 `job` 为 `prometheus`,并且 `group` 为 `canary` 的时序 http_requests_total{job="prometheus", group="canary"} # 匹配标签值时可以是等于,也可以使用正则表达式。总共有下面几种匹配操作符: = : 完全相等 !=: 不相等 =~: 正则表达式包含匹配 !~: 正则表达式不包含不匹配 # 下面的表达式筛选出了 environment 为 staging 或 testing 或 development,并且 method 不是 GET 的时序: http_requests_total{environment=~"staging|testing|development",method!="GET"} {}类似sql中的where # 案例:cpu_load数据抓取(浏览器访问:http://192.168.88.10:9090/graph 进行查询) node_load15 node_load15{job="prometheus"} node_load15{instance="192.168.88.20:9100",job="prometheus"}
时间选择器用于指定需要查询的时间点或时间段,标签键值对用于过滤查询结果集
2.2 **区间向量选择器:**区间向量选择器类似于瞬时向量选择器,不同的是它选择的是过去一段时间的采样值。
# 可以通过在瞬时向量选择器后面添加包含在 `[]` 里的时长来得到区间向量选择器。比如下面的表达式选出了所有度量指标为 `http_requests_total` 且 `job` 为 `prometheus` 的时序在过去 1 或 5 分钟的采样值 node_load15{instance="192.168.88.20:9100",job="prometheus"}[1m] node_load15{instance="192.168.88.20:9100",job="prometheus"}[5m] # 时长的单位可以是下面几种之一 - s:seconds - m:minutes - h:hours - d:days - w:weeks - y:years
2.3 偏移修饰器
前面介绍的选择器默认都是以当前时间为基准时间,偏移修饰器用来调整基准时间,使其往前偏移一段时间。偏移修饰器紧跟在选择器后面,使用 offset 来指定要偏移的量。
# 比如下面的表达式选择度量名称为 `node_load15` 的所有时序在 `5` 分钟前的采样值。 node_load15{instance="192.168.88.20:9100",job="prometheus"} offset 5m # 下面的表达式选择度量名称为 `node_load15` 的所有时序在 `1` 小时前的采样值,并列出连续五分钟内的采样值。 node_load15{instance="192.168.88.20:9100",job="prometheus"}[5m] offset 5m
2. PromQL操作符
二元操作符
PromQL 的二元操作符支持基本的逻辑判断和算术运算,包含算术类、比较类和逻辑类三大类
1.1 算术类二元操作符
+:加 -:减 *:乘 /:除 %:求余 ^:乘方 算术类二元操作符可以使用在标量与标量、向量与标量,以及向量与向量之间 - 标量与标量之间,结果很明显,跟通常的算术运算一致 - 向量与标量之间,相当于把标量跟向量里的每一个标量进行运算,这些计算结果组成了一个新的向量 - 向量与向量之间,会稍微麻烦一些。运算的时候首先会为左边向量里的每一个元素在右边向量里去寻找一个匹配元素(匹配规则后面会讲),然后对这两个匹配元素执行计算,这样每对匹配元素的计算结果组成了一个新的向量。如果没有找到匹配元素,则该元素丢弃 # 标量&向量:简单来比喻就是标量是一个数字,向量是一组数字!
原理图
1.2 比较类二元操作符
== (equal) != (not-equal) > (greater-than) < (less-than) >= (greater-or-equal) <= (less-or-equal) 比较类二元操作符同样可以使用在标量与标量、向量与标量,以及向量与向量之间。默认执行的是过滤,也就是保留值 也可以通过在运算符后面跟 bool 修饰符来使得返回值 0 和 1,而不是过滤 - 标量与标量之间,必须跟 bool 修饰符,因此结果只可能是 0(false) 或 1(true) - 向量与标量之间,相当于把向量里的每一个标量跟标量进行比较,结果为真则保留,否则丢弃。如果后面跟了 bool 修饰符,则结果分别为 1 和 0 - 向量与向量之间,运算过程类似于算术类操作符,只不过如果比较结果为真则保留左边的值(包括度量指标和标签这些属性),否则丢弃,没找到匹配也是丢弃。如果后面跟了 bool 修饰符,则保留和丢弃时结果相应为 1 和 0
1.3 逻辑类二元操作符
and: 交集 or: 合集 unless: 补集 具体运算规则如下: - `vector1 and vector2` 的结果由在 vector2 里有匹配(标签键值对组合相同)元素的 vector1 里的元素组成 - `vector1 or vector2` 的结果由所有 vector1 里的元素加上在 vector1 里没有匹配(标签键值对组合相同)元素的 vector2 里的元素组成 - `vector1 unless vector2` 的结果由在 vector2 里没有匹配(标签键值对组合相同)元素的 vector1 里的元素组成
1.4 二元操作符优先级
#PromQL 的各类二元操作符运算优先级如下: ^ *, /, % +, - ==, !=, <=, <, >=, > and, unless or
向量匹配
前面算术类和比较类操作符都需要在向量之间进行匹配。共有两种匹配类型,
one-to-one
和many-to-one
|one-to-many
2.1 One-to-one 向量匹配
这种匹配模式下,两边向量里的元素如果其标签键值对组合相同则为匹配,并且只会有一个匹配元素。可以使用 `ignoring` 关键词来忽略不参与匹配的标签,或者使用 `on` 关键词来指定要参与匹配的标签。语法如下: <vector expr> <bin-op> ignoring(<label list>) <vector expr> <vector expr> <bin-op> on(<label list>) <vector expr> #例如,当进行运算时,即使两个都是五个值的向量,实际参与运算的有效值可能只有四个,形成的新的向量也将只有四个值。 比如对于下面的输入: method_code:http_errors:rate5m{method="get", code="500"} 24 method_code:http_errors:rate5m{method="get", code="404"} 30 method_code:http_errors:rate5m{method="put", code="501"} 3 method_code:http_errors:rate5m{method="post", code="500"} 6 method_code:http_errors:rate5m{method="post", code="404"} 21 method:http_requests:rate5m{method="get"} 600 method:http_requests:rate5m{method="del"} 34 method:http_requests:rate5m{method="post"} 120 执行下面的查询: method_code:http_errors:rate5m{code="500"} / ignoring(code) method:http_requests:rate5m 得到的结果为: {method="get"} 0.04 # 24 / 600 {method="post"} 0.05 # 6 / 120 也就是每一种 method 里 code 为 500 的请求数占总数的百分比。由于 method 为 put 和 del 的没有匹配元素所以没有出现在结果里
2.2 Many-to-one / one-to-many 向量匹配
这种匹配模式下,某一边会有多个元素跟另一边的元素匹配。这时就需要使用 `group_left` 或 `group_right` 组修饰符来指明哪边匹配元素较多,左边多则用 `group_left`,右边多则用 `group_right`。其语法如下: <vector expr> <bin-op> ignoring(<label list>) group_left(<label list>) <vector expr> <vector expr> <bin-op> ignoring(<label list>) group_right(<label list>) <vector expr> <vector expr> <bin-op> on(<label list>) group_left(<label list>) <vector expr> <vector expr> <bin-op> on(<label list>) group_right(<label list>) <vector expr> 比如对于下面的输入: method_code:http_errors:rate5m{method="get", code="500"} 24 method_code:http_errors:rate5m{method="get", code="404"} 30 method_code:http_errors:rate5m{method="put", code="501"} 3 method_code:http_errors:rate5m{method="post", code="500"} 6 method_code:http_errors:rate5m{method="post", code="404"} 21 method:http_requests:rate5m{method="get"} 600 method:http_requests:rate5m{method="del"} 34 method:http_requests:rate5m{method="post"} 120 组修饰符只适用于算术类和比较类操作符,对于前面的输入,执行下面的查询: rate(http_errors[5m]) / ignoring(code) group_left rate(http_requsts[5m]) #类似笛卡尔积因为左边的数据比较多就让左边多对一(group_left) 将得到下面的结果: {method="get", code="500"} 0.04 // 24 / 600 {method="get", code="404"} 0.05 // 30 / 600 {method="post", code="500"} 0.05 // 6 / 120 {method="post", code="404"} 0.175 // 21 / 120 也就是每种 method 的每种 code 错误次数占每种 method 请求数的比例。这里匹配的时候 ignoring 了 code,才使得两边可以形成 Many-to-one 形式的匹配。由于左边多,所以需要使用 group_left 来指明 Many-to-one / one-to-many 过于高级和复杂,要尽量避免使用。但很多时候通过 ignoring 就可以解决问题
聚合操作符
PromQL 的聚合操作符用来将向量里的元素聚合得更少。总共有下面这些聚合操作符:
sum:求和 min:最小值 max:最大值 avg:平均值 stddev:标准差 stdvar:方差 count:元素个数 count_values:等于某值的元素个数 bottomk:最小的 k 个元素 topk:最大的 k 个元素 quantile:分位数 PromQL 中的聚合操作语法格式可采用如下面两种格式之一 ● <聚合函数>(向量表达式) by|without (标签) ● <聚合函数> by|without (标签) (向量表达式) 聚合操作符语法如下: 其中 `without` 用来指定不需要保留的标签,而 `by` 正好相反,用来指定需要保留的标签 请注意要先分组在聚合 下面来看几个示例: sum(http_requests_total) without (instance) #解释 http_requests_total 度量指标带有 application、instance 和 group 三个标签。上面的表达式会得到每个 application 的每个 group 在所有 instance 上的请求总数。效果等同于下面的表达式: sum(http_requests_total) by (application, group) 示例 (1)每台主机 CPU 在最近 5 分钟内的平均使用率 (1 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance)) * 100 (2)查询 1 分钟的 load average 的时间序列是否超过主机 CPU 数量 2 倍 node_load1 > on (instance) 2 * count (node_cpu_seconds_total{mode="idle"}) by (instance) (3)计算主机内存使用率 可用内存空间:空闲内存、buffer、cache 指标之和 node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes 已用内存空间:总内存空间减去可用空间 node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes) 使用率:已用空间除以总空间 (node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes)) / node_memory_MemTotal_bytes * 100 (4)计算每个 node 节点所有容器总计内存: sum by (instance) (container_memory_usage_bytes{instance=~"node*"})/1024/1024/1024 (5)计算 node01 节点最近 1m 所有容器 cpu 使用率: sum (rate(container_cpu_usage_seconds_total{instance="node01"}[1m])) / sum (machine_cpu_cores{instance="node01"}) * 100 #container_cpu_usage_seconds_total 代表容器占用CPU的时间总和 (6)计算最近 5m 每个容器 cpu 使用情况变化率 sum (rate(container_cpu_usage_seconds_total[5m])) by (container_name) (7)查询 K8S 集群中最近 1m 每个 Pod 的 CPU 使用情况变化率 sum (rate(container_cpu_usage_seconds_total{image!="", pod_name!=""}[1m])) by (pod_name) #由于查询到的数据都是容器相关的,所以最好按照 Pod 分组聚合
4.学习方法
#这是grafanca的模板的PQL语句
(node_filesystem_size_bytes{instance=~"$instance",fstype=~"ext.*|xfs|nfs",mountpoint !~".*pod.*"}-node_filesystem_free_bytes{instance=~"$instance",fstype=~"ext.*|xfs|nfs",mountpoint !~".*pod.*"}) *100/(node_filesystem_avail_bytes {instance=~"$instance",fstype=~"ext.*|xfs|nfs",mountpoint !~".*pod.*"}+(node_filesystem_size_bytes{instance=~"$instance",fstype=~"ext.*|xfs|nfs",mountpoint !~".*pod.*"}-node_filesystem_free_bytes{instance=~"$instance",fstype=~"ext.*|xfs|nfs",mountpoint !~".*pod.*"}))
#先拆分
(node_filesystem_size_bytes{instance=~"192.168.88.130:9100",fstype=~"xfs"}-node_filesystem_free_bytes{instance=~"192.168.88.130:9100",fstype=~"xfs"}) *100/(node_filesystem_avail_bytes {instance=~"192.168.88.130:9100",fstype=~"xfs"}+(node_filesystem_size_bytes{instance=~"192.168.88.130:9100",fstype=~"xfs"}-node_filesystem_free_bytes{instance=~"192.168.88.130:9100",fstype=~"xfs"}))
#在拆分
(node_filesystem_size_bytes-node_filesystem_free_bytes) *100/(node_filesystem_avail_bytes+(node_filesystem_size_bytes-node_filesystem_free_bytes))
#分解
(node_filesystem_size_bytes-node_filesystem_free_bytes)
/
(node_filesystem_avail_bytes+(node_filesystem_size_bytes-node_filesystem_free_bytes))
*
100
#得出结论
(总量-空闲量)/(可用量+(总量-空闲量))*100
#答案
使用量/总量*100
#说明写PQL必须从最后一步开始写,先确定在慢慢精确
总结
1. 不是所有的指标(数据)都可以在数据库中直接查询得到,有些需要使用运算式计算得来。
2. 运算过程没有正确与否,简单或复杂只要得到的结果正确即可
3. 学习promQL(PQL)可以通过grafana的模板学习参考
3. PromQL函数(了解)
Prometheus 内置了一些函数来辅助计算,下面介绍一些典型的
abs():绝对值
sqrt():平方根
exp():指数计算
ln():自然对数
ceil():向上取整
floor():向下取整
round():四舍五入取整
delta():计算区间向量里每一个时序第一个和最后一个的差值
sort():排序
五、Prometheus - AlertManager部署
实验原理:Prometheus中,采集的数据先写入本地数据库,然后由预先设定的告警规则(即数据库查询语句)查询数据库,判断指标是否超阈值。如果超阈值,则会在web界面上显示报警信息。
要实现邮件报警,需要准备两个邮箱地址,并通过alertmanager配置文件声明发件人、收件人的信息以及登录账号和密码。具体步骤包括修改alertmanager配置文件,填写发件人和收件人的邮箱信息,设置好邮件发送的服务器地址和端口,然后重启alertmanager服务。
要实现钉钉报警,请先实现邮件报警,首先借助一个名为“钉钉插件”的工具来实现消息转发,并修改插件的配置文件,填写钉钉机器人的API接口信息,并alertmanager的报警媒介配置文件中声明新的接收消息配置项,使其与插件正确关联,以实现消息的有效转发。该插件的端口是8060端口
1. alertmanager组件安装
下载并安装alertmanager组件
$ tar -xf alertmanager-0.27.0.linux-amd64.tar.gz $ cp -r alertmanager-0.27.0.linux-amd64 /usr/local/alertmanager
编写alertmanager启动脚本
$ cat>/usr/local/alertmanager/alertmanager.service<<EOF [Unit] Description=Alertmanager After=network.target [Service] Type=simple User=root WorkingDirectory=/usr/local/alertmanager ExecStart=/usr/local/alertmanager/alertmanager Restart=on-failure [Install] WantedBy=multi-user.target EOF
添加启动脚本到systemd启动管理中
$ ln -s /usr/local/alertmanager/alertmanager.service /lib/systemd/system/ $ systemctl daemon-reload $ systemctl enable --now alertmanager #默认没有被Prometheus调用,需要修改peometheus配置文件调用alertmanager组件
2. alertmanager组件配置
修改配置文件 - 实现基于邮件的报警(备份原始的,覆盖修改)
$ vim /usr/local/alertmanager/alertmanager.yml global: # 在没有报警的情况下声明为已解决的时间 resolve_timeout: 5m # 配置邮件发送信息 要有2个邮箱一个发信人xbz_002,一个收信人xbz_001,route的信息会被receivers调用 smtp_smarthost: 'smtp.126.com:25' smtp_from: 'qq2783954131@126.com' smtp_auth_username: 'qq2783954131@126.com' smtp_auth_password: 'RRnNbfNSZpiBeBLT' smtp_hello: '126.com' smtp_require_tls: false route: group_by: ['alertname', 'cluster'] group_wait: 30s group_interval: 5m repeat_interval: 5m receiver: default receivers: - name: 'default' email_configs: - to: 'xbz_001@126.com' send_resolved: true
添加报警规则,进行效果测试
# 修改 /usr/local/prometheus/prometheus.yml 文件添加规则文件 $ vim /usr/local/prometheus/prometheus.yml alerting: alertmanagers: - static_configs: - targets: - 192.168.90.101:9093 (alertmanager搭建所在的服务器的IP和端口) rule_files: - "rules/*.yml" # 创建并修改 /usr/local/prometheus/rules/xxxxx.yml 文件添加监控规则 $ mkdir /usr/local/prometheus/rules/ $ vim /usr/local/prometheus/rules/xxxxx.yml #示例 groups: - name: test rules: - alert: CPU负载1分钟告警 expr: node_load1{job!~"(nodes-dev-GPU|hw-nodes-test-server|hw-nodes-prod-ES|hw-nodes-prod-MQ)"} / count (count (node_cpu_seconds_total{job!~"(nodes-dev-GPU|hw-nodes-test-server|hw-nodes-prod-ES|hw-nodes-prod-MQ)"}) without (mode)) by (instance, job) > 2.5 for: 1m labels: level: warning annotations: summary: "{{ $labels.instance }} CPU负载告警 " description: "{{$labels.instance}} 1分钟CPU负载(当前值: {{ $value }})" - alert: CPU使用率告警 expr: 1 - avg(irate(node_cpu_seconds_total{mode="idle",job!~"(IDC-GPU|hw-nodes-prod-ES|nodes-test-GPU|nodes-dev-GPU)"}[30m])) by (instance) > 0.85 for: 1m labels: level: warning annotations: summary: "{{ $labels.instance }} CPU使用率告警 " description: "{{$labels.instance}} CPU使用率超过85%(当前值: {{ $value }} )"
注意:修改后重启prometheus服务,然后网页访问测试。
创建资源消耗任务,触发报警规则实现报警
$ dd if=/dev/zero of=/dev/null & #多次执行消耗CPU性能
创建钉钉机器人流程
6.接入钉钉报警媒介
# 下载 go 环境钉钉转发警告
$ wget https://github.com/timonwong/prometheus-webhook-dingtalk/releases/download/v2.1.0/prometheus-webhook-dingtalk-2.1.0.linux-amd64.tar.gz
$ tar -xf prometheus-webhook-dingtalk-2.1.0.linux-amd64.tar.gz
$ cp -r prometheus-webhook-dingtalk-2.1.0.linux-amd64 /usr/local/dingtalk/
# 创建 service 启动文件
$ cd /usr/local/dingtalk/
$ vim dingtalk.service
[Unit]
Description=dingtalk
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/usr/local/dingtalk/
ExecStart=/usr/local/dingtalk/prometheus-webhook-dingtalk
Restart=on-failure
[Install]
WantedBy=multi-user.target
--------------------------------------------------------------------------------------------------
$ cd /usr/local/dingtalk/
$ cp -a config.example.yml config.yml
#修改dingtalk的配置文件 写入刚刚在机器人上获取的webhook和加签码
#模板如下
vim config.yml
targets:
webhook1:
url: https://oapi.dingtalk.com/robot/send?access_token=2b6e29eb12acef02ea7b8b3cbf0ffe99f81b8f3f8b79c0e670bfe519088c7b26
secret: SEC49aa18d1561068af25418fd4f93e2b363b6f930743de682c63c664b0936d1da4
message:
title: '{{ template "legacy.title" . }}'
text: '{{ template "legacy.content" . }}'
mention:
mobiles: ['19531642291']
ln -s /usr/local/dingtalk/dingtalk.service /lib/systemd/system
$ systemctl daemon-reload
systemctl enable --now dingtalk
$ systemctl restart dingtalk
# alertmanager prometheus 报警结合 修改alertmanaget的配置文件
$ vim /usr/local/alertmanager/alertmanaget.yml
global:
resolve_timeout: 5m
smtp_smarthost: 'smtp.126.com:25'
smtp_from: 'qq2783954131@126.com'
smtp_auth_username: 'qq2783954131@126.com'
smtp_auth_password: 'RRnNbfNSZpiBeBLT'
smtp_hello: '126.com'
smtp_require_tls: false
route:
group_by: ['alertname', 'cluster']
group_wait: 30s
group_interval: 5m
repeat_interval: 5m
receiver: default
receivers:
- name: 'default'
email_configs:
- to: 'xbz_001@126.com'
send_resolved: true
#加入这个配置注意路径的webhook1和上面config.yml的配置文件要同名
webhook_configs:
- url: 'http://192.168.90.101:8060/dingtalk/webhook1/send'
send_resolved: true
#修改完请重新启动这三个服务
systemctl restart prometheus
systemctl restart alertmanager
systemctl restart dingtalk
六、Prometheus - Grafana部署
1. Grafana(古ra符那)组件安装
下载并安装Prometheus Server服务
$ tar -xf grafana-11.3.0.linux-amd64.tar.gz $ cp -r grafana-v11.3.0 /usr/local/grafana
编写Prometheus service启动脚本
$ cat>/usr/local/grafana/grafana-server.service<<EOF [Unit] Description=Grafana Server After=network.target [Service] Type=simple User=root WorkingDirectory=/usr/local/grafana ExecStart=/usr/local/grafana/bin/grafana-server Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF
添加启动脚本到systemd启动管理中
$ ln -s /usr/local/grafana/grafana-server.service /lib/systemd/system/ $ systemctl daemon-reload $ systemctl enable --now grafana-server
2. Grafana组件配置
web访问:http://192.168.88.10:3000/login
安装监控Linux系统资源模板
模板号:8919,由于图形模板作者会更新版本,软件版本和图形模板由于版本变更导致不兼容,要让软件跟随图形模板进行更新。
默认没有数据源,无法选择Proetheus数据源,需要提前创建(根据添加模板的要求)
效果展示
七、Prometheus 扩展
1. Pushgateway 配置
1.1 安装与启动
Pushgateway 采用被动推送的方式,不同于Prometheus Server主动连接exporter获取监控数据。它可以单独运行在一个节点上,需要自定义监控脚本把需要监控的主动推送给Pushgateway的API接口,然后Pushgateway再等待Prometheus Server抓取数据。
推荐在没有Prometheus Server的机器上部署
安装步骤
下载安装包
wget https://github.com/prometheus/pushgateway/releases/download/v1.6.0/pushgateway-1.6.0.linux-amd64.tar.gz tar -xf pushgateway-1.10.0.linux-amd64.tar.gz cp -r /root/pushgateway-1.10.0.linux-amd64 /usr/local/pushgateway
启动服务
cd /usr/local/pushgateway vim pushgateway.service [Unit] Description=pushgateway After=network.target Wants=network-online.target [Service] Type=simple User=root ExecStart=/usr/local/pushgateway/pushgateway Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target ln -s /usr/local/pushgateway/pushgateway.service /lib/systemd/system systemctl enable --now pushgateway #测试 netstat -anpt
默认监听9091端口,可以通过
netstat -antp
检查端口状态。
1.2 配置Prometheus抓取Pushgateway
在Prometheus的server端:编辑Prometheus配置文件prometheus.yml
,添加如下内容:
vim /usr/local/prometheus/prometheus.yml
- job_name: "pushgateway-monitor-metrics"
static_configs:
- targets: ["192.168.90.103:9091"] #pushgateway 地址和端口
honor_labels: true #保留源标签
#在重新启动
systemctl restart prometheus
重新加载Prometheus配置:
curl -X POST http://127.0.0.1:9090/-/reload
1.3 客户端手动推送数据
1.3.1 推送单条数据
#向目标ip推送
echo "mytest_metric 2406" | curl --data-binary @- http://192.168.90.103:9091/metrics/job/mytest_job
1.3.2 推送多条数据
#192.168.90.104向目标ip192.168.90.103推送
cat <<EOF | curl --data-binary @- http://192.168.90.103:9091/metrics/job/test_job/instance/192.168.90.100
#TYPE node_memory_usage gauge
node_memory_usage 4311744512
# TYPE memory_total gauge
memory_total 103481868288
EOF
1.3.3 简易推送数据脚本样例
#!/bin/bash
total_memory=$(free | awk '/Mem/{print $2}')
used_memory=$(free | awk '/Mem/{print $3}')
job_name="custom_memory_monitor"
instance_name=$(ifconfig eth0 | grep -w inet | awk '{print $2}')
pushgateway_server="http://192.168.88.160:9091/metrics/job"
cat <<EOF | curl --data-binary @- ${pushgateway_server}/${job_name}/instance/${instance_name}
#TYPE custom_memory_total gauge
custom_memory_total ${total_memory}
#TYPE custom_memory_used gauge
custom_memory_used ${used_memory}
EOF
1.4 删除数据
curl -X DELETE http://192.168.88.160:9091/metrics/job/test_job/instance/192.168.88.140
2. Blackbox Exporter(黑盒子) 配置
2.1 支持的探测模块
Blackbox Exporter 默认支持以下探测模块:
http_2xx
: HTTP GET 方法,返回状态码为2xx表示正常http_post_2xx
: HTTP POST 方法,返回状态码为2xx表示正常icmp
: ICMP 协议irc_banner
: IRC 协议pop3s_banner
: 邮局协议ssh_banner
: SSH 活跃性探测tcp_connect
: TCP 端口活跃性探测
2.1.1 安装部署Blackbox Exporter
tar -xf blackbox_exporter-0.25.0.linux-amd64.tar.gz
cp -r blackbox_exporter-0.25.0.linux-amd64/ /usr/local/blackbox_exporter
vim /usr/local/blackbox_exporter/blackbox-exporter.service
[Unit]
Description=Prometheus Blackbox Exporter
After=network.target
[Service]
Type=simple
User=root
Group=root
ExecStart=/usr/local/blackbox_exporter/blackbox_exporter \
--config.file=/usr/local/blackbox_exporter/blackbox.yml \
--web.listen-address=:9115
Restart=on-failure
[Install]
WantedBy=multi-user.target
ln -s /usr/local/blackbox_exporter/blackbox-exporter.service /lib/systemd/system/
systemctl enable --now blackbox-exporter.service
netstat -antp|grep 9115
2.2 配置Prometheus抓取Blackbox Exporter
2.2.1 实现URL监控
vim /usr/local/prometheus/prometheus.yml
- job_name: 'http_status'
metrics_path: /probe
params:
module: [http_2xx] #2xx状态码检测
static_configs:
- targets: ['http://www.xiaomi.com', 'http://www.jd.com/'] #对小米 京东检测
labels:
group: web
relabel_configs:
- source_labels: [__address__] #relabel 通过将__address__(当前目标地址)写入__param_target 标签来创建一个 label。
target_label: __param_target #监控目标 www.xiaomi.com,作为__address__的 value
- source_labels: [__param_target] #监控目标
target_label: instance #将监控目标与 url 创建一个 label
- target_label: __address__
replacement: 192.168.100.134:9115
2.2.2 实现ICMP监控(ping)
vim /usr/local/prometheus/prometheus.yml
- job_name: 'icmp_status'
metrics_path: /probe
params:
module: [icmp]
static_configs:
- targets: ['192.168.100.131', '192.168.100.132'] #修改IP
labels:
group: icmp
relabel_configs:
- source_labels: [__address__] #relabel 通过将__address__(当前目标地址)写入__param_target 标签来创建一个 label。
target_label: __param_target #监控目标 www.xiaomi.com,作为__address__的 value
- source_labels: [__param_target] #监控目标
target_label: instance #将监控目标与 url 创建一个 label
- target_label: __address__
replacement: 192.168.100.134:9115 #修改Blackbox Exporterip端口
2.2.3 实现端口监控
vim /usr/local/prometheus/prometheus.yml
- job_name: 'port_status'
metrics_path: /probe
params:
module: [tcp_connect]
static_configs:
- targets: ['192.168.100.131:9100', '192.168.100.132:8080'] #修改IP端口
labels:
group: port
relabel_configs:
- source_labels: [__address__] #relabel 通过将__address__(当前目标地址)写入__param_target 标签来创建一个 label。
target_label: __param_target #监控目标 www.xiaomi.com,作为__address__的 value
- source_labels: [__param_target] #监控目标
target_label: instance #将监控目标与 url 创建一个 label
- target_label: __address__
replacement: 192.168.100.134:9115 #修改Blackbox Exporterip端口
2.3 Grafana 可视化展示
导入模板ID:9965
3. MySQL Exporter 配置
3.1 安装与启动
推荐在没有Prometheus Server的机器上部署
创建MySQL配置文件
#安装mysql并配置用户密码 yum -y install mariadb mariadb-server systemctl enable --now mariadb mysqladmin -uroot password '123456' #部署mysqld_exporter tar -xf mysqld_exporter-0.16.0.linux-amd64.tar.gz cp -r /root/mysqld_exporter-0.16.0.linux-amd64/ /usr/local/mysqld_exporter/ cd /usr/local/prometheus/mysqld_exporter vim .my.cnf #文件的host可以是127.0.0.1或本机IP
文件内容:
[client] user=root password=123456 host=127.0.0.1 port=3306
启动服务
cd /usr/local/mysqld_exporter/ vim mysqld_exporter.service [Unit] Description=mysqldx After=network.target Wants=network-online.target [Service] Type=simple User=root ExecStart=/usr/local/mysqld_exporter/mysqld_exporter --config.my-cnf=/usr/local/mysqld_exporter/.my.cnf Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target ln -s /usr/local/mysqld_exporter/mysqld_exporter.service /lib/systemd/system #如果文件写错可以用ln -sf覆盖软连接 systemctl enable --now mysqld_exporter
确认端口(9104)是否开启:
netstat -anpt
3.2 配置Prometheus抓取MySQL Exporter
在prometheus的server服务器上编辑prometheus.yml
文件,添加如下内容:
vim /usr/local/prometheus/prometheus.yml
- job_name: "mysql_exporter"
static_configs:
- targets: ["192.168.90.103:9104"] #mysql_exporte的IP
#在重新启动
systemctl restart prometheus
重启Prometheus服务。
3.3 Grafana 可视化展示
导入模板ID:17320
4. 自动发现分类
只在Prometheus-server端配置生效
4.1 静态配置
vim /usr/local/prometheus/prometheus.yml
#格式一
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["192.168.90.101:9090","192.168.90.101:9100"]
#格式二
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets:
- 192.168.88.130:9100
#以上两种静态配置格式均可
4.2 基于文件的自动发现
编辑prometheus.yml
:
vim /usr/local/prometheus/prometheus.yml
- job_name: 'host_discovery'
file_sd_configs:
- files:
- "/usr/local/prometheus/host/*.yml"
refresh_interval: 6s
创建并编辑host_discovery.yml
:
mkdir /usr/local/prometheus/host
cd /usr/local/prometheus/host
vim 100.yml #输入带有node_export的主机让其自动发现
- targets:
- "192.168.90.100:9100"
labels:
instance: ""
systemctl restart prometheus
4.3 基于DNS的自动发现
配置dns服务器
vim /etc/named.conf
vim /etc/named.rfc1912.zones
vim /var/named/named.localhost
NS dns.xxhf.com.
dns A 192.168.90.103
www A 192.168.90.100
systemctl enable --now named
编辑prometheus.yml
:
vim /usr/local/prometheus/prometheus/prometheus.yml
#基于dns
- job_name: 'dns_discovery'
dns_sd_configs:
- names: ['www.xxhf.com'] #要解析的域名
type: A
port: 9100
vim /etc/resolv.conf #dns服务器的ip
nameserver 192.168.90.103
systemctl restart prometheus
4.4 基于Consul自动发现
编辑prometheus.yml
:
- job_name: 'consul'
consul_sd_configs:
- server: 'NginxIpAddr'
services: ['redis', 'mysql', 'linux']
组件下载地址:https://releases.hashicorp.com/consul/
启动Consul服务:
consul agent -server -ui -bootstrap-expect 1 -data-dir=/home/consul &
查看Consul成员:
consul members
curl 127.0.0.1:8500/v1/catalog/nodes
4.5 基于黑盒子的自动发现
4.5.1 安装部署Blackbox Exporter
tar -xf blackbox_exporter-0.25.0.linux-amd64.tar.gz
cp -r blackbox_exporter-0.25.0.linux-amd64/ /usr/local/blackbox_exporter
vim /usr/local/blackbox_exporter/blackbox-exporter.service
[Unit]
Description=Prometheus Blackbox Exporter
After=network.target
[Service]
Type=simple
User=root
Group=root
ExecStart=/usr/local/blackbox_exporter/blackbox_exporter \
--config.file=/usr/local/blackbox_exporter/blackbox.yml \
--web.listen-address=:9115
Restart=on-failure
[Install]
WantedBy=multi-user.target
ln -s /usr/local/blackbox_exporter/blackbox-exporter.service /lib/systemd/system/
systemctl enable --now blackbox-exporter.service
netstat -antp|grep 9115
4.5.2 实现URL监控
vim /usr/local/prometheus/prometheus.yml
- job_name: 'http_status'
metrics_path: /probe
params:
module: [http_2xx] #2xx状态码检测
file_sd_configs:
- files:
- "/usr/local/prometheus/host/*.yml"
refresh_interval: 6s
relabel_configs:
- source_labels: [__address__] #relabel 通过将__address__(当前目标地址)写入__param_target 标签来创建一个 label。
target_label: __param_target #监控目标 www.xiaomi.com,作为__address__的 value
- source_labels: [__param_target] #监控目标
target_label: instance #将监控目标与 url 创建一个 label
- target_label: __address__
replacement: 192.168.100.134:9115
4.5.3 基于黑盒的自动发现
创建并编辑host_discovery.yml
:
mkdir /usr/local/prometheus/host
cd /usr/local/prometheus/host
vim bl.yml #输入带有node_export的主机让其自动发现
- targets: ['http://www.xiaomi.com', 'http://www.jd.com/'] #对小米 京东检测
labels:
group: web
systemctl restart prometheus