基于prometheus和k8s构建智能化监控告警系统

介绍k8s集群中部署prometheus、grafana、alertmanager,并且配置prometheus的动态、静态服务发现,实现对容器、物理节点、service、pod等资源指标监控,并在Grafana的web界面展示prometheus的监控指标,然后通过配置自定义告警规则,通过alertmanager实现qq、钉钉、微信报警。Promql 语法、prometheus数据类型。

1、prometheus

1、prometheus介绍

Prometheus是一个开源的系统监控和报警系统,现在已经加入到CNCF基金会,成为继k8s之后第二个在CNCF托管的项目,在kubernetes容器管理系统中,通常会搭配prometheus进行监控,同时也支持多种exporter采集数据,还支持pushgateway进行数据上报,Prometheus性能足够支撑上万台规模的集群。

2、prometheus特点

1、多维度数据模型

每一个时间序列数据都由metric度量指标名称和它的标签labels键值对集合唯一确定:

这个metric度量指标名称指定监控目标系统的测量特征(如:http_requests_total- 接收http请求的总计数)。labels开启了Prometheus的多维数据模型:对于相同的度量名称,通过不同标签列表的结合, 会形成特定的度量维度实例。(例如:所有包含度量名称为/api/tracks的http请求,打上method=POST的标签,则形成了具体的http请求)。这个查询语言在这些度量和标签列表的基础上进行过滤和聚合。改变任何度量上的任何标签值,则会形成新的时间序列图。

2、灵活的查询语言(PromQL)

可以对采集的metrics指标进行加法,乘法,连接等操作

3、可以直接在本地部署,不依赖其他分布式存储

4、通过基于HTTP的pull方式采集时序数据

5、可以通过中间网关pushgateway的方式把时间序列数据推送到prometheus server端

6、可通过服务发现或者静态配置来发现目标服务对象(targets)

7、有多种可视化图像界面,如Grafana等

8、高效的存储,每个采样数据占3.5 bytes左,300万的时间序列,30s间隔,保留60天,消耗磁盘大概200G

9、做高可用,可以对数据做异地备份,联邦集群,部署多套prometheus,pushgateway上报数据

10、样本

在时间序列中的每一个点称为一个样本(sample),样本由以下三部分组成:

1、指标(metric):指标名称和描述当前样本特征的 labelsets;

2、时间戳(timestamp):一个精确到毫秒的时间戳;

3、样本值(value): 一个 folat64 的浮点型数据表示当前样本的值。

表示方式:

通过如下表达方式表示指定指标名称和指定标签集合的时间序列:

{

例如,指标名称为 api_http_requests_total,标签为 method=”POST” 和 handler=”/messages” 的时间序列可以表示为:

api_http_requests_total{method=”POST”, handler=”/messages”}

3、Prometheus组件介绍

1、Prometheus server

用于收集和存储时间序列数据,采集数据使用Retrieval来实现的。

2、Client Library

客户端库,检测应用程序代码,当Protheus抓取实例的HTTP端点时,客户端会将所有追踪的metrics指标的当前状态发送到protheus server端

3、Exporters

prometheus支持多种exporter,通过exporter可以采集metrics数据,然后发送到prometheus server端,所有向prometheus server提供监控数据的程序都可以称为exporter

4、Alertmanager

从prometheus server端接收到alerts后,会进行去重,分组,并路由到相应的接收方,发出警报,常见的接收方式有:电子邮件、微信、钉钉、slack

5、Grafana

监控仪表盘,可视化监控数据

6、pushgateway

各个目标主机可上报数据到pushgateway,然后protheus server统一从pushgateway上拉取数据

image-20220910151420849

从上图可发现,Prometheus整个生态圈组成主要包括prometheus server,Exporter,pushgateway,alertmanager,grafana,Web ui界面,Prometheus server由三个部分组成,Retrieval,Storage,PromQL

1.Retrieval负责在活跃的target主机上抓取监控指标数据

2.Storage存储主要是把采集到的数据存储到磁盘中

3.PromQL是Prometheus提供的查询语言模块。

4、Prometheus工作流程

1.Prometheus server可定期从活跃的(up)目标主机上(target)拉取监控指标数据,目标主机的监控数据可通过配置静态job或者服务发现的方式被prometheus server采集到,这种方式默认的pull方式拉取指标;也可通过pushgateway把采集的数据上报到prometheus server中;还可通过一些组件自带的exporter采集相应组件的数据;

2.Prometheus server把采集到的监控指标数据保存到本地磁盘或者数据库;

3.Prometheus采集的监控指标数据按时间序列存储,通过配置报警规则,把触发的报警发送到alertmanager

4.Alertmanager通过配置报警接收方,发送报警到邮件,微信或者钉钉等

5.Prometheus 自带的web ui界面提供PromQL查询语言,可查询监控数据

6.Grafana可接入prometheus数据源,把监控数据以图形化形式展示出

5、Prometheus和zabbix对比分析

image-20220910152726338

6、Prometheus的集中部署方式

1、基本高可用模式

image-20220910153151496

基本的HA模式只能确保Promthues服务的可用性问题,但是不解决Prometheus Server之间的数据一致性问题以及持久化问题(数据丢失后无法恢复),也无法进行动态的扩展。因此这种部署方式适合监控规模不大,Promthues Server也不会频繁发生迁移的情况,并且只需要保存短周期监控数据的场景。

2、基本高可用+远程存储

image-20220910153847328

在解决了Promthues服务可用性的基础上,同时确保了数据的持久化,当Promthues Server发生宕机或者数据丢失的情况下,可以快速的恢复。 同时Promthues Server可能很好的进行迁移。因此,该方案适用于用户监控规模不大,但是希望能够将监控数据持久化,同时能够确保Promthues Server的可迁移性的场景。

3、基本HA+远程存储+联邦集群方案

image-20220911134131596

Promthues的性能瓶颈主要在于大量的采集任务,因此用户需要利用Prometheus联邦集群的特性,将不同类型的采集任务划分到不同的Promthues子服务中,从而实现功能分区。例如一个Promthues Server负责采集基础设施相关的监控指标,另外一个Prometheus Server负责采集应用监控指标。再有上层Prometheus Server实现对数据的汇聚。

7、Prometheus的四种数据类型

1、Counter

Counter是计数器类型

1、Counter 用于累计值,例如记录请求次数、任务完成数、错误发生次数。

2、一直增加,不会减少。

3、重启进程后,会被重置。

1
2
http_response_total{method="GET",endpoint="/api/tracks"}  100
http_response_total{method="GET",endpoint="/api/tracks"} 160

Counter 类型数据可以让用户方便的了解事件产生的速率的变化,在PromQL内置的相关操作函数可以提供相应的分析,比如以HTTP应用请求量来进行说明:

1、通过rate()函数获取HTTP请求量的增长率

rate(http_requests_total[5m])

2、查询当前系统中,访问量前10的HTTP地址

topk(10, http_requests_total)

2、Gauge

Gauge是测量器类型:

1、Gauge是常规数值,例如温度变化、内存使用变化。

2、可变大,可变小。

3、重启进程后,会被重置

1
2
3
4
memory_usage_bytes{host="master-01"}   100
memory_usage_bytes{host="master-01"} 30
memory_usage_bytes{host="master-01"} 50
memory_usage_bytes{host="master-01"} 80

对于 Gauge 类型的监控指标,通过 PromQL 内置函数 delta() 可以获取样本在一段时间内的变化情况,例如,计算 CPU 温度在两小时内的差异:

dalta(cpu_temp_celsius{host=”zeus”}[2h])

你还可以通过PromQL 内置函数 predict_linear() 基于简单线性回归的方式,对样本数据的变化趋势做出预测。例如,基于 2 小时的样本数据,来预测主机可用磁盘空间在 4 个小时之后的剩余情况:

predict_linear(node_filesystem_free{job=”node”}[2h], 4 * 3600) < 0

3、histogram

histogram是柱状图,在Prometheus系统的查询语言中,有三种作用:

1、在一段时间范围内对数据进行采样(通常是请求持续时间或响应大小等),并将其计入可配置的存储桶(bucket)中. 后续可通过指定区间筛选样本,也可以统计样本总数,最后一般将数据展示为直方图。

2、对每个采样点值累计和(sum)

3、对采样点的次数累计和(count)

度量指标名称: [basename]_上面三类的作用度量指标名称

1、[basename]_bucket{le=”上边界”}, 这个值为小于等于上边界的所有采样点数量

2、[basename]_sum

3、[basename]_count

小结:如果定义一个度量类型为Histogram,则Prometheus会自动生成三个对应的指标

1、为什需要用histogram柱状图?

在大多数情况下人们都倾向于使用某些量化指标的平均值,例如 CPU 的平均使用率、页面的平均响应时间。这种方式的问题很明显,以系统 API 调用的平均响应时间为例:如果大多数 API 请求都维持在 100ms 的响应时间范围内,而个别请求的响应时间需要 5s,那么就会导致某些 WEB 页面的响应时间落到中位数的情况,而这种现象被称为长尾问题。

为了区分是平均的慢还是长尾的慢,最简单的方式就是按照请求延迟的范围进行分组。例如,统计延迟在 010ms 之间的请求数有多少,而 1020ms 之间的请求数又有多少。通过这种方式可以快速分析系统慢的原因。Histogram 和 Summary 都是为了能够解决这样问题的存在,通过 Histogram 和 Summary 类型的监控指标,我们可以快速了解监控样本的分布情况。

Histogram 类型的样本会提供三种指标(假设指标名称为 ):

样本的值分布在 bucket 中的数量,命名为 _bucket{le=”<上边界>”}。解释的更通俗易懂一点,这个值表示指标值小于等于上边界的所有样本数量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
1、在总共2次请求当中。http 请求响应时间 <=0.005 秒 的请求次数为0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.005",} 0.0
2、在总共2次请求当中。http 请求响应时间 <=0.01 秒 的请求次数为0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.01",} 0.0
3、在总共2次请求当中。http 请求响应时间 <=0.025 秒 的请求次数为0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.025",} 0.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.05",} 0.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.075",} 0.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.1",} 0.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.25",} 0.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.5",} 0.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.75",} 0.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="1.0",} 0.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="2.5",} 0.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="5.0",} 0.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="7.5",} 2.0
4、在总共2次请求当中。http 请求响应时间 <=10 秒 的请求次数为 2
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="10.0",} 2.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="+Inf",} 2.0

