Prometheus简介
Prometheus是一个开源的系统监控和报警系统,现在已经加入到CNCF基金会,成为继k8s之后第二个在CNCF托管的项目,在kubernetes容器管理系统中,通常会搭配prometheus进行监控,同时也支持多种exporter采集数据,还支持pushgateway进行数据上报,Prometheus性能足够支撑上万台规模的集群
Prometheus原理
Prometheus由Go语言编写而成,采用Pull方式获取监控信息,并提供了多维度的数据模型和灵活的查询接口。Prometheus不仅可以通过静态文件配置监控对象,还支持自动发现机制,能通过Kubernetes、Consl、DNS等多种方式动态获取监控对象。在数据采集方面,借助Go语音的高并发特性,单机Prometheus可以采取数百个节点的监控数据;在数据存储方面,随着本地时序数据库的不断优化,单机Prometheus每秒可以采集一千万个指标,如果需要存储大量的历史监控数据,则还支持远程存储。
Prometheus的特点
多维度数据模型:
每一个时间序列数据都由metric度量指标名称和它的标签labels键值对集合唯一确定:这个metric度量指标名称指定监控目标系统的测量特征(如:http_requests_total- 接收http请求的总计数)。labels开启了Prometheus的多维数据模型:对于相同的度量名称,通过不同标签列表的结合, 会形成特定的度量维度实例。(例如:所有包含度量名称为/api/tracks的http请求,打上method=POST的标签,则形成了具体的http请求)。这个查询语言在这些度量和标签列表的基础上进行过滤和聚合。改变任何度量上的任何标签值,则会形成新的时间序列图灵活的查询语言(PromQL):可以对采集的metrics指标进行加法,乘法,连接等操作
可以直接在本地部署,不依赖其他分布式存储
通过基于HTTP的pull方式采集时序数据
可以通过中间网关pushgateway的方式把时间序列数据推送到prometheus server端
可通过服务发现或者静态配置来发现目标服务对象(targets)
有多种可视化图像界面,如Grafana等
高效的存储,每个采样数据占3.5 bytes左右,300万的时间序列,30s间隔,保留60天,消耗磁盘大概200G
做高可用,可以对数据做异地备份,联邦集群,部署多套prometheus,pushgateway上报数据
什么是样本
样本:在时间序列中的每一个点称为一个样本(sample),样本由以下三部分组成:
- 指标(metric):指标名称和描述当前样本特征的 labelsets
- 时间戳(timestamp):一个精确到毫秒的时间戳
- 样本值(value): 一个 folat64 的浮点型数据表示当前样本的值
表示方式:通过如下表达方式表示指定指标名称和指定标签集合的时间序列:<metric name>{<label name>=<label value>, ...}
例如:指标名称为 api_http_requests_total
,标签为 method="POST" 和 handler="/messages"
的时间序列可以表示为:api_http_requests_total{method="POST", handler="/messages"}
Prometheus优缺点:
提供多维度数据模型和灵活的查询方式,通过将监控指标关联多个tag,来将监控数据进行任意维度的组合,并且提供简单的PromQL查询方式,还提供HTTP查询接口,可以很方便地结合Grafana等GUI组件展示数据
在不依赖外部存储的情况下,支持服务器节点的本地存储,通过Prometheus自带的时序数据库,可以完成每秒千万级的数据存储;不仅如此,在保存大量历史数据的场景中,Prometheus可以对接第三方时序数据库和OpenTSDB等
定义了开放指标数据标准,以基于HTTP的Pull方式采集时序数据,只有实现了Prometheus监控数据才可以被Prometheus采集、汇总、并支持Push方式向中间网关推送时序列数据,能更加灵活地应对多种监控场景
支持通过静态文件配置和动态发现机制发现监控对象,自动完成数据采集。Prometheus目前已经支持Kubernetes、etcd、Consul等多种服务发现机制
易于维护,可以通过二进制文件直接启动,并且提供了容器化部署镜像。
支持数据的分区采样和联邦部署,支持大规模集群监控
Prometheus 架构
Prometheus的基本原理是通过HTTP周期性抓取被监控组件的状态,任意组件只要提供对应的HTTP接口并符合Prometheus定义的数据格式,就可以介入Prometheus监控
Prometheus Server负载定时在目标上抓取metrics(指标)数据,每个抓取目标都需要暴露一个HTTP服务接口用于Prometheus定时抓取。这种调用被监控对象获取监控数据的方式被称为Pull(拉)。Pull方式体现了Prometheus独特的设计哲学与大多数采用Push(推)方式的监控不同
Pull方式的优势是能够自动进行上游监控和水平监控,配置更少,更容易扩展,更灵活,更容易实现高可用。简单来说就是Pull方式可以降低耦合。由于在推送系统中很容易出现因为向监控系统推送数据失败而导致被监控系统瘫痪的问题。所以通过Pull方式,被采集端无需感知监控系统的存在,完全独立于监控系统之外,这样数据的采集完全由监控系统控制
Prometheus支持两种Pull方式采集数据
- 通过配置文件、文本等进行静态配置
- 支持Zookeeper、Consul、Kubernetes等方式进行动态发现,例如对Kuernetes的动态发现,Prometheus使用Kubernetes的API查询和监控容器信息的变化,动态更新监控对象,这样容器的创建和删除都可以被Prometheus感知
Prometheus组件介绍
Prometheus Server: 用于收集和存储时间序列数据
Client Library: 客户端库,检测应用程序代码,当Prometheus抓取实例的HTTP端点时,客户端库会将所有跟踪的metrics指标的当前状态发送到prometheus server端
Exporters: prometheus支持多种exporter,通过exporter可以采集metrics数据,然后发送到prometheus server端,所有向promtheus server提供监控数据的程序都可以被称为exporter
Alertmanager: 从 Prometheus server 端接收到 alerts 后,会进行去重,分组,并路由到相应的接收方,发出报警,常见的接收方式有:电子邮件,微信,钉钉, slack等
Grafana:监控仪表盘,可视化监控数据
pushgateway: 各个目标主机可上报数据到pushgateway,然后prometheus server统一从pushgateway拉取数据。
从上图可发现,Prometheus整个生态圈组成主要包括prometheus server,Exporter,pushgateway,alertmanager,grafana,Web ui界面,Prometheus server由三个部分组成,Retrieval,Storage,PromQL
- Retrieval负责在活跃的target主机上抓取监控指标数据
- Storage存储主要是把采集到的数据存储到磁盘中
- PromQL是Prometheus提供的查询语言模块
Prometheus工作流程
Prometheus server可定期从活跃的(up)目标主机上(target)拉取监控指标数据,目标主机的监控数据可通过配置静态job或者服务发现的方式被prometheus server采集到,这种方式默认的pull方式拉取指标;也可通过pushgateway把采集的数据上报到prometheus server中;还可通过一些组件自带的exporter采集相应组件的数据
Prometheus server把采集到的监控指标数据保存到本地磁盘或者数据库
Prometheus采集的监控指标数据按时间序列存储,通过配置报警规则,把触发的报警发送到alertmanager
Alertmanager通过配置报警接收方,发送报警到邮件,微信或者钉钉等
Prometheus 自带的web ui界面提供PromQL查询语言,可查询监控数据
Grafana可接入prometheus数据源,把监控数据以图形化形式展示出
Prometheus的几种部署模式
基本高可用模式
基本的HA模式只能确保Promthues服务的可用性问题,但是不解决Prometheus Server之间的数据一致性问题以及持久化问题(数据丢失后无法恢复),也无法进行动态的扩展。因此这种部署方式适合监控规模不大,Promthues Server也不会频繁发生迁移的情况,并且只需要保存短周期监控数据的场景。
基本高可用+远程存储
在解决了Promthues服务可用性的基础上,同时确保了数据的持久化,当Promthues Server发生宕机或者数据丢失的情况下,可以快速的恢复。 同时Promthues Server可能很好的进行迁移。因此,该方案适用于用户监控规模不大,但是希望能够将监控数据持久化,同时能够确保Promthues Server的可迁移性的场景。
基本HA + 远程存储 + 联邦集群方案
Promthues的性能瓶颈主要在于大量的采集任务,因此用户需要利用Prometheus联邦集群的特性,将不同类型的采集任务划分到不同的Promthues子服务中,从而实现功能分区。例如一个Promthues Server负责采集基础设施相关的监控指标,另外一个Prometheus Server负责采集应用监控指标。再有上层Prometheus Server实现对数据的汇聚
环境说明:
系统 | Prometheus版本 |
---|---|
redhat8.2 | 2.31.1 |
部署Prometheus
首先去Prometheus官网下载相应的tar包
[root@localhost opt]# wget https://github.com/prometheus/prometheus/releases/download/v2.31.1/prometheus-2.31.1.linux-amd64.tar.gz
解压tar包
[root@localhost opt]# tar xf prometheus-2.31.1.linux-amd64.tar.gz
做软连接是为了后面操作
[root@localhost opt]# ln -s /opt/prometheus-2.31.1.linux-amd64 /opt/prometheus
进入解压目录
[root@localhost prometheus]# vim prometheus.yml
修改prometheus.yml配置文件,配置要监控的项
// 这里我们监控另一台Linux主机的状态
# 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"
- job_name: "linux" // 写要监控的服务或主机
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ["localhost:9090"]
- targets: ["192.168.182.131:9100"] //linux主机的IP地址
这里我们通过systemctl控制Prometheus。
提供service文件
[root@localhost prometheus]# cat /usr/lib/systemd/system/prometheus.service
[Unit]
Description=prometheus server daemon
After=network.target
[Service]
Type=simple
ExecStart=/opt/prometheus/prometheus \
--config.file=/opt/prometheus/prometheus.yml \
--web.read-timeout=5m \
--web.max-connections=512 \
--storage.tsdb.retention=15d \
--query.timeout=2m
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
[Install]
WantedBy=multi-user.target
启动Prometheus
// 重新加载service让其生效
[root@localhost prometheus]# systemctl daemon-reload
// 开启Prometheus服务
[root@localhost prometheus]# systemctl start prometheus.service // 设置开机自启
[root@localhost prometheus]# systemctl enable --now prometheus.service
Created symlink /etc/systemd/system/multi-user.target.wants/prometheus.service → /usr/lib/systemd/system/prometheus.service.
[root@localhost prometheus]# systemctl status prometheus.service
● prometheus.service - prometheus server daemon
Loaded: loaded (/usr/lib/systemd/system/prometheus.service; enabled; vendor preset: disabled)
Active: active (running) since Thu 2021-11-25 20:40:18 CST; 4min 23s ago
Main PID: 1739 (prometheus)
Tasks: 7 (limit: 23790)
Memory: 107.3M
这里我们用IP+端口号的方式进行访问
在192.168.182.142主机上下载exporter
[root@localhost opt]# wget https://github.com/prometheus/node_exporter/releases/download/v1.3.0/node_exporter-1.3.0.linux-amd64.tar.gz
解压exporter包
[root@localhost opt]# tar xf node_exporter-1.3.0.linux-amd64.tar.gz
做软件链接
[root@localhost opt]# ln -s /opt/node_exporter-1.3.0.linux-amd64 exporter
启动exporter
[root@localhost opt]# nohup /opt/exporter/node_exporter &
看到下图的State为两个UP