K8s资源限制和Prometheus监控

1、K8s里的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
1、资源清单的编写
[root@master01 kubernetes]# vim limit.yaml
apiVersion: v1
kind: Pod
metadata:
name: resource-demo
spec:
containers:
- name: resource-demo
image: nginx:alpine
imagePullPolicy: IfNotPresent
resources:
#最小的需求
requests:
#内存最小需求
memory: 50Mi
#cpu的最小需求
cpu: 200m
#限制占用磁盘最小需求
#storage: 3Gi
#最大需求
limits:
memory: 100Mi
cpu: 1500m
#storage: 5Gi

2、运行
[root@master01 kubernetes]# kubectl apply -f limit.yaml

参数解释:

1
2
3
requests:节点所需的最小计算资源,k8s调度的时候的依据值

limits:限制允许的最大计算资源,真正的资源限制参数

数值转换:

1
2
3
4
1 CPU = 1000m     m是毫核
0.5 CPU = 500m
1 Mib = 1024 Kib
1 MB = 1000 KB

验证方式:

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
docker inspect 容器ID | grep CgroupParent
cd /sys/fs/cgroup/cpu/kubepods.slice/kubepods-burstable.slice/过滤出来的结果
cat cpu.cfs_quota_us

1、查看起在哪个node
[root@master01 kubernetes]# kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE
resource-demo 1/1 Running 0 4m19s 10.2.3.114 node03