所有样本值的大小总和,命名为 <basename>_sum。
5、实际含义: 发生的2次 http 请求总的响应时间为 13.107670803000001 秒
io_namespace_http_requests_latency_seconds_histogram_sum{path="/",method="GET",code="200",} 13.107670803000001

样本总数,命名为 <basename>_count。值和 <basename>_bucket{le="+Inf"} 相同。
6、实际含义: 当前一共发生了 2 次 http 请求
io_namespace_http_requests_latency_seconds_histogram_count{path="/",method="GET",code="200",} 2.0

注意:

bucket 可以理解为是对数据指标值域的一个划分,划分的依据应该基于数据值的分布。注意后面的采样点是包含前面的采样点的,假设 xxx_bucket{…,le=”0.01”} 的值为 10,而 xxx_bucket{…,le=”0.05”} 的值为 30,那么意味着这 30 个采样点中,有 10 个是小于 0.01s的,其余 20 个采样点的响应时间是介于0.01s 和 0.05s之间的。

可以通过 histogram_quantile() 函数来计算 Histogram 类型样本的分位数。分位数可能不太好理解,你可以理解为分割数据的点。我举个例子,假设样本的 9 分位数(quantile=0.9)的值为 x,即表示小于 x 的采样值的数量占总体采样值的 90%。Histogram 还可以用来计算应用性能指标值(Apdex score)。

4、summary

与 Histogram 类型类似,用于表示一段时间内的数据采样结果(通常是请求持续时间或响应大小等),但它直接存储了分位数(通过客户端计算,然后展示出来),而不是通过区间来计算。它也有三种作用:

1、对于每个采样点进行统计,并形成分位图。(如:正态分布一样,统计低于60分不及格的同学比例,统计低于80分的同学比例,统计低于95分的同学比例)

2、统计班上所有同学的总成绩(sum)

3、统计班上同学的考试总人数(count)

带有度量指标的[basename]的summary 在抓取时间序列数据有如命名。

1、观察时间的φ-quantiles (0 ≤ φ ≤ 1), 显示为[basename]{分位数=”[φ]”}

2、[basename]_sum, 是指所有观察值的总和

3、[basename]_count, 是指已观察到的事件计数值

样本值的分位数分布情况,命名为 {quantile="<φ>"}

1、含义:这 12 次 http 请求中有 50% 的请求响应时间是 3.052404983s

io_namespace_http_requests_latency_seconds_summary{path=”/“,method=”GET”,code=”200”,quantile=”0.5”,} 3.052404983

2、含义:这 12 次 http 请求中有 90% 的请求响应时间是 8.003261666s

io_namespace_http_requests_latency_seconds_summary{path=”/“,method=”GET”,code=”200”,quantile=”0.9”,} 8.003261666

所有样本值的大小总和,命名为 _sum

1、含义:这12次 http 请求的总响应时间为 51.029495508s

io_namespace_http_requests_latency_seconds_summary_sum{path=”/“,method=”GET”,code=”200”,} 51.029495508

样本总数,命名为 _count

1、含义:当前一共发生了 12 次 http 请求

io_namespace_http_requests_latency_seconds_summary_count{path=”/“,method=”GET”,code=”200”,} 12.0

现在可以总结一下 Histogram 与 Summary 的异同:

它们都包含了 _sum 和 _count 指标

Histogram 需要通过 _bucket 来计算分位数,而 Summary 则直接存储了分位数的值。

prometheus_tsdb_wal_fsync_duration_seconds{quantile=”0.5”} 0.012352463

prometheus_tsdb_wal_fsync_duration_seconds{quantile=”0.9”} 0.014458005

prometheus_tsdb_wal_fsync_duration_seconds{quantile=”0.99”} 0.017316173

prometheus_tsdb_wal_fsync_duration_seconds_sum 2.888716127000002

prometheus_tsdb_wal_fsync_duration_seconds_count 216

从上面的样本中可以得知当前Promtheus Server进行wal_fsync操作的总次数为216次,耗时2.888716127000002s。其中中位数(quantile=0.5)的耗时为0.012352463,9分位数(quantile=0.9)的耗时为0.014458005s。

8、Promethus能监控什么

• Databases

• Hardware related

• Messaging systems

• Storage

• HTTP

• APIs

• Logging

• Other monitoring systems

• Miscellaneous

• Software exposing Prometheus metrics

1、DATABASES-数据库

• Aerospike exporter

• ClickHouse exporter

• Consul exporter (official)

• Couchbase exporter

• CouchDB exporter

• ElasticSearch exporter

• EventStore exporter

• Memcached exporter (official)

• MongoDB exporter

• MSSQL server exporter

• MySQL server exporter (official)

• OpenTSDB Exporter

• Oracle DB Exporter

• PgBouncer exporter

• PostgreSQL exporter

• ProxySQL exporter

• RavenDB exporter

• Redis exporter

• RethinkDB exporter

• SQL exporter

• Tarantool metric library

• Twemproxy

• apcupsd exporter

• Collins exporter

• IBM Z HMC exporter

• IoT Edison exporter

• IPMI exporter

• knxd exporter

• Netgear Cable Modem Exporter

• Node/system metrics exporter (official)

• NVIDIA GPU exporter

• ProSAFE exporter

• Ubiquiti UniFi exporter

3、Messaging systems-消息服务

• Beanstalkd exporter

• Gearman exporter

• Kafka exporter

• NATS exporter

• NSQ exporter

• Mirth Connect exporter

• MQTT blackbox exporter

• RabbitMQ exporter

• RabbitMQ Management Plugin exporter

4、Storage-存储

• Ceph exporter

• Ceph RADOSGW exporter

• Gluster exporter

• Hadoop HDFS FSImage exporter

• Lustre exporter

• ScaleIO exporter

5、http-网站服务

• Apache exporter

• HAProxy exporter (official)

• Nginx metric library

• Nginx VTS exporter

• Passenger exporter

• Squid exporter

• Tinyproxy exporter

• Varnish exporter

• WebDriver exporter

6、API

• AWS ECS exporter

• AWS Health exporter

• AWS SQS exporter

• Cloudflare exporter

• DigitalOcean exporter

• Docker Cloud exporter

• Docker Hub exporter

• GitHub exporter

• InstaClustr exporter

• Mozilla Observatory exporter

• OpenWeatherMap exporter

• Pagespeed exporter

• Rancher exporter

• Speedtest exporter

7、Logging-日志

• Fluentd exporter

• Google’s mtail log data extractor

• Grok exporter

8、Other monitoring systems

• Akamai Cloudmonitor exporter

• Alibaba Cloudmonitor exporter

• AWS CloudWatch exporter (official)

• Cloud Foundry Firehose exporter

• Collectd exporter (official)

• Google Stackdriver exporter

• Graphite exporter (official)

• Heka dashboard exporter

• Heka exporter

• InfluxDB exporter (official)

• JavaMelody exporter

• JMX exporter (official)

• Munin exporter

• Nagios / Naemon exporter

• New Relic exporter

• NRPE exporter

• Osquery exporter

• OTC CloudEye exporter

• Pingdom exporter

• scollector exporter

• Sensu exporter

• SNMP exporter (official)

• StatsD exporter (official)

9、Miscellaneous-其他

• ACT Fibernet Exporter

• Bamboo exporter

• BIG-IP exporter

• BIND exporter

• Bitbucket exporter

• Blackbox exporter (official)

• BOSH exporter

• cAdvisor

• Cachet exporter

• ccache exporter

• Confluence exporter

• Dovecot exporter

• eBPF exporter

• Ethereum Client exporter

• Jenkins exporter

• JIRA exporter

• Kannel exporter

• Kemp LoadBalancer exporter

• Kibana Exporter

• Meteor JS web framework exporter

• Minecraft exporter module

• PHP-FPM exporter

• PowerDNS exporter

• Presto exporter

• Process exporter

• rTorrent exporter

• SABnzbd exporter

• Script exporter

• Shield exporter

• SMTP/Maildir MDA blackbox prober

• SoftEther exporter

• Transmission exporter

• Unbound exporter

• Xen exporter

10、Software exposing Prometheus metrics-Prometheus度量指标

• App Connect Enterprise

• Ballerina

• Ceph

• Collectd

• Concourse

• CRG Roller Derby Scoreboard (direct)

• Docker Daemon

• Doorman (direct)

• Etcd (direct)

• Flink

• FreeBSD Kernel

• Grafana

• JavaMelody

• Kubernetes (direct)

• Linkerd

