Prometheus 企业监控
一、介绍
本文介绍Prometheus 监控及在k8s集群中使用node-exporter、prometheus、grafana对集群进行监控。实现原理类似ELK、EFK组合。node-exporter组件负责收集节点上的metrics监控数据,并将数据推送给prometheus, prometheus负责存储这些数据,grafana将这些数据通过网页以图形的形式展现给用户。
在开始之前有必要了解下Prometheus是什么?
Prometheus (中文名:普罗米修斯)是由 SoundCloud 开发的开源监控报警系统和时序列数据库(TSDB).自2012年起,许多公司及组织已经采用 Prometheus,并且该项目有着非常活跃的开发者和用户社区.现在已经成为一个独立的开源项目。Prometheus 在2016加入 CNCF ( Cloud Native Computing Foundation 云原生计算基金会 ), 作为在 kubernetes 之后的第二个由基金会主持的项目。 Prometheus 的实现参考了 Google 内部的监控实现,与源自Google的Kubernetes结合起来非常合适。另外相比influxdb的方案,性能更加突出,而且还内置了报警功能。它针对大规模的集群环境设计了拉取式的数据采集方式,只需要在应用里面实现一个metrics接口,然后把这个接口告诉Prometheus就可以完成数据采集了,下图为prometheus的架构图。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jl4k1Khl-1618222030520)(assets/1005768-20181203155201461-1231183520.png)]
promethues是一套开源的系统监控报警框架。Prometheus 所有采集的监控数据均以指标(metric)的形式保存在内置的时间序列数据库当中(TSDB):属于同一指标名称,同一标签集合的、有时间戳标记的数据流。除了存储的时间序列,Prometheus 还可以根据查询请求产生临时的、衍生的时间序列作为返回结果。包含了以下组件
- prometheus server: 主要负责数据采集和存储,提供promQL查询语言支持。prometheus是一个时序数据库,将采集到的监控数据按照时间序列的方式存储到本地磁盘。
- Push Gateway: 支持临时性job主动推送指标的中间网关。
- PromDash: 使用rails开发的dashboard,用于可视化指标数据。
- Exporters: 负责监控机器运行状态,提供被监控组件信息的 HTTP 接口被叫做 exporter。
- 直接采集: exporter内置了prometheus支持,直接向prometheus暴露数据端点。
- 间接采集:原不支持prometheus。通过prometheus提供的clien library编写的目标监控采集程序。
- Altermanager: 从 Prometheus server 端接收到 alerts 后,会进行去除重复数据,分组,并路由到对收的接受方式,发出报警。常见的接收方式有:电子邮件,企业微信,钉钉 , webhook
- WebUI: Prometheus内置一个简单的Web控制台,可以查询指标,查看配置信息或者Service Discovery等,实际工作中,查看指标或者创建仪表盘通常使用Grafana,Prometheus作为Grafana的数据源;9090提供图形化界面功能。
promethues 的各个组件基本都是用 golang 编写,对编译和部署十分友好.并且没有特殊依赖.基本都是独立工作。
二、基本工作原理
- Prometheus server 定期从配置好的 jobs 或者 exporters 中拉 metrics,或者接收来自 Pushgateway 发过来的 metrics,或者从其他的 Prometheus server 中拉 metrics。
- Prometheus server 在本地存储收集到的 metrics,并运行已定义好的 alert.rules,记录新的时间序列或者向 Alertmanager 推送警报。
- Alertmanager 根据配置文件,对接收到的警报进行处理,发出告警。
- 在图形界面中,可视化采集数据。
三、Prometheus 的优势和不足
1、prometheus 的优势
- 强大的多维度数据模型:
时间序列数据通过 metric 名和键值对来区分。
所有的 metrics 都可以设置任意的多维标签。
数据模型更随意,不需要刻意设置为以点分隔的字符串。
可以对数据模型进行聚合,切割和切片操作。
支持双精度浮点类型,标签可以设为全 unicode。 - 灵活而强大的查询语句(PromQL):
在同一个查询语句,可以对多个 metrics 进行乘法、加法、连接、取分数位等操作。 - 易于管理:
Prometheus server 是一个单独的二进制文件,可直接在本地工作,不依赖于分布式存储。 - 高效:
平均每个采样点仅占 3.5 bytes,且一个 Prometheus server 可以处理数百万的 metrics。
使用 pull 模式采集时间序列数据,这样不仅有利于本机测试而且可以避免有问题的服务器推送坏的 metrics。 - 可以采用 push gateway 的方式把时间序列数据推送至 Prometheus server 端。
- 可以通过服务发现或者静态配置去获取监控的 targets。
- 有多种可视化图形界面。
- 易于伸缩。
2、prometheus 的不足有待于改进
- 不支持集群化 (这个是当前最迫切的需求)
- 被监控集群过大后 本身性能有一定瓶颈(如果有集群 就可以解决这个问题)
- 偶尔发生数据丢失(这个问题 在2.0之前 会偶尔发生几次, 2.0之后貌似已经彻底解决 )
- 中文支持不好 中文资料也很少(这个问题 也是老生常谈了 往往新的 很牛的国外工具都不太支持中文)
注:
由于数据采集可能会有丢失,所以 Prometheus 不适用对采集数据要 100% 准确的情形。但如果用于记录时间序列数据,Prometheus 具有很大的查询优势,此外,Prometheus 适用于微服务的体系架构。
四、prometheus 的基本概念
1、数据模型
prometheus中存储的数据为时间序列,是由Metric的名字和一系列的标签(键值对)唯一标识的,不同的标签代表不同的时间序列。
样本:实际时间序列,每个序列包括一个float64的值和一个毫秒级的时间戳。(指标+时间戳+样本值)
metric名字: 具有语义,表示功能:例如:http_requeststotal, 表示 http 请求的总数。其中,metric 名字由 ASCII 字符,数字,下划线,以及冒号组成,且必须满足正则表达式[a-zA-Z:][a-zA-Z0-9_:]*。
标签:使一个时间序列有不同未读的识别。例如 http_requeststotal{method=“Get”} 表示所有 http 请求中的 Get 请求。当 method=“post” 时,则为新的一个 metric。标签中的键由 ASCII 字符,数字,以及下划线组成,且必须满足正则表达式[a-zA-Z:][a-zA-Z0-9_:]*。
格式:{
2、Metric类型
Prometheus 客户端库主要提供四种主要的 metric 类型:
1、Counter(累加性metirc)
一种累加的 metric,典型的应用如:
请求的个数
结束的任务数
出现的错误数
。。。
例如:
查询 promhttp_metric_handler_requests_total{code=“200”,instance=“localhost:9090”,job=“prometheus”}
返回 8,10 秒后再次查询,则返回 14。
2、Gauge(可增减性metric)
一种常规的 metric,典型的应用如:
温度
运行的 go routines 的个数
可以任意加减。
例如:
go_goroutines{instance=“localhost:9090”,job=“prometheus”}
返回值 147,10 秒后返回 124。
注:
routines: go的日常工作?
3、Histogram(树状图)
注:
histogram 英[ˈhɪstəɡræm] 美[ˈhɪstəɡræm] 直方图;矩形图
可以理解为柱状图,典型的应用如:
请求持续时间
响应大小
可以对观察结果采样,分组及统计。
例如:
查询 go_gc_duration_seconds_sum{instance=“localhost:9090”,job=“prometheus”}时
返回结果如下:Histogram metric 返回结果图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lAMAcnGy-1618222030522)(assets/image-20190504160404467-1558565443544.png)]
4、Summary(汇总)
类似于 Histogram,典型的应用如:
请求持续时间
响应大小
提供观测值的 count 和 sum 功能。
提供百分位的功能,即可以按百分比划分跟踪结果。
instance 和 jobs
instance:
一个单独 scrape(抓取) 的目标, 一般对应于一个进程。
jobs:
一组同种类型的 instances(主要用于保证可扩展性和可靠性),例如:
注:
scrape 英[skreɪp] 美[skreɪp] 刮掉; 削去; 擦坏; 擦伤; 刮坏; 蹭破; (使) 发出刺耳的刮擦声
当 scrape 目标时,Prometheus 会自动给这个 scrape 的时间序列附加一些标签以便更好的分别
例如: instance,job。
下面以实际的 metric 为例,对上述概念进行说明:
Metrics 示例
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZzMwpjc6-1618222030523)(assets/image-20190504160428088.png)]
如图所示,这三个 metric 的名字都一样,他们仅凭 handler 不同而被标识为不同的 metrics。
这类 metrics 只会向上累加,是属于 Counter 类型的 metric,且 metrics 中都含有 instance 和 job 这两个标签。
五、Prometheus 配置并监控自己
1、安装Prometheus Server
Prometheus基于Golang编写,编译后的软件包,不依赖于任何的第三方依赖。用户只需要下载对应平台的二进制包,解压并且添加基本的配置即可正常启动Prometheus Server。
1、从二进制包安装
对于非Docker用户,可以从https://prometheus.io/download/找到最新版本的Prometheus Sevrer软件包:
export VERSION=2.14.0
curl -LO https://github.com/prometheus/prometheus/releases/download/v$VERSION/prometheus-$VERSION.linux-amd64.tar.gz
解压,并将Prometheus相关的命令,添加到系统环境变量路径即可:
tar -xzf prometheus-${VERSION}.linux-amd64.tar.gz -C /usr/local/
cd /usr/local/prometheus-${VERSION}.linux-amd64
解压后当前目录会包含默认的Prometheus配置文件promethes.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']
scrape_interval:
抓取采样数据的 时间间隔, 默认 每15秒去被监控机上 采样一次,这个就是 prometheus的自定义数据采集频率了
evaluation_interval:
监控数据规则的评估频率
这个参数是prometheus多长时间会进行一次监控规则的评估
例: 假如 我们设置 当 内存使用量 > 70%时 发出报警 这么一条rule(规则) 那么prometheus 会默认 每15秒来执行一次这个规则 检查内存的情况
Alertmanager:
是prometheus的一个用于管理和发出报警的 插件
这里对 Alertmanger 暂时先不做介绍 暂时也不需要 (采用 4.0最新版的 Grafana , 本
身就已经支持报警发出功能了 往后我们会学习到)
再往后 从这里开始 进入prometheus重要的 配置采集节点的设置
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090','localhost:9100']
先定义一个 job的名称,然后 定义监控节点 targets,默认带了一个 prometheus本机的
这里可以继续扩展加入其他需要被监控的节点,如下是一个生产配置例子:
- job_name: ‘aliyun’
static_configs:- targets: [‘server04:9100’,‘IP:9100’,‘nginx06:9100’,‘web7:9100’,‘redis1:9100’,‘log:9100’,‘redis2:9100’]
targets:
可以并列写入 多个节点 用逗号隔开, 机器名+端口号
端口号:
通常用的就是 exporters 的端口 在这里 9100 其实是 node_exporter 的默认端口
如此 prometheus 就可以通过配置文件 识别监控的节点,持续开始采集数据
prometheus到此就算初步的搭建好了
Promtheus作为一个时间序列数据库,其采集的数据会以文件的形似存储在本地中,默认的存储路径为data/
,因此我们需要先手动创建该目录:
mkdir -p data
用户也可以通过参数--storage.tsdb.path="data/"
修改本地数据存储的路径。
启动prometheus服务,其会默认加载当前路径下的prometheus.yaml文件:
./prometheus
正常的情况下,你可以看到以下输出内容:
level=info ts=2018-10-23T14:55:14.499484Z caller=main.go:554 msg="Starting TSDB ..."
level=info ts=2018-10-23T14:55:14.499531Z caller=web.go:397 component=web msg="Start listening for connections" address=0.0.0.0:9090
level=info ts=2018-10-23T14:55:14.507999Z caller=main.go:564 msg="TSDB started"
level=info ts=2018-10-23T14:55:14.508068Z caller=main.go:624 msg="Loading configuration file" filename=prometheus.yml
level=info ts=2018-10-23T14:55:14.509509Z caller=main.go:650 msg="Completed loading of configuration file" filename=prometheus.yml
level=info ts=2018-10-23T14:55:14.509537Z caller=main.go:523 msg="Server is ready to receive web requests."
2、使用容器安装
对于Docker用户,直接使用Prometheus的镜像即可启动Prometheus Server:
docker run -p 9090:9090 -v /etc/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus
启动完成后,可以通过http://localhost:9090访问Prometheus的UI界面:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z6uMeZqR-1618222030525)(assets/assets_-LBdoxo9EmQ0bJP2BuUi_-LPMFlGDFIX7wuLhSHx9_-LPMFp6uLzmEmN2Fa-ZF_prometheus_ui_graph_query.png)]
使用Node Exporter采集主机数据
2、安装Node Exporter
在Prometheus的架构设计中,Prometheus Server并不直接服务监控特定的目标,其主要任务负责数据的收集,存储并且对外提供数据查询支持。因此为了能够能够监控到某些东西,如主机的CPU使用率,我们需要使用到Exporter。Prometheus周期性的从Exporter暴露的HTTP服务地址(通常是/metrics)拉取监控样本数据。
从上面的描述中可以看出Exporter可以是一个相对开放的概念,其可以是一个独立运行的程序独立于监控目标以外,也可以是直接内置在监控目标中。只要能够向Prometheus提供标准格式的监控样本数据即可。
这里为了能够采集到主机的运行指标如CPU, 内存,磁盘等信息。我们可以使用Node Exporter。
Node Exporter同样采用Golang编写,并且不存在任何的第三方依赖,只需要下载,解压即可运行。可以从https://prometheus.io/download/获取最新的node exporter版本的二进制包。
curl -OL https://github.com/prometheus/node_exporter/releases/download/v0.18.1/node_exporter-0.18.1.linux-amd64.tar.gz
tar -xzf node_exporter-0.18.1.linux-amd64.tar.gz -C /usr/local/
运行node exporter:
cd node_exporter-0.18.1.linux-amd64
cp node_exporter-0.18.1.linux-amd64/node_exporter /usr/local/bin/
node_exporter
启动成功后,可以看到以下输出:
INFO[0000] Listening on :9100 source="node_exporter.go:76"
访问http://localhost:9100/可以看到以下页面:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KVKKtFnx-1618222030527)(assets/assets_-LBdoxo9EmQ0bJP2BuUi_-LPMFlGDFIX7wuLhSHx9_-LPMFp6oc_SZOU4__NeX_node_exporter_home_page.png)]
Node Exporter页面
1、初始Node Exporter监控指标
访问http://localhost:9100/metrics,可以看到当前node exporter获取到的当前主机的所有监控数据,如下所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mqby6REK-1618222030529)(assets/assets_-LBdoxo9EmQ0bJP2BuUi_-LPMFlGDFIX7wuLhSHx9_-LPMFp6q8o3vUrTJOaFo_node_exporter_metrics_page.png)]
主机监控指标
每一个监控指标之前都会有一段类似于如下形式的信息:
# HELP node_cpu Seconds the cpus spent in each mode.
# TYPE node_cpu counter
node_cpu{
cpu="cpu0",mode="idle"} 362812.7890625
# HELP node_load1 1m load average.
# TYPE node_load1 gauge
node_load1 3.0703125
其中HELP用于解释当前指标的含义,TYPE则说明当前指标的数据类型。在上面的例子中node_cpu的注释表明当前指标是cpu0上idle进程占用CPU的总时间,CPU占用时间是一个只增不减的度量指标,从类型中也可以看出node_cpu的数据类型是计数器(counter),与该指标的实际含义一致。又例如node_load1该指标反映了当前主机在最近一分钟以内的负载情况,系统的负载情况会随系统资源的使用而变化,因此node_load1反映的是当前状态,数据可能增加也可能减少,从注释中可以看出当前指标类型为仪表盘(gauge),与指标反映的实际含义一致。
除了这些以外,在当前页面中根据物理主机系统的不同,你还可能看到如下监控指标:
- node_boot_time:系统启动时间
- node_cpu:系统CPU使用量
- node*disk**:磁盘IO
- node*filesystem**:文件系统用量
- node_load1:系统负载
- node*memeory**:内存使用量
- node*network**:网络带宽
- node_time:当前系统时间
- go_*:node exporter中go相关指标
- process_*:node exporter自身进程相关运行指标
2、从Node Exporter收集监控数据
为了能够让Prometheus Server能够从当前node exporter获取到监控数据,这里需要修改Prometheus配置文件。编辑prometheus.yml并在scrape_configs节点下添加以下内容:
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
# 采集node exporter监控数据
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']
重新启动Prometheus Server
访问http://localhost:9090,进入到Prometheus Server。如果输入“up”并且点击执行按钮以后,可以看到如下结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nMB6agJP-1618222030529)(assets/assets_-LBdoxo9EmQ0bJP2BuUi_-LPMFlGDFIX7wuLhSHx9_-LPMFp6sd1HomUq2AhEt_prometheus_ui_up_query.png)]
Expression Browser
如果Prometheus能够正常从node exporter获取数据,则会看到以下结果:
up{
instance="localhost:9090",job="prometheus"} 1
up{
instance="localhost:9100",job="node"} 1
其中“1”表示正常,反之“0”则为异常。
3、使用PromQL查询监控数据
Prometheus UI是Prometheus内置的一个可视化管理界面,通过Prometheus UI用户能够轻松的了解Prometheus当前的配置,监控任务运行状态等。 通过Graph
面板,用户还能直接使用PromQL
实时查询监控数据:
增加 cpu 负载
cat /dev/urandom | md5sum
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qzE5T842-1618222030530)(assets/assets_-LBdoxo9EmQ0bJP2BuUi_-LPMFlGDFIX7wuLhSHx9_-LPMFp6uLzmEmN2Fa-ZF_prometheus_ui_graph_query.png)]
Graph Query
切换到Graph
面板,用户可以使用PromQL表达式查询特定监控指标的监控数据。如下所示,查询主机负载变化情况,可以使用关键字node_load1
可以查询出Prometheus采集到的主机负载的样本数据,这些样本数据按照时间先后顺序展示,形成了主机负载随时间变化的趋势图表:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Aq8VUbi-1618222030531)(assets/assets_-LBdoxo9EmQ0bJP2BuUi_-LPMFlGDFIX7wuLhSHx9_-LPMFp6w2a-tNlAZqMYf_node_node1_graph.png)]
主机负载情况
PromQL是Prometheus自定义的一套强大的数据查询语言,除了使用监控指标作为查询关键字以为,还内置了大量的函数,帮助用户进一步对时序数据进行处理。例如使用rate()
函数,可以计算在单位时间内样本数据的变化情况即增长率,因此通过该函数我们可以近似的通过CPU使用时间计算CPU的利用率:
rate(node_cpu_seconds_total[2m])
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eZ7ALtnS-1618222030532)(assets/assets_-LBdoxo9EmQ0bJP2BuUi_-LPMFlGDFIX7wuLhSHx9_-LPMFp6ykiXFktbE7AoS_node_cpu_usage_by_cpu_and_mode.png)]
系统进程的CPU使用率
这时如果要忽略是哪一个CPU的,只需要使用without表达式,将标签CPU去除后聚合数据即可:
avg without(cpu) (rate(node_cpu_seconds_total[2m]))
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zt3HB7SE-1618222030532)(assets/assets_-LBdoxo9EmQ0bJP2BuUi_-LPMFlGDFIX7wuLhSHx9_-LPMFp7-zSOBoQPoKmGt_node_cpu_usage_by_mode.png)]
系统各mode的CPU使用率
那如果需要计算系统CPU的总体使用率,通过排除系统闲置的CPU使用率即可获得:
avg without(cpu) (rate(node_cpu_seconds_total{
mode="idle"}[2m]))
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yAxPI6Q0-1618222030533)(assets/assets_-LBdoxo9EmQ0bJP2BuUi_-LPMFlGDFIX7wuLhSHx9_-LPMFp71s5xiaeewHj_D_node_cpu_usage_total.png)]
系统CPU使用率
通过PromQL我们可以非常方便的对数据进行查询,过滤,以及聚合,计算等操作。通过这些丰富的表达书语句,监控指标不再是一个单独存在的个体,而是一个个能够表达出正式业务含义的语言。
4、监控数据可视化
Prometheus UI提供了快速验证PromQL以及临时可视化支持的能力,而在大多数场景下引入监控系统通常还需要构建可以长期使用的监控数据可视化面板(Dashboard)。这时用户可以考虑使用第三方的可视化工具如Grafana,Grafana是一个开源的可视化平台,并且提供了对Prometheus的完整支持。