2、查看node03上的容器
[root@node03 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2463239ecc3f c7b4f26a7d93 "/docker-entrypoint.…" 5 minutes ago Up 5 minutes k8s_resource-demo_resource-demo_default_cb221617-6b64-41d8-83de-d1766988dddd_0

[root@node03 ~]# docker inspect 2463239ecc3f | grep CgroupParent
"CgroupParent": "kubepods-burstable-podcb221617_6b64_41d8_83de_d1766988dddd.slice",

[root@node03 ~]# cd /sys/fs/cgroup/cpu/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podcb221617_6b64_41d8_83de_d1766988dddd.slice

[root@node03 kubepods-burstable-podcb221617_6b64_41d8_83de_d1766988dddd.slice]# cat cpu.cfs_quota_us
150000


#如果查看到的结果是-1,就是没做限制
不能盲目的做资源限制,所以要做监控

2、Prometheus的介绍

1
2
3
4
5
6
7
8
9
10
11
   Prometheus是一个开源系统监控和警报工具包,最初是在SoundCloud上构建的。自2012年成立以来,许多公司和组织都采用了Prometheus,该项目拥有非常活跃的开发者和用户社区。

Prometheus现在是一个独立的开源项目,独立于任何公司进行维护。为了强调这一点,并澄清项目的治理结构,Prometheus于2016年加入云原生计算基金会,作为继Kubernetes之后的第二个托管项目。

我们可以简单的理解Prometheus是一个监控系统同时也是一个时间序列数据库。

推荐阅读:
官网地址:https://prometheus.io
官方文档:https://prometheus.io/docs/introduction/overview/
GitHub地址:https://github.com/prometheus
架构图地址:https://prometheus.io/docs/introduction/overview/

3、Prometheus架构

image-20240926113735188

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
如下图所示,展示了普罗米修斯(prometheus)的建筑和它的一些生态系统组成部分。
(1)Prometheus server:
prometheus的服务端,负责收集指标和存储时间序列数据,并提供查询接口。

(2)exporters:
如果想要监控,前提是能获取被监控端数据,并且这个数据格式必须遵循Prometheus数据模型,这样才能识别和采集,一般使用exporter数据采集器(类似于zabbix_agent端)提供监控指标数据。
exporter数据采集器,除了官方和GitHub提供的常用组件exporter外,我们也可以为自己自研的产品定制exporters组件哟。

(3)Pushgateway:
短期存储指标数据,主要用于临时性的任务。比如备份数据库任务监控等。
本质上我们可以理解为Pushgateway可以帮咱们监控自定义的监控项,这需要咱们自己编写脚本来推送到Pushgateway端,而后由Prometheus server从Pushgateway去pull监控数据。
换句话说,请不要被官方的架构图蒙骗了,咱们完全可以基于Pushgateway来监控咱们自定义的监控项哟,这些监控项完全可以是长期运行的呢!

(4)Service discovery:
服务发现,例如我们可以配置动态的服务监控,无需重启Prometheus server实例就能实现动态监控。

(5)Alertmanager:
支持报警功能,比如可以支持基于邮件,微信,钉钉报警。
据网友反馈该组件在生产环境中存在缺陷,因此我们可以考虑使用Grafana来展示并实现报警功能。

(6)Prometheus Web UI
Prometheus比较简单的Web控制台,通常我们可以使用grafana来集成做更漂亮的Web展示哟。
温馨提示:
大多数Prometheus组件都是用Go编写的,这使得它们易于构建和部署为静态二进制文件

4、二进制方式部署Prometheus

环境准备

hostname ip roles 配置(application) 配置
master01 10.0.0.200 / 172.16.1.200 Prometheus服务端 promethues,pushgateway,alertmanager,
node_exporter,cAdVidor,grafana
1h2G
node01 10.0.0.201 / 172.16.1.201 prometheus客户端(收集数据指标) node_exporter,cAdVidor 1h2G
node02 10.0.0.202 / 172.16.1.202 prometheus客户端(收集数据指标) node_exporter,cAdVidor 1h2G
node03 10.0.0.203 / 172.16.1.203 prometheus客户端(收集数据指标) node_exporter,cAdVidor 2h4G

1、下载包

image-20240926155738935

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
pushgateway:自定义监控
alertmanager:告警
node_exporter:master起容器了,apiserver,controller组件都是以容器方式起来的需要监控
cAdVidor:监控容器

https://prometheus.io/download/

1、下载二进制包
版本的选择bata是预上线版本,当前稳定版LTS 生产中最好用文档版的
#下载Prometheus
wget https://github.com/prometheus/prometheus/releases/download/v2.54.1/prometheus-2.54.1.linux-amd64.tar.gz

#下载alertmanager(告警组件)
wget https://github.com/prometheus/alertmanager/releases/download/v0.27.0/alertmanager-0.27.0.linux-amd64.tar.gz

#下载node_exporter(宿主机指标收集器)
wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz

#下载pushgateway(自定义监控组件)
cAdVidor不是自己的组件

2、部署Prometheus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1、安装Prometheus
[root@master01 ~]# tar xf prometheus-2.54.1.linux-amd64.tar.gz -C /app
[root@master01 ~]# mv /app/prometheus-2.54.1.linux-amd64 /app/prometheus-2.54.1
[root@master01 ~]# ln -s /app/prometheus-2.54.1 /app/prometheus
制作好软连接,就安装完成

[root@master01 prometheus-2.54.1]# ll /app/
lrwxrwxrwx 1 root root 22 Sep 26 12:01 prometheus -> /app/prometheus-2.54.1
drwxr-xr-x 4 1001 docker 132 Sep 26 12:44 prometheus-2.54.1
[root@master01 ~]# ll /app/prometheus-2.54.1/
total 265552
drwxr-xr-x 2 1001 docker 38 Aug 27 19:11 console_libraries#库文件
drwxr-xr-x 2 1001 docker 173 Aug 27 19:11 consoles
-rw-r--r-- 1 1001 docker 11357 Aug 27 19:11 LICENSE
-rw-r--r-- 1 1001 docker 3773 Aug 27 19:11 NOTICE
-rwxr-xr-x 1 1001 docker 140096826 Aug 27 18:58 prometheus #启动程序
-rw-r--r-- 1 1001 docker 934 Aug 27 19:11 prometheus.yml #配置文件
-rwxr-xr-x 1 1001 docker 131802216 Aug 27 18:58 promtool

​ Prometheus配置文件解读

image-20240926163353506

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2、修改配置文件
[root@master01 prometheus-2.54.1]# vim prometheus.yml
......
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["10.0.0.200:9090"]
#这里写Prometheus的安装机器的ip:端口

3、查看帮助,查看启动服务都需要哪些参数
[root@master01 prometheus]# /app/prometheus/prometheus --help


4、启动Prometheus
[root@master01 prometheus]# /app/prometheus/prometheus --config.file=/app/prometheus/prometheus.yml &
会有日志输出在终端
#启动之后,这次不需要写systemd脚本管理,这次使用另外一种管理方式supervisor

5、浏览器访问
10.0.0.200:9090

image-20240926164644789

3、二进制安装node_export,并加入Prometheus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1、安装
[root@master01 ~]# tar xf node_exporter-1.8.2.linux-amd64.tar.gz -C /app
[root@master01 app]# mv /app/node_exporter-1.8.2.linux-amd64/ /app/node_exporter-1.8.2
[root@master01 app]# ln -s /app/node_exporter-1.8.2 /app/node_exporter
#这里可以先做第5步,把配置文件改了

2、查看
[root@master01 app]# cd /app/node_exporter
[root@master01 node_exporter]# ll
total 20040
-rw-r--r-- 1 1001 1002 11357 Jul 14 19:57 LICENSE
-rwxr-xr-x 1 1001 1002 20500541 Jul 14 19:54 node_exporter #启动程序文件
-rw-r--r-- 1 1001 1002 463 Jul 14 19:57 NOTICE

3、启动
[root@master01 node_exporter]# /app/node_exporter/node_exporter &
启动,之后,Prometheus挂了

4、浏览器访问
10.0.0.200:9100

image-20240926170004149

image-20240926170140793

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
5、修改配置文件,将node_exporter的信息加入Prometheus
[root@master01 prometheus-2.54.1]# vim prometheus.yml
......
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["10.0.0.200:9090"]
- job_name: "node_exporter"
static_configs:
#写node_exporter的地址和端口
- targets: ["10.0.0.200:9100"]

6、再次重新启动Prometheus
[root@master01 prometheus]# jobs
[1]- Running /app/prometheus/prometheus --config.file=/app/prometheus/prometheus.yml &
[2]+ Running /app/node_exporter/node_exporter & (wd: /app/node_exporter)
[root@master01 prometheus]# kill %1

[root@master01 prometheus]# /app/prometheus/prometheus --config.file=/app/prometheus/prometheus.yml &

7、刷新页面,可以看到node_exporter的节点

image-20240926171311595

4、部署supervisor

node_exporter和Prometheus服务,启停没有使用systemd管理,这次使用supervisor管理服务

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
1、安装supervisor   是python写的
[root@master01 prometheus-2.54.1]# yum -y install supervisor
[root@master01 prometheus]# systemctl start supervisord
[root@master01 prometheus]# systemctl enable supervisord
如果公司有一些前端或者后端的页面要启动都可以放到这里管理


2、查看配置文件
[root@master01 prometheus]# vim /etc/supervisord.conf
[include]
files = supervisord.d/*.ini #子配置文件的写法


3、编写promethues启动脚本
[root@master01 prometheus]# vim /etc/supervisord.d/prome.ini
[program:prometheus]
directory=/app/prometheus/
command=/bin/bash -c "/app/prometheus/prometheus --config.file=/app/prometheus/prometheus.yml"
autostart=true
autorestart=true
stdout_logfile=/var/log/prome_stdout.log
stderr_logfile=/var/log/prome_stderr.log
user=root
stopsignal=TERM
startsecs=5
startretries=3
stopasgroup=true
killasgroup=true

#进程/程序:程序名
[program:prometheus]
#程序的工作目录
directory=/app/prometheus/
#启动命令
command=/bin/bash -c "/app/prometheus/prometheus --config.file=/app/prometheus/prometheus.yml"
#自动启动,可以看做开机自启动,只要superviso启动,他就启动,所以要给superviso设置开机自启动
autostart=true
#自动启动
autorestart=true
#标准输出的日志
stdout_logfile=/var/log/prome_stdout.log
#错误输出的日志
stderr_logfile=/var/log/prome_stderr.log
#程序的启动用户
user=root
#stop的信号是term,kill -l可以看到所有信号,有一个15)的信号 相当于kill -15 进程名,这个是最标准最安全的杀进程
stopsignal=TERM
#启动的超时时间5s,超过5s没起来就是超时
startsecs=5
#重试次数
startretries=3
#如果你的这个脚本停了,这个脚本里面的其他程序也停掉
stopasgroup=true
#这个脚本里面的其中一个服务杀掉,其他服务也杀掉
killasgroup=true



4、需要更新启动脚本,每次更改这个启动脚本都要更新,相当于执行systemctl daemon-reload
[root@master01 prometheus]# supervisorctl update
prometheus: added process group

5、先把后台的2个进程停止掉,
[root@master01 prometheus]# jobs
[2]- Running /app/node_exporter/node_exporter & (wd: /app/node_exporter)
[3]+ Running /app/prometheus/prometheus --config.file=/app/prometheus/prometheus.yml &
[root@master01 prometheus]# kill %1
-bash: kill: %1: no such job
[root@master01 prometheus]# kill %2
[root@master01 prometheus]# kill %3


6、supervisor控制服务的启停
[root@master01 prometheus]# supervisorctl start all
prometheus: started
[root@master01 prometheus]# supervisorctl stop all
prometheus: stopped

或者
[root@master01 prometheus]# supervisorctl stop prometheus
prometheus: stopped
[root@master01 prometheus]# supervisorctl start prometheus
prometheus: started

image-20240926181219003

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
#supervisor的多服务管理
7、编写node_exporter的启动脚本
[root@master01 prometheus]# vim /etc/supervisord.d/prome.ini
[program:prometheus]
...
...
#加入node_exporter的启停止脚本
[program:node_exporter]
directory=/app/node_exporter/
command=/bin/bash -c "/app/node_exporter/node_exporter"
autostart=true
autorestart=true
stdout_logfile=/var/log/node_exporter_stdout.log
stderr_logfile=/var/log/node_exporter_stderr.log
user=root
stopsignal=TERM
startsecs=5
startretries=3
stopasgroup=true
killasgroup=true

8、更新启动脚本
[root@master01 prometheus]# supervisorctl update
node_exporter: added process group
加进去会自动启动,因为写了autostart=true


9、如果使用如下目录,就会2个服务一起启动或停止
[root@master01 prometheus]# supervisorctl stop all
node_exporter: stopped
prometheus: stopped
[root@master01 prometheus]# supervisorctl start all
node_exporter: started
prometheus: started

[root@master01 ~]# supervisorctl status
node_exporter RUNNING pid 33788, uptime 0:05:37
prometheus RUNNING pid 33789, uptime 0:05:37

5、安装pushgateway

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
1、安装
[root@master01 ~]# tar xf pushgateway-1.10.0.linux-amd64.tar.gz -C /app/
[root@master01 ~]# mv /app/pushgateway-1.10.0.linux-amd64/ /app/pushgateway-1.10.0
[root@master01 ~]# ln -s /app/pushgateway-1.10.0/ /app/pushgateway

2、启动命令
[root@master01 ~]# /app/pushgateway/pushgateway

3、修改启动脚本
[root@master01 ~]# vim /etc/supervisord.d/prome.ini
[program:prometheus]
[program:node_exporter]
...
...
#加入pushgateway的启停止脚本
[program:pushgateway]
directory=/app/pushgateway/
command=/bin/bash -c "/app/pushgateway/pushgateway"
autostart=true
autorestart=true
stdout_logfile=/var/log/pushgateway_stdout.log
stderr_logfile=/var/log/pushgateway_stderr.log
user=root
stopsignal=TERM
startsecs=5
startretries=3
stopasgroup=true
killasgroup=true

4、更新启动脚本
[root@master01 prometheus]# supervisorctl update
pushgateway: added process group

[root@master01 ~]# supervisorctl status
node_exporter RUNNING pid 33788, uptime 1:20:01
prometheus RUNNING pid 33789, uptime 1:20:01
pushgateway RUNNING pid 77783, uptime 0:01:20

5、浏览器访问
10.0.0.200:9091

image-20240926195532979

6、部署alertmanager

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1、安装
[root@master01 ~]# tar xf alertmanager-0.27.0.linux-amd64.tar.gz -C /app/
[root@master01 ~]# mv /app/alertmanager-0.27.0.linux-amd64/ /app/alertmanager-0.27.0
[root@master01 ~]# ln -s /app/alertmanager-0.27.0/ /app/alertmanager
[root@master01 ~]# ll /app/alertmanager/
里面有配置文件,但是不需要改

2、查看帮助
[root@master01 ~]# /app/alertmanager/alertmanager --help

3、启动
[root@master01 ~]# /app/alertmanager/alertmanager --config.file=/app/alertmanager/alertmanager.yml

4、浏览器访问
10.0.0.200:9093

image-20240926194338396

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
5、修改启动脚本
[root@master01 ~]# vim /etc/supervisord.d/prome.ini
[program:prometheus]
[program:node_exporter]
...
...
#加入alertmanager的启停止脚本
[program:alertmanager]
directory=/app/alertmanager/
command=/bin/bash -c "/app/alertmanager/alertmanager --config.file=/app/alertmanager/alertmanager.yml "
autostart=true
autorestart=true
stdout_logfile=/var/log/alertmanager_stdout.log
stderr_logfile=/var/log/alertmanager_stderr.log
user=root
stopsignal=TERM
startsecs=5
startretries=3
stopasgroup=true
killasgroup=true

8、更新启动脚本
[root@master01 ~]# supervisorctl update
alertmanager: added process group

[root@master01 ~]# supervisorctl status
alertmanager RUNNING pid 77780, uptime 0:01:20
node_exporter RUNNING pid 33788, uptime 1:20:01
prometheus RUNNING pid 33789, uptime 1:20:01
pushgateway RUNNING pid 77783, uptime 0:01:20

7、3台node节点部署node_exporter

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
-----------#3台都要安装------------------------
1、安装node_exporter
[root@node01 ~]# mkdir /app
[root@node01 ~]# tar xf node_exporter-1.8.2.linux-amd64.tar.gz -C /app
[root@node01 ~]# mv /app/node_exporter-1.8.2.linux-amd64/ /app/node_exporter-1.8.2
[root@node01 ~]# ln -s /app/node_exporter-1.8.2 /app/node_exporter
[root@node01 ~]# cd /app/node_exporter
[root@node01 node_exporter]# ll
total 20040
-rw-r--r-- 1 1001 1002 11357 Jul 14 19:57 LICENSE
-rwxr-xr-x 1 1001 1002 20500541 Jul 14 19:54 node_exporter
-rw-r--r-- 1 1001 1002 463 Jul 14 19:57 NOTICE
[root@node01 node_exporter]# yum -y install supervisor
[root@node01 node_exporter]# systemctl start supervisord
[root@node01 node_exporter]# systemctl enable supervisord

2、编写启动脚本
[root@node01 node_exporter]# vim /etc/supervisord.d/prome.ini
[program:node_exporter]
directory=/app/node_exporter/
command=/bin/bash -c "/app/node_exporter/node_exporter"
autostart=true
autorestart=true
stdout_logfile=/var/log/node_exporter_stdout.log
stderr_logfile=/var/log/node_exporter_stderr.log
user=root
stopsignal=TERM
startsecs=5
startretries=3
stopasgroup=true
killasgroup=true

[root@node01 node_exporter]# supervisorctl update
node_exporter: added process group
[root@node01 node_exporter]# supervisorctl start all
------------------------------------------------

--------------#master操作---------------------
3、#master操作
修改prometheus配置文件,将node_exporter的信息加入Prometheus
[root@master01 prometheus-2.54.1]# vim prometheus.yml
......
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["10.0.0.200:9090"]
- job_name: "node_exporter"
static_configs:
#写node_exporter的地址和端口,将node01 02 03的ip端口添加
- targets: ["10.0.0.200:9100", "10.0.0.201:9100", "10.0.0.202:9100", "10.0.0.203:9100"]

4、重启
[root@master01 prometheus]# supervisorctl restart all

5、访问页面,可以看到node节点都起来了
10.0.0.200:9090

image-20240926210750410

8、3台node节点安装cAdVisor

1
2
3
4
5
1、3台node节点拉取cadvisor镜像
docker pull google/cadvisor:latest

2、运行镜像
[root@node01 ~]# docker run --volume=/:/rootfs:ro --volume=/var/run:/var/run:rw --volume=/sys:/sys:ro --volume=/data/cadvisor:/var/lib/docker.io --publish=8080:8080 --detach=true --name=cadvisor google/cadvisor:latest

5、Prometheus自动发现——file-sd(文件发现)

1、先把Prometheus收集到的node节点在Prometheus的配置文件里面删除

1
2
3
4
5
6
7
8
9
10
11
1、修改配置文件
[root@master01 prometheus-2.54.1]# vim prometheus.yml
......
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["10.0.0.200:9090"]
- job_name: "node_exporter"
static_configs:
#改回只获取master01的
- targets: ["10.0.0.200:9100"]

2、修改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
1、修改配置文件
[root@master01 prometheus]# vim prometheus.yml
scrape_configs:
.....
#添加自动发现规则
- job_name: "prome_file_sd"
file_sd_configs:
- files:
- /app/prometheus/file_sd/agent.yml
refresh_interval: 5s


2、创建文件发现配置存放目录
[root@master01 prometheus]# mkdir -p /app/prometheus/file_sd

3、编辑文件发现的配置文件
以后可能像pushgateway也要加进来
[root@master01 prometheus]# vim /app/prometheus/file_sd/agent.yml
[
{
"targets": ["10.0.0.201:9100","10.0.0.202:9100","10.0.0.203:9100"],
"labels": {
"agent": "node_exporter"
}
},
{
"targets": ["10.0.0.201:8080","10.0.0.202:8080","10.0.0.203:8080"],
"labels": {
"agent": "cAdVisor"
}
}
]

2、重启Prometheus
[root@master01 prometheus]# supervisorctl restart all

image-20240927135935380

6、Prometheus数据格式

①、Prometheus指标类型

image-20240927100110091

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#数据描述
# 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"} 335802.19 #空闲
node_cpu_seconds_total{cpu="0",mode="iowait"} 115.16 #等待
node_cpu_seconds_total{cpu="0",mode="irq"} 0 #
node_cpu_seconds_total{cpu="0",mode="nice"} 3.2
node_cpu_seconds_total{cpu="0",mode="softirq"} 602.95
node_cpu_seconds_total{cpu="0",mode="steal"} 0
node_cpu_seconds_total{cpu="0",mode="system"} 11580.34 #内核态
node_cpu_seconds_total{cpu="0",mode="user"} 8994.06 #用户态

#cpu2个核心的
node_cpu_seconds_total{cpu="1",mode="idle"} 337368.67
node_cpu_seconds_total{cpu="1",mode="iowait"} 10.91
node_cpu_seconds_total{cpu="1",mode="irq"} 0
node_cpu_seconds_total{cpu="1",mode="nice"} 3.41
node_cpu_seconds_total{cpu="1",mode="softirq"} 520.71
node_cpu_seconds_total{cpu="1",mode="steal"} 0
node_cpu_seconds_total{cpu="1",mode="system"} 11293.66
node_cpu_seconds_total{cpu="1",mode="user"} 9194.18
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、gauge:瞬时值,当前最新的值 #(常用的)
比如收集用户最新的登录数量
Gauges是最简单的度量指标,只有一个简单的返回值,或者叫瞬时状态。
例如:我们想衡量一个待处理队列中任务的个数,这个个数是会变化的。
当我们要监控硬盘容量或者内存的使用量,那么就应该使用Gauges的metrics格式来衡量,因为硬盘的容量或者内存的使用量是随时间的推移,不断瞬时且无规则变化的。
这种变化没有规律,当前是多少,采集回来的就是多少。


2、counter:计数器类型 #(常用的)
Counters就是计数器,从数据量0开始积累计算,在理想情况下,只能是永远的增长,不会降低(一些特殊情况另说,比如说粉丝数,未必就是只增不减.)。
比如统计一小时,一天,一周,一个月的用户的访问量,这就是一个累加的操作。


3、histograms:统计数据的发布情况。比如最小值,最大值,中间值,还有中位数 (很少用)

# 举个例子:
如果我们想通过监控的方式抓取当天nginx的access.log,并且想监控用户的访问服务出现的故障时间,我们应该怎么做呢?
# 错误解决方案
把日志每行的"http_response_time"数值统统采集下来,然后计算一下总的平均值。这是毫无意义的,因为故障发生时间可能只有一小段时间,比如网络延迟放生在12:30-12:40之间,其它时间都是正常的,如果计算总的平均值,则结果看起来会很正常,无法触发报警功能,运维人员可能也不知道这件事情发生了。
# 正确解决方案:
通过Histograms函数,可以分别统计出全部用户的响应时间在0.05秒,1秒,2秒,5秒,10秒的量。这样运维人员就能根据这个值进行报警,分析这些时间的产生原因,从而避免以后类似的问题发生。


4、summary:相当于升级版的histograms
因为histogram在客户端就是简单的分桶计数,在prometheus服务端基于这么有限的数据做百分位估算,所以的确不是很准确,summary就是解决百分位准确的问题而来的。
我们可以简单理解summary是Histogram的扩展类型,如果想要清除的了解histograms和summary的更多细节,可自行查阅相关的文档。

②、指标数据格式

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
#数据描述
# 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"} 335802.19
node_cpu_seconds_total{cpu="0",mode="iowait"} 115.16
node_cpu_seconds_total{cpu="0",mode="irq"} 0
node_cpu_seconds_total{cpu="0",mode="nice"} 3.2
node_cpu_seconds_total{cpu="0",mode="softirq"} 602.95
node_cpu_seconds_total{cpu="0",mode="steal"} 0
node_cpu_seconds_total{cpu="0",mode="system"} 11580.34
node_cpu_seconds_total{cpu="0",mode="user"} 8994.06
node_cpu_seconds_total{cpu="1",mode="idle"} 337368.67
node_cpu_seconds_total{cpu="1",mode="iowait"} 10.91
node_cpu_seconds_total{cpu="1",mode="irq"} 0
node_cpu_seconds_total{cpu="1",mode="nice"} 3.41
node_cpu_seconds_total{cpu="1",mode="softirq"} 520.71
node_cpu_seconds_total{cpu="1",mode="steal"} 0
node_cpu_seconds_total{cpu="1",mode="system"} 11293.66
node_cpu_seconds_total{cpu="1",mode="user"} 9194.18


key:node_cpu_seconds_total{cpu="0",mode="idle"}
value:335802.19

#指标数据格式就是如下:
1、要有一行描述
2、要有一行指标类型定义
3、真实数据(数据格式是Key value)

以后自定义监控收集到的数据要组成key value的形式

③、PromeQL查询结果的类型

1
2
3
4
5
6
7
8
9
10
11
12
PromQL的表达式中支持一下4种数据类型
1、即时向量(Instant Vector):
特定或全部的时间序列集合上,具有相同时间戳的一组样本称为即时向量。

2、范围向量(Range Vector):
特定或全部的时间序列集合上,在指定的同一范围内的所有样本值

3、标量(Scalar):
一个浮点型的数据值。带小数点的

4、字符串(String):
支持使用单引号,双引号或反引号进行引用,但反引号中不会转移字符进行转义

1、即时向量

image-20240927151046205

这些数据在同一时刻,同一秒,汇成一台线的数据值,叫即时向量,每一个指标在同一个时间点获取到的数据值

2、范围向量 比如从10点~11点查出来的结果集

③、Prometheus常用的函数

1、increase函数

1
2
3
4
5
6
7
8
9
10
11
12
13
increase函数:求指定时间内的增量
在prometheus中是用来针对Counter这种持续增长的数值,截取其中的一段时间的增量。

#举个例子:
increase(node_cpu_seconds_total[1m]):
获取CPU总使用时间在1分钟内的增量,计算的是1分钟内增加的总量。
在实际工作中,我们的服务器通常是多核的,因此这个采集的是所有核心的值哟。
increase(node_cpu_seconds_total{instance="10.0.0.101:9100"}[100m]):
我们也可以借助标签选择器过滤查看某个服务器实例的配置.


cpu 1分钟的增长量
increase(node_cpu_seconds_total{instance='10.0.0.202:9100',job='prome_file_sd',mode='system'}[1m])

image-20240927102930773

image-20240927153951299

2、sum函数

1
2
3
4
5
6
7
8
9
sum函数: 主要是起到加和的作用。

#举个例子:
sum(increase(node_cpu_seconds_total[1m])):
sum(increase(node_cpu_seconds_total{job='prome_file_sd',mode='system'}[1m]))
"increase(node_cpu[1m])"外面套用一个sum函数就可以把所有CPU核心数在1分钟内的增量做一个累加。


sum(increase(node_cpu_seconds_total{instance='10.0.0.202:9100',job='prome_file_sd',mode='system'}[1m]))

image-20240927103557200

3、by函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
by函数:
将数据进行分组,类似于MySQL的"group by"


#举个例子:
by (instance):
这里的"instance"代表的是机器名称,意思是将数据按照instance标签进行强行拆分。
该函数通常会和sum函数搭配使用,比如"(sum(increase(node_cpu_seconds_total[1m]))by (instance))",表示把sum函数中累加和按照"instance"(机器名称)强行拆分成多组数据。当然,如果只有一个机器名称的话,你会发现只有一组数据,因此从结果上可能看不到明显的变化哟。

温馨提示:
instance是node_exporter内置的标签,当然,我们也可以自定义标签,比如根据生产环境中不同的集群添加相应的标签。比如基于自定义的"cluster_name"标签进行分组等。


sum(increase(node_cpu_seconds_total{job='prome_file_sd',mode='system'}[1m]))by(instance)

sum(increase(node_cpu_seconds_total{agent='node_exporter',mode='system'}[1m])) by(instance)

image-20240927104801961

4、rate函数

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
rate函数:
它的功能是按照设置的一个时间段,取counter在这个时间段中的平均每秒的增量。因此是专门搭配counter类型数据使用的函数。

#举个例子:
rate(node_cpu_seconds_total[1m]):
获取CPU总使用时间在1分钟内的增加的总量并除以60秒,计算的是每秒的增量。

rate(node_network_receive_bytes_total[1m]):
获取一分钟内网络接收的总量。
查看的时间越短,某一瞬间的突起或降低在成图的时候会体现的更细致,更敏感。

rate(node_network_receive_bytes_total[20m])
获取二十分钟内网络接收的总量。
查看的时间越长,那么当发生瞬间的突起或降低时候,会显得平缓一些,因为取得时间段越长会把波峰波谷都给平均消下去了。


#increase函数和rate函数如此相似如何选择?
(1)对于采集频率较低的数据采用建议使用increase函数,因为使用rate函数可能会出现断点(比如按照5分钟采样数据量较小的场景,以采集硬盘可用容量为例,可能会出现某次采集数据未采集到的情况,因为会按照平均每秒来计算最终的增量)的情况;

(2)对于采集频率较高的数据采用建议使用rate函数,比如对CPU,内存,网络流量等都可以基于rate函数来采样,当然,硬盘也是可以用rate函数来采样的哟;
温馨提示:

在实际工作中,我们取监控频率为1分钟还是5分钟这取决与我们对于监控数据的敏感程度来挑选。



rate(node_cpu_seconds_total{agent='node_exporter',mode='system'}[1m])

image-20240927105435679

5、irate函数

1
2
3
4
5
6
7
8
9
  irate函数:主要用于计算向量(通常是Counter类型的时间序列)在每个时间范围内的每秒瞬时增长率。与rate函数不同,irate特别关注于时间范围内的最后两个数据点,通过这两个点的差值除以它们之间的时间差来得到瞬时增长率。这种方式使得irate在捕捉快速变化或波动较大的数据时更加敏感。


#举个例子:
假设有一个名为http_requests_total的Counter类型时间序列,记录了HTTP请求的总数。要计算过去5分钟内每秒的HTTP请求瞬时增长率,可以使用以下PromQL表达式:
irate(http_requests_total[5m])


irate(node_cpu_seconds_total{agent='node_exporter',mode='system'}[1m])

image-20240927105526235

6、topk函数

1
2
3
4
5
6
7
8
9
10
11
12
topk函数:
取top榜的前n名。实际使用的时候一般会用该函数进行瞬时报警,而不是为了观察曲线图。

#举个例子:
topk(3,rate(node_cpu_seconds_total[1m])):
获取CPU总使用时间在1分钟内的增加的总量并除以60秒,计算的是每秒的数量。并只查看top3。

温馨提示:
我们通常使用topk只会关注"Console"中的瞬时结果,不太会关心Graph的出图效果,因为关注他并没有太大意义,存在太多的断点啦!
如果出图会出现中断的情况,是因为在xx分钟内这一刻的数据其并没有排进top3,自然就会出现断点的状况

topk(10,rate(node_cpu_seconds_total{agent='node_exporter'}[1m]))

image-20240927161431883

7、count函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
count(container_last_seen{instance='10.0.0.201:8080',image!=''})

count函数:
把数值符合条件的,输出数目进行累计加和。一般用它进行一些模糊的监控判断。
比如说企业中有100台服务器,那么只有10台服务器CPU使用率高于80%的时候,这个时候不需要报警,当符合80%CPU的服务器数量超过70台的时候那么就触发报警。

#举个例子:
count(aaa_tcp_wait_conn > 500):
我们假设aaa_tcp_wait_conn是咱们自定义的KEY,上述案例是找出当前(或者历史的)当前TCP等待数大于500的机器数量。


#统计node01上有多少台容器
image!='' image不等于空的就是容器

count统计他有多少行
count(container_last_seen{instance='10.0.0.201:8080',image!=''})

image-20240927162241644

函数练习:

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
1、计算各节点的CPU的总使用率,参考公式:100%-(CPU空闲时间/总时间)
(1)我们需要先找到查看CPU的key名称
node_cpu_seconds_total

(2)按机器分组,计算出每个机器的空闲时间
sum(node_cpu_seconds_total{mode='idle'})by(instance)

(3)按机器分组,计算出每个机器的总时间
sum(node_cpu_seconds_total) by(instance)


(4)CPU空闲时间/总时间=空闲率
sum(node_cpu_seconds_total{mode='idle'})by(instance)/sum(node_cpu_seconds_total) by(instance)

(5)每台机器的CPU的总使用率
1-(sum(node_cpu_seconds_total{mode='idle'})by(instance)/sum(node_cpu_seconds_total) by(instance))


2、计算用户态的CPU使用率
sum(node_cpu_seconds_total{mode='user'})by(instance)/sum(node_cpu_seconds_total) by(instance)

3、计算内核态的CPU使用率
sum(node_cpu_seconds_total{mode='system'})by(instance)/sum(node_cpu_seconds_total) by(instance)

4、计算IO等待的CPU使用率
sum(node_cpu_seconds_total{mode='iowait'})by(instance)/sum(node_cpu_seconds_total) by(instance)

7、使用pushgateway自定义监控

pushgateway介绍

1
2
3
4
5
使用脚本监控将数据推送到pushgateway上,Promethues从pushgateway中拉取数据 (可以把pushgateway当初Prometheus的客户端,Prometheus也是拉取数据)

它是可以单独运行在任何节点(不一定是在被监控客户端)上的插件,然后通过用户自定义开发脚本把需要监控的数据发送给pushgateway,再由pushgateway暴露http接口,而后由把prometheus server去pull数据。

pushgateway组件本身是没有任何抓取监控数据功能的,它只能被动的等待监控数据被推送过来。

Prometheus关联pushgateway

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
#方法一:修改Prometheus配置文件
[root@master01 prometheus]# vim prometheus.yml
scrape_configs:
.....
#添加自动发现规则
- job_name: "prome_file_sd"
file_sd_configs:
- files:
- /app/prometheus/file_sd/agent.yml
refresh_interval: 5s

2、重启Prometheus
[root@master01 prometheus]# supervisorctl restart all


#方法二:编辑文件发现的配置文件
以后可能像pushgateway也要加进来
[root@master01 prometheus]# vim /app/prometheus/file_sd/agent.yml
[
.....
{
"targets": ["10.0.0.200:9091"],
"labels": {
"agent": "pushgateway"
}
}
]

#不需要重启

image-20240930182759622

pushgateway的优缺点

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
pushgateway默认会有一些数据,并不多,主要是自定义,我们自定义数据要写脚本,只要能写脚本获取到的数据都可以监控


#优点:
灵活性更强。

#缺点:
(1)存在单点瓶颈,假如有多个脚本同时发给一个pushgateway进程,如果该pushgateway进程挂掉了,那么监控数据也就没了。
(2)pushgateway并不能对发送过来的脚本采集数据进行更智能的判断,假如脚本中间采集出了问题,那么有问题的数据pushgateway组件会照单全收发送给Prometheus server。(也就是说他不能做判断,收集到啥就传啥,所以写的脚本一定要精确)


温馨提示:
对于缺点一,建议大家在生产环境中多开启几个pushgateway进程,前面加个负载均衡,以便于备份使用。
如果使用负载均衡,配置文件的写法是:
[root@master01 prometheus]# vim /app/prometheus/file_sd/agent.yml
[
.....
{
"targets": ["用域名或者负载均衡的ip:9091"],
"labels": {
"agent": "pushgateway"
}
}
]
对于缺点二,建议大家在编写脚本时要注意业务逻辑,尽可能避免脚本出错的情况发生。

单个数据自定义监控——用户登录数量

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
#首先你想监控哪台机器,就把脚本写在哪个机器上

1、编写自定义监控——用户登录数量的脚本
[root@node03 ~]# vim user_count.sh
#!/bin/bash
#获取主机名hostname -s短的主机名 hostname长的主机名
INSTANCE_NAME=$(hostname -s)
#判断如果是没有修改主机名就报错
if [ "$INSTANCE_NAME" == "localhost" ];then
echo "必须要完整的主机名"
exit
fi

#定义Prometheus抓取到的监控项的key名字,
METRICS_NAME="user_count"
#获取用户的登录数量(监控项的值的获取)
USER_COUNT_VALUE=$(uptime |grep -Po '[0-9]+(?= user)')
#发送数据 把echo的内容交给curl --data-binary 发送二进制的数据,后面的路径可以自定义
echo "$METRICS_NAME $USER_COUNT_VALUE" |curl --data-binary @- http://10.0.0.200:9091/metrics/job/sh_job/instance/$INSTANCE_NAME


2、执行脚本
[root@node03 ~]# sh user_count.sh

3、查看页面
10.0.0.200:9091

image-20240930202019536

首先图中的数据类型是 UNTYPED 我并没有定义数据类型的,查看数据指标10.0.0.200:9091/metric,他自己加的untype

image-20240930203034740

Prometheus查看数据

image-20240930202427231

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
user_count{agent="pushgateway", exported_instance="node03", exported_job="sh_job", instance="10.0.0.200:9091", job="prome_file_sd"}   显示的结果是自定义的



上面提到过
#指标数据格式就是如下:
1、要有一行描述
2、要有一行指标类型定义
3、真实数据(数据格式是Key value)
#数据描述
# HELP node_cpu_seconds_total Seconds the CPUs spent in each mode.
#数据类型 (指标类型)
# TYPE key名字 counter
node_cpu_seconds_total{cpu="0",mode="idle"} 335802.19


4、修改脚本,定义数据类型,并加上循环
[root@node03 ~]# vim user_count.sh
#!/bin/bash
while true;do
#获取主机名hostname -s短的主机名 hostname长的主机名
INSTANCE_NAME=$(hostname -s)
#判断如果是没有修改主机名就报错
if [ "$INSTANCE_NAME" == "localhost" ];then
echo "必须要完整的主机名"
exit
fi

#定义Prometheus抓取到的监控项的key名字,
METRICS_NAME="user_count"
#获取用户的登录数量(监控项的值的获取)
USER_COUNT_VALUE=$(uptime |grep -Po '[0-9]+(?= user)')
#发送数据 把echo的内容交给curl --data-binary 发送二进制的数据,后面的路径可以自定义 \n回车 gauge:瞬时值,当前最新的值
echo -e "# TYPE ${METRICS_NAME} gauge\n$METRICS_NAME $USER_COUNT_VALUE" |curl --data-binary @- http://10.0.0.200:9091/metrics/job/sh_job/instance/$INSTANCE_NAME
sleep 1
done



5、由于脚本里面写了死循环,不能直接执行脚本,可以用supervisor去管理
以后所以得监控脚本都可以放这里,所有的监控项都可以起来
[root@node03 ~]# vim /etc/supervisord.d/push.ini
[program:user_count]
#这里建议脚本建一个目录存放
directory=/root
command=/bin/bash -c "/bin/sh /root/user_count.sh"
autostart=true
autorestart=true
stdout_logfile=/var/log/node_exporter_stdout.log
stderr_logfile=/var/log/node_exporter_stderr.log
user=root
stopsignal=TERM
startsecs=5
startretries=3
stopasgroup=true
killasgroup=true
[root@node03 ~]# supervisorctl update
[root@node03 ~]# supervisorctl restart all
[root@node03 ~]# supervisorctl status
node_exporter RUNNING pid 8440, uptime 1 day, 12:35:41
user_count RUNNING pid 107360, uptime 0:02:39


6、验证是否运行
多开几个终端,去Prometheus里面查询数据

image-20240930212805096

1
2
3
4
5
6
#命令行简历监控数据
echo -e "# TYPE key名字 gauge\nkey名字 value" |curl --data-binary @- http://10.0.0.200:9091/metrics/job/项目名/instance/主机名

[root@node03 ~]# echo -e "# TYPE aaa gauge\naaa 111" |curl --data-binary @- http://10.0.0.200:9091/metrics/job/aaa/instance/node03

数据指标中就会生成aaa的key

image-20240930224338728

image-20240930224429624

多个数据自定义监控——监控容器运行时间

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
获取cadvisor的运行时间
[root@node03 ~]# docker inspect -f '{{.State.StartedAt}}' cadvisor
2024-09-30T10:06:13.136629499Z
[root@node03 ~]# docker inspect -f '{{.State.StartedAt}}' cadvisor
2024-09-30T10:06:13.136629499Z
[root@node03 ~]# docker inspect -f '{{.State.StartedAt}}' cadvisor
2024-09-30T10:06:13.136629499Z
[root@node03 ~]# date +%s -d 2024-09-30T10:06:13.136629499Z
1727690773
[root@node03 ~]# date +%s
1727708230
[root@node03 ~]# let res=1727708230-1727690773
[root@node03 ~]# echo $res
17457
[root@node03 ~]# python
>>> 17457/60/60
4

echo """# TYPE ${metrics_name} gauge
# HELP ${metrics_name} time sec""" > docker_temp.log

1、编写多个数据自定义监控——监控容器运行时间的脚本
[root@node03 ~]# vim runtime.sh
#!/bin/bash

while true;do
#获取主机名hostname -s短的主机名 hostname长的主机名
instance_name=$(hostname -s)
metrics_name=docker_runtime
#判断如果是没有修改主机名就报错
if [ "$instance_name" == "localhost" ];then
echo "必须要完整的主机名"
exit
fi

#获取所以运行容器的名称 {{.Names}}相当于金甲模版的调用变量
allname=$(docker ps --format "{{.Names}}")

function docker_run(){
#获取各个容器的启动时间
start_time=$(docker inspect -f '{{.State.StartedAt}}' $1)
#将时间转换位时间戳
time1=$(date +%s -d "$start_time")
#获取当前的时间戳
time2=$(date +%s)
#计算运行时间
let tt=$time2-$time1
echo $tt
return $tt
}

# 将需要往pushgateway上传的数据写入"docker_temp.log"文件
echo "# TYPE ${metrics_name} gauge" > docker_temp.log
echo "# HELP ${metrics_name} time sec" >> docker_temp.log

for i in ${allname};do
start_time=$(docker_run $i)
echo "$metrics_name{name=\"$i\",aaa=\"xxx\"} $start_time" >> docker_temp.log # 格式化写入数据
done

# 修改地址和参数名向特定的url上传数据,数据在doceker_temp.log文件中
#curl 二进制 @文件名 把个文件里面的内容交给后面的url
curl --data-binary "@docker_temp.log" http://10.0.0.200:9091/metrics/job/docker_runtime/instance/$instance_name

#情况临时文件
#rm -rf docker_temp.log
sleep 1
done

2、将脚本加入supervisor
[root@node03 ~]# vim /etc/supervisord.d/push.ini
[program:docker_runtime]
directory=/root
command=/bin/bash -c "/bin/sh /root/runtime.sh"
autostart=true
autorestart=true
stdout_logfile=/var/log/node_exporter_stdout.log
stderr_logfile=/var/log/node_exporter_stderr.log
user=root
stopsignal=TERM
startsecs=5
startretries=3
stopasgroup=true
killasgroup=true
[root@node03 ~]# supervisorctl update
[root@node03 ~]# supervisorctl status
docker_runtime RUNNING pid 29434, uptime 0:00:07
node_exporter RUNNING pid 8372, uptime 5:48:45
user_count RUNNING pid 8374, uptime 5:48:45

3、浏览器访问
10.0.0.200:9091 10.0.0.200:9091/metrics

image-20241001220001771

image-20241001220252497

Prometheus查看数据

image-20241001220418085

1
验证没问题之后,把脚本发送给其他node节点,并执行,就可以获取到数据了

监控内存使用率 (这个是自带的,不需要写脚本,直接可以查出来)

1
2
参考案例:
(1 - (node_memory_Buffers_bytes + node_memory_Cached_bytes + node_memory_MemFree_bytes) / node_memory_MemTotal_bytes) * 100

image-20241001223311889

监控硬盘的使用情况 (这个是自带的,不需要写脚本,直接可以查出来)

1
2
3
4
5
6
参考案例:
(node_filesystem_free_bytes / node_filesystem_size_bytes) < 0.95

温馨提示:
(1)生产环境中建议大家将0.95改为0.20,表示当空闲硬盘小于20%的时候就显示在图上;
(2)我之所以写0.95是因为我的空闲硬盘挺大的,为了让大家看到出图的效果而已。

image-20241001223441812

监控硬盘I/O使用情况 (这个是自带的,不需要写脚本,直接可以查出来)

1
2
3
4
5
参考案例:
rate(node_network_transmit_bytes_total[1m]) / 1024 / 1024

node_network_transmit_bytes_total:
网络传输字节数。

image-20241001223636224

监控文件描述符

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
参考案例:
(node_filefd_allocated / node_filefd_maximum) * 100


node_filefd_allocated:
已分配的文件描述符。


node_filefd_maximum:
一个进程运行最大打开文件描述符的总量。

(1)编写脚本
[root@docker201 ~]# vim network_delay.sh
#!/bin/bash
#instance_name=`hostname -i` # 该指令要求hosts文件必须有解析
instance_name=$(hostname -s)

# 要求机器名不能是"localhost"不然标签就没有区分了
if [ $instance_name == "localhost" ];then
echo "Must FQDN hostname"
exit
fi

# 指定需要ping的主机
monitoring_site="www.aaa.com"
# 获取丢包率相关字段
# -q:
# 安静模式ping,即不输出每次ping的返回的中间结果,仅返回最终的结果。
# -A:
# 启用并行的ping效果,可以加快ping的处理过程。
# -s:
# 一个ping包的大小。
# -W:
# 执行ping命令最大的延迟等待时间(timeout),以ms为单位。
# -c:
# 发送多少个数据包。
package_loss_rate=`timeout 5 ping -q -A -s 500 -W 1000 -c 100 $monitoring_site |
grep transmitted | awk '{print $6}'`

# 获取延迟情况的相关字段(本质上是执行ping命令所耗费的时间哟~)
delay_time=`timeout 5 ping -q -A -s 500 -W 1000 -c 100 $monitoring_site | grep transmitted | awk '{print $10}'`

# 获取数字类型
package_loss_rate_number=`echo $package_loss_rate | sed "s/%//g"`
delay_time_number=`echo $delay_time | sed "s/ms//g"`
# 将数据上传到pushgateway
echo "sh_linux_package_loss_rate_$instance_name $package_loss_rate_number" | curl --data-binary @-
http://docker201.zls.com:9091/metrics/job/zls_linux_package_loss_rate/instance/localhost:9092
echo "sh_linux_delay_time_$instance_name $delay_time_number" | curl --data-binary @- http://docker201.zls.com:9091/metrics/job/zls_linux_package_loss_rate/instance/localhost:9092


(2)编写周期性任务
[root@docker201~]# crontab -l
...
*/10 * * * * /root/network_delay.sh


(3)在Prometheus server中查看KEY
sh_linux_package_loss_rate_docker201
sh_linux_delay_time_docker201
温馨提示:
(1)对于较多的网络监控我建议还是使用专业的smokeping监控系统,尤其是在IDC公司,smokeping基本上是必用软件哟。

8、使用alertmanager告警

1、修改配置文件(配置报警媒介类型)

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
1、先停掉alertmanager
[root@master01 kubernetes]# supervisorctl stop alertmanager

2、修改配置文件,配置报警媒介类型
[root@master01 kubernetes]# vim /app/alertmanager/alertmanager.yml
global:
resolve_timeout: 5m
smtp_from: 'xxx@qq.com'
smtp_smarthost: 'smtp.qq.com:465'
smtp_auth_username: 'xxxx@qq.com'
smtp_auth_password: 'xxxgreaga'
smtp_require_tls: false
smtp_hello: 'qq.com'
route:
group_by: ['alertname']
group_wait: 5s
group_interval: 5s
repeat_interval: 5m
receiver: 'email'
receivers:
- name: 'email'
email_configs:
- to: 'xxx85@qq.com'
send_resolved: true
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']


相关参数说明
global:
#解析超时时间
resolve_timeout: 5m
#发件人邮箱地址
smtp_from: 'xxxxxxxx@qq.com'
#邮箱的服务器的地址及端口,例如: 'smtp.qq.com:465'
smtp_smarthost: 'smtp.qq.com:465'
#发送人的邮箱用户名
smtp_auth_username: 'xxxxxxxx@qq.com'
#发送人的邮箱的授权码
smtp_auth_password: 'xxxxxxxxxxxxxxx'
#是否基于tls加密
smtp_require_tls: false
#邮箱服务器,例如: 'qq.com'
smtp_hello: 'qq.com'
route:
#重复报警的间隔时间,如果没有解即报警问题,则会间隔指定时间一直触发报警,比如:5m
group_by: ['alertname']
group_wait: 5s
group_interval: 5s
repeat_interval: 5m
#采用什么方式接收报警,例如'email'
receiver: 'email'
receivers:
#定义接收者的名称,注意这里的name要和上面的route对应,例如: 'email'
- name: 'email'
email_configs:
#邮箱发给谁
- to: 'xxxxxxxx@qq.com'
send_resolved: true
inhibit_rules:
- source_match:
#匹配报警级别,例如: 'critical'
severity: 'critical'
target_match:
#只要是warning就报警
severity: 'warning'
equal: ['alertname', 'dev', 'instance']


3、启动alertmanager
[root@master01 kubernetes]# supervisorctl start alertmanager

2、配置让Prometheus关联alertmanager

1
2
3
4
5
6
7
8
9
10
[root@master01 kubernetes]# vim /app/prometheus/prometheus.yml 
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
#这里写alertmanager的安装地址
- 10.0.0.200:9093

[root@master01 kubernetes]# supervisorctl restart prometheus

3、配置触发器

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
1、配置触发器规则存放目录
#一个触发器,一个文件
[root@master01 kubernetes]# vim /app/prometheus/prometheus.yml
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
#配置触发器规则存放目录
- "/app/prometheus/alertmanager/user_count.yml"
#- "second_rules.yml"

[root@master01 kubernetes]# supervisorctl restart prometheus


2、创建存放目录
[root@master01 kubernetes]# mkdir -p /app/prometheus/alertmanager/

3、编写触发器规则文件
[root@master01 kubernetes]# vim /app/prometheus/alertmanager/user_count.yml
groups:
- name: user-count
rules:
- alert: user-count
expr: user_count > 3
for: 15s
labels:
severity: 1
team: node
annotations:
summary: "{{ $labels.exported_instance }} 登录用户数量超过 3!"

#参数解释
groups:
#名字自定义
- name: user-count
rules:
#告警信息,user-count的值的key
- alert: user-count
#expr: key名字{job="xxx"} == 3
expr: user_count == 3
for: 15s
labels:
severity: 1
team: node
annotations:
#exported_instance是获取机器的ip
summary: "{{ $labels.exported_instance }} 登录用户数量超过 3!"

image-20241002124047891

4、测试,node03多开几个终端,浏览器访问10.0.0.200:9093,查看有报警信息,就可以查看邮箱,会收到报警邮件

image-20241002145740578

image-20241002145916255

5、当登录用户数量少于3个时间,也会发恢复的邮件

image-20241002150222081

9、K8s部署Prometheus的资源清单——这个是部署在容器里面

1、ConfigMap 资源

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
cat > prom-cm.yaml <<EOF
---
apiVersion: v1
kind: Namespace
metadata:
name: prom-config
namespace: prom
---
apiVersion: v1
kind: ConfigMap
metadata:
name: prom-config
namespace: prom
data:
prometheus.yml: |
#全局配置
global:
scrape_interval: 15s #抓取数据间隔时间
scrape_timeout: 15s #抓取数据超时时间
scrape_configs: #抓取配置
#任务名称
- job_name: "prometheus"
#静态配置
static_configs:
#抓取数据节点的IP端口,起在容器里面,只能写localhost
- targets: ["localhost:9090"]
EOF


#如果要添加客户端,就要edit这个资源清单,添加客户端

2、PV和PVC资源

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
1、你要安装在哪台机器,就先创建挂载目录,因为下面使用的是local
mkdir /data/k8s/prometheus

2、资源清单
cat > prom-pv-pvc.yaml <<EOF
apiVersion: v1
kind: PersistentVolume
metadata:
name: prom-localhost
labels:
app: prometheus
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
storageClassName: local-storage
local:
path: /data/k8s/prometheus
#这里是亲和性
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
#In,就是主机名包含node,都起
operator: In
values:
#- 你想安装在哪台机器,就写他的主机名
- node03
persistentVolumeReclaimPolicy: Retain
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: prom-data
namespace: prom
spec:
selector:
matchLabels:
app: prometheus
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: local-storage
EOF

3、RBAC 权限资源

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
cat > prom-rbac.yml <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: prometheus
namespace: prom
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prometheus
rules:
- apiGroups:
- ""
resources:
- nodes
- services
- endpoints
- pods
- nodes/proxy
verbs:
- get
- list
- watch
- apiGroups:
- "extensions"
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
- nodes/metrics
verbs:
- get
- nonResourceURLs:
- /metrics
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prometheus
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus
subjects:
- kind: ServiceAccount
name: prometheus
namespace: prom
EOF

4、Deployment 资源

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
cat > prom-dp.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus
namespace: prom
labels:
app: prometheus
spec:
selector:
matchLabels:
app: prometheus
template:
metadata:
labels:
app: prometheus
spec:
serviceAccountName: prometheus
volumes:
- name: data
persistentVolumeClaim:
claimName: prom-data
- name: config-volume
configMap:
name: prom-config
initContainers:
- name: fix-permissions
image: busybox
command: [chown, -R, "nobody:nobody", /prometheus]
volumeMounts:
- name: data
mountPath: /prometheus
containers:
- name: prometheus
image: prom/prometheus:v2.24.1
args:
- "--config.file=/etc/prometheus/prometheus.yml" # 配置文件路径
- "--storage.tsdb.path=/prometheus" # 数据保存路径
- "--storage.tsdb.retention.time=24h" # 数据保留,默认15天
- "--web.enable-admin-api" # 控制对admin HTTP API访问
- "--web.enable-lifecycle" # 支持热更新
ports:
- containerPort: 9090
volumeMounts:
- name: config-volume
mountPath: /etc/prometheus
- name: data
mountPath: /prometheus
resources:
requests:
cpu: 100m
memory: 512Mi
limits:
cpu: 100m
memory: 512Mi
EOF

5、Service资源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cat > prom-svc.yaml <<EOF
apiVersion: v1
kind: Service
metadata:
name: prometheus
namespace: prom
labels:
app: prometheus
spec:
selector:
app: prometheus
ports:
- name: web
port: 9090
targetPort: 9090
type: ClusterIP
EOF

6、ingress资源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
cat > prom-ingress.yaml <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prometheus
namespace: prom
labels:
app: prometheus
spec:
rules:
- host: prom.drz.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: prometheus
port:
number: 9090
EOF

7、安装完成,应该是起到node03上的

1
2
3
4
5
1、物理机做域名解析
10.0.0.203 prom.drz.com

浏览器访问域名
prom.drz.com