9、Prometheus对kubernetes的监控

对于Kubernetes而言,我们可以把当中所有的资源分为几类:

• 基础设施层(Node):集群节点,为整个集群和应用提供运行时资源

• 容器基础设施(Container):为应用提供运行时环境

• 用户应用(Pod):Pod中会包含一组容器,它们一起工作,并且对外提供一个(或者一组)功能

• 内部服务负载均衡(Service):在集群内,通过Service在集群暴露应用功能,集群内应用和应用之间访问时提供内部的负载均衡

• 外部访问入口(Ingress):通过Ingress提供集群外的访问入口,从而可以使外部客户端能够访问到部署在Kubernetes集群内的服务

因此,如果要构建一个完整的监控体系,我们应该考虑,以下5个方面:

• 集群节点状态监控:从集群中各节点的kubelet服务获取节点的基本运行状态;

• 集群节点资源用量监控:通过Daemonset的形式在集群中各个节点部署Node Exporter采集节点的资源使用情况;

• 节点中运行的容器监控:通过各个节点中kubelet内置的cAdvisor中获取个节点中所有容器的运行状态和资源使用情况;

• 如果在集群中部署的应用程序本身内置了对Prometheus的监控支持,那么我们还应该找到相应的Pod实例,并从该Pod实例中获取其内部运行状态的监控指标。

• 对k8s本身的组件做监控:apiserver、scheduler、controller-manager、kubelet、kube-proxy

10、node-exporter组件安装和配置

1、介绍

node-exporter可以采集机器(物理机、虚拟机、云主机等)的监控指标数据,能够采集到的指标包括CPU, 内存,磁盘,网络,文件数等信息。

2、安装node-exporter

将node-export.tar.gz镜像压缩包上传到k8s集群的各个节点上,手动解压

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@master1 ~]# docker images | grep node-exporter
prom/node-exporter v0.16.0 188af75e2de0 4 years ago 22.9MB

[root@master2 ~]# docker images | grep node-exporter
prom/node-exporter v0.16.0 188af75e2de0 4 years ago 22.9MB

[root@master3 ~]# docker images | grep node-exporter
prom/node-exporter v0.16.0 188af75e2de0 4 years ago 22.9MB

[root@node1 ~]# docker images | grep node-exporter
prom/node-exporter v0.16.0 188af75e2de0 4 years ago 22.9MB

[root@node2 ~]# docker images | grep node-exporter
prom/node-exporter v0.16.0 188af75e2de0 4 years ago 22.9MB

[root@node3 ~]# docker images | grep node-exporter
prom/node-exporter v0.16.0 188af75e2de0 4 years ago 22.9MB

创建node-export.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
[root@master1 promethus]# cat node-export.yml 
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
namespace: monitor-sa
labels:
name: node-exporter
spec:
selector:
matchLabels:
name: node-exporter
template:
metadata:
labels:
name: node-exporter
spec:
hostPID: true
hostIPC: true
hostNetwork: true
# hostNetwork、hostIPC、hostPID都为True时,表示这个Pod里的所有容器,会直接使用宿主机的网络,直接与宿主机进行IPC(进程间通信)通信,可以看到宿主机里正在运行的所有进程。加入了hostNetwork:true会直接将我们的宿主机的9100端口映射出来,从而不需要创建service 在我们的宿主机上就会有一个9100的端口
containers:
- name: node-exporter
image: prom/node-exporter:v0.16.0
ports:
- containerPort: 9100
resources:
requests:
cpu: 0.15 #这个容器运行至少需要0.15核cpu
securityContext:
privileged: true #开启特权模式
args:
- --path.procfs #配置挂载宿主机(node节点)的路径
- /host/proc
- --path.sysfs #配置挂载宿主机(node节点)的路径
- /host/sys
- --collector.filesystem.ignored-mount-points
- '"^/(sys|proc|dev|host|etc)($|/)"' #通过正则表达式忽略某些文件系统挂载点的信息收集
volumeMounts:
- name: dev
mountPath: /host/dev
- name: proc
mountPath: /host/proc
- name: sys
mountPath: /host/sys
- name: rootfs
mountPath: /rootfs
#将主机/dev、/proc、/sys这些目录挂在到容器中,这是因为我们采集的很多节点数据都是通过这些文件来获取系统信息的。
tolerations:
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"
volumes:
- name: proc
hostPath:
path: /proc
- name: dev
hostPath:
path: /dev
- name: sys
hostPath:
path: /sys
- name: rootfs
hostPath:
path: /



[root@master1 promethus]# kubectl get pods -n monitor-sa -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
node-exporter-fbpkr 1/1 Running 0 7m52s 192.168.106.22 node2 <none> <none>
node-exporter-ffn4x 1/1 Running 0 7m52s 192.168.106.21 node1 <none> <none>
node-exporter-z78gj 1/1 Running 0 7m52s 192.168.106.23 node3 <none> <none>

查看主机的cpu使用情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
[root@master1 promethus]# curl http://192.168.106.21:9100/metrics | grep node_cpu_seconds
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0# HELP node_cpu_seconds_total Seconds the cpus spent in each mode.
# TYPE node_cpu_seconds_total counter
node_cpu_seconds_total{cpu="0",mode="idle"} 623938.6
node_cpu_seconds_total{cpu="0",mode="iowait"} 318.36
node_cpu_seconds_total{cpu="0",mode="irq"} 0
node_cpu_seconds_total{cpu="0",mode="nice"} 0.27
node_cpu_seconds_total{cpu="0",mode="softirq"} 386.91
node_cpu_seconds_total{cpu="0",mode="steal"} 474.33
node_cpu_seconds_total{cpu="0",mode="system"} 9936.77
node_cpu_seconds_total{cpu="0",mode="user"} 11128.03
node_cpu_seconds_total{cpu="1",mode="idle"} 623877.85
node_cpu_seconds_total{cpu="1",mode="iowait"} 466.91
node_cpu_seconds_total{cpu="1",mode="irq"} 0
node_cpu_seconds_total{cpu="1",mode="nice"} 0.27
node_cpu_seconds_total{cpu="1",mode="softirq"} 181.27
node_cpu_seconds_total{cpu="1",mode="steal"} 488.87
node_cpu_seconds_total{cpu="1",mode="system"} 9762.55
node_cpu_seconds_total{cpu="1",mode="user"} 11358.75
node_cpu_seconds_total{cpu="2",mode="idle"} 623435.87
node_cpu_seconds_total{cpu="2",mode="iowait"} 483.85
node_cpu_seconds_total{cpu="2",mode="irq"} 0
node_cpu_seconds_total{cpu="2",mode="nice"} 0.13
node_cpu_seconds_total{cpu="2",mode="softirq"} 136.85
node_cpu_seconds_total{cpu="2",mode="steal"} 495.61
node_cpu_seconds_total{cpu="2",mode="system"} 9875.75
node_cpu_seconds_total{cpu="2",mode="user"} 11594.71
node_cpu_seconds_total{cpu="3",mode="idle"} 625033.69
node_cpu_seconds_total{cpu="3",mode="iowait"} 455.69
node_cpu_seconds_total{cpu="3",mode="irq"} 0
node_cpu_seconds_total{cpu="3",mode="nice"} 0.18
node_cpu_seconds_total{cpu="3",mode="softirq"} 121
node_cpu_seconds_total{cpu="3",mode="steal"} 488.24
node_cpu_seconds_total{cpu="3",mode="system"} 9200.91
node_cpu_seconds_total{cpu="3",mode="user"} 11219.9
100 101k 100 101k 0 0 5913k 0 --:--:-- --:--:-- --:--:-- 6333k

#HELP:解释当前指标的含义,上面表示在每种模式下node节点的cpu花费的时间,以s为单位

#TYPE:说明当前指标的数据类型,上面是counter类型

node_cpu_seconds_total{cpu=”0”,mode=”idle”} :

cpu0上idle进程占用CPU的总时间,CPU占用时间是一个只增不减的度量指标,从类型中也可以看出node_cpu的数据类型是counter(计数器)

counter计数器:只是采集递增的指标

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@master1 promethus]# curl http://192.168.106.21:9100/metrics | grep node_load
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0# HELP node_load1 1m load average.
# TYPE node_load1 gauge
node_load1 0
# HELP node_load15 15m load average.
# TYPE node_load15 gauge
node_load15 0.1
# HELP node_load5 5m load average.
# TYPE node_load5 gauge
node_load5 0.04
100 101k 100 101k 0 0 6262k 0 --:--:-- --:--:-- --:--:-- 6753k

node_load1该指标反映了当前主机在最近一分钟以内的负载情况,系统的负载情况会随系统资源的使用而变化,因此node_load1反映的是当前状态,数据可能增加也可能减少,从注释中可以看出当前指标类型为gauge(标准尺寸)

gauge标准尺寸:统计的指标可增加可减少

11、Promethus server安装和配置

1、创建一个sa账号,对sa做rbac授权

1
2
3
4
5
6
7
[root@master1 promethus]# kubectl create serviceaccount monitor -n monitor-sa 
serviceaccount/monitor created


#对sa账号进行授权,monitor-sa:momitor,monitor-sa表示的是名称空间。对monitor-sa名称空间下的monitor账号进行操作
[root@master1 promethus]# kubectl create clusterrolebinding monitor-clusterrolebinding -n monitor-sa --clusterrole=cluster-admin --serviceaccount=monitor-sa:monitor
clusterrolebinding.rbac.authorization.k8s.io/monitor-clusterrolebinding created

