前言
运维工程师的3大核心职能:服务器资源管理、变更管理、故障管理;
目前维护一些云原生项目,这些项目采用K8s部署,相较于传统的监控,Kubernetes云监控会面临以下棘手问题;
- 容器的封闭性、隔离性
- 容器的动态调度
- 容器网络的虚拟化、软件定义网络
我想通过1款监控系统对
- 物理服务器层
- 系统层
- 网络层
- K8s集群层
- 运行在K8s集群之上的基础设施类应用+业务类应用(应用层)
进行全方位无死角监控;
一款监控系统软件应具备以下核心功能
- 数据采集:通过pull/push的方式采集数据
- 数据存储:SQL、NoSQL(K/V、Document、Colum列式存储、TSDB时序数据库)
- 展示:Grafana
- 告警:通过各种媒介(E-maill、短信、微信、钉钉)通知到报警接收人
一、Prometheus监控系统概述
Prometheus是前Goole工程师模仿Goole的Brogmon监控系统,而开发出来开源监控系统;
Kubernets是参考Goole的Borg系统开发的容器编排工具,所以Prometheus更适用于监控Kubernets集群;
Prometheus的优势
- Metric有独创的指标格式
- 多维度标签,每个独立的标签组合都代表1个独立的时间序列
- 内建时序数据的聚合、切割、切片功能
- 支持双精度浮点型数据,但无法存储日志
- 被监控端自动发现
- 数据时序存储:Prometheus内置TSDB,通过PromQL进行TSDB的查询
Prometheus的劣势
- 无法存储日志,使用Lock或者ELK/EFK收集日志;
- Prometheus内建的时序(Time Series)数据库只能存储1个月历史数据;
二、Prometheus监控系统组成
PrometheusServer
PrometheusServer无需配置,既可自动发现待监控的目标对象Target;
PrometheusServer的Retrieval(监控信息采集器) 只能通过Pull的方式,从被监控端拉取监控数据;
程序自建Prometheus仪表盘(Instrumentation)
任何能支持Prometheus去Scrape指标数据的应用程序都首先具备1个测量系统;
在Prometheus的语境中,Instrumentation是指附加到应用程序内部,用于暴露程序指标的客户端库;
from prometheus_client import Gauge, Counter, Histogram, Summary # 1.Prometheus指标类型
from prometheus_client.core import CollectorRegistry
程序员借助这些客户端库编写代码,生产可暴露的指标数据;
Prometheus主要通过3种类型的途径,使用HTTP协议,从Targart上抓取指标数据
- Exporter: 针对没有集成Instrumentation的应用程序,Prometheus社区提供Exporter
- Instrumentation:程序在开发时在代码中内建了Instrumentation(仪表板)功能;
- Pushgateway: 临时任务Push监控指标
其中
基础设施类应用监控:将Prometheus提供Expoerter,例如MySQL/Redis/Nginx.......都可以从Prometheus社区获取相应的Exporter安装到对应Target上;
业务类应用的监控(应用程序内置Prometheus仪表板): 将Prometheus提供Instrumentation集成到程序代码中;
import prometheus_client
from prometheus_client import Gauge, Counter, Histogram, Summary # 1.Prometheus指标类型
from prometheus_client.core import CollectorRegistry
from flask import Response, Flask
app = Flask(__name__)
REGISTRY = CollectorRegistry(auto_describe=False)
#2.定义Prometheus指标的数据模型
cup_gauge = Gauge(
"cpu_usage", #指标名称(key)
"统计CUP使用率", # 指标说明
["core_number", "machine_ip"], # Lable:同1指标可能会匹配到多个目标或者设备,因此使用标签作为指标的元数据可以为指标添加多维度的描述信息,这些Lable作为过滤器进行指标的过滤和聚合;
registry=REGISTRY)
@app.route('/metrics')
def metrics():
#3.Prometheus指标的数据模型填充数据
cup_gauge.labels("1", "192.168.56.18").set(25)
cup_gauge.labels("2", "192.168.56.18").set(25)
cup_gauge.labels("3", "192.168.56.18").set(25)
cup_gauge.labels("4", "192.168.56.18").set(25)
cup_gauge.labels("1", "192.168.56.19").set(23)
cup_gauge.labels("2", "192.168.56.19").set(27)
cup_gauge.labels("3", "192.168.56.19").set(28)
cup_gauge.labels("4", "192.168.56.19").set(22)
cup_gauge.labels("1", "192.168.56.20").set(21)
cup_gauge.labels("2", "192.168.56.20").set(29)
cup_gauge.labels("3", "192.168.56.20").set(32)
cup_gauge.labels("4", "192.168.56.20").set(28)
return Response(prometheus_client.generate_latest(REGISTRY),
mimetype="text/plain")
@app.route('/')
def index():
return "<h1>Customized Exporter</h1><br> <a href='metrics'>Metrics</a>"
if __name__ == "__main__":
app.run(host='0.0.0.0', port=9100, debug=True)
"""
# HELP cpu_usage 统计CUP使用率
# TYPE cpu_usage gauge
cpu_usage{core_number="1",machine_ip="192.168.56.18"} 25.0
cpu_usage{core_number="2",machine_ip="192.168.56.18"} 25.0
cpu_usage{core_number="3",machine_ip="192.168.56.18"} 25.0
cpu_usage{core_number="4",machine_ip="192.168.56.18"} 25.0
cpu_usage{core_number="1",machine_ip="192.168.56.19"} 23.0
cpu_usage{core_number="2",machine_ip="192.168.56.19"} 27.0
cpu_usage{core_number="3",machine_ip="192.168.56.19"} 28.0
cpu_usage{core_number="4",machine_ip="192.168.56.19"} 22.0
cpu_usage{core_number="1",machine_ip="192.168.56.20"} 21.0
cpu_usage{core_number="2",machine_ip="192.168.56.20"} 29.0
cpu_usage{core_number="3",machine_ip="192.168.56.20"} 32.0
cpu_usage{core_number="4",machine_ip="192.168.56.20"} 28.0
"""
Python程序内建Prometheus仪表盘
Exporters
对于那些未内建Instrumentation,没有暴露Prometheus所支持格式的指标数据的应用程序来说,常用的监控方法是在待监控目标应用程序外,单独部署1个指标暴露程序,该类程序统称为Exporter;
换句话说Exporter负责从被监控的目标应用程序上主动采集和聚合原始的数据,并转换/聚合为Prometheus的指标数据格式
Prometheus社区提供了大量的Exporter例如Node Exporter、MogoDB Exporter、MySQL Exporter等;
PushGateway
如果Prometheus的被监控端是1些短期存在的应用程序, 只能通过Push的方式推送报警,可以借助PushGateway组件;
被监控端推送(Push)监控数据到PushGateway,PrometheusServer的Retrieval(监控信息采集器) 通过Pull的方式,从PushGateway拉取监控数据;
AlertManager
PrometheusServer只能获取报警指标但无法告警,当PrometheusServer抓取到异常值之后,Prometheus支持通过告警机制向用户发送反馈或者警示,已触发用户能及时采取应对措施;
PrometheusServer通过Push的方式,向AlertManager组件推送告警信息;
AlertManager再把各种告警信息,根据用户配置的告警路由,通过各种告警媒介,通知到各种告警接收人;
1.告警状态
PrometheusAlert告警的生命周期中包含有3种状态:Inactive、Pending、Firing。
1.1.Inactive状态
非活动状态,表示正在监控,但是还未有任何警报触发。
1.2.Pending状态
表示这个警报必须被触发。由于警报可以被分组、压抑/抑制或静默/静音,所以等待验证,一旦所有的验证都通过,则将转到Firing 状态,将警报发送到AlertManager。
1.3.Firing状态
此时报警将按照AlertManager的配置规则,将警报的发送给报警的接收者,一旦警旦警报解除,则将状态转到Inactive状态,如此循环。
远端TSDB
数据就是金矿,但Prometheus内建的时序(Time Series)数据库只能存储1个月历史数据;
如果想要保存更长时间的历史监控数据可以使用远端的TSDB例如InfluxDB,对历史告警数据进行长期存储;
有了大量的历史告警数据以及日志,就可以通过机器学习技术,做告警趋势预测,最终达成智能运维目标;
三、Prometheus部署
1.下载相关组件
2.启动PrometheusServer
PrometheusServer程序是Go语言开发的,直接运行二进制文件即可;
PrometheusServer程序自建了仪表板(Instrumentation)工作在http://安装主机的外网IP:9090/metrics;
[root@localhost prometheus-2.40.2]# ls
console_libraries consoles data LICENSE NOTICE prometheus prometheus.yml promtool
[root@localhost prometheus-2.40.2]# ./prometheus
热加载配置文件
curl -X POST http://localhost:9090/-/reload
若使用这种方式进行热加载操作,需要在 Prometheus 服务启动时指定 --web.enable-lifecycle,添加到以上的 Prometheus 自启动文件中使用。
3.启动node_exporter
把node_exporter部署在被监控端,貌似没有Windows系统的node_exporter,不过可以自己开发1个自定义的Exporter;
/usr/bin/node_exporter
--web.listen-address=10.65.0.46:49100 #监听的端口
--collector.meminfo_numa
--no-collector.bcache
--no-collector.arp --no-collector.edac
--no-collector.entropy --no-collector.hwmon
--no-collector.ipvs --no-collector.timex
--no-collector.nfs --no-collector.nfsd
--no-collector.wifi
--no-collector.zfs
--no-collector.xfs
--collector.textfile.directory=/data/textfile #指定从/data/textfile目录下,读取某些自定义的监控指标信息。
启动node_exporter之后监听在http://被监控主机IP:9100/metrics,PrometheusServer会通过Htttp协议和Pull的方式来抓取数据;
[root@localhost node_exporter-1.4.0.linux-amd64]# ls
LICENSE node_exporter NOTICE
[root@localhost node_exporter-1.4.0.linux-amd64]# ./node_exporter
ts=2022-11-18T10:22:19.410Z caller=node_exporter.go:182 level=info msg="Starting node_exporter" version="(version=1.4.0, branch=HEAD, revision=7da1321761b3b8dfc9e496e1a60e6a476fec6018)"
ts=2022-11-18T10:22:19.410Z caller=node_exporter.go:183 level=info msg="Build context" build_context="(go=go1.19.1, user=root@83d90983e89c, date=20220926-12:32:56)"
ts=2022-11-18T10:22:19.410Z caller=node_exporter.go:185 level=warn msg="Node Exporter is running as root user. This exporter is designed to run as unprivileged user, root is not required."
ts=2022-11-18T10:22:19.410Z caller=filesystem_common.go:111 level=info collector=filesystem msg="Parsed flag --collector.filesystem.mount-points-exclude" flag=^/(dev|proc|run/credentials/.+|sys|var/lib/docker/.+|var/lib/containers/storage/.+)($|/)
ts=2022-11-18T10:22:19.410Z caller=filesystem_common.go:113 level=info collector=filesystem msg="Parsed flag --collector.filesystem.fs-types-exclude" flag=^(autofs|binfmt_misc|bpf|cgroup2?|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|iso9660|mqueue|nsfs|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|selinuxfs|squashfs|sysfs|tracefs)$
ts=2022-11-18T10:22:19.411Z caller=diskstats_common.go:100 level=info collector=diskstats msg="Parsed flag --collector.diskstats.device-exclude" flag=^(ram|loop|fd|(h|s|v|xv)d[a-z]|nvme\d+n\d+p)\d+$
ts=2022-11-18T10:22:19.411Z caller=node_exporter.go:108 level=info msg="Enabled collectors"
ts=2022-11-18T10:22:19.411Z caller=node_exporter.go:115 level=info collector=arp
3.1.扩展自己的监控指标
利用node_exporter的--collector.textfile.directory=/data/textfile启动选项,扩展监控指标。
监控salt中状态为Not connected和No response的minion
3.1.1.crontab
每5分钟定时执行检测minion命令( salt \* test.ping>file)输出到文件,基于该文件进行数据分析,统计出监控指标。
*/5 * * * * /home/scripts/sa_utils/salt-check-minion-new.sh
3.1.2.Shell脚本
#!/bin/bash
logfile="/tmp/salt-check.txt"
textfile_directory="/data/textfile"
[ -d $textfile_directory ] || mkdir $textfile_directory
salt \* test.ping > ${logfile} 2>&1
/bin/python3 salt_check_minion.py $logfile $textfile_directory
/home/scripts/sa_utils/salt-check-minion-new.sh
3.1.3.Python脚本
# !/usr/bin/python
# -*- coding: utf-8 -*-
#Author: Zhanglijia
#Created: 2023-05-15
import sys
class MinionStatusChecking(object):
def __init__(self, logfile, textfile_directory):
self.logfile = logfile
self.textfile_directory = textfile_directory
self.no_response_position = []
self.no_response_hosts = []
self.no_connected_position = []
self.no_connected_hosts = []
def get_log_data(self):
with open(self.logfile) as f:
line_list = f.readlines()
self.log_data = line_list
def mark_error_minion_position(self):
line_number = 0
for line in self.log_data:
line = line.strip()
line_number += 1
if line.endswith("[No response]"):
self.no_response_position.append(line_number - 1)
elif line.endswith("[Not connected]"):
self.no_connected_position.append(line_number - 1)
def mark_error_minion_hosts(self):
line_number = 0
for line in self.log_data:
line = line.strip()
line_number += 1
if line_number in self.no_response_position:
self.no_response_hosts.append(line)
elif line_number in self.no_connected_position:
self.no_connected_hosts.append(line)
def mark_error_metrics(self):
with open(self.textfile_directory, "w") as f:
line = 'salt_minion_errors{status="host_not_connected",hosts="%s"} %d\n' % (
",".join(self.no_connected_hosts), len(self.no_connected_hosts))
f.write(line)
line = 'salt_minion_errors{status="host_not_response",hosts="%s"} %d\n' % (
",".join(self.no_response_hosts), len(self.no_response_hosts))
f.write(line)
def __call__(self, *args, **kwargs):
print("#######开始执行#######")
self.get_log_data()
self.mark_error_minion_position()
self.mark_error_minion_hosts()
self.mark_error_metrics()
print("#######执行成功请检查%s#######" % (self.textfile_directory))
if __name__ == '__main__':
try:
log_file = sys.argv[1]
textfile_directory_file = sys.argv[2] + "/salt_minion_errors.prom"
except Exception as e:
print("请输入log_file和textfile_directory_file")
else:
MinionStatusChecking(log_file, textfile_directory_file)()
/home/scripts/sa_utils/salt_check_minion.py
3.1.4.定义监控指标数据格式
salt_minion_errors{status="host_not_connected",hosts="datanode065.eq-sg-3.zhanggen.com:,kafka010.eq-sg-3.apus.com:,vm-cleanapi003.eq-sg-2.zhanggen.com:"} 72
salt_minion_errors{status="host_not_response",hosts="datanode065.eq-sg-2.zhanggen.com:,kafka010.eq-sg-2.apus.com:,vm-cleanapi003.eq-sg-2.zhanggen.com:"} 19
/data/textfile/salt_minion_errors.prom
3.1.5.查看采集到的指标数据
salt_minion_errors{status=~"host_not_connected|host_not_response"}
3.1.6.Alertmanager配置
groups:
- name: default
rules:
- alert: "salt-minion节点故障"
expr: salt_minion_errors{status=~"host_not_connected|host_not_response"} >= 1
for: 5m
labels:
level: P4
annotations:
summary: "salt-minion节点故障"
description: "salt master:{{$labels.idc}}|{{$labels.instance}}|{{$labels.hosts}}|故障的minion数量为{{$value}},可能是salt-minion进程有问题,请尽快排查。"
/data/prometheus/conf/rules/alert/default.yml
4.prometheus.yml 配置
先通过静态配置的方式指定Prometheus去Pull哪些Target;
Prometheus会定时加载prometheus.yml配置文件;
我们可以借助Eureka/Consul/Zookeeper这些配置管理中心,实现在不重启PrometheusServer的情况下,被监控端服务自动发现功能;
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"
static_configs:
- targets: ["localhost:9090"]
- job_name: "zhanggen_nodes"
metrics_path: "/metrics"
static_configs:
- targets:
- "192.168.56.18:9100"
通过Prometheus的主配置文件扩展其他子配置文件。
# 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:
- 10.65.9.102:9093
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
- "/data/prometheus/conf/rules/alert/*.yml"
- "/data/prometheus/conf/rules/record/*.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"
static_configs:
- targets: ["localhost:9090"]
- job_name: "federate"
scrape_interval: 45s
scrape_timeout: 45s
honor_labels: true
metrics_path: '/federate'
params:
'match[]':
- '{job=~"..*"}'
static_configs:
- targets: ['10.65.9.102:32717','10.65.9.102:31860']
labels:
cluster: 'sg2'
- targets: ['10.65.9.112:32434','10.65.9.112:31866']
labels:
cluster: 'sg1'
- job_name: "node"
scrape_interval: 30s
scrape_timeout: 30s
file_sd_configs:
- files:
- /data/prometheus/conf/file-sd/node.yaml
- job_name: "tc-sg-xallog"
scrape_interval: 30s
scrape_timeout: 30s
file_sd_configs:
- files:
- /data/prometheus/conf/file-sd/tc-xallog.yaml
- job_name: "kafka"
scrape_interval: 45s
scrape_timeout: 45s
file_sd_configs:
- files:
- /data/prometheus/conf/file-sd/kafka.yaml
- job_name: "rabbitmq"
scrape_interval: 45s
scrape_timeout: 45s
file_sd_configs:
- files:
- /data/prometheus/conf/file-sd/rabbitmq.yaml
- job_name: "elasticsearch"
scrape_interval: 60s
scrape_timeout: 60s
file_sd_configs:
- files:
- /data/prometheus/conf/file-sd/elasticsearch.yaml
- job_name: zookeeper
scrape_interval: 60s
scrape_timeout: 60s
file_sd_configs:
- files:
- /data/prometheus/conf/file-sd/zookeeper.yaml
- job_name: 'blackbox'
metrics_path: /probe
scrape_interval: 1m
params:
module: [http_2xx] # Look for a HTTP 200 response.
file_sd_configs:
- files:
- /data/prometheus/conf/file-sd/http.yaml
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 127.0.0.1:9115 # The blackbox exporter's real hostname:port.
- job_name: 'https'
scrape_interval: 4m
metrics_path: /probe
params:
module: [https_tls] # Look for a HTTP 200 response.
file_sd_configs:
- files:
- /data/prometheus/conf/file-sd/https.yaml
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 127.0.0.1:9115 # The blackbox exporter's real hostname:port.
- job_name: 'tcp-connect'
metrics_path: /probe
params:
module: [tcp_connect] # Look for a HTTP 200 response.
file_sd_configs:
- files:
- /data/prometheus/conf/file-sd/tcp.yaml
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 127.0.0.1:9115 # The blackbox exporter's real hostname:port.
prometheus.yml
5.查看被监控的Targets
6.PromQL查询同1个Job下的报警
运维标准化是运维自动化的前提条件;
如果在配置时,系统层、K8s层、业务应用层,都使用同1个Lable,例如归类为1个Job,就可以把各层相关的报警内容串联起来发送;
四、Prometheus监控指标
PrometheusServer定时通过HTTP协议去Target暴露的Exporter中Pull监控指标信息;
PrometheusServer把采集到的监控指标(时间序列)存储到时序数据库。
1.metrics数据类型
Prometheus使用4种方法来描述监视的指标
Counter
计数器用于保存单调递增的数据,例如站点访问次数,不能为负值,也不支持减少,但可以重置为0;
Gauge
仪表盘用于存储有起伏特征的指标数据,例如内存空闲大小
Gauge是Counter的超集,相较于Counter存在指标数据丢失的可能性;
Counter能让用户确切了解指标随着时间的变化状态,而Gauge则可能随着时间流逝而变得精准度越来越低;
Histogram
求平均值是避免异常值;
直方图指标用于描述指标的分布情况,比如对于请求响应时间,总共10w个请求,小于10ms的有5w个,小于50ms的有2w个,小于100ms的有3w个;
Summary
和直方图类似,Summary也是用于描述指标分布情况,不过表现形式不同,比如还是对于请求响应时间,Summary描述则是,总共10w个请求,20%小于10ms,30%小于50ms,50%小于100ms;
2.metrics数据格式
Prometheus仅用于以"键值"形式存储时序式的聚合数据,它并不支持存储文本数据;
# HELP cpu_usage 统计CUP使用率
# TYPE cpu_usage gauge
cpu_usage{core_number="1",machine_ip="192.168.56.18"} 25.0
cpu_usage{core_number="2",machine_ip="192.168.56.18"} 25.0
cpu_usage{core_number="3",machine_ip="192.168.56.18"} 25.0
cpu_usage{core_number="4",machine_ip="192.168.56.18"} 25.0
cpu_usage{core_number="1",machine_ip="192.168.56.19"} 23.0
cpu_usage{core_number="2",machine_ip="192.168.56.19"} 27.0
cpu_usage{core_number="3",machine_ip="192.168.56.19"} 28.0
cpu_usage{core_number="4",machine_ip="192.168.56.19"} 22.0
cpu_usage{core_number="1",machine_ip="192.168.56.20"} 21.0
cpu_usage{core_number="2",machine_ip="192.168.56.20"} 29.0
cpu_usage{core_number="3",machine_ip="192.168.56.20"} 32.0
cpu_usage{core_number="4",machine_ip="192.168.56.20"} 28.0
键=指标名称+标签
- 指标名称:Key称为指标(Metric)名称+标签(label),通常意味着CPU速率、内存使用率/分区比例等;
- 标签: 1个指标无法精确匹配到1个监控目标或者设备,指标+标签可以更加精确的描述出同1个监控目标或者设备的不同监控项(多维度的描述信息);
另外通过指标+Lable作为过滤器,进行指标的过滤和聚合;
值
浮点型数值
五、PromQL
Prometheus采用向量数据格式保存监控数据。
提供了内置的数据查询语句PromQL(Prometheus Query Language)也称为向量表达式,以支持用户进行实时的向量查询及聚合操作;
1.PromQL语法
PromQL通过指标名称+Label标签作为查询条件,从Prometheus的时间序列数据库中,查询出符合查询条件的时间序列(向量),作为当前PromQL的查询结果。
2.PromQL查询结果
PromQL查询结果也称向量,向量分为瞬时向量和范围向量,2种不同的数据类型;
- Instant vector: - a set of time series containing a single sample for each time series, all sharing the same timestamp
- Range vector: - a set of time series containing a range of data points over time for each time series
- Scalar: - a simple numeric floating point value
- String: - a simple string value: currently unused
比较常见的是
- "瞬时向量" #查询得到最新的值,(实时数据)通常用于报警、实时监控。(1维数组)
- "区间向量" #查询某1段时间范围内所有的样本值,多用于数据分析、预测。(2维数组)
2.1.瞬时向量(Instance vector)
PromQL查询出的每1个向量(时间序列)之中只包含:1个时间戳+1个值。
curl 'http://localhost:9090/api/v1/query' \
--data 'query=http_requests_total{code="200"}' \
--data time=1608481001
{
"metric": {"__name__": "http_requests_total", "code": "200"},
"value": [1608481001(1个时间戳), "881(1个值)"]
}
Instance vector(瞬时向量)向量就是1个方向的数据,表示1个时间序列的集合,但是每1个时序上只有最近的1个点,而不是线。
2.2.范围向量(RangeVector)
PromQL查询出的每1个向量(时间序列)之中只包含:N个时间戳+N个值。(二维数组)
curl 'http://localhost:9090/api/v1/query' \
--data 'query=http_requests_total{code="200"}[30s]' \
--data time=1608481001
{
"metric": {"__name__": "http_requests_total", "code": "200"},
"values":
[ [1608480978, "863"], [1608480986, "874"], [1608480094, "881"] ]
}
Range vector(范围向量)表示一段时间范围里的时序,每个时序可包含多个点。
min_over_time(kube_pod_container_status_ready{namespace=~"aimaster-user-namespace.*",pod=~"app-workspace.*"}[4h]) == 1
六、Alertmanager告警策略
上文提到PrometheusServer和Alertmanager是2个不同的组件;
PrometheusServer负责去Exporter上Pull、存储、分析报警信息,并且触发告警,而Alertmanager负责把告警推送出去;
在PrometheusServer的主配置文件(prometheys.yml)中配置产生的条件以及产生告警,配置产生告警之后推送给哪些Alertmanager;
Prometheus通过alter-rule告警规则,触发告警通知给altermanager;
Alertmanager组件则用于处理这些由Prometheus触发的告警;
Alertmanager组件除了提供基本的告警通知能力以外,还主要提供了如:分组、抑制以及静默等告警特性:
1.Prometheus配置Alertmanager的地址
在Prometheus的主配置文件(prometheys.yml)中,配置触发报警之后,报警传递(push)给哪些AlertManager去处理报警;
/data/prometheus/conf/prometheus.yml
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
- 10.65.9.102:9093
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
- "/data/prometheus/conf/rules/alert/*.yml"
- "/data/prometheus/conf/rules/record/*.yml"
2.Prometheus配置触发报警的条件
在Prometheus的主配置文件(prometheys.yml)中,配置触发报警的条件。
/data/prometheus/conf/rules/alert/default.yml
groups:
- name: test-mysql-rule
rules:
- alert: "连接数报警"
expr: mysql_global_variables_mysqlx_max_connections > 90 #连接数大于90就告警PromQL
for: 1s
labels:
severity: warning
annotations:
summary: "服务名:{{$labels.alertname}}"
description: "业务msyql连接数不够报警: 当前值为:{{ $value }}"
value: "{{ $value }}"