Prometheus
Prometheus
一,简介
1.1 监控目标:
白盒监控:通过白盒监控了解其内部的运行状态,通过对监控目标的观察能够预判可能出现的问题;从而对潜在的不确定因素进行优化;
黑盒监控:可以在系统或服务发生故障能够快速的通知相关人员;
目的:
趋势数据
对照分析
告警
故障分析与定位
数据可视化
1.2 prometheus的优势:
易于管理,监控服务的内部运行状态,强大的数据模型,PromQL,高效,可扩展,易于集成,可视化,开放性;
监控服务的内部运行状态, 基于Prometheus丰富的Client库,用户可以轻松的在应用程序中添加对Prometheus的支持,从而让用户可以获取服务和应用内部真正的运行状态 ;
强大的数据模型, 所有采集的监控数据均以指标(metric)的形式保存在内置的时间序列数据库当中(TSDB) ;
http_request_status{code='200',content_path='/api/path', environment='produment'} => [value1@timestamp1,value2@timestamp2...]
强大的查询语言promQL
高效, 每秒处理数十万的数据点;
可扩展
易于集成
可视化,
开放性
1.3 安装promethuse server
https://prometheus.io/download/ ,下载文件,解压
[root@prometheus02 local]# systemctl cat promethues.service
# /usr/lib/systemd/system/promethues.service
[Unit]
Description=prometheus
After=network.target
[Service]
ExecStart=/usr/local/prometheus/prometheus --config.file=/usr/local/prometheus/prome
Restart=on-failure
[Install]
WantedBy=multi-user.target
###启动服务
# systemctl enable --nwo promethues.service
# ls -io:9090
[Unit]
Description=prometheus
After=network.target
[Service]
ExecStart=/usr/local/prometheus/prometheus --config.file=/usr/local/prometheus/prometheus.yml --web.listen-address=:9090
Restart=on-failure
[Install]
WantedBy=multi-user.target
默认配置文件四个部份
# 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"]
1.4node_exporter安装:
[root@test01 ~]# wget https://github.com/prometheus/node_exporter/releases/download/v1.3.1/node_exporter-1.3.1.linux-amd64.tar.gz
tar -xf node_exporter-1.3.1.linux-amd64.tar.gz
mv node_exporter-1.3.1.linux-amd64 /usr/local/node_exporter
[root@test01 ~]# ls /usr/local/node_exporter/
LICENSE NOTICE node_exporter
###添加到服务
[root@test01 ~]# systemctl cat exporter.service
# /usr/lib/systemd/system/exporter.service
[Unit]
Description=prometheus
After=network.target
[Service]
ExecStart=/usr/bin/nohup /usr/local/node_exporter/node_exporter
Restart=on-failure
[Install]
WantedBy=multi-user.target
[root@test01 ~]# systemctl enable --now exporter.service
1.5 修改promethues server 文件
添加如下文件:
- job_name: "CentOS-TEST01"
static_configs:
- targets: ["10.30.162.63:9100"]
- job_name: "promethues-node-exporter"
static_configs:
- targets: ["10.30.162.192:9100"]
- job_name: "nodes"
static_configs:
- targets: ["10.30.162.194:9100","10.30.162.198:9100","10.30.162.195:9100"]
登录网页,输入up,查看添加的主机状态;
1.6 prometheus组件
Prometheus架构
二 PromQL
2.1 理解时间序列
2.1.1样本
Prometheus采集到的样本数据以时间序列(time-series)的方式保存在内存数据库存中,并且定时存在硬盘上。(TSDB)
time-series是按照时间戳和值的序列顺序存放的,称之为向量(vector).
^
│ . . . . . . . . . . . . . . . . . . . node_cpu{cpu="cpu0",mode="idle"}
│ . . . . . . . . . . . . . . . . . . . node_cpu{cpu="cpu0",mode="system"}
│ . . . . . . . . . . . . . . . . . . node_load1{}
│ . . . . . . . . . . . . . . . . . .
v
<------------------ 时间 ---------------->
在time-series中每一个点称为一个样本(sample),样本由下面三个部分组成 :
- 指标(metric):metirc name+labelsets
- 时间戳(timestamp):可以精确到毫秒;
- 样本值(Value):
2.2 指标(metric)
2.2.1 基本介绍
格式如下:
<metric name>{<label name>=<label value>, ...}
指标名称只能由ASCII字符、数字、下划线以及冒号组成并必须符合正则表达式[a-zA-Z_:][a-zA-Z0-9_:]*
。 反映样本的含义;
标签(label)反映当前样本的特征维度, 以对样本数据进行过滤,聚合等 , 名称只能由ASCII字符、数字以及下划线组成并满足正则表达式[a-zA-Z_][a-zA-Z0-9_]*
其中_作为前缀的标签,是系统保留的关键字,只能在系统内部使用,
api_http_requests_total{method="POST", handler="/messages"}
{__name__="api_http_requests_total",method="POST", handler="/messages"}
Prometheus源码中,metirc的数据结构如下:
type Metric LabelSet
type LabelSet map[LabelName]LabelValue
type LabelName string
type LabelValue string
Prometheus定义了4中不同的指标类型(metric type):Counter(计数器)、Gauge(仪表盘)、Histogram(直方图)、Summary(摘要)。
2.2.2 metric类型-Counter(计数器)
特点:只增不减,除非系统发生重置;可以通过一些函数获取变化速率;
如:通过rate()获取HTTP请求的增长率:
rate(http_requests_total[5m])
访问前10的http地址:
topk(10, http_requests_total)
2.2.3 metric类型-Gauge(仪表盘)
Gauge类型的指标侧重于反应系统的当前状态 , 样本数据可增可减 。
如下:
node_memory_MemFree_bytes
通过delta()来查看变化情况
delta(node_memory_MemFree_bytes[2h])
idelta(node_memory_MemFree_bytes[2h])
可以使用deriv()计算样本的线性回归,
deriv(node_memory_MemFree_bytes[2h])
使用predict_linear()对数据的变化趋势进行预测
predict_linear(node_memory_MemFree_bytes[2h],20*3600)
2.2.4 metric类型- Histogram和Summary的指标类型
Histogram和Summary主用用于统计和分析样本的分布情况,解决长尾问题;
为了区分是平均的慢还是长尾的慢,最简单的方式就是按照请求延迟的范围进行分组。
如下:quantile为分位数0-1
Summary
# HELP prometheus_rule_group_duration_seconds The duration of rule group evaluations.
# TYPE prometheus_rule_group_duration_seconds summary
prometheus_rule_group_duration_seconds{quantile="0.01"} 0.003513586
prometheus_rule_group_duration_seconds{quantile="0.05"} 0.003740832
prometheus_rule_group_duration_seconds{quantile="0.5"} 0.005341571
prometheus_rule_group_duration_seconds{quantile="0.9"} 0.009430996
prometheus_rule_group_duration_seconds{quantile="0.99"} 0.010494519
prometheus_rule_group_duration_seconds_sum 1772.5477663010008
prometheus_rule_group_duration_seconds_count 299810
Histogram
# HELP prometheus_tsdb_compaction_chunk_range_seconds Final time range of chunks on their first compaction
# TYPE prometheus_tsdb_compaction_chunk_range_seconds histogram
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="100"} 22
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="400"} 22
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="1600"} 22
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="6400"} 22
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="25600"} 102
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="102400"} 659
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="409600"} 827
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="1.6384e+06"} 2141
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="6.5536e+06"} 5.785815e+06
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="2.62144e+07"} 5.785815e+06
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="+Inf"} 5.785815e+06
prometheus_tsdb_compaction_chunk_range_seconds_sum 1.0331562126854e+13
prometheus_tsdb_compaction_chunk_range_seconds_count 5.785815e+06
与Summary类型的指标相似之处在于Histogram类型的样本同样会反应当前指标的记录的总数(以_count作为后缀)以及其值的总量(以_sum作为后缀)。不同在于Histogram指标直接反应了在不同区间内样本的个数,区间通过标签len进行定义。
同时对于Histogram的指标,我们还可以通过histogram_quantile()函数计算出其值的分位数。不同在于Histogram通过histogram_quantile函数是在服务器端计算的分位数。 而Sumamry的分位数则是直接在客户端计算完成。因此对于分位数的计算而言,Summary在通过PromQL进行查询时有更好的性能表现,而Histogram则会消耗更多的资源。反之对于客户端而言Histogram消耗的资源更少。
2.3 初识PromQL
2.3.1 查询时间序列
瞬时向量
PromQL支持使用`=`和`!=`两种完全匹配模式
node_memory_MemAvailable_bytes{instance="10.30.162.194:9100"}
node_memory_MemAvailable_bytes{instance!="10.30.162.194:9100"}
- 使用
label=~regx
表示选择那些标签符合正则表达式定义的时间序列; - 反之使用
label!~regx
进行排除;
node_memory_MemAvailable_bytes{job=~"nodes|Graylog"}
node_memory_MemAvailable_bytes{job!~"nodes|Graylog"}
2.3.2 查询区间(区间向量)
node_memory_MemAvailable_bytes{job!~"nodes|Graylog"}[5m]
- s-秒
- m-分
- h-小时
- d-天
- w-周
- y-年
2.3.3 时间位移操作
5分钟前的瞬时样本数据,或昨天一天的区间内的样本数据 :
node_memory_MemAvailable_bytes{job!~"nodes|Graylog"} offset 5m
node_memory_MemAvailable_bytes{job!~"nodes|Graylog"}[1h] offset 1h
2.3.4 使用聚合操作
# 查询系统所有http请求的总量
sum(http_request_total)
# 按照mode计算主机CPU的平均使用时间
avg(node_cpu) by (mode)
# 按照主机查询各个主机的CPU使用率
sum(sum(irate(node_cpu{mode!='idle'}[5m])) / sum(irate(node_cpu[5m]))) by (instance)
2.3.5 标量(scalar)和字符串(string)
注意: 当使用表达式count(http_requests_total),返回的数据类型,依然是瞬时向量。用户可以通过内置函数scalar()将单个瞬时向量转换为标量。
2.3.6 合法的PromQL表达式
PromQL表达式都必须至少包含一个指标名称(例如http_request_total),或者一个不会匹配到空字符串的标签过滤器(例如{code="200"})。
还可以使用 name 标签来指定监控指标名称;
2.4 操作符
2.4.1 数学运算符,布尔运算符,逻辑运算符等等。
瞬时向量与标量之间进行数学运算时,数学运算符会依次作用域瞬时向量中的每一个样本值,从而得到一组新的时间序列。
node_memory_MemFree_bytes /(1024*1024*1024)
瞬时向量与瞬时向量之间进行数学运算时 , 新的时间序列将不会包含指标名称
node_disk_read_time_seconds_total+node_disk_write_time_seconds_total
使用bool修改符后,布尔运算不会对时间序列进行过滤,而是直接依次瞬时向量中的各个样本数据与标量的比较结果0或者1。从而形成一条新的时间序列
node_memory_MemFree_bytes /(1024*1024*1024) >bool 6
同时需要注意的是,如果是在两个标量之间使用布尔运算,则必须使用bool修饰符
2==bool 2
2.4.2 集合运算符:
and or unless
2.4.3 操作符的优先级
^
*, /, %
+, -
==, !=, <=, <, >=, >
and, unless
or
2.4.4 匹配模式
向量与向量之间进行运算操作时会基于默认的匹配规则:依次找到与左边向量元素匹配(标签完全一致)的右边向量元素进行运算,如果没找到匹配元素,则直接丢弃。
一对一, 从操作符两边表达式获取的瞬时向量依次比较并找到唯一匹配(标签完全一致)的样本值。 两边不一致的情况下,可用on(label list)或ignoring(lable list)来修改标签的匹配行为。
有如下样本值:
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
多对一和一对多, 必须使用group修饰符:group_left或者group_right来确定哪一个向量具有更高的基数(充当“多”的角色)。
表达式和结果如下:
method_code:http_errors:rate5m / ignoring(code) group_left method:http_requests:rate5m
结果如下:
{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
提醒:group修饰符只能在比较和数学运算符中使用。在逻辑运算and,unless和or才注意操作中默认与右向量中的所有元素进行匹配。
2.5 PromQL聚合操作
sum
(求和)min
(最小值)max
(最大值)avg
(平均值)stddev
(标准差)stdvar
(标准差异)count
(计数)count_values
(对value进行计数)bottomk
(后n条时序)topk
(前n条时序)quantile
(分布统计)聚合语法如下:
<aggr-op>([parameter,] <vector expression>) [without|by (<label list>)]
其中只有count_values
, quantile
, topk
, bottomk
支持参数(parameter)。
这里面有by,without参数的使用。
得到总量:
sum(prometheus_http_requests_total)
结果 :
{} 11863
sum(prometheus_http_requests_total) without(instance)
等于
sum(prometheus_http_requests_total) by(code,job,handler)
count_values用于时间序列中每一个样本值出现的次数。count_values会为每一个唯一的样本值输出一个时间序列,并且每一个时间序列包含一个额外的标签
count_values("count",prometheus_http_requests_total)
topk和bottomk则用于对样本值进行排序,返回当前样本值前n位,或者后n位的时间序列 。
topk(5,prometheus_http_requests_total)
bottomk(5,prometheus_http_requests_total)
quantile用于计算当前样本数据值的分布情况quantile(φ, express)其中0 ≤ φ ≤ 1。φ 为分位数。
示例如下:
quantile(0.5, http_requests_total)
2.6 内置函数
样本值:value 指标:metrics instant-vector: instant range-vector: range
**注意:**参数类型,instant,range
instant-vector
https://icloudnative.io/prometheus/3-prometheus/functions.html
2.6.0 函数简介
1,abs(v instant-vector):绝对值;
abs(delta(node_memory_MemFree_bytes[5m]))
{instance="10.30.162.195:9100", job="node-test"} 10533187.368421052
2,absent(v instant-vector),absent_over_time(v rang-vector)
如果v有value,返回空,如果没有value,则返回没有指标名但带有标签的时间序列,值为1;适合用于报警;
absent(node_boot_time_seconds{instance="10.30.162.195:9100", job="node-test"}) ==> no data
##
absent(node_boot_time_seconds{instance="10.30.162.195:9100", job="node"})
结果:{instance="10.30.162.195:9100", job="node"} 1
absent_over_time(prometheus_http_requests_total{job="test"}[10m])
{job="test"} 1
3,ceil(v instant-vector)
将样本值四舍五入为整数;
**floor(v instant),**向下取整;
changes(v rang-vector)
返回这个区间向量每个value变化的次数;
changes(prometheus_http_requests_total[10m])
4,clamp(v instant,min scalar,max scalar)
clamp_max(v instant,max scalar):value>max,则为max clamp_min(v instant,min scalar): value<min则为min
max>value>=min value=min
value>max value=max
max < min #输出为空
clamp(changes(prometheus_http_requests_total[10m]),2,50)
5,时间
day_of_month(v=vector(time()),instant) 返回当月的第几天; day_of_week(v=vector(time()),instant) day_of_year(v=vector(time()),instant) days _in_month(v=vector(time()),instant),返回当月有多少天; hour(v=vector(time()),instant),当前第几个小时 minute(v=vector(time()),instant), month(v=vector(time()),instant), year(v=vector(time()),instant),
day_of_month(node_boot_time_seconds )
day_of_week(node_boot_time_seconds )
day_of_week(node_boot_time_seconds )##新增函数,旧版本没有
day_of_week(node_boot_time_seconds )
delta() ,idelta()
返回区间向量中第一个值与j最后一个值之间的差值,及时value为整数,得到的值也可能不是整数;最后一个减第一个值 delta(v range):第一个值与j最后一个值之间的差值 idelta(v range),最新两个value之前的差值,
delta(node_memory_MemFree_bytes[10m])
idelta(node_memory_MemFree_bytes[10m])
6,deriv(v range)
使用简单线性回归计算范围向量 V 中时间序列的每秒导数。范围向量必须至少有两个样本才能执行计算。当在距离矢量中找到 +Inf 或 -Inf 时,计算的斜率和偏移值将为 NaN.一般用于Gauge
deriv(node_memory_MemFree_bytes[20m]) ##y=kx+b,中的k
7,exp(v instant)
返回各个样本值的 e
的指数值 ;
exp(prometheus_http_requests_total)
8,histogram_quantile()
histogram_quantile(φ float, b instant-vector)
9, holt_winters()
holt_winters(v range-vector, sf scalar, tf scalar)
函数基于区间向量 v,生成时间序列数据平滑值。平滑因子 sf
越低, 对旧数据的重视程度越高。趋势因子 tf
越高,对数据的趋势的考虑就越多。其中,0< sf, tf <=1
。
10,increase(v range)
rate( v range),irate(v range)下面有介绍
获取区间中的第一个值 和最后一个值,返回其示增长量,只用于count类型;
11,label_join()
label_join(v instant-vector, dst_label string, separator string, src_label_1 string, src_label_2 string, ...)
增加标签des_label, des_label的值为src_label_1的值+separator+src_label_2的值。。。
label_join(up{instance="localhost:9090", job="prometheus"},"test",",","instance","job")
#结果:
up{instance="localhost:9090", job="prometheus", test="localhost:9090,prometheus"}
12,label_replace()
label_replace(v instant-vector, dst_label string, replacement string, src_label string, regex string)
label_replace(up,"host_port","$2","instance","(.*):(.*)")
#结果:##增加host_port标签名,标签值为instance以":"做为分割符的第二个值;
up{host_port="9100", instance="10.30.162.195:9100", job="node-test"} 1
up{host_port="9090", instance="localhost:9090", job="prometheus"} 1
13,predict_linear()
表达式:predict_linear(v range-vector, t time-scalar)
根据range-vector,估测t秒后的样本值;
#根2h的样本值,预测4个小时后磁盘剩余空间;
predict_linear(node_filesystem_free_bytes[2h],4*3600)
14,restets(v range)
count被重置的次数, 两个连续样本之间的值的减少被认为是一次计数器重置 ;使用数据类型:count
例:resets(node_filesystem_free_bytes[2h])
15,round(v instant,to_near scalar)
返回向量中所有样本值的最接近to_near整数倍的整数 ;
round(node_filesystem_files,1024*1024) /(1024*1024)
16,scalar(node_filesystem_files_free)
函数的参数是一个单元素的瞬时向量,它返回其唯一的时间序列的值作为一个标量。如果度量指标的样本数量大于 1 或者等于 0, 则返回 NaN
。
scalar(node_filesystem_files)
17,sort()
sort(v vector-instant):value升序;
sort_desc(v vector-instant):value降序;
例:
sort(node_filesystem_files)
18,time()
time():返回当前时间;
timestamp(v vector-instant):返回value的时间戳
aggregation
_over_time()
19,avg_over_time(range-vector)
: 区间向量内每个度量指标的平均值。min_over_time(range-vector)
: 区间向量内每个度量指标的最小值。max_over_time(range-vector)
: 区间向量内每个度量指标的最大值。sum_over_time(range-vector)
: 区间向量内每个度量指标的求和。count_over_time(range-vector)
: 区间向量内每个度量指标的样本数据个数。quantile_over_time(scalar, range-vector)
: 区间向量内每个度量指标的样本数据值分位数,φ-quantile (0 ≤ φ ≤ 1)。stddev_over_time(range-vector)
: 区间向量内每个度量指标的总体标准差。stdvar_over_time(range-vector)
: 区间向量内每个度量指标的总体标准方差。
2.6.1 示counter增长率
increase(v rang-vector):获取区间中第一个,最后一个的的值,计算增长率;
increase(prometheus_http_requests_total[2m])/120
rate (v range-vector)计算方法同样 ,更简单一些
rate(prometheus_http_requests_total[2m])
irate(v range-vector):取区间的最后两个值,来计算增长率,更准确的瞬时增长率;
irate(prometheus_http_requests_total[2m])
2.6.2 预测Gauge指标变化趋势
predict_linear(v range-vector,t scalar): predict_linear函数可以预测时间序列v在t秒后的值
predict_linear(node_filesystem_free_bytes[2h],4000*3600)/(1024*1024*1024)<0
2.6.3 Histogram指标分位数
histogram_quantile(φ float, b instant-vector) (0<φ<1)
histogram_quantile(0.5,prometheus_http_request_duration_seconds_bucket)
2.6.4 动态标签替换
格式如下:
label_replace(v instant-vector, dst_label string, replacement string, src_label string, regex string)
label_join(v instant-vector, dst_label string, separator string, src_label_1 string, src_label_2 string, ...)
实例:
label_replace(up, "host", "$1", "instance", "(.*):.*")
2.6.5 其他内置函数
官网文档;
2.7 在HTTP API中使用PromQL
2.7.1 瞬时数据查询
```bash
GET /api/v1/query ```
- query=:PromQL表达式。
- time=:用于指定用于计算PromQL的时间戳。可选参数,默认情况下使用当前系统时间。
- timeout=:超时设置。可选参数,默认情况下使用-query,timeout的全局设置
# curl 'http://localhost:9090/api/v1/query?query=up'
{"status":"success","data":{"resultType":"vector","result":[{"metric":{"__name__":"up","instance":"10.30.162.192:9100","job":"promethues-node-exporter"},"value":[1650525415.782,"1"].....}
{"status":"success","data":
{"resultType":"vector",
"result":[{"metric":{"__name__":"up","instance":"10.30.162.192:9100","job":"promethues-node-exporter"},"
value":[1650525415.782,"1"].....}
根返回的数据类型不同,返回的result也有所不同:
瞬时向量:vetor
[
{
"metric": { "<label_name>": "<label_value>", ... },
"value": [ <unix_time>, "<sample_value>" ]
},
...
]
区间向量:matrix
[
{
"metric": { "<label_name>": "<label_value>", ... },
"values": [ [ <unix_time>, "<sample_value>" ], ... ]
},
...
]
标量:scalar
[ <unix_time>, "<scalar_value>" ]
字符串:string
[ <unix_time>, "<string_value>" ]
2.7.2 区间数据查询
格式:
GET /api/v1/query_range
- query=: PromQL表达式。
- start=: 起始时间。
- end=: 结束时间。
- step=: 查询步长。
- timeout=: 超时设置。可选参数,默认情况下使用-query,timeout的全局设置。
结果格式如下:
{
"resultType": "matrix",
"result": <value>
}
up在30秒内,以15秒为间隔
# curl 'http://localhost:9090/api/v1/query_range?query=up&start=2022-04-20T20:10:30.781Z&end=2022-04-20T20:11:00.781Z&step=15s'
结果如下:
{"status":"success","data":{"resultType":"matrix","result":[{"metric":{"__name__":"up","instance":"10.30.162.192:9100","job":"promethues-node-exporter"},"values":[[1650485430.781,"1"],[1650485445.781,"1"],[1650485460.781,"1"]]},{"metric":{"__name__":"up","instance":"10.30.162.194:9100","job":"nodes"},"values":[[1650485430.781,"1"],[1650485445.781,"1"],[1650485460.781,"1"]]},{"metric":{"__name__":"up","instance":"10.30.162.195:9100","job":"nodes"},"values":[[1650485430.781,"1"],[1650485445.781,"1"],[1650485460.781,"1"]]},{"metric":{"__name__":"up","instance":"10.30.162.198:9100","job":"nodes"},"values":[[1650485430.781,"1"],[1650485445.781,"1"],[1650485460.781,"1"]]},{"metric":{"__name__":"up","instance":"10.30.162.60:9100","job":"Graylog"},"values":[[1650485430.781,"1"],[1650485445.781,"1"],[1650485460.781,"1"]]},{"metric":{"__name__":"up","instance":"10.30.162.63:9100","job":"CentOS-TEST01"},"values":[[1650485430.781,"1"],[1650485445.781,"1"],[1650485460.781,"1"]]},{"metric":{"__name__":"up","instance":"localhost:9090","job":"prometheus"},"values":[[1650485430.781,"1"],[1650485445.781,"1"],[1650485460.781,"1"]]}]}}
2,8 ,最佳实践
2.8.1监控所有
级别 | 监控什么 | Exporter |
---|---|---|
网络 | 网络协议:http、dns、tcp、icmp;网络硬件:路由器,交换机等 | BlockBox Exporter;SNMP Exporter |
主机 | 资源用量 | node exporter |
容器 | 资源用量 | cAdvisor |
应用(包括Library) | 延迟,错误,QPS,内部状态等 | 代码中集成Prmometheus Client |
中间件状态 | 资源用量,以及服务状态 | 代码中集成Prmometheus Client |
编排工具 | 集群资源用量,调度等 | Kubernetes Component |
2.8.2 四个黄金指标
延迟:服务请求所需时间。
通讯量:监控当前系统的流量,用于衡量服务的容量需求。
错误:监控当前系统所有发生的错误请求,衡量当前系统错误发生的速率。
饱和度:衡量当前服务的饱和度。
2.8.3 RED方法
RED方法是Weave Cloud在基于Google的“4个黄金指标”的原则下结合Prometheus以及Kubernetes容器实践,细化和总结的方法论,特别适合于云原生应用以及微服务架构应用的监控和度量。
- (请求)速率:服务每秒接收的请求数。
- (请求)错误:每秒失败的请求数。
- (请求)耗时:每个请求的耗时。
2.8.4 USE方法
USE方法全称"Utilization Saturation and Errors Method"
- 使用率:关注系统资源的使用情况。 这里的资源主要包括但不限于:CPU,内存,网络,磁盘等等。100%的使用率通常是系统性能瓶颈的标志。
- 饱和度:例如CPU的平均运行排队长度,这里主要是针对资源的饱和度(注意,不同于4大黄金信号)。任何资源在某种程度上的饱和都可能导致系统性能的下降。
- 错误:错误计数。例如:“网卡在数据包传输过程中检测到的以太网网络冲突了14次”。
2.9 prometheus数据模型和存储机制
2.9.1 数据模型DataModel
Prometheus 的监控数据以指标(metric)的形式保存在内置的时间序列数据库(TSDB)当中 .
指标名称和标签(metrics name+labels)
每一条时间序列由指标名称以及一组标签唯一标识
样本(Sample)
三个组成部分:
指标(metric):指标名称Metric Name和标签Labels 时间戳(timestamp):一个精确到毫秒的时间点; 样本值(value):一个float64的浮点型数据; ##后加 Series 由很多相关的samples组成的时间序列;
# 方便理解,如下三个样本 <-------------------- metric ------------------><-----timestamp-----><--value--> <--- metric name---><--------labels------------><-----timestamp-----><--value--> http_request_total{status="200", method="GET"}@1434417560938 => 94355 http_request_total{status="200", method="GET"}@1434417561287 => 94334 http_request_total{status="200", method="POST"}@1434417561287 => 93656
根据时间顺序,把样本数据放在一起,就可以形成一条曲线,如下:
特定的metric、timestamp、value构成的时间序列(TimeSeries) 在Prometheus中被称作==Series==。
2.9.2 Prometheus中Samples和Series的监控
##查看每少收到samples数量;超10万,可以考虑分片拆分;
rate(prometheus_tsdb_head_samples_appended_total[5m])
##Prometheus内存中最新的一次的series数量,也可以理解时间序列的数量 ;
prometheus_tsdb_head_series
查询所有时间序列的方法
#查询所有时间序列Series
{__name__=~".+"}
#统计所有时间序列Series的数量
count({__name__=~".+"})
2.9.3 Prometheus存储机制[^20221130]
为了查询效率,Prometheus将最近的数据保存在内存中,然后通过一个compactor定时将数据打包到磁盘, 数据在内存中最少保留2个小时(storage.tsdb.min-block-duration ), 压缩率在2小时时候达到最大值 。为了防止程序崩溃,实现了WAL(write-ahead-log)机制。
如上图, HeadBlock是数据库的内存部分,灰色块是存在磁盘上的不可更改的持久块Block。 我们有一个预写日志(WAL)用于持久写入。 传入的样本(粉红色方框)首先进入HeadBlock并在内存中停留一会儿,然后刷新到磁盘并映射到内存(蓝色的方框)。当这些内存映射 chunks 或内存中的 chunks 变旧到一定程度时,它们将作为持久块Block刷新到磁盘。 在Prometheus内部,chunk是用来存储压缩后的样本sample数据的最小单位。chunk的大小1KB,每个chunk可以存储最多120个样本,当chunk存满120个样本或超过了chunkRange的时间范围(默认情况为 2h),就会写到新的chunk里。 chunk写满以后,Prometheus会存入到磁盘,并使用MMAP做映射关系,来节省内存的消耗。如下。
Prometheus磁盘存储结构如下:
每个block又分为:
chunk dir:里面的chunk文件(最大512M)存储了具体的监控数据; index:索引 meta.json:元数据文件,标识了一些基本信息 tombstones:标识了一些删除文件;
Prometheus默认会对旧的Block数据进行合并和压缩,以减少文件的数量 ,应该把监控数据备份到其他地方,重启Prometheus实例会加载历史数据,如果历史数据量很大,将会耗时长;
磁盘容量规划
通过对Prometheus使用磁盘目录的分析,每个Block占用磁盘空间主要有三部分:
Chunk数据 :241M index数据:87M WAL数据:3913M(历史数据) index数据量比chunk总数据量比例是: 35:100
每2个小时生成一个block,先计算2小时内新增sample数量,
# 先计算2小时内新增sample数量13733662
$ increase(prometheus_tsdb_head_samples_appended_total[2h])
{container="prometheus", endpoint="web", instance="10.244.145.39:9090", job="prometheus-k8s", namespace="monitoring", pod="prometheus-k8s-1", service="prometheus-k8s"}
13733662.594142258
{container="prometheus", endpoint="web", instance="10.244.145.44:9090", job="prometheus-k8s", namespace="monitoring", pod="prometheus-k8s-0", service="prometheus-k8s"}
13733463.765690375
# sample平均大小,约1Btyes
$ rate(prometheus_tsdb_compaction_chunk_size_bytes_sum[1d])
/
rate(prometheus_tsdb_compaction_chunk_samples_sum[1d])
{container="prometheus", endpoint="web", instance="10.244.145.39:9090", job="prometheus-k8s", namespace="monitoring", pod="prometheus-k8s-1", service="prometheus-k8s"}
0.9777944440923069
{container="prometheus", endpoint="web", instance="10.244.145.44:9090", job="prometheus-k8s", namespace="monitoring", pod="prometheus-k8s-0", service="prometheus-k8s"}
1.0713163056751385
chunk数据占用存储空间=两小时内新增sample数量 * 每个sample平均大小 = 14M index数据存储空间 = chunk数据占用存储空间* 35% =5M 总磁盘占用量= (chunk数据占用存储空间 + index数据存储空间)*Block数量 + WAL磁盘存储空间(历史数据)
三,Prometheus告警处理
结构图:
Prometheus中,还可以通过Group(告警组)对一组相关的告警进行统一定义。当然这些定义都是通过YAML文件来统一管理的。 AlertManager还提供了静默和告警抑制机制来对告警通知行为进行优化。
3.1 Alertmanager特性
3.1.1 分组
如由于系统宕机导致大量的告警被同时触发,在这种情况下分组机制可以将这些被触发的告警合并为一个告警通知,避免一次性接受大量的告警通知,而无法对问题进行快速定位
告警分组,告警时间,以及告警的接受方式可以通过Alertmanager的配置文件进行配置。
3.1.2 抑制
当集群不可访问时触发了一次告警,通过配置Alertmanager可以忽略与该集群有关的其它所有告警。这样可以避免接收到大量与实际问题无关的告警通知。
抑制机制同样通过Alertmanager的配置文件进行设置。
3.1.3 静默
在web界面,让他闭嘴;
3.1.4 alert三种状态
Alert的三种状态:
pending:警报被激活,但是低于配置的持续时间。这里的持续时间即rule里的FOR字段设置的时间。改状态下不发送报警。
firing:警报已被激活,而且超出设置的持续时间。该状态下发送报警。
inactive:既不是pending也不是firing的时候状态变为inactive
prometheus触发一条告警的过程:
prometheus--->触发阈值--->超出持续时间--->alertmanager--->分组|抑制|静默--->媒体类型--->邮件|钉钉|微信等
3.2 自定义告警规则
3.2.1 定义告警规则
groups:
- name: node-alert
rules:
- alert: NodeDown
expr: up{job="nodes"} == 0
for: 5m
labels:
severity: critical
instance: "{{ $labels.instance }}"
annotations:
summary: "instance: {{ $labels.instance }} down"
description: "Instance: {{ $labels.instance }} 已经宕机 5分钟"
value: "{{ $value }}"
如上图: 一条告警规则主要由以下几部分组成:
alert:告警规则的名称。
expr:基于PromQL表达式告警触发条件,用于计算是否有时间序列满足该条件。
for:评估等待时间,可选参数。用于表示只有当触发条件持续一段时间后才发送告警。在等待期间新产生告警的状态为pending。
labels:自定义标签,允许用户指定要附加到告警上的一组附加标签。
annotations:用于指定一组附加信息,比如用于描述告警详细信息的文字等,annotations的内容在告警产生时会一同作为参数发送到Alertmanager
模板化: 通过
$labels.
变量可以访问当前告警实例中指定标签的值。$value则可以获取当前PromQL表达式计算的样本值。
须要能过promethues server的配置文件到指定rules目录的路径,默认Promethues每分钟会对这些告警计算,两样通过server的配置文件可以修改。如下图:
3.3 部署Alertmanager
下载文件,解压
# wget https://github.com/prometheus/alertmanager/releases/download/v0.24.0/alertmanager-0.24.0.linux-amd64.tar.gz
tar -xf
mv ... alertmanager
改成服务,添加开机启动项
[root@prometheus02 system]# cat alertmanager.service
[Unit]
Description=prometheus
After=network.target
[Service]
ExecStart=/usr/bin/nohup /usr/local/alertmanager/alertmanager --config.file=/usr/local/alertmanager/alertmanager.yml --storage.path=/usr/local/alertmanager/data/
Restart=on-failure
[Install]
WantedBy=multi-user.target
访问:http://ip:9093
3.4 Alertmanage 配置概述
3.4.1 配置文件主要分为以下几个部分:
- 全局配置(global):用于定义一些全局的公共参数,如全局的SMTP配置,Slack配置等内容;
- 模板(templates):用于定义告警通知时的模板,如HTML模板,邮件模板等;
- 告警路由(route):根据标签匹配,确定当前告警应该如何处理;
- 接收人(receivers):接收人是一个抽象的概念,它可以是一个邮箱也可以是微信,Slack或者Webhook等,接收人一般配合告警路由使用;
- 抑制规则(inhibit_rules):合理设置抑制规则可以减少垃圾告警的产生
3.5 基于标签的告警路由
在Alertmanager的配置中会定义一个基于标签匹配规则的告警路由树;
如下,默认配置文件 中的路由:
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 5m
repeat_interval: 1h
receiver: 'web.hook'
receivers:
- name: 'web.hook'
webhook_configs:
- url: 'http://127.0.0.1:5001/'
3.5.1 路由匹配
每一个警告都会经过顶级路由进入路由树,顶级路由必须匹配所有规则(不能有任何的match和match_re个人感觉是空接口), 每一个路由都可以定义自己的接受人以及匹配规则。默认情况下,告警进入到顶级route后会遍历所有的子节点,直到找到最深的匹配route,并将告警发送到该route定义的receiver中。但如果route中设置continue的值为false,那么告警在匹配到第一个子节点之后就直接停止。
匹配有两种方式:
一 ,基于字符串验证,match
二, 基于正则表达式: match_re
设置发送警告通知之前要等待时间,则通过repeat_interval设置
match:
[ <labelname>: <labelvalue>, ... ]
match_re:
[ <labelname>: <regex>, ... ]
3.5.2 告警分组
分组规则: 通过group_by, 基于告警中包含的标签 ,group_wait参数设置等待时间,如果在当前的等待时间内,group收到新告警,会合并成一个发送给receiver.
group_interval配置,则用于定义相同的Group之间发送告警通知的时间间隔。
如下例子:
route:
receiver: 'default-receiver' ##接收所告警
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
group_by: [cluster, alertname]
routes:
- receiver: 'database-pager'
group_wait: 10s
match_re:
service: mysql|cassandra
- receiver: 'frontend-pager'
group_by: [product, environment]
match:
team: frontend ## 分组中如果有team,且值为frontend
3.6 receiver
如下:revceiver有多种的通知方式
name: <string>
email_configs:
[ - <email_config>, ... ]
hipchat_configs:
[ - <hipchat_config>, ... ]
pagerduty_configs:
[ - <pagerduty_config>, ... ]
pushover_configs:
[ - <pushover_config>, ... ]
slack_configs:
[ - <slack_config>, ... ]
opsgenie_configs:
[ - <opsgenie_config>, ... ]
webhook_configs:
[ - <webhook_config>, ... ]
victorops_configs:
[ - <victorops_config>, ... ]
一配置文件 邮箱
global:
resolve_timeout: 5m
smtp_smarthost: 'smtp.qiye.163.com:25'
smtp_from: 'zabbix-server@leadchina.cn'
smtp_auth_username: 'zabbix-server@leadchina.cn'
smtp_auth_password: 'Leadchina@147258'
smtp_require_tls: true
templates:
- './template/*.tmpl'
route:
group_by: ['alertname','cluster','service']
group_wait: 10s
group_interval: 10s
repeat_interval: 10m
receiver: 'default-receiver'
receivers:
- name: 'default-receiver'
email_configs:
- to: 'weijie.wang@leadchina.cn'
send_resolved: true
# html: '{{ template "__alertmanager" . }}'
html: '{{ template "email.default.html" . }}'
headers: { Subject: "Prometheus 告警邮件" }
企业微信:
例文:
global:
resolve_timeout: 10m
wechat_api_url: 'https://qyapi.weixin.qq.com/cgi-bin/'
wechat_api_secret: '应用的secret,在应用的配置页面可以看到'
wechat_api_corp_id: '企业id,在企业的配置页面可以看到'
templates:
- '/etc/alertmanager/config/*.tmpl'
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 5m
repeat_interval: 12h
routes:
- receiver: 'wechat'
continue: true
inhibit_rules:
- source_match:
receivers:
- name: 'wechat'
wechat_configs:
- send_resolved: false
corp_id: '企业id,在企业的配置页面可以看到'
to_user: '@all'
to_party: ' PartyID1 | PartyID2 '
message: '{{ template "wechat.default.message" . }}'
agent_id: '应用的AgentId,在应用的配置页面可以看到'
api_secret: '应用的secret,在应用的配置页面可以看到'
配置模板如下:
{{ define "wechat.default.message" }}
{{- if gt (len .Alerts.Firing) 0 -}}
{{- range $index, $alert := .Alerts -}}
{{- if eq $index 0 -}}
告警类型: {{ $alert.Labels.alertname }}
告警级别: {{ $alert.Labels.severity }}
=====================
{{- end }}
===告警详情===
告警详情: {{ $alert.Annotations.message }}
故障时间: {{ $alert.StartsAt.Format "2006-01-02 15:04:05" }}
===参考信息===
{{ if gt (len $alert.Labels.instance) 0 -}}故障实例ip: {{ $alert.Labels.instance }};{{- end -}}
{{- if gt (len $alert.Labels.namespace) 0 -}}故障实例所在namespace: {{ $alert.Labels.namespace }};{{- end -}}
{{- if gt (len $alert.Labels.node) 0 -}}故障物理机ip: {{ $alert.Labels.node }};{{- end -}}
{{- if gt (len $alert.Labels.pod_name) 0 -}}故障pod名称: {{ $alert.Labels.pod_name }}{{- end }}
=====================
{{- end }}
{{- end }}
{{- if gt (len .Alerts.Resolved) 0 -}}
{{- range $index, $alert := .Alerts -}}
{{- if eq $index 0 -}}
告警类型: {{ $alert.Labels.alertname }}
告警级别: {{ $alert.Labels.severity }}
=====================
{{- end }}
===告警详情===
告警详情: {{ $alert.Annotations.message }}
故障时间: {{ $alert.StartsAt.Format "2006-01-02 15:04:05" }}
恢复时间: {{ $alert.EndsAt.Format "2006-01-02 15:04:05" }}
===参考信息===
{{ if gt (len $alert.Labels.instance) 0 -}}故障实例ip: {{ $alert.Labels.instance }};{{- end -}}
{{- if gt (len $alert.Labels.namespace) 0 -}}故障实例所在namespace: {{ $alert.Labels.namespace }};{{- end -}}
{{- if gt (len $alert.Labels.node) 0 -}}故障物理机ip: {{ $alert.Labels.node }};{{- end -}}
{{- if gt (len $alert.Labels.pod_name) 0 -}}故障pod名称: {{ $alert.Labels.pod_name }};{{- end }}
=====================
{{- end }}
{{- end }}
{{- end }}
Prometheus通过Recoding Rule规则支持这种后台计算的方式,可以实现对复杂查询的性能优化,提高查询效率。
Recording Rule其中的一个
groups:
- name: node-record
rules:
#system
- record: node:up
expr: up{job="nodes"}
labels:
job: "nodes"
unit:
desc: "节点是否在线,在线1,不在线0"
Alert Rule
groups:
- name: node-alert
rules:
- alert: NodeDown
expr: up{job="nodes"} == 0
for: 1m
labels:
severity: critical
instance: "{{ $labels.instance }}"
annotations:
3.7 Alertmanager高可用搭建
日期:230222
$ groupadd alertmanager
$ useradd -g alertmanager -s /sbin/nologin alertmanager
$ mkdir -p /data/alertmanager_data
$ vim /usr/lib/systemd/system/alertmanager.service
[Unit]
Description=alertmanager
Documentation=https://github.com/prometheus/alertmanager
After=network.target
[Service]
Type=simple
User=root
ExecStart=/usr/local/alertmanager/alertmanager \
--config.file="/usr/local/alertmanager/alertmanager.yml" \
--web.listen-address=":9093" \
--data.retention=48h \
--storage.path="/data/alertmanager" \
--cluster.listen-address="0.0.0.0:9083" \
--log.level=debug \
> logs/alertmanager.out 2>&1 &
Restart=on-failure
[Install]
WantedBy=multi-user.target
--config.file="/usr/local/alertmanager/alertmanager.yml" \
--web.listen-address=":9093" \
--data.retention=48h \
--storage.path="/data/alertmanager" \
--cluster.listen-address="0.0.0.0:9083" \
--log.level=debug \
> logs/alertmanager.out 2>&1 &
[Unit]
Description=alertmanager
Documentation=https://github.com/prometheus/alertmanager
After=network.target
[Service]
Type=simple
User=root
ExecStart=/usr/local/alertmanager/alertmanager \
--config.file=/usr/local/alertmanager/alertmanager.yml \
--web.listen-address=:9093 \
--data.retention=48h \
--storage.path=/usr/local/alertmanager/data/ \
--cluster.listen-address=10.30.162.48:9083 \
--log.level=debug >> /var/log/alertmanager.out 2>&1
Restart=on-failure
[Install]
WantedBy=multi-user.target
/usr/local/alertmanager/alertmanager \
--config.file=/usr/local/alertmanager/alertmanager.yml \
--web.listen-address=:9093 \
--data.retention=48h \
--storage.path=/usr/local/alertmanager/data/ \
--cluster.listen-address=0.0.0.0:9083 \
--cluster.peer=10.30.162.48:9083 \
--log.level=debug >> /var/log/alertmanager.out 2>&1
k8s alertmanager
apiVersion: v1
kind: Service
metadata:
name: alertmanager-divine-soldier
namespace: monitoring
spec:
type: ClusterIP
ports:
- port: 9093
name: alertmanager
protocol: TCP
targetPort: 9093
---
apiVersion: v1
kind: Endpoints
metadata:
name: alertmanager-divine-soldier
subsets:
- addresses:
- ip: 10.30.162.195
- ip: 10.30.162.48
- ip: 10.30.162.198
ports:
- port: 9093
name: alertmanager
protocol: TCP
3.8 Prometheus联邦
四 Exporter详解
4.1 简介
范围 | 常用Exporter |
---|---|
数据库 | MySQL Exporter, Redis Exporter, MongoDB Exporter, MSSQL Exporter等 |
硬件 | Apcupsd Exporter,IoT Edison Exporter, IPMI Exporter, Node Exporter等 |
消息队列 | Beanstalkd Exporter, Kafka Exporter, NSQ Exporter, RabbitMQ Exporter等 |
存储 | Ceph Exporter, Gluster Exporter, HDFS Exporter, ScaleIO Exporter等 |
HTTP服务 | Apache Exporter, HAProxy Exporter, Nginx Exporter等 |
API服务 | AWS ECS Exporter, Docker Cloud Exporter, Docker Hub Exporter, GitHub Exporter等 |
日志 | Fluentd Exporter, Grok Exporter等 |
监控系统 | Collectd Exporter, Graphite Exporter, InfluxDB Exporter, Nagios Exporter, SNMP Exporter等 |
其它 | Blockbox Exporter, JIRA Exporter, Jenkins Exporter, Confluence Exporter等 |
4.1.2 运行方式
独立运行:手动安装exporter,exporter做中间人的角色;
集成到应用中:提前已经集成到应用中;
4.1.3 Exporter的规范
分成三个部分: HELP(注释) TYPE(类型定义),样本,TYPE一定要在样本之前,
# HELP go_memstats_mallocs_total Total number of mallocs.
# TYPE go_memstats_mallocs_total counter
go_memstats_mallocs_total 55424
对于histogramt和summary:
- 类型为summary或者histogram的指标x,该指标所有样本的值的总和需要使用一个单独的x_sum指标表示。
- 类型为summary或者histogram的指标x,该指标所有样本的总数需要使用一个单独的x_count指标表示。
- 对于类型为summary的指标x,其不同分位数quantile所代表的样本,需要使用单独的x{quantile="y"}表示。
- 对于类型histogram的指标x为了表示其样本的分布情况,每一个分布需要使用x_bucket{le="y"}表示,其中y为当前分布的上位数。同时必须包含一个样本x_bucket{le="+Inf"},并且其样本值必须和x_count相同。
- 对于histogram和summary的样本,必须按照分位数quantile和分布le的值的递增顺序排序。
4.1.4 指定样本格式的版本(看不懂)
Exporter响应的HTTP头信息中,可以通过Content-Type指定特定的规范版本
HTTP/1.1 200 OK
Content-Encoding: gzip
Content-Length: 2906
Content-Type: text/plain; version=0.0.4
Date: Sat, 17 Mar 2018 08:47:06 GMT
4.2 常用Exporter
4.2.1 docker---CAdvisor
CAdvisor是Google开源的一款用于展示和分析容器运行状态的可视化工具 .
安装如下
docker run \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:rw \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--publish=8080:8080 \
--detach=true \
--name=cadvisor \
google/cadvisor:latest
访问: http://ip:8080
CAdvisor默认只保存2分钟的监控数据, CAdvisor已经内置了对Prometheus的支持。
直接访问:http://IP:8080/metrics http://10.30.162.64:8080/metrics
修改promethues.yml文件,添加任务主机
- job_name: "CAdvisor"
static_configs:
- targets: ["10.30.162.64:8080"]
简单几个样本查看,metrics前面都container的标识
可以通过以下表达式计算容器的CPU使用率:
sum(irate(container_cpu_usage_seconds_total{image!=""}[1m])) without (cpu)
查询容器内存使用量(单位:字节):
container_memory_usage_bytes{image!=""}
查询容器网络接收量速率(单位:字节/秒):
sum(rate(container_network_receive_bytes_total{image!=""}[1m])) without (interface)
查询容器网络传输量速率(单位:字节/秒):
sum(rate(container_network_transmit_bytes_total{image!=""}[1m])) without (interface)
查询容器文件系统读取速率(单位:字节/秒):
sum(rate(container_fs_reads_bytes_total{image!=""}[1m])) without (device)
查询容器文件系统写入速率(单位:字节/秒):
sum(rate(container_fs_writes_bytes_total{image!=""}[1m])) without (device)
4.2.2 mysql-exporter
1,下载 安装 :
##添加配置文件并编辑
[root@localhost mysql_exporter]# cat localhost_db.cnf
[client]
user=mysqld_exporter
password=12345678
编辑文件,添加为服务:
[root@localhost system]# cat mysql_exporter.service
[Unit]
Description=prometheus
After=network.target
[Service]
ExecStart=/data/mysql_exporter/mysqld_exporter --config.my-cnf=/data/mysql_exporter/localhost_db.cnf
Restart=on-failure
[Install]
WantedBy=multi-user.target
2,使用方面:
mysql_global_status_questions反映当前Questions计数器的大小
查看当前MySQL实例写操作速率的变化情况:
sum(rate(mysql_global_status_commands_total{command=~"insert|update|delete"}[2m])) without (command)
3,连接数
下面列举了与MySQL连接相关的监控指标:
- mysql_global_variables_max_connections: 允许的最大连接数;
- mysql_global_status_threads_connected: 当前开放的连接;
- mysql_global_status_threads_running:当前开放的连接;
- mysql_global_status_aborted_connects:当前开放的连接;
- mysql_global_status_connection_errors_total{error="max_connections"}:由于超出最大连接数导致的错误;
- mysql_global_status_connection_errors_total{error="internal"}:由于系统内部导致的错误;
4,监控缓冲澉使用情况
查看buffer_pool_read的使用数量
# HELP mysql_global_status_innodb_buffer_pool_read_requests Generic metric from SHOW GLOBAL STATUS.
# TYPE mysql_global_status_innodb_buffer_pool_read_requests untyped
mysql_global_status_innodb_buffer_pool_read_requests 1.821222609e+09
计算2分钟内磁盘读取请求次数的增长率的变化情况
rate(mysql_global_status_innodb_buffer_pool_reads[2m])
5,查询性能
Slow_queries的计数器
# HELP mysql_global_status_slow_queries Generic metric from SHOW GLOBAL STATUS.
# TYPE mysql_global_status_slow_queries untyped
mysql_global_status_slow_queries 0
增长率:
irate(mysql_global_status_slow_queries[2m])
4.2.3 网络探测:Black_Exporter
1,相对白盒监控,黑盒监控即以用户身份测试服务的外部可见性,常见的黑盒监控包括HTTP探针,TCP探针等用于检测站点或者服务的可以访问性,以及访问效率等。
2,配置文件
Blackbox Exporter每一个探针的配置称为一个module,module包含:探针类型:prober,timeout,,以及当前探针的具体配置选项;格式如下:
# 探针类型:http、 tcp、 dns、 icmp.
prober: <prober_string>
# 超时时间
[ timeout: <duration> ]
# 探针的详细配置,最多只能配置其中的一个
[ http: <http_probe> ]
[ tcp: <tcp_probe> ]
[ dns: <dns_probe> ]
[ icmp: <icmp_probe> ]
官方提供一个简单配置文件 如下:,默认配置文件在压缩包里有:
modules:
http_2xx:
prober: http
http:
method: GET
http_post_2xx:
prober: http
http:
method: POST
启动 blackbax_exporter
访问: http://10.30.162.192:9115/probe?module=http_2xx&target=baidu.com ,可以看到dns响应等metrics
3,与Prometheus集成
修改Prometheus配置文件 ,添加如下内容:
- job_name: baidu_http2xx_probe
params:
module:
- http_2xx
target:
- baidu.com
metrics_path: /probe
static_configs:
- targets:
- 10.30.162.192:9115
- job_name: prometheus_http2xx_probe
params:
module:
- http_2xx
target:
- prometheus.io
metrics_path: /probe
static_configs:
- targets:
- 10.30.162.192:9115
以下 是官方提供,N个站点,M种探测方式,如下配置的话,须要N*M个采集任务;采用 Prometheus的Relabeling能力,这里我们也可以采用Relabling的方式对这些配置进行简化 ;如下:
scrape_configs:
- job_name: 'blackbox' #只有一个任务
metrics_path: /probe
params:
module: [http_2xx] #探针
static_configs:
- targets:
- http://prometheus.io # Target to probe with http.
- https://prometheus.io # Target to probe with https.
- http://example.com:8080 # Target to probe with http on port 8080.
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
在采集样本数据之前通过relabel_configs对采集任务进行动态设置 ,一个采集任务
第1步,根据Target实例的地址,写入
__param_target
标签中。__param_
形式的标签表示,在采集任务时会在请求目标地址中添加``参数,等同于params的设置;第2步,获取__param_target的值,并覆写到instance标签中;
第3步,覆写Target实例的
__address__
标签值为BlockBox Exporter实例的访问地址。
4,HTTP探针
如下:
modules:
http_2xx_example:
prober: http
http:
如上,http配置选项中没有添加任何配置,表示完全使用HTTP探针的默认配置,使用GET的方式对目标服务进行探测,并验证返回状态吗是否为2XX,是则表示成功,否则失败;
5,自定义HTTP探针 请求方法(看不太懂)
如下:用method定义了探测时使用的方法,通过header定义相关的请求头信息,使用body定义请求内容:
http_post_2xx:
prober: http
timeout: 5s
http:
method: POST
headers:
Content-Type: application/json
body: '{}'
如果HTTP采用了安全认证,如下:basic_auth:username,password
http_basic_auth_example:
prober: http
timeout: 5s
http:
method: POST
headers:
Host: "login.example.com"
basic_auth:
username: "username"
password: "mysecret"
HTTPS,须要自定义证书服务,如下,通过tls_config指定相关的证书信息:
http_custom_ca_example:
prober: http
http:
method: GET
tls_config:
ca_file: "/certs/my_cert.crt"
6 ,自定义探针行为
用户需要指定HTTP返回状态码,或者对HTTP版本有特殊要求,如下所示,可以使用valid_http_versions和valid_status_codes进行定义
http_2xx_example:
prober: http
timeout: 5s
http:
valid_http_versions: ["HTTP/1.1", "HTTP/2"]
valid_status_codes: []
如果用户对于HTTP服务是否启用SSL有强制的标准,则使用fail_if_ssl和fail_if_not_ssl进行配置, fail_if_ssl为true时,表示如果站点启用了SSL则探针失败,反之成功 ,fail_if_not_ssl刚好相反。如下:
http_2xx_example:
prober: http
timeout: 5s
http:
valid_status_codes: []
method: GET
no_follow_redirects: false
fail_if_ssl: false
fail_if_not_ssl: false
还可以定义正则表达式来,fail_if_matches_regexp和fail_if_not_matches_regexp
http_2xx_example:
prober: http
timeout: 5s
http:
method: GET
fail_if_matches_regexp:
- "Could not connect to database"
fail_if_not_matches_regexp:
- "Download the latest version here"
默认情况 下,HTTP探针为走IPV6协议,可以通过 preferred_ip_protocol=ip4强制通过IPV4的方式进行探测 ,
除了支持对HTTP协议进行网络探测以外,Blackbox还支持对TCP、DNS、ICMP等其他网络协议
4.3 监控Redis
下载,运行文件 ,Redis有没有设置密码,有密码在程序运行时要加上密码,两个参数下:
-redis.addr -redis.password
cat redis_exporter.service
[Unit]
Description=redis_exporter
After=network.target
[Service]
Type=simple
User=prometheus
ExecStart=/data/redis_exporter/redis_exporter -redis.addr 172.26.42.229:6379 -redis.password 123456
Restart=on-failure
[Install]
WantedBy=multi-user.target
Promethues配置文件的修改
- job_name: redis
static_configs:
- targets: ["10.30.xx.xx:9121"]
labels:
instance: redis120
4.3 监控域名和证书过期 (没有实践)
# 下载安装
wget https://github.com/prometheus/blackbox_exporter/releases/download/v0.16.0/blackbox_exporter-0.16.0.linux-amd64.tar.gz
tar -xvf blackbox_exporter-0.16.0.linux-amd64.tar.gz
mv blackbox_exporter-0.16.0.linux-amd64/ /data/redis_exporter
# 创建配置文件
cat > /data/black_exporter/black_exporter.yml << EOF
modules:
http_2xx:
prober: http
timeout: 20s
http:
preferred_ip_protocol: "ip4"
http_post_2xx_query:
prober: http
timeout: 20s
http:
preferred_ip_protocol: "ip4" ##使用ipv4
method: POST
headers:
Content-Type: application/json ##header头
body: '{"hmac":"","params":{"publicFundsKeyWords":"xxx"}}' ##传参
tls_connect_tls:
prober: tcp
timeout: 5s
tcp:
tls: true
tcp_connect:
prober: tcp
timeout: 5s
#
pop3s_banner:
prober: tcp
tcp:
query_response:
- expect: "^+OK"
tls: true
tls_config:
insecure_skip_verify: false
ssh_banner:
prober: tcp
tcp:
query_response:
- expect: "^SSH-2.0-"
irc_banner:
prober: tcp
tcp:
query_response:
- send: "NICK prober"
- send: "USER prober prober prober :prober"
- expect: "PING :([^ ]+)"
send: "PONG ${1}"
- expect: "^:[^ ]+ 001"
icmp:
prober: icmp
timeout: 20s
EOF
# 配置systemd
cat > /etc/systemd/system/blackbox_exporter.service <<EOF
[Unit]
Description=blackbox_exporter
Documentation=https://prometheus.io/
After=network.target
[Service]
Type=simple
User=prometheus
ExecStart=/data/blackbox_exporter/blackbox_exporter --config.file=/data/blackbox_exporter/blackbox.yml
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
# 启动服务
systemctl enable blackbox_exporter.service
systemctl start blackbox_exporter.service
systemctl status blackbox_exporter.service
# 配置Consul自动发现
cat > /data/consul/server1/config/blackbox-exporter.json <<EOF
{
"service":{
"name":"blackbox-exporter",
"tags":[
"prod",
"blackbox-exporter"
],
"address": "172.26.42.229",
"port":9115,
"check":{
"http":"http://172.26.42.229:9115",
"interval":"10s"
},
"token":"your_token"
}
}
EOF
# 热加载Consul配置
consul reload
# Grafana导入Dashboard-ID:7587
五 Grafana(跳过)
六,集群和高可能
6.1 数据存储
6.1.1 本地存储
时间单元为两个小时,每两个小时的数据打包成一块,存储到硬盘上,如块下面的目录结构:
[root@prometheus02 01G1KD1K826GEYCQPKJXPB88DE]# tree
.
|-- chunks ##所有样本数据
| `-- 000001
|-- index ##索引文件
|-- meta.json ##元数据文件
`-- tombstones ##相当于回收站
1 directory, 4 files
如果 在获取样本数据是出现问题,promethues启动时会从预写日志WAL(Write Ahead Log)进行重播,回复数据。通过API删除时间时间序列,删除的记录也会保存在单独的逻辑文件tombstones中。
提高查询数据的效率,删除历史数据时,给个时间界限,只要块在这个时间界限外,直接丢弃就好了。过期块的清理是在后台,删除块最多可能需要两个小时,块必须完全过期。
6.1.2 本地存储配置
用户可以通过命令行启动参数的方式修改本地存储的配置。
启动参数 | 默认值 | 含义 |
---|---|---|
--storage.tsdb.path | data/ | Base path for metrics storage |
--storage.tsdb.retention | 15d | How long to retain samples in the storage |
--storage.tsdb.min-block-duration | 2h | The timestamp range of head blocks after which they get persisted |
--storage.tsdb.max-block-duration | 36h | The maximum timestamp range of compacted blocks,It's the minimum duration of any persisted block. |
--storage.tsdb.no-lockfile | false | Do not create lockfile in data directory |
服务器磁盘空间规划,可以用以下公式简单计算:
needed_disk_space = retention_time_seconds * ingested_samples_per_second * bytes_per_sample
6.1.3 从失败中恢复
如果本地存储损坏,解决问题的最佳策略就是关闭proemthues,删除整个存储目录,也可以尝试删除单独的块或WAL目录来解决问题。
6.2 远程存储
本地存储也意味着Prometheus无法持久化数据,无法存储大量历史数据,同时也无法灵活扩展和迁移。
remote_write和remote_write具体配置如下所示: (复制)
remote_write:
url: <string>
[ remote_timeout: <duration> | default = 30s ]
write_relabel_configs:
[ - <relabel_config> ... ]
basic_auth:
[ username: <string> ]
[ password: <string> ]
[ bearer_token: <string> ]
[ bearer_token_file: /path/to/bearer/token/file ]
tls_config:
[ <tls_config> ]
[ proxy_url: <string> ]
remote_read:
url: <string>
required_matchers:
[ <labelname>: <labelvalue> ... ]
[ remote_timeout: <duration> | default = 30s ]
[ read_recent: <boolean> | default = false ]
basic_auth:
[ username: <string> ]
[ password: <string> ]
[ bearer_token: <string> ]
[ bearer_token_file: /path/to/bearer/token/file ]
[ <tls_config> ]
[ proxy_url: <string> ]
目前,第三方数据库支持Remote Storage的有:
- AppOptics: write
- AWS Timestream: read and write
- Azure Data Explorer: read and write
- Azure Event Hubs: write
- Chronix: write
- Cortex: read and write
- CrateDB: read and write
- Elasticsearch: write
- Gnocchi: write
- Google BigQuery: read and write
- Google Cloud Spanner: read and write
- Grafana Mimir: read and write
- Graphite: write
- InfluxDB: read and write
- Instana: write
- IRONdb: read and write
- Kafka: write
- M3DB: read and write
- New Relic: write
- OpenTSDB: write
- PostgreSQL/TimescaleDB: read and write
- QuasarDB: read and write
- SignalFx: write
- Splunk: read and write
- Sysdig Monitor: write
- TiKV: read and write
- Thanos: read and write
- VictoriaMetrics: write
- Wavefront: write
6.2.2 实例 集成influxDB (测试)
influxDB官网提供:
cat <<EOF | sudo tee /etc/yum.repos.d/influxdb.repo
[influxdb]
name = InfluxDB Repository - RHEL \$releasever
baseurl = https://repos.influxdata.com/rhel/\$releasever/\$basearch/stable
enabled = 1
gpgcheck = 1
gpgkey = https://repos.influxdata.com/influxdb.key
EOF
sudo yum install influxdb2
这里我用的influxdb,面不是用的influxdb2
下载rpm包,利用yun localinstall xxx.rpm
https://repos.influxdata.com/rhel/7Server/x86_64/stable/
# influx
>create database prometheus;
>show databases;
修改prometheus配置文件
# 添加如下两行
remote_write:
- url: "http://10.30.162.64:8086/api/v1/prom/write?db=prometheus"
remote_read:
- url: "http://10.30.162.64:8086/api/v1/prom/read?db=prometheus"
重启prometheus服务,查看数据库中有没有数据
influx
>use prometheus
>show MEASUREMENTS;
# 可以看到相关的数据,简单实现远程存储数据
6.3 联邦集群
如下图
联邦集群的核心在于每一个Promethues Server都包含额一个用于获取当前实例中监控样本的接口(federate),对于Promethues Sever来说,无论是从其他的Prometheus实例还是Exporter实例中获取数据实际并没有差异。
接口配置如下:官网,自己并未测试
scrape_configs:
- job_name: 'federate'
scrape_interval: 15s
honor_labels: true
metrics_path: '/federate'
params:
'match[]':
- '{job="prometheus"}'
- '{__name__=~"job:.*"}'
- '{__name__=~"node.*"}'
static_configs:
- targets:
- '192.168.77.11:9090'
- '192.168.77.12:9090'
可以对Prometheus进行功能分区,不再集群分区,扩展性。
- job_name: 'federate'
scrape_interval: 15s
honor_labels: true
metrics_path: '/federate'
params:
'match[]':
- '{job="serviceMonitor/monitoring/node-exporter/0"}'
- '{__name__=~"job:.*"}'
- '{__name__=~"node.*"}'
static_configs:
- targets:
- '10.30.162.64:30004'
6.4 Prometheus高可用
6.4.1基本HA
6.4.2基本HA+远程存储
6.4.3基本HA+远程存储+联邦集群
6.4.4 功能分区实例
Prometheus Server 配置
global:
external_labels:
slave: 1 # This is the 2nd slave. This prevents clashes between slaves.
scrape_configs:
- job_name: some_job
relabel_configs:
- source_labels: [__address__]
modulus: 4
target_label: __tmp_hash
action: hashmod
- source_labels: [__tmp_hash]
regex: ^1$
action: keep
中心Prometheus Sever聚合任务配置
- scrape_config:
- job_name: slaves
honor_labels: true
metrics_path: /federate
params:
match[]:
- '{__name__=~"^slave:.*"}' # Request all slave-level time series
static_configs:
- targets:
- slave0:9090
- slave1:9090
- slave3:9090
- slave4:9090
6.4.5 高可用方案
选项\需求 | 服务可用性 | 数据持久化 | 水平扩展 |
---|---|---|---|
主备HA | v | x | x |
远程存储 | x | v | x |
联邦集群 | x | x | v |
七、 kube-operator
Prometheus operator的本职就是一组用户自定义的CRD资源以及Controller的实现,Prometheus Operator负责监听这些自定义资源的变化,并且根据这些资源的定义自动化的完成如Prometheus Server自身以及配置的自动化管理工作。
自定义4类资源 :
- Prometheus:声明式创建和管理Prometheus Server实例;
- ServiceMonitor:负责声明式的管理监控配置;
- PrometheusRule:负责声明式的管理告警配置;
- Alertmanager:声明式的创建和管理Alertmanager实例。
上图是Prometheus-Operator官方提供的架构图,从下向上看,Operator可以部署并且管理Prometheus Server,并且Operator可以观察Prometheus,那么这个观察是什么意思呢,上图中Service1 - Service5其实就是kubernetes的service,kubernetes的资源分为Service、Deployment、ServiceMonitor、ConfigMap等等,所以上图中的Service和ServiceMonitor都是kubernetes资源,一个ServiceMonitor可以通过labelSelector的方式去匹配一类Service(一般来说,一个ServiceMonitor对应一个Service),Prometheus也可以通过labelSelector去匹配多个ServiceMonitor。
- Operator : Operator是整个系统的主要控制器,会以Deployment的方式运行于Kubernetes集群上,并根据自定义资源(Custom Resources Definition)CRD 来负责管理与部署Prometheus,Operator会通过监听这些CRD的变化来做出相对应的处理。
- Prometheus : Operator会观察集群内的Prometheus CRD(Prometheus 也是一种CRD)来创建一个合适的statefulset在monitoring(.metadata.namespace指定)命名空间,并且挂载了一个名为prometheus-k8s的Secret为Volume到/etc/prometheus/config目录,Secret的data包含了以下内容
- configmaps.json指定了rule-files在configmap的名字
- prometheus.yaml为主配置文件
- ServiceMonitor : ServiceMonitor就是一种kubernetes自定义资源(CRD),Operator会通过监听ServiceMonitor的变化来动态生成Prometheus的配置文件中的Scrape targets,并让这些配置实时生效,operator通过将生成的job更新到上面的prometheus-k8s这个Secret的Data的prometheus.yaml字段里,然后prometheus这个pod里的sidecar容器
prometheus-config-reloader
当检测到挂载路径的文件发生改变后自动去执行HTTP Post请求到/api/-reload-
路径去reload配置。该自定义资源(CRD)通过labels选取对应的Service,并让prometheus server通过选取的Service拉取对应的监控信息(metric) - Service :Service其实就是指kubernetes的service资源,这里特指Prometheus exporter的service,比如部署在kubernetes上的mysql-exporter的service
想象一下,我们以传统的方式去监控一个mysql服务,首先需要安装mysql-exporter,获取mysql metrics,并且暴露一个端口,等待prometheus服务来拉取监控信息,然后去Prometheus Server的prometheus.yaml文件中在scarpe_config中添加mysql-exporter的job,配置mysql-exporter的地址和端口等信息,再然后,需要重启Prometheus服务,就完成添加一个mysql监控的任务
现在我们以Prometheus-Operator的方式来部署Prometheus,当我们需要添加一个mysql监控我们会怎么做,首先第一步和传统方式一样,部署一个mysql-exporter来获取mysql监控项,然后编写一个ServiceMonitor通过labelSelector选择刚才部署的mysql-exporter,由于Operator在部署Prometheus的时候默认指定了Prometheus选择label为:prometheus: kube-prometheus
的ServiceMonitor,所以只需要在ServiceMonitor上打上prometheus: kube-prometheus
标签就可以被Prometheus选择了,完成以上两步就完成了对mysql的监控,不需要改Prometheus配置文件,也不需要重启Prometheus服务,是不是很方便,Operator观察到ServiceMonitor发生变化,会动态生成Prometheus配置文件,并保证配置文件实时生效
十二,k8s-Prometheus
Kerbenetes storageclass搭建
7.0 nfs server搭建
$ yum install nfs-utils rpcbind
$ cat /etc/exports
/data/nfs 10.30.162.0/24(rw,sync)
$ systemctl enable --now rpcbind ##有先后顺序
$ systemctl enable --now nfs
$ cat /var/lib/nfs/etab
/data/nfs 10.30.162.0/24(rw,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,no_subtree_check,secure_locks,acl,no_pnfs,anonuid=65534,anongid=65534,sec=sys,rw,secure,root_squash,no_all_squash)
##测试:
$ showmount -e
Export list for localhost.localdomain:
/data/nfs 10.30.162.0/24
## 客户端操作:
$ yum install nfs-utils rpcbind
$ mount -t nfs 10.30.162.49:/data/nfs /share
#卸载
$ umount /share
7.2 使用RBAC进行授权:
修改两处为:apiVersion: rbac.authorization.k8s.io/v1
原文件为: apiVersion: rbac.authorization.k8s.io/v1beta1
$ kubectl apply -f prometheus-rbac.yaml
7.3 Storage Class
下载相关文件:
$ git clone https://github.com/kubernetes-incubator/external-storage.git ##或者
$ git clone https://github.com/kubernetes-retired/external-storage.git
$ ls /root/external-storage-master/nfs-client/deploy
class.yaml deployment.yaml objects test-claim.yaml
deployment-arm.yaml deployment.yaml.bak rbac.yaml test-pod.yaml
部署权限
$ kubectl apply -f rbac.yaml #默认文件,没有修改
rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-client-provisioner-runner
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io
部署插件:
$ kubectl apply -f deployment.yaml
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
labels:
app: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
spec:
replicas: 3
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
#image: quay.io/external_storage/nfs-client-provisioner:latest
#image: registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner:latest
#坑
image: registry.cn-hangzhou.aliyuncs.com/xzjs/nfs-subdir-external-provisioner:v4.0.0
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
#要和部署class中的yaml文件中的一致;
value: fuseim.pri/ifs
- name: NFS_SERVER
#见7.0中的nfs部署,中的地址,还有nfs目录
value: 10.30.162.49
- name: NFS_PATH
value: /data/nfs
volumes:
- name: nfs-client-root
nfs:
server: 10.30.162.49
path: /data/nfs
部署storageclass
$ kubectl apply -f class.yaml
$ kubectl get storageclasses.storage.k8s.io
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
managed-nfs-storage fuseim.pri/ifs Delete Immediate false 12d
class.yaml,没有做修改
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: managed-nfs-storage provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME' parameters: archiveOnDelete: "false"
测试
$ kubectl apply -f test-claim.yaml
$ [root@docker-k8s01 deploy]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
test-claim Bound pvc-6351255f-c88e-4670-903d-ed65a60b2483 1Mi RWX managed-nfs-storage 36m
#pvc测试
$ kubectl apply -f test-pod.yaml
#可以去nfs服务器去查看nfs目录;
Prometheus部署
1,Prometheus-server部署
1.1 下载相关文件
$ git clone https://github.com/zhangdongdong7/k8s-prometheus.git
$ cd k8s-prometheus
$ ls
alertmanager-configmap.yaml kube-state-metrics-rbac.yaml prometheus-rbac.yaml
alertmanager-configmap.yaml.bak kube-state-metrics-service.yaml prometheus-rules.yaml
alertmanager-deployment.yaml node_exporter-0.17.0.linux-amd64.tar.gz prometheus-service.yaml
alertmanager-pvc.yaml node_exporter-0.17.0.linux-amd64.tar.gz.1 prometheus-statefulset-static-pv.yaml
alertmanager-service.yaml node_exporter.sh prometheus-statefulset.yaml
grafana.yaml OWNERS prometheus-statefulset.yamlbak
kube-state-metrics-deployment.yaml prometheus-configmap.yaml README.md
1.2 使用RBAC进行授权
[root@docker-k8s01 k8s-prometheus]# kubectl apply -f prometheus-rbac.yaml
serviceaccount/prometheus created
clusterrole.rbac.authorization.k8s.io/prometheus created
clusterrolebinding.rbac.authorization.k8s.io/prometheus created
# 没有修改任何内容;prometheus-server的配置文件;
1.3 配置管理
[root@docker-k8s01 k8s-prometheus]# kubectl apply -f prometheus-configmap.yaml
[root@docker-k8s01 k8s-prometheus]# kubectl get configmaps prometheus-config -n kube-system
NAME DATA AGE
prometheus-config 1 14d
[root@docker-k8s01 k8s-prometheus]# vim prometheus-configmap.yaml
##修改主机IP地址:
…………
- job_name: kubernetes-nodes
scrape_interval: 30s
static_configs:
- targets:
- 10.30.162.64:9100
- 10.30.162.65:9100
- 10.30.162.66:9100
…………
1.4 添加rules
#由于有状态部署Prometheus时,要用到rules,没有这个目录为直接报错;
[root@docker-k8s01 k8s-prometheus]# kubectl apply -f prometheus-rules.yaml
1.5 有状态部署prometheus
[root@docker-k8s01 k8s-prometheus]# kubectl apply -f prometheus-statefulset.yaml
# 这里用到持久存储,之前搭建好的storageclass
[root@docker-k8s01 k8s-prometheus]# kubectl get storageclasses.storage.k8s.io
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
managed-nfs-storage fuseim.pri/ifs Delete Immediate false 12d
[root@docker-k8s01 k8s-prometheus]# cat prometheus-statefulset.yaml
…………
volumeClaimTemplates:
- metadata:
name: prometheus-data
spec:
storageClassName: managed-nfs-storage
accessModes:
- ReadWriteOnce
resources:
requests:
storage: "16Gi"
[root@docker-k8s01 k8s-prometheus]# kubectl get pods -n kube-system | grep prometheus
prometheus-0 2/2 Running 0 19h
1.6 创建Service暴露端口访问
[root@docker-k8s01 k8s-prometheus]# kubectl apply -f prometheus-service.yaml
[root@docker-k8s01 k8s-prometheus]# cat prometheus-service.yaml kind: Service apiVersion: v1 metadata: name: prometheus namespace: kube-system labels: kubernetes.io/name: "Prometheus" kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile spec: type: NodePort ports: - name: http port: 9090 protocol: TCP targetPort: 9090 nodePort: 30090 ##对外端口 selector: k8s-app: prometheus
2, 在k8s平台创建Grafana
##直接使用文件
[root@docker-k8s01 k8s-prometheus]# kubectl apply -f grafana.yaml
3,监控K8S中的Pod,Node,资源对象的数据方法:
1)Pod kubelet的节点使用cAdvisor提供的metrics接口获取该节点所有Pod和容器相关的性能指标数据,安装kubelet默认就开启了 暴露接口地址:
https://NodeIP:10255/metrics/cadvisorhttps://NodeIP:10250/metrics/cadvisor
2)Node 需要使用node_exporter收集器采集节点资源利用率。
3)资源对象
使用metric-server
[root@docker-k8s01 k8s-prometheus]# cat node_exporter.sh
#!/bin/bash
##这边文件已经下载好了,所以注释掉了
#wget https://github.com/prometheus/node_exporter/releases/download/v0.17.0/node_exporter-0.17.0.linux-amd64.tar.gz
tar zxf node_exporter-0.17.0.linux-amd64.tar.gz
mv node_exporter-0.17.0.linux-amd64 /usr/local/node_exporter
cat <<EOF >/usr/lib/systemd/system/node_exporter.service
[Unit]
Description=https://prometheus.io
[Service]
Restart=on-failure
ExecStart=/usr/local/node_exporter/node_exporter --collector.systemd --collector.systemd.unit-whitelist=(docker|kubelet|kube-proxy|flanneld).service
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable node_exporter
systemctl restart node_exporter
##在所有Node上安装node_exporter
$ ./node_exporter.sh
[root@docker-k8s02 ~]# systemctl status node_exporter.servic ##查看服务状态;
3.2 部署metircs server
[root@docker-k8s01 k8s-prometheus]# ls | grep metric
kube-state-metrics-deployment.yaml
kube-state-metrics-rbac.yaml
kube-state-metrics-service.yaml
#创建rbac的yaml对metrics进行授权;
[root@docker-k8s01 k8s-prometheus]# kubectl apply -f kube-state-metrics-rbac.yaml
#对metric pod进行部署;
[root@docker-k8s01 k8s-prometheus]# kubectl apply -f kube-state-metrics-deployment.yaml
# service对外暴露端口
[root@docker-k8s01 k8s-prometheus]# kubectl apply -f kube-state-metrics-service.yaml
[root@docker-k8s01 k8s-prometheus]# kubectl get pod,svc -n kube-system
NAME READY STATUS RESTARTS AGE
pod/alertmanager-7cf4d5d7b8-p7lx7 2/2 Running 0 16h
pod/calico-kube-controllers-6949477b58-xqr7c 1/1 Running 0 74d
pod/calico-node-d9m27 1/1 Running 0 74d
pod/calico-node-swxtv 1/1 Running 0 74d
pod/calico-node-v5vp8 1/1 Running 0 74d
pod/coredns-7f89b7bc75-2kf7q 1/1 Running 0 74d
pod/coredns-7f89b7bc75-6trkg 1/1 Running 0 74d
pod/etcd-docker-k8s01 1/1 Running 0 74d
pod/fluentd-logging-test-hzlzd 0/1 CrashLoopBackOff 8573 31d
pod/grafana-0 1/1 Running 0 19h
pod/kube-apiserver-docker-k8s01 1/1 Running 0 74d
pod/kube-controller-manager-docker-k8s01 1/1 Running 0 74d
pod/kube-proxy-dbtxh 1/1 Running 0 74d
pod/kube-proxy-fklzd 1/1 Running 0 74d
pod/kube-proxy-jbk6v 1/1 Running 0 74d
pod/kube-scheduler-docker-k8s01 1/1 Running 0 74d
pod/kube-state-metrics-5dd5dc67fc-tp29m 2/2 Running 0 18h
pod/prometheus-0 2/2 Running 0 19h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/alertmanager ClusterIP 10.10.227.79 <none> 80/TCP 16h
service/grafana NodePort 10.10.102.113 <none> 80:30091/TCP 19h
service/kube-dns ClusterIP 10.10.0.10 <none> 53/UDP,53/TCP,9153/TCP 74d
service/kube-state-metrics ClusterIP 10.10.254.80 <none> 8080/TCP,8081/TCP 18h
service/prometheus NodePort 10.10.46.163 <none> 9090:30090/TCP 19h
4,在K8S中部署Alertmanager
4.1 configmap,增加alertmanager告警配置
[root@docker-k8s01 k8s-prometheus]# cat alertmanager-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: alertmanager-config
namespace: kube-system
labels:
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: EnsureExists
data:
alertmanager.yml: |
global:
resolve_timeout: 5m
smtp_smarthost: 'smtp.qiye.163.com:25'
smtp_from: 'zabbix-server@leadchina.cn'
smtp_auth_username: 'zabbix-server@leadchina.cn'
smtp_auth_password: 'xxx'
receivers:
- name: default-receiver
email_configs:
- to: "xxx"
route:
group_interval: 1m
group_wait: 10s
receiver: default-receiver
repeat_interval: 60m
[root@docker-k8s01 k8s-prometheus]# kubectl apply -f alertmanager-configmap.yaml
4.2 创建PVC,进行数据持久化,
[root@docker-k8s01 k8s-prometheus]# kubectl apply -f alertmanager-pvc.yaml
4.3部署alertmanager的Pod
#没做修改
[root@docker-k8s01 k8s-prometheus]# kubectl apply -f alertmanager-deployment.yaml
4.4 创建service对暴露端口
[root@docker-k8s01 k8s-prometheus]# kubectl apply -f alertmanager-service.yaml
[root@docker-k8s01 k8s-prometheus]# kubectl get pod,svc -n kube-system
NAME READY STATUS RESTARTS AGE
pod/alertmanager-7cf4d5d7b8-p7lx7 2/2 Running 0 16h
pod/calico-kube-controllers-6949477b58-xqr7c 1/1 Running 0 74d
pod/calico-node-d9m27 1/1 Running 0 74d
pod/calico-node-swxtv 1/1 Running 0 74d
pod/calico-node-v5vp8 1/1 Running 0 74d
pod/coredns-7f89b7bc75-2kf7q 1/1 Running 0 74d
pod/coredns-7f89b7bc75-6trkg 1/1 Running 0 74d
pod/etcd-docker-k8s01 1/1 Running 0 74d
pod/fluentd-logging-test-hzlzd 0/1 CrashLoopBackOff 8573 31d
pod/grafana-0 1/1 Running 0 19h
pod/kube-apiserver-docker-k8s01 1/1 Running 0 74d
pod/kube-controller-manager-docker-k8s01 1/1 Running 0 74d
pod/kube-proxy-dbtxh 1/1 Running 0 74d
pod/kube-proxy-fklzd 1/1 Running 0 74d
pod/kube-proxy-jbk6v 1/1 Running 0 74d
pod/kube-scheduler-docker-k8s01 1/1 Running 0 74d
pod/kube-state-metrics-5dd5dc67fc-tp29m 2/2 Running 0 18h
pod/prometheus-0 2/2 Running 0 19h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/alertmanager ClusterIP 10.10.227.79 <none> 80/TCP 16h
service/grafana NodePort 10.10.102.113 <none> 80:30091/TCP 19h
service/kube-dns ClusterIP 10.10.0.10 <none> 53/UDP,53/TCP,9153/TCP 74d
service/kube-state-metrics ClusterIP 10.10.254.80 <none> 8080/TCP,8081/TCP 18h
service/prometheus NodePort 10.10.46.163 <none> 9090:30090/TCP 19h
4.4邮件告警测试
+++
Prometheus operator部署
下载相关文件:
https://github.com/prometheus-operator/kube-prometheus/releases
#找到指定版本
a,部署operator
[root@docker-k8s01 ~]# kubectl apply -f kube-prometheus-0.8.0/manifests/setup/
namespace/monitoring created
customresourcedefinition.apiextensions.k8s.io/alertmanagerconfigs.monitoring.coreos.com created
customresourcedefinition.apiextensions.k8s.io/alertmanagers.monitoring.coreos.com created
customresourcedefinition.apiextensions.k8s.io/podmonitors.monitoring.coreos.com created
customresourcedefinition.apiextensions.k8s.io/probes.monitoring.coreos.com created
customresourcedefinition.apiextensions.k8s.io/prometheuses.monitoring.coreos.com created
customresourcedefinition.apiextensions.k8s.io/prometheusrules.monitoring.coreos.com created
customresourcedefinition.apiextensions.k8s.io/servicemonitors.monitoring.coreos.com created
customresourcedefinition.apiextensions.k8s.io/thanosrulers.monitoring.coreos.com created
clusterrole.rbac.authorization.k8s.io/prometheus-operator created
clusterrolebinding.rbac.authorization.k8s.io/prometheus-operator created
deployment.apps/prometheus-operator created
service/prometheus-operator created
serviceaccount/prometheus-operator created
[root@docker-k8s01 ~]# kubectl get customresourcedefinitions.apiextensions.k8s.io | grep monitor
alertmanagerconfigs.monitoring.coreos.com 2022-11-23T07:41:30Z
alertmanagers.monitoring.coreos.com 2022-11-23T07:41:30Z
podmonitors.monitoring.coreos.com 2022-11-23T07:41:30Z
probes.monitoring.coreos.com 2022-11-23T07:41:30Z
prometheuses.monitoring.coreos.com 2022-11-23T07:41:30Z
prometheusrules.monitoring.coreos.com 2022-11-23T07:41:30Z
servicemonitors.monitoring.coreos.com 2022-11-23T07:41:30Z
thanosrulers.monitoring.coreos.com 2022-11-23T07:41:30Z
[root@docker-k8s01 ~]# kubectl get deployments.apps -n monitoring
NAME READY UP-TO-DATE AVAILABLE AGE
prometheus-operator 1/1 1 1 80s
[root@docker-k8s01 ~]# kubectl get services -n monitoring
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
prometheus-operator ClusterIP None <none> 8443/TCP 92s
[root@docker-k8s01 ~]#
b, 部署prometheus其他组件
- prometheus prometheus核心组件
- prometheus-adapter prometheus适配器,做数据转换
- kube-state-metrics kubernetes指标转换器,转换为apiserver能识别的指标
- alertmanager 告警管理器,用于指标阀值告警实现
- node-exporter exporters,客户端监控上报agent,用于实现数据上报
- grafana 数据显示展板
- configmaps grafana数据展板配置模版,封装在configmap中
- clusterrole,clusterrolebinding prometheus访问kubernetes的RBAC授权
$ kubectl apply -f kube-prometheus-0.8.0/manifests/
##检查资源对象状态
##node exporter通过daemonset部署;
[root@docker-k8s01 ~]# kubectl get daemonsets.apps -n monitoring
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
node-exporter 3 3 3 3 3 kubernetes.io/os=linux 17h
[root@docker-k8s01 ~]# kubectl get pods -n monitoring | grep node-exporter
node-exporter-bglkr 2/2 Running 0 18h
node-exporter-kxt4z 2/2 Running 0 18h
node-exporter-vsfx4 2/2 Running 0 18h
c,检查资源对象状态
##node exporter通过daemonset部署;
[root@docker-k8s01 ~]# kubectl get daemonsets.apps -n monitoring
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
node-exporter 3 3 3 3 3 kubernetes.io/os=linux 17h
[root@docker-k8s01 ~]# kubectl get pods -n monitoring | grep node-exporter
node-exporter-bglkr 2/2 Running 0 18h
node-exporter-kxt4z 2/2 Running 0 18h
node-exporter-vsfx4 2/2 Running 0 18h
# prometheus-adapter,grafana,kube-state-metrics以deployments的形式部署;
[root@docker-k8s01 ~]# kubectl get deployments.apps -n monitoring
NAME READY UP-TO-DATE AVAILABLE AGE
blackbox-exporter 1/1 1 1 18h
grafana 1/1 1 1 18h
kube-state-metrics 1/1 1 1 16h
prometheus-adapter 2/2 2 2 18h
prometheus-operator 1/1 1 1 18h
kube-state-metrics一开始部署有问题imageBackoff,下载镜像失败,修改如下
$ mv kube-state-metrics-* ./metrics/ 标签为:app.kubernetes.io/version: 2.0.0,全部换为:app.kubernetes.io/version: 2.3.0 $ cat kube-state-metrics-deployment.yaml #修改镜像地址, ………… #image: k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.0.0 image: registry.cn-wulanchabu.aliyuncs.com/moge1/kube-state-metrics:v2.3.0 #image: quay.io/coreos/kube-state-metrics:v2.0.0 #image: harbor.od.com/public/kube-state-metrics:v2.0.0 …………
# Prometheus,alertmanager以statefulsets形式部署
[root@docker-k8s01 metrics]# kubectl get statefulsets.apps -n monitoring
NAME READY AGE
alertmanager-main 3/3 18h
prometheus-k8s 2/2 18h
# 暴露服务状态
[root@docker-k8s01 metrics]# kubectl get services -n monitoring
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
alertmanager-main ClusterIP 10.10.117.119 <none> 9093/TCP 18h
alertmanager-operated ClusterIP None <none> 9093/TCP,9094/TCP,9094/UDP 18h
blackbox-exporter ClusterIP 10.10.46.163 <none> 9115/TCP,19115/TCP 18h
grafana NodePort 10.10.102.113 <none> 3000:30338/TCP 18h
kube-state-metrics ClusterIP None <none> 8443/TCP,9443/TCP 18h
node-exporter ClusterIP None <none> 9100/TCP 18h
prometheus-adapter ClusterIP 10.10.254.80 <none> 443/TCP 18h
prometheus-k8s NodePort 10.10.227.79 <none> 9090:30004/TCP 18h
prometheus-operated ClusterIP None <none> 9090/TCP 18h
prometheus-operator ClusterIP None <none> 8443/TCP 18h
# 查看pods状态
[root@docker-k8s01 ~]# kubectl get pods -n monitoring
NAME READY STATUS RESTARTS AGE
alertmanager-main-0 2/2 Running 0 18h
alertmanager-main-1 2/2 Running 0 18h
alertmanager-main-2 2/2 Running 0 18h
blackbox-exporter-55c457d5fb-tp29m 3/3 Running 0 18h
grafana-9df57cdc4-r565d 1/1 Running 0 18h
kube-state-metrics-cd7c68998-d2lff 3/3 Running 0 15h
node-exporter-bglkr 2/2 Running 0 18h
node-exporter-kxt4z 2/2 Running 0 18h
node-exporter-vsfx4 2/2 Running 0 18h
prometheus-adapter-59df95d9f5-grtd8 1/1 Running 0 18h
prometheus-adapter-59df95d9f5-nzjnn 1/1 Running 0 18h
prometheus-k8s-0 2/2 Running 1 18h
prometheus-k8s-1 2/2 Running 1 18h
prometheus-operator-7775c66ccf-gv4rd 2/2 Running 0 18h
d,Prometheus,grafana使用
# 添加NodePort
# service Prometheus
[root@docker-k8s01 ~]# kubectl patch -p '{"spec":{"type": "NodePort"}}' services -n monitoring prometheus-k8s
service/prometheus-k8s patched
# service grafana
[root@docker-k8s01 ~]# kubectl patch -p '{"spec": {"type": "NodePort"}}' services grafana -n monitoring
service/grafana patched
[root@docker-k8s01 ~]# kubectl get service -n monitoring
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
alertmanager-main ClusterIP 10.10.117.119 <none> 9093/TCP 18h
alertmanager-operated ClusterIP None <none> 9093/TCP,9094/TCP,9094/UDP 18h
blackbox-exporter ClusterIP 10.10.46.163 <none> 9115/TCP,19115/TCP 18h
grafana NodePort 10.10.102.113 <none> 3000:30338/TCP 18h
kube-state-metrics ClusterIP None <none> 8443/TCP,9443/TCP 18h
node-exporter ClusterIP None <none> 9100/TCP 18h
prometheus-adapter ClusterIP 10.10.254.80 <none> 443/TCP 18h
prometheus-k8s NodePort 10.10.227.79 <none> 9090:30004/TCP 18h
prometheus-operated ClusterIP None <none> 9090/TCP 18h
prometheus-operator ClusterIP None <none> 8443/TCP 18h
e,增加持久存储
prometheus-prometheus.yaml
retention: 30d
storage:
volumeClaimTemplate:
spec:
storageClassName: managed-nfs-storage
resources:
requests:
storage: 16Gi
grafana-deployment.yaml
...
serviceAccountName: grafana
volumes:
# - emptyDir: {}
# name: grafana-storage
- name: grafana-storage
persistentVolumeClaim:
claimName: grafana-data
grafana-pvc.yaml
$ vim grafana-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: grafana-data
namespace: monitoring
annotations:
volume.beta.kubernetes.io/storage-class: "managed-nfs-storage"
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
f, KubeControllerManagerDown
$ netstat -lntup | grep kube-control
tcp 0 0 127.0.0.1:10257 0.0.0.0:* LISTEN 21086/kube-controll
#修改监听地址
$ netstat -lntup | grep kube-con
tcp6 0 0 :::10257 :::* LISTEN 29942/kube-controll
创建service文件kube-controller-manager-svc.yaml,
apiVersion: v1
kind: Service
metadata:
namespace: kube-system
name: kube-controller-manager
labels:
#k8s-app: kube-controller-manager
app.kubernetes.io/name: kube-controller-manager
spec:
ports:
- name: https-metrics
port: 10257
selector:
component: kube-controller-manager
查看kubernetes-serviceMonitorKubeControllerManager.yaml
$ tail -3 kubernetes-serviceMonitorKubeControllerManager.yaml
selector:
matchLabels:
app.kubernetes.io/name: kube-controller-manager
g,KubeSchedulerDown
apiVersion: v1
kind: Service
metadata:
namespace: kube-system
name: kube-scheduler
labels:
#k8s-app: kube-scheduler
app.kubernetes.io/name: kube-scheduler
spec:
ports:
- name: https-metrics
port: 10259
selector:
component: kube-scheduler
$ kubectl apply -f kube-controller-manager-svc.yaml -f kube-scheduler-svc.yaml
h,添加邮件报警
修改alertmanager-secret.yaml文件:
stringData:
alertmanager.yaml: |- ##保留每行的换行符,删除结尾的换行符
"global":
"resolve_timeout": "5m"
"smtp_smarthost": "smtp.qiye.163.com:25" ##添加相关配置
"smtp_from": "zabbix-server@leadchina.cn"
"smtp_auth_username": "zabbix-server@leadchina.cn"
"smtp_auth_password": "xxxxx"
"inhibit_rules":
…………
"receivers":
- "name": "Default" ##指定用户
"email_configs":
- "to": "xxx"
- "name": "Watchdog"
…………
+++
j,添加报警规则
# prometheus 报警规则文件位置:通过prometheus页面-configration中的可以看到
rule_files:
- /etc/prometheus/rules/prometheus-k8s-rulefiles-0/*.yaml
$ kubectl -n monitoring exec -it prometheus-k8s-0 -- /bin/sh
Defaulting container name to prometheus.
Use 'kubectl describe pod/prometheus-k8s-0 -n monitoring' to see all of the containers in this pod.
/prometheus $ cd /etc/prometheus/rules/prometheus-k8s-rulefiles-0/
/etc/prometheus/rules/prometheus-k8s-rulefiles-0 $ ls
monitoring-alertmanager-main-rules.yaml monitoring-kube-state-metrics-rules.yaml monitoring-prometheus-k8s-prometheus-rules.yaml
monitoring-kubernetes-monitoring-rules.yaml monitoring-prometheus-operator-rules.yaml monitoring-kube-prometheus-rules.yaml monitoring-node-exporter-rules.yaml
我们创建的 prometheus 这个资源对象,里面有非常重要的一个属性 ruleSelector,用来匹配 rule 规则的过滤器,要求匹配具有 prometheus=k8s 和 role=alert-rules 标签的 PrometheusRule 资源对象
#手动添加 报警规则,创建一个具有 prometheus=k8s 和 role=alert-rules 标签的 PrometheusRule 对象
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
labels:
prometheus: k8s
role: alert-rules
name: disk-free-rules
namespace: monitoring
spec:
groups:
- name: disk
rules:
- alert: diskFree
annotations:
summary: "{{ $labels.job }} 项目实例 {{ $labels.instance }} 磁盘使用率大于 80%"
description: "{{ $labels.instance }} {{ $labels.mountpoint }} 磁盘使用率大于80% (当前的值: {{ $value }}%),请及时处理"
expr: |
(1-(node_filesystem_free_bytes{fstype=~"ext4|xfs",mountpoint!="/boot"} / node_filesystem_size_bytes{fstype=~"ext4|xfs",mountpoint!="/boot"}) )*100 > 85
for: 3m
labels:
level: disaster
Prometheus热更新
curl -X POST http://IP/-/reload
4,添加企业微信报警
alertmanager.yaml模板
global:
resolve_timeout: 5m
wechat_api_url: 'https://qyapi.weixin.qq.com/cgi-bin/'
wechat_api_secret: 'X82vlGwRUAoauFlK-9jhxNvL_vTayo48oUuxDDWIuBM'
wechat_api_corp_id: 'ww6ae02f1fb738be91'
templates: ##消息模板
- '*.tmpl'
route:
group_by: ['alertname','job']
group_wait: 10s
group_interval: 10s
repeat_interval: 1m
receiver: 'wechat'
receivers:
- name: 'wechat'
wechat_configs:
- send_resolved: true
to_party: '2' #中心ID
agent_id: '1000002' #部门ID
默认配置文件
global:
resolve_timeout: 5m
wechat_api_url: 'https://qyapi.weixin.qq.com/cgi-bin/'
wechat_api_secret: 'X82vlGwRUAoauFlK-9jhxNvL_vTayo48oUuxDDWIuBM'
wechat_api_corp_id: 'ww6ae02f1fb738be91'
inhibit_rules:
- equal:
- namespace
- alertname
source_matchers:
- severity = critical
target_matchers:
- severity =~ warning|info
- equal:
- namespace
- alertname
source_matchers:
- severity = warning
target_matchers:
- severity = info
- equal:
- namespace
source_matchers:
- alertname = InfoInhibitor
target_matchers:
- severity = info
receivers:
- name: "null"
route:
group_by:
- namespace
group_interval: 5m
group_wait: 30s
receiver: "null"
repeat_interval: 12h
routes:
- matchers:
- alertname =~ "InfoInhibitor|Watchdog"
receiver: "null"
templates:
- /etc/alertmanager/config/*.tmpl
企业微信告警模板:
apiVersion: v1
kind: ConfigMap
metadata:
name: wechat-tmpl
namespace: kube-ops
data:
wechat.tmpl: |
{{ define "wechat.default.message" }}
{{ range .Alerts }}
========start==========
告警程序: prometheus_alert
告警级别: {{ .Labels.severity }}
告警类型: {{ .Labels.alertname }}
故障主机: {{ .Labels.instance }}
告警主题: {{ .Annotations.summary }}
告警详情: {{ .Annotations.description }}
触发时间: {{ .StartsAt.Format "2006-01-02 15:04:05" }}
========end==========
{{ end }}
{{ end }}
#####################################################另一份
[root@prometheus-bpmdev alertmanager]# cat template/wechat.tmpl
{{ define "wechat.default.message" }}
{{- if gt (len .Alerts.Firing) 0 -}}
{{- range $index, $alert := .Alerts -}}
{{- if eq $index 0 }}
=========xxx环境监控报警 =========
告警状态:{{ .Status }}
告警级别:{{ .Labels.severity }}
告警类型:{{ $alert.Labels.alertname }}
故障主机: {{ $alert.Labels.instance }} {{ $alert.Labels.pod }}
告警主题: {{ $alert.Annotations.summary }}
告警详情: {{ $alert.Annotations.message }}{{ $alert.Annotations.description}};
触发阀值:{{ .Annotations.value }}
故障时间: {{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
========= = end = =========
{{- end }}
{{- end }}
{{- end }}
{{- if gt (len .Alerts.Resolved) 0 -}}
{{- range $index, $alert := .Alerts -}}
{{- if eq $index 0 }}
=========xxx环境异常恢复 =========
告警类型:{{ .Labels.alertname }}
告警状态:{{ .Status }}
告警主题: {{ $alert.Annotations.summary }}
告警详情: {{ $alert.Annotations.message }}{{ $alert.Annotations.description}};
故障时间: {{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
恢复时间: {{ ($alert.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
{{- if gt (len $alert.Labels.instance) 0 }}
实例信息: {{ $alert.Labels.instance }}
{{- end }}
========= = end = =========
{{- end }}
{{- end }}
{{- end }}
{{- end }}
###########################模板3#########
[root@centos74 home]# cat /usr/local/prometheus/alertmanager/wechat.tmpl
{{ define "wechat.default.message" }}
{{- if gt (len .Alerts.Firing) 0 -}}
{{- range $index, $alert := .Alerts -}}
======== 异常告警 ========
告警名称:{{ $alert.Labels.alertname }}
告警级别:{{ $alert.Labels.severity }}
告警机器:{{ $alert.Labels.instance }} {{ $alert.Labels.device }}
告警详情:{{ $alert.Annotations.summary }}
告警时间:{{ $alert.StartsAt.Format "2006-01-02 15:04:05" }}
========== END ==========
{{- end }}
{{- end }}
{{- if gt (len .Alerts.Resolved) 0 -}}
{{- range $index, $alert := .Alerts -}}
======== 告警恢复 ========
告警名称:{{ $alert.Labels.alertname }}
告警级别:{{ $alert.Labels.severity }}
告警机器:{{ $alert.Labels.instance }}
告警详情:{{ $alert.Annotations.summary }}
告警时间:{{ $alert.StartsAt.Format "2006-01-02 15:04:05" }}
恢复时间:{{ $alert.EndsAt.Format "2006-01-02 15:04:05" }}
========== END ==========
{{- end }}
{{- end }}
{{- end }}