2、创建prometheus数据存储目录(在node1节点上)

1
2
[root@node1 ~]# mkdir /data/prometheus/ -p
[root@node1 ~]# chmod 777 /data/prometheus/

3、安装prometheus server服务

创建configmap存储卷,用来存放prometheus配置信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
[root@master1 promethus]# cat prometheus-cfg.yaml 
---
kind: ConfigMap
apiVersion: v1
metadata:
labels:
app: prometheus
name: prometheus-config
namespace: monitor-sa
data:
prometheus.yml: |
global:
scrape_interval: 15s #采集目标主机监控数据时间间隔
scrape_timeout: 10s #采集数据超时时间,默认为10秒
evaluation_interval: 1m #触发告警检测的时间,默认是一分钟
scrape_configs:
#配置数据源,称为target,每个target用job_name命名。分为静态配置和服务发现
- job_name: 'kubernetes-node'
kubernetes_sd_configs:
#使用的k8s的服务发现
- role: node
#使用node角色,它使用默认是kubelet提供的http端口来发现集群中每个node节点
relabel_configs:
#重新标记
- source_labels: [__address__] #配置的原始标签,匹配地址
regex: '(.*):10250' #匹配带有10250端口的url
replacement: '${1}:9100' #把匹配到的ip:10250的ip保留
target_label: __address__ #把新生成的url是${1}获取到的ip:9100
action: replace #动作:替换
- action: labelmap
#匹配到下面正则表达式的标签会被保留,如果不做regex正则的话,默认只是会显示instance标签
regex: __meta_kubernetes_node_label_(.+)
- job_name: 'kubernetes-node-cadvisor'
#抓取cadvisor数据,是获取kubelet上/metrics/cadvisor接口数据来获取容器的资源使用情况
kubernetes_sd_configs:
- role: node
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- action: labelmap #把匹配的标签保留
regex: __meta_kubernetes_node_label_(.+)
#保留匹配到的具有__meta_kubernetes_node_label的标签
- target_label: __address__
#获取到的地址:__address__="192.168.106.21:10250"
replacement: kubernetes.default.svc:443
#把获取到的地址替换成新的地址kubernetes.default.svc:443
- source_labels: [__meta_kubernetes_node_name]
#把原始标签中的__meta_kubernetes_node_name值匹配到
regex: (.+)
target_label: __metrics_path__
#获取__metrics_path__对应的值
replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
#把metrics替换成新的值/api/v1/nodes/node1/proxy/metrics/cadvisor
- job_name: 'kubernetes-apiserver'
kubernetes_sd_configs:
- role: endpoints #使用k8s中的endpoint服务发现,采集apiserver 6443端口获取到的数据
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep #采集满足条件的实例,其他实例不采集
regex: default;kubernetes;https #正则匹配到的默认空间下的service名字是kubernetes,协议是https的endpoint类型保留下来
- job_name: 'kubernetes-service-endpoints'
kubernetes_sd_configs:
- role: endpoints #使用k8s中的endpoint服务发现,采集apiserver 6443端口获取到的数据
relabel_configs:
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
action: keep
regex: true
# 重新打标仅抓取到的具有 "prometheus.io/scrape: true" 的annotation的端点,意思是说如果某个service具有prometheus.io/scrape = true annotation声明则抓取,annotation本身也是键值结构,所以这里的源标签设置为键,而regex设置值true,当值匹配到regex设定的内容时则执行keep动作也就是保留,其余则丢弃。
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
action: replace
target_label: __scheme__
regex: (https?)
#重新设置scheme,匹配源标签__meta_kubernetes_service_annotation_prometheus_io_scheme也就是prometheus.io/scheme annotation,如果源标签的值匹配到regex,则把值替换为__scheme__对应的值。
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
# 应用中自定义暴露的指标,也许你暴露的API接口不是/metrics这个路径,那么你可以在这个POD对应的service中做一个"prometheus.io/path = /mymetrics" 声明,上面的意思就是把你声明的这个路径赋值给__metrics_path__,其实就是让prometheus来获取自定义应用暴露的metrices的具体路径,不过这里写的要和service中做好约定,如果service中这样写 prometheus.io/app-metrics-path: '/metrics' 那么你这里就要__meta_kubernetes_service_annotation_prometheus_io_app_metrics_path这样写。
- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
action: replace
target_label: __address__
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
# 暴露自定义的应用的端口,就是把地址和你在service中定义的 "prometheus.io/port = <port>" 声明做一个拼接,然后赋值给__address__,这样prometheus就能获取自定义应用的端口,然后通过这个端口再结合__metrics_path__来获取指标,如果__metrics_path__值不是默认的/metrics那么就要使用上面的标签替换来获取真正暴露的具体路径。
- action: labelmap
regex: __meta_kubernetes_service_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_service_name]
action: replace
target_label: kubernetes_name




[root@master1 promethus]# kubectl apply -f prometheus-cfg.yaml

创建prometheus的service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@master1 prometheus]# cat prometheus-svc.yaml 
apiVersion: v1
kind: Service
metadata:
name: prometheus
namespace: monitor-sa
labels:
app: prometheus
spec:
type: NodePort
ports:
- port: 9090
targetPort: 9090
protocol: TCP
selector:
app: prometheus
component: server

部署prometheus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
[root@master1 prometheus]# cat prometheus-deploy.yaml 
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus-server
namespace: monitor-sa
labels:
app: prometheus
spec:
replicas: 1
selector:
matchLabels:
app: prometheus
component: server
#matchExpressions:
#- {key: app, operator: In, values: [prometheus]}
#- {key: component, operator: In, values: [server]}
template:
metadata:
labels:
app: prometheus
component: server
annotations:
prometheus.io/scrape: 'false'
spec:
nodeName: node1
serviceAccountName: monitor
containers:
- name: prometheus
image: prom/prometheus:v2.2.1
imagePullPolicy: IfNotPresent
command:
- prometheus
- --config.file=/etc/prometheus/prometheus.yml
- --storage.tsdb.path=/prometheus
- --storage.tsdb.retention=720h
- --web.enable-lifecycle
ports:
- containerPort: 9090
protocol: TCP
volumeMounts:
- mountPath: /etc/prometheus/prometheus.yml
name: prometheus-config
subPath: prometheus.yml
- mountPath: /prometheus/
name: prometheus-storage-volume
volumes:
- name: prometheus-config
configMap:
name: prometheus-config
items:
- key: prometheus.yml
path: prometheus.yml
mode: 0644
- name: prometheus-storage-volume
hostPath:
path: /data/prometheus/
type: Directory

4、prometheus配置文件自动加载

热加载(速度特别慢)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#修改配置文件configmap中的参数“scrape_timeout”为15s
[root@master1 prometheus]# cat prometheus-cfg.yaml | grep scrape_timeout
scrape_timeout: 15s
[root@master1 prometheus]# kubectl apply -f prometheus-cfg.yaml


#查看prometheus-server的ip应用配置文件
[root@master1 prometheus]# kubectl get pods -o wide -n monitor-sa -l app=prometheus | awk {'print $6'} | sed -n 2p
10.244.166.162
[root@master1 prometheus]# curl -X POST http://10.244.166.162:9090/-/reload


#验证配置文件是否被修改
[root@master2 ~]# kubectl exec -it prometheus-server-859df54466-hb8f9 -n monitor-sa -- /bin/sh

2、可视化UI界面Grafana的安装和配置

1、Grafana介绍

Grafana是一个跨平台的开源的度量分析和可视化工具,可以将采集的数据可视化的展示,并及时通知给告警接收方。它主要有以下六大特点:

1、展示方式:快速灵活的客户端图表,面板插件有许多不同方式的可视化指标和日志,官方库中具有丰富的仪表盘插件,比如热图、折线图、图表等多种展示方式;

2、数据源:Graphite,InfluxDB,OpenTSDB,Prometheus,Elasticsearch,CloudWatch和KairosDB等;

3、通知提醒:以可视方式定义最重要指标的警报规则,Grafana将不断计算并发送通知,在数据达到阈值时通过Slack、PagerDuty等获得通知;

4、混合展示:在同一图表中混合使用不同的数据源,可以基于每个查询指定数据源,甚至自定义数据源;

5、注释:使用来自不同数据源的丰富事件注释图表,将鼠标悬停在事件上会显示完整的事件元数据和标记。

2、安装grafana

1、上传镜像压缩包并解压到node节点

1
2
3
4
5
6
[root@node1 ~]# docker load -i heapster-grafana-amd64_v5_0_4.tar.gz
[root@node2 ~]# docker load -i heapster-grafana-amd64_v5_0_4.tar.gz
[root@node1 ~]# docker images | grep grafan
k8s.gcr.io/heapster-grafana-amd64 v5.0.4
[root@node2 ~]# docker images | grep grafan
k8s.gcr.io/heapster-grafana-amd64 v5.0.4

