前言

运维工程师的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(直方图)

直方图,将时间范围内的数据划分成不同的Buket,每个Buket各自评估其样本个数及样本值之和,因而可计算出分位数;

  • 可用于分析因异常值而引起的平均值过大的问题;
  • 分位数计算要使用专用的histogram_quantile函数

直方图指标用于描述指标的分布情况,比如对于请求响应时间,总共10w个请求,小于10ms的有5w个,小于50ms的有2w个,小于100ms的有3w个;

Summary

类似于Histogram,但客户端会直接计算并上报分位数;

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 }}"

参考

posted on 2022-11-14 13:14  Martin8866  阅读(602)  评论(0编辑  收藏  举报