2、更新yaml配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
[root@master1 prometheus]# cat grafana.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
name: monitoring-grafana
namespace: kube-system
spec:
replicas: 2
selector:
matchLabels:
task: monitoring
k8s-app: grafana
template:
metadata:
labels:
task: monitoring
k8s-app: grafana
spec:
containers:
- name: grafana
image: k8s.gcr.io/heapster-grafana-amd64:v5.0.4
ports:
- containerPort: 3000
protocol: TCP
volumeMounts:
- mountPath: /etc/ssl/certs
name: ca-certificates
readOnly: true
- mountPath: /var
name: grafana-storage
env:
- name: INFLUXDB_HOST
value: monitoring-influxdb
- name: GF_SERVER_HTTP_PORT
value: "3000"
# The following env variables are required to make Grafana accessible via
# the kubernetes api-server proxy. On production clusters, we recommend
# removing these env variables, setup auth for grafana, and expose the grafana
# service using a LoadBalancer or a public IP.
- name: GF_AUTH_BASIC_ENABLED
value: "false"
- name: GF_AUTH_ANONYMOUS_ENABLED
value: "true"
- name: GF_AUTH_ANONYMOUS_ORG_ROLE
value: Admin
- name: GF_SERVER_ROOT_URL
# If you're only using the API Server proxy, set this value instead:
# value: /api/v1/namespaces/kube-system/services/monitoring-grafana/proxy
value: /
volumes:
- name: ca-certificates
hostPath:
path: /etc/ssl/certs
- name: grafana-storage
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
labels:
# For use as a Cluster add-on (https://github.com/kubernetes/kubernetes/tree/master/cluster/addons)
# If you are NOT using this as an addon, you should comment out this line.
kubernetes.io/cluster-service: 'true'
kubernetes.io/name: monitoring-grafana
name: monitoring-grafana
namespace: kube-system
spec:
# In a production setup, we recommend accessing Grafana through an external Loadbalancer
# or through a public IP.
# type: LoadBalancer
# You could also use NodePort to expose the service at a randomly-generated port
# type: NodePort
ports:
- port: 80
targetPort: 3000
selector:
k8s-app: grafana
type: NodePort

3、grafana界面接入Prometheus数据源

查看grafana前端的service

1
2
[root@master1 prometheus]# kubectl get svc -n kube-system | grep grafana 
monitoring-grafana NodePort 10.10.78.198 <none> 80:32361/TCP 12m

登录grafana,在浏览器访问192.168.100.21:32361

image-20220922221414217

配置grafana界面(点击Create your first data source)

image-20220922221447225

image-20220922221606521

导入监控模板

1
https://grafana.com/dashboards?dataSource=prometheus&search=kubernetes

可直接导入node_exporter.json监控模板,这个可以把node节点指标显示出来

node_exporter.json在课件里

可直接导入docker_rev1.json,显示容器资源指标的,docker_rev1.json在课件里

image-20220922224146659

导入docker_rev1.json监控模板,步骤和上面导入node_exporter.json步骤一样,导入之后显示如下:

image-20220922224432258

3、安装kube-state-metrics组件

1、kube-state-metrics简介

kube-state-metrics通过监听API Server生成有关资源对象的状态指标,比如Deployment、Node、Pod,需要注意的是kube-state-metrics只是简单的提供一个metrics数据,并不会存储这些指标数据,所以我们可以使用Prometheus来抓取这些数据然后存储,主要关注的是业务相关的一些元数据,比如Deployment、Pod、副本状态等;调度了多少个replicas?现在可用的有几个?多少个Pod是running/stopped/terminated状态?Pod重启了多少次?我有多少job在运行中。

2、创建sa,并对sa进行授权

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
[root@master1 prometheus]# cat kube-state-metrics-rbac.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: kube-state-metrics
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kube-state-metrics
rules:
- apiGroups: [""]
resources: ["nodes", "pods", "services", "resourcequotas", "replicationcontrollers", "limitranges", "persistentvolumeclaims", "persistentvolumes", "namespaces", "endpoints"]
verbs: ["list", "watch"]
- apiGroups: ["extensions"]
resources: ["daemonsets", "deployments", "replicasets"]
verbs: ["list", "watch"]
- apiGroups: ["apps"]
resources: ["statefulsets"]
verbs: ["list", "watch"]
- apiGroups: ["batch"]
resources: ["cronjobs", "jobs"]
verbs: ["list", "watch"]
- apiGroups: ["autoscaling"]
resources: ["horizontalpodautoscalers"]
verbs: ["list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kube-state-metrics
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kube-state-metrics
subjects:
- kind: ServiceAccount
name: kube-state-metrics
namespace: kube-system


[root@master1 prometheus]# kubectl apply -f kube-state-metrics-rbac.yaml
serviceaccount/kube-state-metrics created
clusterrole.rbac.authorization.k8s.io/kube-state-metrics created
clusterrolebinding.rbac.authorization.k8s.io/kube-state-metrics created

3、上传镜像到node节点

1
2
[root@node1 ~]# docker load -i kube-state-metrics_1_9_0.tar.gz
[root@node2 ~]# docker load -i kube-state-metrics_1_9_0.tar.gz

4、部署pod与service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
[root@master1 prometheus]# cat kube-state-metrics-deploy.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
name: kube-state-metrics
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app: kube-state-metrics
template:
metadata:
labels:
app: kube-state-metrics
spec:
serviceAccountName: kube-state-metrics
containers:
- name: kube-state-metrics
image: quay.io/coreos/kube-state-metrics:v1.9.0
ports:
- containerPort: 8080


[root@master1 prometheus]# cat kube-state-metrics-svc.yaml
apiVersion: v1
kind: Service
metadata:
annotations:
prometheus.io/scrape: 'true'
name: kube-state-metrics
namespace: kube-system
labels:
app: kube-state-metrics
spec:
ports:
- name: kube-state-metrics
port: 8080
protocol: TCP
selector:
app: kube-state-metrics

3、基于Alertmanager发送报警到多个接收方

1、配置Alertmanager发送报警到qq邮箱

报警:指prometheus将监测到的异常事件发送给alertmanager

通知:alertmanager将报警信息发送到邮件、微信、钉钉等

1、创建alertmanager配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@master1 prometheus]# cat alertmanager-cm.yaml 
kind: ConfigMap
apiVersion: v1
metadata:
name: alertmanager
namespace: monitor-sa
data:
alertmanager.yml: |-
global:
resolve_timeout: 1m
smtp_smarthost: 'smtp.163.com:25'
smtp_from: '[email protected]'
smtp_auth_username: '13164377870'
smtp_auth_password: 'DJDDZXJFFTSLRJYG'
smtp_require_tls: false
route: #配置告警分发策略
group_by: [alertname] #采用哪个标签来作为分组依据
group_wait: 10s #组告警等待时间:告警等待10秒,如果有同组告警一并发出
group_interval: 10s #上下两组发送告警的间隔时间
repeat_interval: 10m #重复发送告警的时间,减少相同邮件发送频率,默认是1小时
receiver: default-receiver #定义谁来接受告警
receivers:
- name: 'default-receiver'
email_configs:
- to: '[email protected]'
send_resolved: true


[root@master1 prometheus]# kubectl apply -f alertmanager-cm.yaml

2、Prometheus一条报警的触发流程

\1. Prometheus Server监控目标主机上暴露的http接口(这里假设接口A),通过Promethes配置的’scrape_interval’定义的时间间隔,定期采集目标主机上监控数据。
\2. 当接口A不可用的时候,Server端会持续的尝试从接口中取数据,直到”scrape_timeout”时间后停止尝试。这时候把接口的状态变为“DOWN”。
\3. Prometheus同时根据配置的”evaluation_interval”的时间间隔,定期(默认1min)的对Alert Rule进行评估;当到达评估周期的时候,发现接口A为DOWN,即UP=0为真,激活Alert,进入“PENDING”状态,并记录当前active的时间;
\4. 当下一个alert rule的评估周期到来的时候,发现UP=0继续为真,然后判断警报Active的时间是否已经超出rule里的‘for’ 持续时间,如果未超出,则进入下一个评估周期;如果时间超出,则alert的状态变为“FIRING”;同时调用Alertmanager接口,发送相关报警数据。
\5. AlertManager收到报警数据后,会将警报信息进行分组,然后根据alertmanager配置的“group_wait”时间先进行等待。等wait时间过后再发送报警信息。
\6. 属于同一个Alert Group的警报,在等待的过程中可能进入新的alert,如果之前的报警已经成功发出,那么间隔“group_interval”的时间间隔后再重新发送报警信息。比如配置的是邮件报警,那么同属一个group的报警信息会汇总在一个邮件里进行发送。
\7. 如果Alert Group里的警报一直没发生变化并且已经成功发送,等待‘repeat_interval’时间间隔之后再重复发送相同的报警邮件;如果之前的警报没有成功发送,则相当于触发第6条条件,则需要等待group_interval时间间隔后重复发送。

同时最后至于警报信息具体发给谁,满足什么样的条件下指定警报接收人,设置不同报警发送频率,这里有alertmanager的route路由规则进行配置。

3、创建prometheus和告警规则配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#先删除prometheus-cfg.yaml,之前的配置文件里面没有告警规则
[root@master1 prometheus]# kubectl delete -f prometheus-cfg.yaml
configmap "prometheus-config" deleted

#删除prometheus-server的pod,名字冲突,配置文件也冲突
[root@master1 prometheus]# kubectl delete deployments.apps prometheus-server -n monitor-sa

[root@master1 prometheus]# cat prometheus-alertmanager-cfg.ymal | wc -l
540


#应用新的cm配置文件
[root@master1 prometheus]# kubectl apply -f prometheus-alertmanager-cfg.ymal
configmap/prometheus-config created


#生成一个etcd-certs,部署prometheus需要
[root@master1 prometheus]# kubectl -n monitor-sa create secret generic etcd-certs --from-file=/etc/kubernetes/pki/etcd/server.key --from-file=/etc/kubernetes/pki/etcd/server.crt --from-file=/etc/kubernetes/pki/etcd/ca.crt
secret/etcd-certs created


#应用新的配置文件(检查挂载的位置为卷权限是否为777)
[root@master1 prometheus]# cat prometheus-alertmanager-deploy.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus-server
namespace: monitor-sa
labels:
app: prometheus
spec:
replicas: 1
selector:
matchLabels:
app: prometheus
component: server
#matchExpressions:
#- {key: app, operator: In, values: [prometheus]}
#- {key: component, operator: In, values: [server]}
template:
metadata:
labels:
app: prometheus
component: server
annotations:
prometheus.io/scrape: 'false'
spec:
nodeName: node1
serviceAccountName: monitor
containers:
- name: prometheus
image: prom/prometheus:v2.2.1
imagePullPolicy: IfNotPresent
command:
- "/bin/prometheus"
args:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus"
- "--storage.tsdb.retention=24h"
- "--web.enable-lifecycle"
ports:
- containerPort: 9090
protocol: TCP
volumeMounts:
- mountPath: /etc/prometheus
name: prometheus-config
- mountPath: /prometheus/
name: prometheus-storage-volume
- name: k8s-certs
mountPath: /var/run/secrets/kubernetes.io/k8s-certs/etcd/
- name: localtime
mountPath: /etc/localtime
- name: alertmanager
image: prom/alertmanager:v0.14.0
imagePullPolicy: IfNotPresent
args:
- "--config.file=/etc/alertmanager/alertmanager.yml"
- "--log.level=debug"
ports:
- containerPort: 9093
protocol: TCP
name: alertmanager
volumeMounts:
- name: alertmanager-config
mountPath: /etc/alertmanager
- name: alertmanager-storage
mountPath: /alertmanager
- name: localtime
mountPath: /etc/localtime
volumes:
- name: prometheus-config
configMap:
name: prometheus-config
- name: prometheus-storage-volume
hostPath:
path: /data/prometheus
type: Directory
- name: k8s-certs
secret:
secretName: etcd-certs
- name: alertmanager-config
configMap:
name: alertmanager
- name: alertmanager-storage
hostPath:
path: /data/alertmanager
type: DirectoryOrCreate
- name: localtime
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
[root@master1 prometheus]# kubectl apply -f prometheus-alertmanager-deploy.yaml


#检查服务是否布置成功
[root@master1 prometheus]# kubectl get pods -n monitor-sa | grep prometheus
prometheus-server-57cc7947d8-c8d8g 2/2 Running 0 4m51s


#部署alertmanager的service,浏览器进行访问
[root@master1 prometheus]# cat alertmanager-svc.yaml
---
apiVersion: v1
kind: Service
metadata:
labels:
name: prometheus
kubernetes.io/cluster-service: 'true'
name: alertmanager
namespace: monitor-sa
spec:
ports:
- name: alertmanager
nodePort: 30066
port: 9093
protocol: TCP
targetPort: 9093
selector:
app: prometheus
sessionAffinity: None
type: NodePort
[root@master1 prometheus]# kubectl apply -f alertmanager-svc.yaml
service/alertmanager created

4、修改配置文件(在第三步之前进行操作,安装集群的时候就进行修改)

/etc/kubernetes/manifests/kube-scheduler.yaml

1
2
3
4
5
修改如下内容:
把--bind-address=127.0.0.1变成--bind-address=192.168.100.11
把httpGet:字段下的hosts由127.0.0.1变成192.168.100.11
把—port=0删除
#注意:192.168.100.11是k8s的控制节点master1的ip

/etc/kubernetes/manifests/kube-controller-manager.yaml

1
2
3
把--bind-address=127.0.0.1变成--bind-address=192.168.100.11
把httpGet:字段下的hosts由127.0.0.1变成192.168.100.11
把—port=0删除

在所有节点上执行重新启动kubelet服务

1
2
3
4
5
6
7
8
9
10
systemctl restart kubelet 


#查看集群的状态
[root@master1 ~]# kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME STATUS MESSAGE ERROR
controller-manager Healthy ok
scheduler Healthy ok
etcd-0 Healthy {"health":"true"}

5、修改kube-proxy的监听端口

1
[root@master1 ~]# kubectl edit cm kube-proxy -n kube-system

将其中的“metricsBindAddress”改成“**metricsBindAddress:”0.0.0.0:10249”**”,然后保存并退出

重新启动kube-proxy这个pod

1
[root@master1 ~]# kubectl get pods -n kube-system | grep kube-proxy | awk '{print $1}' | xargs kubectl delete pods -n kube-system 

全部的target运行正常

image-20220927223140949

2、配置Alertmanager发送报警到钉钉群组

1、创建钉钉机器人

打开电脑版钉钉,创建一个群,创建自定义机器人,按如下步骤创建

1
https://open.dingtalk.com/document/group/custom-robot-access

我创建的机器人如下:

群设置–>智能群助手–>添加机器人–>自定义–>添加

image-20221005113803054

1
webhook:https://oapi.dingtalk.com/robot/send?access_token=3e1762172067b61bd276bfa0cd32ab98b2e4ad1996b3394e0e472adfad338aa8

2、解压prometheus-webhook-dingtalk-0.3.0.linux-amd64二进制文件

1
[root@master1 ~]# tar -xf prometheus-webhook-dingtalk-0.3.0.linux-amd64.tar.gz 

3、启动钉钉报警插件

1
2
3
4
5
6
7
8
9
#这个操作会生成一个nohup.out的操作日志文件
nohup /usr/local/bin/prometheus-webhook-dingtalk \
--web.listen-address="0.0.0.0:8060" \
--ding.profile="cluster1=https://oapi.dingtalk.com/robot/send? access_token=3e1762172067b61bd276bfa0cd32ab98b2e4ad1996b3394e0e472adfad338aa8"&



[root@master1 system]# netstat -tunpl | grep :8060
tcp6 0 0 :::8060 :::* LISTEN 7369/prometheus-web

4、备份原来的prometheus-cm.yml文件

1
[root@master1 prometheus]# cp alertmanager-cm.yml alertmanager-cm.yml.bak 

5、修改配置文件prometheus-cm.yml并应用配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
[root@master1 prometheus]# cat alertmanager-cm.yml
kind: ConfigMap
apiVersion: v1
metadata:
name: alertmanager
namespace: monitor-sa
data:
alertmanager.yml: |-
global:
resolve_timeout: 1m
smtp_smarthost: 'smtp.163.com:25'
smtp_from: '[email protected]'
smtp_auth_username: '13164377870'
smtp_auth_password: 'DJDDZXJFFTSLRJYG'
smtp_require_tls: false
route: #配置告警分发策略
group_by: [alertname] #采用哪个标签来作为分组依据
group_wait: 10s #组告警等待时间:告警等待10秒,如果有同组告警一并发出
group_interval: 10s #上下两组发送告警的间隔时间
repeat_interval: 10m #重复发送告警的时间,减少相同邮件发送频率,默认是1小时
receiver: cluster1 #定义谁来接受告警
receivers:
- name: 'cluster1'
webhook_configs:
- url: 'http://192.168.106.11:8060/dingtalk/cluster1/send'
send_resolved: true



[root@master1 prometheus]# kubectl apply -f alertmanager-cm.yml
configmap/alertmanager configured

[root@master1 prometheus]# kubectl delete -f prometheus-alertmanager-deploy.yaml
deployment.apps "prometheus-server" deleted
[root@master1 prometheus]# kubectl apply -f prometheus-alertmanager-deploy.yaml
deployment.apps/prometheus-server created

image-20221007103631421

3、配置Alermanager发送报警到微信

4、Prometheus PromQL语法

PromQL(Prometheus Query Language)是 Prometheus 自己开发的表达式语言,语言表现力很丰富,内置函数也很多。使用它可以对时序数据进行筛选和聚合。

1、数据类型

PromQL 表达式计算出来的值有以下几种类型:

瞬间向量(Instant vector):一组时序,每个时序只有一个采样值

区间向量(Range vector):一组时序,每个时序包含一段时间内的多个采样值

标量数据(String):一个字符串,暂时未使用

1、瞬时向量选择器

瞬时向量选择器用来选择一组时序在某个采样点的采样值。
最简单的情况就是指定一个度量指标,选择出所有属于该度量指标的时序的当前采样值。比如下面的表达式:

apiserver_request_total

image-20221008211032331

可以通过在后面添加用大括号包围起来的一组标签键值对来对时序进行过滤。比如下面的表达式筛选出了 job 为 kubernetes-apiservers,并且 resource为 pod的时序:

apiserver_request_total{job=”kubernetes-apiserver”,resource=”pods”}

匹配标签值时可以是等于,也可以使用正则表达式。总共有下面几种匹配操作符:

=:完全相等

!=: 不相等

=~: 正则表达式匹配

!~: 正则表达式不匹配

下面的表达式筛选出了container是kube-scheduler或kube-proxy或kube-apiserver的时序数据

container_processes{container=~”kube-scheduler|kube-proxy|kube-apiserver”}

2、区间向量选择器

区间向量选择器类似于瞬时向量选择器,不同的是它选择的是过去一段时间的采样值。可以通过在瞬时向量选择器后面添加包含在 [] 里的时长来得到区间向量选择器。比如下面的表达式选出了所有度量指标为apiserver_request_total且resource是pod的时序在过去1 分钟的采样值。

image-20221009153919864

这个不支持Graph,需要选择Console,才会看到采集的数据

说明:时长的单位可以是下面几种之一:

s:seconds

m:minutes

h:hours

d:days

w:weeks

y:years

3、偏移向量选择器

前面介绍的选择器默认都是以当前时间为基准时间,偏移修饰器用来调整基准时间,使其往前偏移一段时间。偏移修饰器紧跟在选择器后面,使用 offset 来指定要偏移的量。比如下面的表达式选择度量名称为apiserver_request_total的所有时序在 5 分钟前的采样值

apiserver_request_total{job=”kubernetes-apiserver”,resource=”pods”} offset 5m

下面的表达式选择apiserver_request_total 度量指标在 1 周前的这个时间点过去 5 分钟的采样值。

apiserver_request_total{job=”kubernetes-apiserver”,resource=”pods”} [5m] offset 1w

4、聚合操作符号

PromQL 的聚合操作符用来将向量里的元素聚合得更少。总共有下面这些聚合操作符:

sum:求和

min:最小值

max:最大值

avg:平均值

stddev:标准差

stdvar:方差

count:元素个数

count_values:等于某值的元素个数

bottomk:最小的 k 个元素

topk:最大的 k 个元素

quantile:分位数

如:

计算master1节点所有容器总计内存

sum(container_memory_usage_bytes{instance=~”master1”})/1024/1024/1024

计算master1节点最近1m所有容器cpu使用率

sum (rate (container_cpu_usage_seconds_total{instance=“master1”}[1m])) / sum (machine_cpu_cores{ instance =“master1”}) * 100

计算最近1m所有容器cpu使用率

sum (rate (container_cpu_usage_seconds_total{id!=”/“}[1m])) by (id)

#把id会打印出来

image-20221010100157143

5、函数

Prometheus 内置了一些函数来辅助计算,下面介绍一些典型的。

abs():绝对值

sqrt():平方根

exp():指数计算

ln():自然对数

ceil():向上取整

floor():向下取整

round():四舍五入取整

delta():计算区间向量里每一个时序第一个和最后一个的差值

sort():排序

5、Prometheus监控扩展

1、prometheus采集tomcat日志

1、下载war包和jar包

1
https://note.youdao.com/ynoteshare/index.html?id=0ddfc17eaf7bac94ad4497d7f5356213&type=note

2、制作tomcat镜像

1
2
3
4
5
6
7
8
9
10
11
[root@master1 tomcat]# cat Dockerfile_tomcat_v1 
FROM tomcat
ADD metrics.war /usr/local/tomcat/webapps/
ADD simpleclient-0.8.0.jar /usr/local/tomcat/lib/
ADD simpleclient_common-0.8.0.jar /usr/local/tomcat/lib/
ADD simpleclient_hotspot-0.8.0.jar /usr/local/tomcat/lib/
ADD simpleclient_servlet-0.8.0.jar /usr/local/tomcat/lib/
ADD tomcat_exporter_client-0.0.12.jar /usr/local/tomcat/lib/


[root@master1 tomcat]# docker build -t='zy/tomcat_prometheus:v1' -f=Dockerfile_tomcat_v1 .

3、查看tomcat镜像

1
2
[root@master1 tomcat]# docker images | grep zy
zy/tomcat_prometheus v1 f361fa5d5181 About a minute ago 680MB

4、登录dockerhub仓库

1
2
3
4
5
6
7
[root@master1 tomcat]# docker login 
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

5、上传镜像到dockerhub仓库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@master1 tomcat]# docker push vorabend/tomcat_prometheus:v1 
The push refers to repository [docker.io/vorabend/tomcat_prometheus]
a3c5dda2d577: Pushed
c6c3536d5155: Pushed
5d2adf33b723: Pushed
8af756fc9dff: Pushed
efc436679e04: Pushed
092bc7cd79cd: Pushed
3e2ed6847c7a: Mounted from library/tomcat
bd2befca2f7e: Mounted from library/tomcat
59c516e5b6fa: Mounted from library/tomcat
3bb5258f46d2: Mounted from library/tomcat
832e177bb500: Mounted from library/tomcat
f9e18e59a565: Mounted from library/tomcat
26a504e63be4: Mounted from library/tomcat
8bf42db0de72: Mounted from library/tomcat
31892cc314cb: Mounted from library/tomcat
11936051f93b: Mounted from library/tomcat
v1: digest: sha256:e8c2d36966c2e8132ceed722900eb450e15ec806a8d3a99f6b5cf033186b90ba size: 3673

6、在k8s的node节点拉取镜像

1
2
3
[root@node1 ~]# docker pull vorabend/tomcat_prometheus:v1 
[root@node2 ~]# docker pull vorabend/tomcat_prometheus:v1
[root@node3 ~]# docker pull vorabend/tomcat_prometheus:v1

7、写tomcat_deploy.yml文件,创建pod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[root@master1 tomcat]# cat tomcat_deploy.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-deployment
namespace: default
spec:
selector:
matchLabels:
app: tomcat
replicas: 2
template:
metadata:
labels:
app: tomcat
annotations:
prometheus.io/scrape: 'true'
spec:
containers:
- name: tomcat
image: vorabend/tomcat_prometheus:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
securityContext:
privileged: true


[root@master1 tomcat]# kubectl apply -f tomcat_deploy.yml
deployment.apps/tomcat-deployment created

8、创建service

  • port: 8080 , Service暴露出来的Port
  • nodePort: 31360, Node 暴露出来的Port
  • targetPort: 80, Container上暴露的Port
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@master1 tomcat]# cat tomcat_svc.yml 
apiVersion: v1
kind: Service
metadata:
name: tomcat-service
spec:
selector:
app: tomcat
ports:
- nodePort: 31360
port: 80
protocol: TCP
targetPort: 8080
type: NodePort


[root@master1 tomcat]# kubectl apply -f tomcat_svc.yml

9、开启prometheus的服务自动发现

1
2
[root@master1 tomcat]# kubectl edit pods prometheus-server-d7d996b8-dv5bh -n monitor-sa 
prometheus.io/scrape: "true"

image-20221010221003000

2、prometheus监控redis

1、redis_deploy.yml

redis 这个 Pod 中包含了两个容器,一个就是 redis 本身的主应用,另外一个容器就是 redis_exporter

由于Redis服务的metrics接口在redis-exporter 9121上,所以我们添加了prometheus.io/port=9121这样的annotation,在prometheus就会自动发现redis了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
[root@master1 redis]# cat redis_deploy.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:4
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 6379
- name: redis-exporter
image: oliver006/redis_exporter:latest
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 9121
---
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: kube-system
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9121"
spec:
selector:
app: redis
ports:
- name: redis
port: 6379
targetPort: 6379
- name: prom
port: 9121
targetPort: 9121


[root@master1 redis]# kubectl apply -f redis_deploy.yml

2、测试监控是否正常

1
2
3
4
[root@master1 redis]# curl 10.244.135.7:9121/metrics -I
HTTP/1.1 200 OK
Content-Type: text/plain; version=0.0.4; charset=utf-8
Date: Mon, 10 Oct 2022 14:49:29 GMT

image-20221011100942368

image-20221011103307335

3、Prometheus监控mysql

1、在master1上安装mariadb-server

1
2
3
4
[root@master1 ~]# yum  install mariadb-server.x86_64 -y 

#设置服务下次开机启动
[root@master1 ~]# systemctl enable mariadb --now

2、解压mysqld_exporter压缩包

1
2
3
4
5
6
7
8
[root@master1 redis]# tar -xf mysqld_exporter-0.10.0.linux-amd64.tar.gz

#将二进制文件拷贝到环境变量的目录中去
[root@master1 mysqld_exporter-0.10.0.linux-amd64]# cp -ar mysqld_exporter /usr/local/bin/


#设置二进制文件的可执行权限
[root@master1 ~]# chmod u+x /usr/local/bin/mysqld_exporter

3、登录mysql为mysql_exporter设置账号与权限

1
2
3
4
MariaDB [(none)]> CREATE USER 'mysql_exporter'@'localhost' IDENTIFIED BY 'password';


MariaDB [(none)]> GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'mysql_exporter'@'localhost';

4、创建mysql配置文件,运行时可免密码连接数据库

1
2
3
4
[root@master1 mysqld_exporter-0.10.0.linux-amd64]# cat my.cnf 
[client]
user=mysql_exporter
password=password

5、启动mysql_exporter客户端

mysqld_exporter的监听端口是9104

1
2
3
4
5
[root@master1 mysqld_exporter-0.10.0.linux-amd64]# nohup ./mysqld_exporter --config.my-cnf=./my.cnf &


[root@master1 mysqld_exporter-0.10.0.linux-amd64]# netstat -tunpl | grep :9104
tcp6 0 0 :::9104 :::* LISTEN 18186/./mysqld_expo

6、修改prometheus-alertmanager-cfg.yml

1
2
3
4
5
6
7
8
[root@master1 prometheus]# cat prometheus-alertmanager-cfg.yaml | grep msyql -A2
- job_name: 'msyql'
static_configs:
- targets: ['192.168.106.11:9104']



[root@master1 prometheus]# kubectl apply -f prometheus-alertmanager-cfg.yaml

7、应用配置文件

1
2
3
4
[root@master1 prometheus]# kubectl delete -f prometheus-alertmanager-deploy.yaml 
deployment.apps "prometheus-server" deleted
[root@master1 prometheus]# kubectl apply -f prometheus-alertmanager-deploy.yaml
deployment.apps/prometheus-server created

image-20221011104813605

4、prometheus监控nginx

1、配置nginx-module-vts-master模块

1
2
3
4
[root@node1 prometheus]# unzip nginx-module-vts-master.zip

#将解压出的目录整体移送到/usr/local/下
[root@node1 prometheus]# mv nginx-module-vts-master /usr/local/

2、在node1安装nginx

1
2
3
4
[root@node1 prometheus]# tar -xf nginx-1.15.7.tar.gz 
[root@node1 prometheus]# cd nginx-1.15.7
[root@node1 nginx-1.15.7]# ./configure --prefix=/usr/local/nginx --with-http_gzip_static_module --with-http_stub_status_module --with-http_ssl_module --with-pcre --with-file-aio --with-http_realip_module --add-module=/usr/local/nginx-module-vts-master
[root@node1 nginx-1.15.7]# make && make install

3、修改配置文件

1
2
3
4
5
6
7
8
9
10
[root@node1 nginx-1.15.7]# vim /usr/local/nginx/conf/nginx.conf
#server下添加:
location /status {
vhost_traffic_status_display;
vhost_traffic_status_display_format html;
}


#http下添加:
vhost_traffic_status_zone;

4、测试配置文件是否正确

1
2
3
[root@node1 nginx-1.15.7]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

5、启动nginx

1
[root@node1 nginx-1.15.7]# /usr/local/nginx/sbin/nginx 

6、访问查看监控数据

image-20221017093253475

7、在master1上安装nginx-vts-exporter

1
2
3
4
5
[root@master1 nginx]# unzip nginx-vts-exporter-0.5.zip
[root@master1 nginx]# mv nginx-vts-exporter-0.5 /usr/local/
[root@master1 nginx]# chmod +x /usr/local/nginx-vts-exporter-0.5/bin/nginx-vts-exporter
[root@master1 nginx]# cd /usr/local/nginx-vts-exporter-0.5/bin/
[root@master1 bin]# nohup ./nginx-vts-exporter -nginx.scrape_uri http://192.168.106.21/status/format/json&

nginx-vts-exporter的监听端口是9913

1
2
[root@master1 ~]# netstat -tunpl |grep :9913
tcp6 0 0 :::9913 :::* LISTEN 3873/./nginx-vts-ex

8、修改prometheus-cfg.yaml文件

1
2
3
4
5
#添加如下job_name,targets中的IP为运行nginx-vts-exporter
- job_name: 'nginx'
scrape_interval: 5s
static_configs:
- targets: ['192.168.106.11:9913']

9、应用配置文件

1
2
3
[root@master1 prometheus]# kubectl apply -f  prometheus-cfg.yaml 
[root@master1 prometheus]# kubectl delete -f prometheus-deploy.yml
[root@master1 prometheus]# kubectl apply -f prometheus-deploy.yml

image-20221018093255392

image-20221018093324185

5、prometheus监控mongodb

1
https://note.youdao.com/ynoteshare/index.html?id=39b54acb1fbc0199f966115ce9523bb6&type=note

1、下载mongodb和mongodb_exporter镜像

1
2
[root@master1 ~]# docker pull mongo
[root@master1 ~]# docker pull percona/mongodb_exporter:0.34.0

2、启动mongodb

1
2
3
[root@master1 ~]# mkdir /data/mongodb
[root@master1 ~]# docker run -dt --name mongodb -p 27017:27017 -v /data/mongodb:/data/db mongo
[root@master1 ~]# docker exec -it mongodb /bin/bash

3、登录mongo容器,设置密码

1
2
3
4
5
[root@master1 ~]# docker exec -it mongodb /bin/bash
root@143020f29095:/# mongo admin
> use admin
> db.createUser({ user: 'admin', pwd: 'admin', roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] })
> exit

4、启动mongo_exporter

1
2
[root@master1 prometheus]# docker run -d --name mongodb_exporter -p 30056:9216  percona/mongodb_exporter:0.34.0   --mongodb.uri mongodb://admin:[email protected]:27017
2ca7384506204d23b3880a9e65e69bd0df9df6c52d4f54d62ddae667ef3d0a21

5、查看mongo_exporter是否启动成功

1
2
[root@master1 prometheus]# docker ps  -a | grep mongodb_export
2ca738450620 percona/mongodb_exporter:0.34.0 "/mongodb_exporter -…" About a minute ago Up About a minute 0.0.0.0:30056->9216/tcp, :::30056->9216/tcp mongodb_exporter

6、修改prometheus-cfg.yaml文件

1
2
3
4
5
[root@master1 prometheus]# cat prometheus-cfg.yaml  | grep mongodb -A4
- job_name: 'mongodb'
scrape_interval: 5s
static_configs:
- targets: ['192.168.106.11:30056']

7、应用配置文件

1
2
3
[root@master1 prometheus]# kubectl apply -f prometheus-cfg.yaml 
[root@master1 prometheus]# kubectl delete -f prometheus-deploy.yml
[root@master1 prometheus]# kubectl apply -f prometheus-deploy.yml

image-20221020113357920

6、pushgateway

1、pushgateway简介

Pushgateway是prometheus的一个组件,prometheus server默认是通过exporter主动获取数据(默认采取pull拉取数据),pushgateway则是通过被动方式推送数据到prometheus server,用户可以写一些自定义的监控脚本把需要监控的数据发送给pushgateway, 然后pushgateway再把数据发送给Prometheus server

2、pushgateway的优点

Prometheus 默认采用定时pull 模式拉取targets数据,但是如果不在一个子网或者防火墙,prometheus就拉取不到targets数据,所以可以采用各个target往pushgateway上push数据,然后prometheus去pushgateway上定时pull数据

在监控业务数据的时候,需要将不同数据汇总, 汇总之后的数据可以由pushgateway统一收集,然后由 Prometheus 统一拉取。

3、pushgateway的缺点

Prometheus拉取状态只针对 pushgateway, 不能对每个节点都有效;

Pushgateway出现问题,整个采集到的数据都会出现问题

监控下线,prometheus还会拉取到旧的监控数据,需要手动清理 pushgateway不要的数据。

4、在node1节点上安装pushgateway

1、拉取镜像

1
[root@node1 ~]# docker pull  prom/pushgateway

2、运行pushgateway容器

1
2
[root@node1 ~]# docker run -dt --name pushgateway -p 9091:9091 prom/pushgateway
dcc6ce136668031f422f045a051c9a871dbcf25dfa5514fc4f60810f47632df1

3、测试浏览器访问node1节点的9091端口

image-20221021094601986

4、修改prometheus-alertmanager-cfg.yaml配置文件

1
2
3
4
5
6
[root@master1 prometheus]# cat prometheus-cfg.yaml | grep pushgateway -A4
- job_name: 'pushgateway'
scrape_interval: 5s
static_configs:
- targets: ['192.168.106.21:9091']
honor labels: true

5、应用配置文件

1
2
3
[root@master1 prometheus]# kubectl apply -f prometheus-cfg.yaml
[root@master1 prometheus]# kubectl delete -f prometheus-deploy.yaml
[root@master1 prometheus]# kubectl apply -f prometheus-deploy.yaml

image-20221021110313189

6、推送指定数据格式到pushgateway

1
[root@master1 prometheus]# echo " metric 3.6" | curl --data-binary @- http://192.168.106.21:9091/metrics/job/test_job

注:–data-binary 表示发送二进制数据,注意:它是使用POST方式发送的!

image-20221021110627738

7、测试推送复杂数据

1
2
3
4
5
6
cat << EOF | curl --data-binary @- http://192.168.106.21:9091/metrics/job/test_job/instance/test_instance
#TYPE node_memory_usage gauge
node_memory_usage 36
# TYPE memory_total gauge
node_memory_total 36000
EOF

image-20221021112645162

8、删除某个组下某个实例的所有数据

1
[root@master1 ~]# curl -X DELETE http://192.168.106.21:9091/metrics/job/test_job/instance/test_instance

9、删除某个组下的所有实例

1
[root@master1 ~]# curl -X DELETE http://192.168.106.21:9091/metrics/job/test_job

10、把数据上报到pushgateway

在被监控服务所在的机器配置数据上报,把192.168.106.21这个节点的内存数据上报到pushgateway,下面的步骤需要在192.168.106.21上进行操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#编写pushgateway脚本
[root@node1 ~]# cat pushgateway.sh
#!/bin/bash
node_memory_usages=$(free -m | grep -i mem | awk {'print $3/$2*100'})
job_name="memory"
instance_name=$(hostname)
cat <<EOF | curl --data-binary @- http://192.168.106.21:9091/metrics/job/$job_name/instance/$instance_name
#TYPE node_memory_usages gauge
node_memory_usages $node_memory_usages
EOF


#执行上传脚本
[root@node1 ~]# bash pushgateway.sh
[root@node1 ~]# chmod u+x pushgateway.sh


#设置脚本定期执行,每分钟执行一次
[root@node1 ~]# crontab -l
*/1 * * * * /usr/bin/bash /root/pushgateway.sh

image-20221021223546319

注意:从上面配置可以看到,我们上传到pushgateway中的数据有job也有instance,而prometheus配置pushgateway这个job_name中也有job和instance,这个job和instance是指pushgateway实例本身,添加 honor_labels: true 参数, 可以避免promethues的targets列表中的job_name是pushgateway的 job 、instance 和上报到pushgateway数据的job和instance冲突。