前言

使用docker部署Prometheus+Grafana+Alertmanager监控系统,并集成钉钉告警

环境准备

(1)使用脚本安装docker、docker-compose

1
bash <(wget -qO- https://xuanyuan.cloud/docker.sh)

(2)配置镜像加速

1
2
3
4
5
6
7
8
vi /etc/docker/daemon.json

{
"data-root": "/data/dockerData",
"registry-mirrors": ["https://docker.1ms.run"],
"log-driver":"json-file",
"log-opts":{"max-size" :"50m","max-file":"3"}
}

(3)启动docker服务,验证docker版本

1
2
3
4
systemctl restart docker
systemctl enable docker
systemctl status docker
docker --version && docker compose version

(4)创建所需目录和文件

1
2
3
mkdir -p /data/scripts /data/alertmanager /data/grafana /data/notice /data/prometheus /data/grafana/data
mkdir -p /data/prometheus/config /data/prometheus/config/rules /data/prometheus/pstorage
touch /data/prometheus/config/prometheus.yml

(5)编写Prometheus配置文件prometheus.yml(注意修改IP)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
vi /data/prometheus/config/prometheus.yml

*****************************************************
global:
scrape_interval: 15s
evaluation_interval: 15s

alerting:
alertmanagers:
- static_configs:
- targets:
- "本机IP:9093"

rule_files:
- "rules/*.yml"

scrape_configs:

- job_name: prometheus
static_configs:
- targets: ['localhost:9090']
labels:
instance: prometheus
*****************************************************

(6)编写Alertmanager的配置文件alertmanager.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
vi /data/alertmanager/alertmanager.yml

*****************************************************
global:
resolve_timeout: 5m

route:
group_by: ['alertname']
group_wait: 30s
group_interval: 1m
repeat_interval: 5m
receiver: 'dingtalk.webhook1'
routes:
- receiver: "dingtalk.webhook1"
match_re:
alertname: ".*"
continue: true

receivers:
- name: 'dingtalk.webhook1'
webhook_configs:
- url: 'http://本机ip:8060/dingtalk/webhook1/send'
send_resolved: true

inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname','instance']
*****************************************************

(7)创建临时Grafana容器,提取grafana.ini文件

1
2
3
docker run -d --name=grafana grafana/grafana
docker cp grafana:/etc/grafana/grafana.ini /data/grafana/data/grafana.ini
docker rm -f grafana

集成钉钉告警

(1)在要添加告警通知的钉钉群里选择自定义钉钉机器人。

(2)在添加机器人的安全设置中勾选加签,并将密钥保存(可选自定义关键词)。

(3)完成创建后,复制Webhook地址保存。

(4)创建钉钉告警模板

模板default0.tmpl

配置文件

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
vi /data/notice/default0.tmpl

*****************************************************
{{ define "__subject" }}
[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}]
{{ end }}

{{ define "__severity_icon" }}
{{ if eq .Labels.severity "严重" }}🔴{{ else if eq .Labels.severity "警告" }}🟠{{ else if eq .Labels.severity "提示" }}🟡{{ else }}⚪️{{ end }}
{{ end }}

{{ define "__alert_list" }}{{ range . }}
---

{{ if .Labels.owner }}@{{ .Labels.owner }} {{ end }}

{{ template "__severity_icon" . }} `告警主题`: {{ .Annotations.summary }}

> `告警类型`: {{ .Labels.alertname }}
> `告警级别`: {{ .Labels.severity }}
> `告警来源`: 【{{ .Labels.instance }}】
> `告警信息`: {{ index .Annotations "description" }}

⏱ `触发时间`: {{ dateInZone "2006-01-02 15:04:05" (.StartsAt) "Asia/Shanghai" }}
{{ end }}{{ end }}


{{ define "__resolved_list" }}{{ range . }}
---

{{ if .Labels.owner }}@{{ .Labels.owner }} {{ end }}

🟢 `恢复主题`: {{ .Annotations.summary }}

> `告警类型`: {{ .Labels.alertname }}
> `告警级别`: {{ .Labels.severity }}
> `告警来源`: 【{{ .Labels.instance }}】

⏱ `故障时长`: {{ dateInZone "15:04:05" (.StartsAt) "Asia/Shanghai" }} ~ {{ dateInZone "15:04:05" (.EndsAt) "Asia/Shanghai" }}
{{ end }}{{ end }}


{{ define "default.title" }}
{{ template "__subject" . }}
{{ end }}

{{ define "default.content" }}
{{ if gt (len .Alerts.Firing) 0 }}

**==== 🚨 侦测到 {{ .Alerts.Firing | len }} 个故障 ====**

{{ template "__alert_list" .Alerts.Firing }}

{{ end }}

{{ if gt (len .Alerts.Resolved) 0 }}

---

**==== ✅ 恢复 {{ .Alerts.Resolved | len }} 个故障 ====**

{{ template "__resolved_list" .Alerts.Resolved }}

{{ end }}
{{ end }}


{{ define "ding.link.title" }}{{ template "default.title" . }}{{ end }}
{{ define "ding.link.content" }}{{ template "default.content" . }}{{ end }}
{{ template "default.title" . }}
{{ template "default.content" . }}
*****************************************************

效果图

模板default1.tmpl

配置文件

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
vi /data/notice/default1.tmpl

*****************************************************
{{ define "__subject" }}
[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}]
{{ end }}


{{ define "__alert_list" }}{{ range . }}
---

{{ if .Labels.owner }}@{{ .Labels.owner }}{{ end }}

**告警主题**: {{ .Annotations.summary }}

**告警类型**: {{ .Labels.alertname }}

**告警级别**: {{ .Labels.severity }}

**告警来源**: {{ .Labels.instance }}

**告警信息**: {{ index .Annotations "description" }}

**告警时间**: {{ dateInZone "2006.01.02 15:04:05" (.StartsAt) "Asia/Shanghai" }}
{{ end }}{{ end }}

{{ define "__resolved_list" }}{{ range . }}
---

{{ if .Labels.owner }}@{{ .Labels.owner }}{{ end }}

**告警主题**: {{ .Annotations.summary }}

**告警类型**: {{ .Labels.alertname }}

**告警级别**: {{ .Labels.severity }}

**告警来源**: {{ .Labels.instance }}

**告警信息**: {{ index .Annotations "description" }}

**告警时间**: {{ dateInZone "2006.01.02 15:04:05" (.StartsAt) "Asia/Shanghai" }}

**恢复时间**: {{ dateInZone "2006.01.02 15:04:05" (.EndsAt) "Asia/Shanghai" }}
{{ end }}{{ end }}


{{ define "default.title" }}
{{ template "__subject" . }}
{{ end }}

{{ define "default.content" }}
{{ if gt (len .Alerts.Firing) 0 }}
**====侦测到{{ .Alerts.Firing | len }}个故障====**

{{ template "__alert_list" .Alerts.Firing }}
---

{{ end }}

{{ if gt (len .Alerts.Resolved) 0 }}
**====恢复{{ .Alerts.Resolved | len }}个故障====**
{{ template "__resolved_list" .Alerts.Resolved }}
{{ end }}
{{ end }}


{{ define "ding.link.title" }}{{ template "default.title" . }}{{ end }}
{{ define "ding.link.content" }}{{ template "default.content" . }}{{ end }}
{{ template "default.title" . }}
{{ template "default.content" . }}

*****************************************************

效果图

(5)创建钉钉告警配置文件config.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
vi  /data/notice/config.yml

*****************************************************
templates: #模板文件路径
- /etc/prometheus-webhook-dingtalk/default0.tmpl


targets:
webhook1:
url: 钉钉机器人Webhook地址
secret: 密钥

*****************************************************

部署Prometheus

撰写docker compose文件,创建Prometheus、Grafana、Alertmanager、Prometheus-webhook-dingtalk容器。

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
vi /data/scripts/pga.yml

*****************************************************
services:
prometheus:
image: prom/prometheus
container_name: prometheus
restart: always
user: "0"
volumes:
- /data/prometheus/config:/etc/prometheus/
- /data/prometheus/pstorage:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
ports:
- "9090:9090"
networks:
net:
ipv4_address: 172.20.112.11

grafana:
image: grafana/grafana
container_name: grafana
restart: always
user: "0"
volumes:
- /data/grafana/data:/var/lib/grafana
- /data/grafana/data/grafana.ini:/etc/grafana/grafana.ini
environment:
- GF_USERS_ALLOW_SIGN_UP=false #禁止新用户注册
ports:
- "3000:3000"
networks:
net:
ipv4_address: 172.20.112.12

alertmanager:
image: prom/alertmanager
container_name: alertmanager
restart: always
volumes:
- /data/alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml
command:
- '--config.file=/etc/alertmanager/alertmanager.yml'
ports:
- "9093:9093"
networks:
net:
ipv4_address: 172.20.112.13


dingtalk-webhook:
image: timonwong/prometheus-webhook-dingtalk
container_name: dingtalk-webhook
restart: always
volumes:
- /data/notice:/etc/prometheus-webhook-dingtalk
ports:
- "8060:8060"
networks:
net:
ipv4_address: 172.20.112.14


networks:
net:
driver: bridge
ipam:
config:
- subnet: 172.20.112.0/24

*****************************************************

(4)执行命令,创建容器

1
docker compose -f /data/scripts/pga.yml up -d

(5)允许端口通过防火墙

1
2
3
firewall-cmd --permanent --add-port={9090,3000,9093,8060}/tcp
firewall-cmd --reload
firewall-cmd --list-all

(6)访问系统web界面

名称访问地址备注
Prometheushttp://本机IP:9090
Grafanahttp://本机IP:3000默认账户:admin默认密码:admin
Alertmanagerhttp://本机IP:9093

配置Grafana

(1)修改默认语言;在Administration-General-Default preferences-Language选项中,选择语言为中文(简体),保存设置即可。

(2)集成Prometheus;在连接-添加新连接中搜索Prometheus,选择Prometheus数据源,点击添加新数据源,在设置页填写Prometheus的访问地址,点击保存并测试,提示Successfully queried the Prometheus API.,即为连接成功。

(3)选择仪表板-新建-Import dashboard,添加对应监控服务的仪表板:

Linux主机模板选择推荐ID:16098

Windows主机模板选择推荐ID:16523

blackbox_exporter模板选择推荐ID:14792

安装node_exporter

(1)下载node_exporter

1
wget https://github.com/prometheus/node_exporter/releases/download/v1.11.1/node_exporter-1.11.1.linux-amd64.tar.gz

(2)创建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
tar -vzxf node_exporter-1.11.1.linux-amd64.tar.gz
mv node_exporter-1.11.1.linux-amd64/node_exporter /usr/local/bin
chmod +x /usr/local/bin/node_exporter
chown root:root /usr/local/bin/node_exporter

# 修改文件的 SELinux 安全上下文为标准二进制文件 context
chcon -t bin_t /usr/local/bin/node_exporter
vi /etc/systemd/system/node-exporter.service

[Unit]
Description=Node Exporter for Prometheus
Documentation=https://prometheus.io/docs/guides/node-exporter/
After=network.target

[Service]
User=root
Group=root
Type=simple
ExecStart=/usr/local/bin/node_exporter \
--web.listen-address=0.0.0.0:9100 \
--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($|/) \
--no-collector.ipvs

[Install]
WantedBy=multi-user.target

(3)启动node_exporter服务

1
2
3
4
systemctl daemon-reload
systemctl start node-exporter
systemctl enable node-exporter
systemctl status node-exporter

(4)允许端口通过防火墙

1
2
3
firewall-cmd --permanent --add-port=9100/tcp
firewall-cmd --reload
firewall-cmd --list-all

(5)编写告警规则文件

node_alived.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
vi /data/prometheus/config/rules/node_alived.yml

*****************************************************
groups:
- name: 主机宕机报警规则
rules:
- alert: 主机宕机告警
expr: up == 0
for: 1m
labels:
severity: '严重'
annotations:
summary: "主机宕机告警"
description: "主机 【{{ $labels.instance }}】 已经宕机,宕机已超过 1 分钟"
*****************************************************

linux.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
vi /data/prometheus/config/rules/linux.yml

*****************************************************
groups:
- name: Linux基础资源报警规则
rules:
- alert: LinuxCPU使用率告警
expr: 100 - (avg by (instance)(irate(node_cpu_seconds_total{mode="idle"}[1m]))) * 100 > 95
for: 2m
labels:
severity: '警告'
annotations:
summary: "主机 【{{ $labels.instance }}】CPU使用率正在飙升。"
description: "主机 【{{ $labels.instance }}】CPU使用率超过95%(当前值:{{ $value | printf \"%.2f\" }}%)"

- alert: Linux磁盘使用率告警
expr: (1 - (node_filesystem_avail_bytes{fstype=~"xfs|ext4"} / node_filesystem_size_bytes{fstype=~"xfs|ext4"})) * 100 > 90
for: 2m
labels:
severity: '严重'
annotations:
summary: "主机 【{{ $labels.instance }}】 磁盘空间不足"
description: "主机 【{{ $labels.instance }}】分区 {{ $labels.mountpoint }} (设备: {{ $labels.device }}) 使用率大于 90%,当前值:{{ $value | printf \"%.1f\" }}%"

- alert: Linux内存使用率异常告警
expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 95
for: 2m
labels:
severity: '警告'
annotations:
summary: "主机 【{{ $labels.instance }}】Linux服务器可用内存不足。"
description: "主机 【{{ $labels.instance }}】内存使用率异常已超过95%(当前值:{{ $value | printf \"%.2f\" }}%)"

- alert: Linux网卡接收流量过高
expr: sum by (instance, device) (rate(node_network_receive_bytes_total{device!~"lo|veth.*|docker.*|br-.*"}[1m])) * 8 > 80000000
for: 1m
labels:
severity: '警告'
annotations:
summary: "主机 【{{ $labels.instance }}】 网卡 【{{ $labels.device }}】 接收流量过高"
description: "主机 【{{ $labels.instance }}】 网卡 【{{ $labels.device }}】 持续1分钟接收速率超过 10MB/s(当前值:{{ $value | printf \"%.2f\" }} bps)"

- alert: Linux网卡发送流量过高
expr: sum by (instance, device) (rate(node_network_transmit_bytes_total{device!~"lo|veth.*|docker.*|br-.*"}[1m])) * 8 > 80000000
for: 1m
labels:
severity: '警告'
annotations:
summary: "主机 【{{ $labels.instance }}】 网卡 【{{ $labels.device }}】 发送流量过高"
description: "主机 【{{ $labels.instance }}】 网卡 【{{ $labels.device }}】 持续1分钟发送速率超过 10MB/s(当前值:{{ $value | printf \"%.2f\" }} bps)"

- alert: Linux网卡接收流量异常飙升
expr: predict_linear(node_network_receive_bytes_total{device!~"lo|veth.*|docker.*|br-.*"}[5m], 60) * 8 > 80000000 and on(instance, device) rate(node_network_receive_bytes_total{device!~"lo|veth.*|docker.*|br-.*"}[1m]) * 8 > 8000000
for: 3m
labels:
severity: '严重'
annotations:
summary: "主机 【{{ $labels.instance }}】 【网卡 {{ $labels.device }}】 接收流量异常飙升"
description: "主机 【{{ $labels.instance }}】 【网卡 {{ $labels.device }}】 流量在3分钟内急剧上升,预测1分钟后将超过10MB/s,可能存在异常业务或DDoS攻击。(当前预测值:{{ $value | printf \"%.2f\" }} bps)"

- alert: Linux网卡状态异常
expr: node_network_operstate{device!~"lo|veth.*|docker.*|br-.*", operstate!="up"} == 1
for: 1m
labels:
severity: '严重'
annotations:
summary: "主机 【{{ $labels.instance }}】 【网卡 {{ $labels.device }}】 状态异常"
description: "主机 【{{ $labels.instance }}】 【网卡 {{ $labels.device }}】 当前状态为 {{ $labels.operstate }},非 up 状态,可能导致网络中断。"
*****************************************************

(6)将要监控的Linux主机加入prometheus.yml

1
2
3
4
5
- job_name: node-exporter
static_configs:
- targets: ['xxxx:9100']
labels:
instance: xxxx

安装windows_exporter

(1)在要监控的Windows系统下载windows_exporter

1
https://github.com/prometheus-community/windows_exporter/releases/download/v0.31.7/windows_exporter-0.31.7-amd64.msi

(2)编写告警规则文件windows.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
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
vi /data/prometheus/config/rules/windows.yml

*****************************************************
groups:
- name: Windows基础资源报警规则
rules:
# -------------------------
# 内存告警 (使用物理内存剩余率)
# -------------------------

- alert: Windows内存严重不足告警
expr: (1 - (windows_cs_physical_memory_available_bytes / windows_cs_physical_memory_total_bytes)) * 100 > 95
for: 3m
labels:
severity: '警告'
annotations:
summary: "节点 【{{ $labels.instance }}】 内存即将耗尽"
description: "节点 【{{ $labels.instance }}】 的内存使用率已达到 {{ $value | printf \"%.1f\" }}%,系统可能面临 OOM 风险!"

# -------------------------
# 系统盘 (C盘) 空间告警
# -------------------------

- alert: Windows系统盘空间耗尽
expr: (1 - (windows_logical_disk_free_bytes{volume="C:"} / windows_logical_disk_size_bytes{volume="C:"})) * 100 > 90
for: 3m
labels:
severity: '严重'
annotations:
summary: "节点 【{{ $labels.instance }}】 系统盘【C盘】即将耗尽"
description: "节点 【{{ $labels.instance }}】 的 【C】 盘使用率高达 {{ $value | printf \"%.1f\" }}%,系统或程序可能无法正常运行!"

# -------------------------
# 其他数据盘空间告警 (排除C盘)
# -------------------------
- alert: Windows数据盘空间不足
expr: (1 - (windows_logical_disk_free_bytes{volume!="C:"} / windows_logical_disk_size_bytes{volume!="C:"})) * 100 > 90
for: 3m
labels:
severity: '严重'
annotations:
summary: "节点 【{{ $labels.instance }}】 数据盘【{{ $labels.volume }}】空间不足"
description: "节点 【{{ $labels.instance }}】 的 【{{ $labels.volume }}】 盘使用率已达到 {{ $value | printf \"%.1f\" }}%。"

# -------------------------
# CPU 告警
# -------------------------
- alert: WindowsCPU使用率过高
expr: 100 - (avg by(instance) (rate(windows_cpu_time_total{mode="idle"}[2m])) * 100) > 95
for: 3m
labels:
severity: '警告'
annotations:
summary: "节点 【{{ $labels.instance }}】 CPU使用率过高"
description: "节点 【{{ $labels.instance }}】 的 CPU 使用率已达到 {{ $value | printf \"%.1f\" }}%,持续 3 分钟。请检查是否有异常进程。"

# -------------------------
# 磁盘 I/O 延迟告警 (可选,针对高IO业务)
# -------------------------
- alert: Windows磁盘IO延迟过高
expr: rate(windows_logical_disk_read_seconds_total[5m]) + rate(windows_logical_disk_write_seconds_total[5m]) > 0.05
for: 3m
labels:
severity: '警告'
annotations:
summary: "节点 【{{ $labels.instance }}】 磁盘 【{{ $labels.volume }}】 IO延迟过高"
description: "节点 【{{ $labels.instance }}】 的 【{{ $labels.volume }}】 盘平均 IO 延迟超过 50ms (当前: {{ $value | printf \"%.2f\" }}s),可能存在磁盘性能瓶颈。"


# -------------------------
# 网卡接收流量过高
# -------------------------
- alert: Windows网卡接收流量过高
expr: sum by (instance, nic) (rate(windows_net_bytes_received_total{nic!~"isatap.*|VPN.*|Loopback.*|.*Virtual.*"}[1m])) * 8 > 80000000
for: 1m
labels:
severity: '警告'
annotations:
summary: "节点 【{{ $labels.instance }}】 网卡 【{{ $labels.nic }}】 接收流量过高"
description: "节点 【{{ $labels.instance }}】 网卡 【{{ $labels.nic }}】 持续1分钟接收速率超过 10MB/s(当前值:{{ $value | printf \"%.2f\" }} bps)"

# -------------------------
# 网卡发送流量过高
# -------------------------
- alert: Windows网卡发送流量过高
expr: sum by (instance, nic) (rate(windows_net_bytes_sent_total{nic!~"isatap.*|VPN.*|Loopback.*|.*Virtual.*"}[1m])) * 8 > 80000000
for: 1m
labels:
severity: '警告'
annotations:
summary: "节点 【{{ $labels.instance }}】 网卡 【{{ $labels.nic }}】 发送流量过高"
description: "节点 【{{ $labels.instance }}】 网卡 【{{ $labels.nic }}】 持续1分钟发送速率超过 10MB/s(当前值:{{ $value | printf \"%.2f\" }} bps)"

# -------------------------
# 网卡接收流量异常飙升
# 使用 predict_linear 预测未来1分钟流量,并增加当前基线判断,防止误报
# -------------------------
- alert: Windows网卡接收流量异常飙升
expr: predict_linear(windows_net_bytes_received_total{nic!~"isatap.*|VPN.*|Loopback.*|.*Virtual.*"}[5m], 60) * 8 > 80000000
and on (instance, nic)
rate(windows_net_bytes_received_total{nic!~"isatap.*|VPN.*|Loopback.*|.*Virtual.*"}[1m]) * 8 > 8000000
for: 3m
labels:
severity: '严重'
annotations:
summary: "节点 【{{ $labels.instance }}】 网卡 【{{ $labels.nic }}】 接收流量异常飙升"
description: "节点 【{{ $labels.instance }}】 网卡 【{{ $labels.nic }}】 流量在3分钟内急剧上升,预测1分钟后将超过10MB/s,可能存在异常业务或网络攻击。"

# -------------------------
# 网卡状态异常
# -------------------------
- alert: Windows网卡状态异常
expr: windows_net_adapter_info{nic!~"isatap.*|VPN.*|Loopback.*|.*Virtual.*", net_connection_status!="2"} == 1
for: 1m
labels:
severity: '严重'
annotations:
summary: "节点 【{{ $labels.instance }}】 网卡 【{{ $labels.nic }}】 状态异常"
description: "节点 【{{ $labels.instance }}】 网卡 【{{ $labels.nic }}】 当前状态码为 {{ $labels.net_connection_status }} (非2/已连接),可能导致网络中断。"
*****************************************************

(3)将要监控的Windows主机加入prometheus.yml

1
2
3
4
5
- job_name: windows
static_configs:
- targets: ['xxxx:9182']
labels:
instance: xxxx

安装blackbox_exporter

(1)下载blackbox_exporter

1
wget https://github.com/prometheus/blackbox_exporter/releases/download/v0.28.0/blackbox_exporter-0.28.0.linux-amd64.tar.gz

(2)创建blackbox_exporter服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
tar -xf blackbox_exporter-0.28.0.linux-amd64.tar.gz -C /usr/local/bin/
mv /usr/local/bin/blackbox_exporter-0.28.0.linux-amd64 /usr/local/bin/blackbox_exporter
vi /etc/systemd/system/blackbox-exporter.service

[Unit]
Description=blackbox-exporter
After=network.target

[Service]
User=root
Group=root
Type=simple
ExecStart=/usr/local/bin/blackbox_exporter/blackbox_exporter --config.file=/usr/local/bin/blackbox_exporter/blackbox.yml
Restart=on-failure

[Install]
WantedBy=multi-user.target

(3)启动blackbox_exporter服务

1
2
3
4
systemctl daemon-reload
systemctl start blackbox-exporter
systemctl enable blackbox-exporter
systemctl status blackbox-exporter

(4)允许端口通过防火墙

1
2
3
firewall-cmd --permanent --add-port=9115/tcp
firewall-cmd --reload
firewall-cmd --list-all

(5)编写告警规则文件blackbox.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
vi /data/prometheus/config/rules/blackbox.yml

*****************************************************
groups:
- name: 应用服务监控规则
rules:
- alert: 应用服务访问异常
expr: probe_success == 0
for: 10s
annotations:
summary: "{{ $labels.group }}应用服务访问异常{{ $labels.instance }}"
description: "{{ $labels.group }}应用服务 【{{ $labels.instance }}】访问不可用,状态异常或连接失败"
labels:
severity: '严重'
- alert: 应用服务访问响应时间>10s
expr: probe_duration_seconds >= 10
for: 30s
annotations:
summary: "{{ $labels.group }}应用服务响应异常{{ $labels.instance }}"
description: "{{ $labels.group }}应用服务 【{{ $labels.instance }}】访问缓慢,响应时间超过10秒"
labels:
severity: '警告'
*****************************************************

(6)将要监控的应用服务加入到prometheus.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
 # 网站监控
- job_name: 'http_status'
metrics_path: /probe
params:
module: [http_2xx]
static_configs:
- targets:
- http://xxxx:8080
- http://xxxx
labels:
group: web
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 本机IP:9115

# ping 检测
- job_name: 'ping_status'
metrics_path: /probe
params:
module: [icmp]
static_configs:
- targets:
- xxxx
labels:
group: 'icmp'
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 本机IP:9115

# 端口监控
- job_name: 'port_status'
metrics_path: /probe
params:
module: [tcp_connect]
static_configs:
- targets:
- xxxx:8080
labels:
group: 'port'
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 本机IP:9115

安装vmware_exporter监控ESXi

(1)在/data/scripts/目录下创建.env文件,存储环境变量

1
2
3
4
5
VSPHERE_HOST=地址
VSPHERE_USER=用户名
VSPHERE_PASSWORD=密码
VSPHERE_IGNORE_SSL=True
VSPHERE_SPECS_SIZE=2000

(2)在/data/scripts/pga.yml文件中添加vmware_exporter的容器构建片段

1
2
3
4
5
6
7
8
9
10
11
vmware-exporter:
image: pryorda/vmware_exporter
container_name: vmware-exporter
ports:
- "9272:9272"
env_file:
- ./.env
restart: always
networks:
net:
ipv4_address: 172.20.112.15

(3)创建容器,允许端口通过防火墙

1
2
3
firewall-cmd --permanent --add-port=9272/tcp
firewall-cmd --reload
firewall-cmd --list-all

创建完成后,浏览器输入http://本机IP:9272/metrics,访问服务是否正常运行

(4)编写告警规则文件vmware.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
vi /data/prometheus/config/rules/vmware.yml

*****************************************************
groups:
- name: ESXi基础资源报警规则
rules:
# ESXi主机宕机
- alert: ESXi主机宕机
expr: vmware_host_power_state == 0
for: 1m
labels:
severity: '严重'
annotations:
summary: "ESXi主机 【{{ $labels.instance }}】 已离线"
description: "ESXi主机 【{{ $labels.instance }}】 已经宕机,宕机已超过 1 分钟。"

# 虚拟机已关闭
- alert: ESXi虚拟机已关闭
expr: vmware_vm_power_state == 0
for: 1m
labels:
severity: '警告'
annotations:
summary: "ESXi主机 【{{ $labels.instance }}】的虚拟机【{{ $labels.vm_name }}】已关闭"
description: "ESXi主机 【{{ $labels.instance }}】的虚拟机【'{{ $labels.vm_name }}'】的当前电源状态为关闭,且已持续 1 分钟。请检查是否为意外宕机或计划内关机。"

# ESXi数据存储空间不足(使用率超过90%)
- alert: ESXi数据存储空间不足
expr: (1 - vmware_datastore_freespace_size / vmware_datastore_capacity_size) * 100 > 90
for: 5m
labels:
severity: '警告'
annotations:
summary: "ESXi主机 【{{ $labels.instance }}】 的数据存储 【{{ $labels.ds_name }}】 空间不足"
description: "ESXi主机 【{{ $labels.instance }}】 的数据存储 '【{{ $labels.ds_name }}】' 使用率已达 {{ $value | humanize }}%,请及时清理或扩容。"

# 虚拟机CPU使用率持续过高
- alert: ESXi虚拟机CPU使用率过高
expr: vmware_vm_cpu_usage_average / 100 > 95
for: 5m
labels:
severity: '警告'
annotations:
summary: ESXi主机 【{{ $labels.instance }}】的虚拟机 【{{ $labels.vm_name }}】的CPU 使用率过高"
description: "ESXi主机 【{{ $labels.instance }}】的虚拟机 '【{{ $labels.vm_name }}】'的CPU使用率持续5分钟超过95%,当前值: {{ $value | humanize }}%。"

# 虚拟机内存使用率持续过高
- alert: ESXi虚拟机内存使用率过高
expr: vmware_vm_mem_usage_average / 100 > 95
for: 5m
labels:
severity: '警告'
annotations:
summary: "ESXi主机 【{{ $labels.instance }}】的虚拟机 【{{ $labels.vm_name }}】的内存使用率过高"
description: "ESXi主机 【{{ $labels.instance }}】的虚拟机 【'{{ $labels.vm_name }}'】的内存使用率持续5分钟超过95%,当前值: {{ $value | humanize }}%。"
*****************************************************

(6)将要监控的应用服务加入到prometheus.yml

1
2
3
4
5
6
7
8
9
10
11
12
- job_name: 'ESXi'
metrics_path: '/metrics'
static_configs:
- targets:
- '192.168.1.11-ESXi'
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 本机IP:9272

监控Windows物理机硬件

(1)在被监控物理机上安装PawnIOOhmGraphite

\安装PawnIO**

下载exe文件后,按步骤安装即可,提示PawnlO was successfully installed.字样,即为安装成功。

📌

若安装提示报错,尝试安装低版本

\安装OhmGraphite**

下载解压安装包,在OhmGraphite.exe.config文件中添加Prometheus配置

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="host" value="localhost" />
<add key="port" value="2003" />
<add key="interval" value="5" />
<--Prometheus配置-->
<add key="type" value="prometheus" />
<add key="prometheus_port" value="4445" />
<add key="prometheus_host" value="*" />
<add key="prometheus_path" value="metrics/" />
</appSettings>
</configuration>

打开Windows PowerShell (管理员)(A),切换至安装目录,运行以下命令

1
2
3
4
# 安装服务 
.\OhmGraphite.exe install
#启动程序
.\OhmGraphite.exe start

创建完成后,浏览器输入http://本机IP:4445/metrics,访问服务是否正常运行

(2)编写告警规则文件windows_hardware.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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
vi /data/prometheus/config/rules/windows_hardware.yml

*****************************************************

groups:
- name: WindowsHardwareAlerts
rules:

# ==========================================
# CPU 温度告警
# ==========================================
- alert: WinCPUTemperatureHigh
expr: ohm_cpu_temperature{hw_instance!~".*%5C.*"} > 85
for: 2m
labels:
severity: warning
annotations:
summary: "服务器 {{ $labels.instance }} CPU 温度过高"
description: "硬件: {{ $labels.hardware }} | 传感器: {{ $labels.sensor }} | 当前温度: {{ $value }}°C"

- alert: WinCPUTemperatureCritical
expr: ohm_cpu_temperature{hw_instance!~".*%5C.*"} > 95
for: 1m
labels:
severity: critical
annotations:
summary: "服务器 {{ $labels.instance }} CPU 温度严重超标!"
description: "硬件: {{ $labels.hardware }} | 当前温度: {{ $value }}°C,可能触发降频或关机。"


# ==========================================
# 显卡 (GPU) 温度告警
# 注意:OhmGraphite 对不同品牌显卡的指标名不同!
# Intel 显卡通常是 ohm_gpuintel_temperature
# Nvidia 显卡通常是 ohm_gpu_nvidia_temperature
# 请根据你 Grafana 里的实际名称修改下面的 __name__ 正则
# ==========================================
- alert: WinGPUTemperatureHigh
expr: {__name__=~"ohm_gpu.*_temperature", hw_instance!~".*%5C.*"} > 80
for: 2m
labels:
severity: warning
annotations:
summary: "服务器 {{ $labels.instance }} 显卡温度过高"
description: "硬件: {{ $labels.hardware }} | 传感器: {{ $labels.sensor }} | 当前温度: {{ $value }}°C"


# ==========================================
# 硬盘 (HDD/SSD) 温度告警
# 机械硬盘超过 50°C 就要注意了,固态可以适当放宽到 65°C
# ==========================================
- alert: WinHardDriveTemperatureHigh
expr: ohm_hdd_temperature{hw_instance!~".*%5C.*"} > 50
for: 5m
labels:
severity: warning
annotations:
summary: "服务器 {{ $labels.instance }} 硬盘温度偏高"
description: "硬件: {{ $labels.hardware }} | 当前温度: {{ $value }}°C"


# ==========================================
# CPU 使用率告警 (可选,如果你觉得 node_exporter 的不准,可以用这个)
# ==========================================
- alert: WinCPULoadHigh
expr: ohm_cpu_load_percent{hw_instance!~".*%5C.*", sensor="Total"} > 90
for: 5m
labels:
severity: warning
annotations:
summary: "服务器 {{ $labels.instance }} CPU 使用率过高"
description: "当前使用率: {{ $value }}%"


# ==========================================
# 风扇告警 (防止风扇停转导致烧毁)
# ==========================================
- alert: WinFanStopped
expr: ohm_fan_fan_rpm{hw_instance!~".*%5C.*"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "服务器 {{ $labels.instance }} 有风扇停转!"
description: "硬件: {{ $labels.hardware }} | 传感器: {{ $labels.sensor }} | 转速为 0 RPM,请立即检查!"

- alert: WinFanSpeedLow
expr: ohm_fan_fan_rpm{hw_instance!~".*%5C.*"} < 500 and ohm_fan_fan_rpm{hw_instance!~".*%5C.*"} > 0
for: 5m
labels:
severity: warning
annotations:
summary: "服务器 {{ $labels.instance }} 风扇转速过低"
description: "硬件: {{ $labels.hardware }} | 当前转速: {{ $value }} RPM,可能积灰严重或轴承老化。"

*****************************************************

(3)将要监控的Windows物理主机加入prometheus.yml

1
2
3
4
5
- job_name: windows_hardware
static_configs:
- targets: ['xxxx:4445']
labels:
instance: xxxx

安装snmp_exporter监控网络设备

(1)在/data/scripts/pga.yml文件中添加snmp_exporter的容器构建片段

1
2
3
4
5
6
7
8
9
10
11
12
13
snmp-exporter:
image: prom/snmp-exporter
container_name: snmp-exporter
ports:
- "9116:9116"
volumes:
- /data/scripts/snmp-exporter/:/etc/snmp_exporter/
environment:
TZ: Asia/Shanghai
restart: always
networks:
net:
ipv4_address: 172.20.112.16

(2)从https://github.com/prometheus/snmp_exporter/blob/main/snmp.yml下载配置文件到本地的/data/scripts/snmp-exporter/目录下,将public_v2community改为设置的团体字

(3)创建容器,允许端口通过防火墙

1
2
3
firewall-cmd --permanent --add-port=9116/tcp
firewall-cmd --reload
firewall-cmd --list-all

创建完成后,浏览器输入http://本机IP:9116/snmp?target=网络设备IP,访问服务是否正常运行

(4)编写告警规则文件snmp.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
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
vi /data/prometheus/config/rules/snmp.yml

*****************************************************
groups:
- name: 网络设备资源报警规则
rules:
# ================= 采集与连通性监控 =================
- alert: Snmp采集失效
expr: up{job=~".*snmp.*|.*router.*|.*switch.*"} == 0
for: 3m
labels:
severity: '严重'
annotations:
summary: "设备【{{ $labels.instance }}】SNMP 目标不可达"
description: "Prometheus 已连续 3 分钟无法从设备【{{ $labels.instance }}】获取 SNMP 指标,请检查设备网络连通性、SNMP 服务状态及团体字/认证配置。"

- alert: Snmp采集耗时过长
expr: snmp_scrape_duration_seconds > 10
for: 5m
labels:
severity: '警告'
annotations:
summary: "设备【{{ $labels.instance }}】SNMP 采集耗时过长 "
description: "设备【{{ $labels.instance }}】的模块 {{ $labels.module }} 的采集时间持续超过 10 秒 (当前值: {{ printf \"%.2f\" $value }}s),可能存在网络拥堵或设备 CPU 负载过高。"

- alert: Snmp采集断连频繁
expr: rate(snmp_scrape_packets_retried[5m]) > 5
for: 5m
labels:
severity: '警告'
annotations:
summary: "设备【{{ $labels.instance }}】SNMP 采集重试频繁"
description: "设备【{{ $labels.instance }}】的模块 {{ $labels.module }} 在过去 5 分钟内重试包速率过高,可能存在网络丢包或设备响应慢的问题。"

# ================= 接口状态监控 =================

- alert: 接口Down
# 条件:管理状态为 Up(1),但实际运行状态为 Down(2),且必须是物理接口(1)
expr: ifOperStatus{ifName=~"Gi0/1|Gi0/2"} == 2 and ifAdminStatus == 1 and ifConnectorPresent == 1
for: 2m
labels:
severity: '警告'
annotations:
summary: "设备【{{ $labels.instance }}】物理接口 Down ({{ $labels.ifName }})"
description: "设备 {{ $labels.instance }} 的物理接口 {{ $labels.ifDescr }} 管理状态为 Up,但实际状态为 Down。"

- alert: 接口频繁切换
# 条件:接口状态在过去 10 分钟内发生改变(计数器非 0 且持续变动)
# 需要注意:ifCounterDiscontinuityTime 在部分设备上可能不生效,可根据实际情况调整
expr: changes(ifOperStatus[10m]) > 2
for: 1m
labels:
severity: '警告'
annotations:
summary: "设备【{{ $labels.instance }}】接口状态频繁震荡 ({{ $labels.ifName }})"
description: "设备【{{ $labels.instance }}】接口 {{ $labels.ifName }} 在过去 10 分钟内状态改变超过 2 次,可能存在链路质量问题。"

# ================= 接口错误与丢包监控 =================

- alert: 接口入方向错误包增长
# 监控入方向错误包速率(包含 CRC 错误、帧错误等)
expr: rate(ifInErrors[2m]) > 10
for: 3m
labels:
severity: '警告'
annotations:
summary: "设备【{{ $labels.instance }}】接口入方向错误包增长 ({{ $labels.ifName }})"
description: "设备【{{ $labels.instance }}】接口 {{ $labels.ifName }} 持续 3 分钟每秒接收超过 10 个错误包 (当前速率: {{ printf \"%.2f\" $value }}/s)。请检查物理线缆或光模块。"

- alert: 接口出方向错误包增长
# 监控出方向错误包速率
expr: rate(ifOutErrors[2m]) > 10
for: 3m
labels:
severity: '警告'
annotations:
summary: "设备【{{ $labels.instance }}】接口出方向错误包增长 ({{ $labels.ifName }})"
description: "设备【{{ $labels.instance }}】接口 {{ $labels.ifName }} 持续 3 分钟每秒发送超过 10 个错误包 (当前速率: {{ printf \"%.2f\" $value }}/s)。"

- alert: 接口存在丢包
# 监控接口丢包(由于缓冲区满或 QoS 策略导致的丢弃)
expr: rate(ifInDiscards[5m]) + rate(ifOutDiscards[5m]) > 50
for: 5m
labels:
severity: '信息'
annotations:
summary: "设备【{{ $labels.instance }}】接口存在丢包 ({{ $labels.ifName }})"
description: "设备【{{ $labels.instance }}】接口 {{ $labels.ifName }} 入+出方向丢包速率总和超过 50/s,可能存在带宽拥塞或缓存溢出。"

# ================= 带宽利用率监控 (基于 64 位计数器) =================
# 注意:除以 ifHighSpeed(单位 Mbps),结果乘以 100 转为百分比。

- alert: 接口入方向带宽利用率过高
# 入方向带宽利用率 > 85%
expr: (rate(ifHCInOctets[2m]) * 8) / (ifHighSpeed * 1000000) * 100 > 85
for: 5m
labels:
severity: '警告'
annotations:
summary: "设备【{{ $labels.instance }}】接口入方向带宽超载 ({{ $labels.ifName }})"
description: "设备【{{ $labels.instance }}】接口 {{ $labels.ifName }} 的入方向带宽利用率持续 5 分钟超过 85% (当前: {{ printf \"%.2f\" $value }}%)。"

- alert: 接口出方向带宽利用率过高
# 出方向带宽利用率 > 85%
expr: (rate(ifHCOutOctets[2m]) * 8) / (ifHighSpeed * 1000000) * 100 > 85
for: 5m
labels:
severity: '警告'
annotations:
summary: "设备【{{ $labels.instance }}】接口出方向带宽超载 ({{ $labels.ifName }})"
description: "设备【{{ $labels.instance }}】接口 {{ $labels.ifName }} 的出方向带宽利用率持续 5 分钟超过 85% (当前: {{ printf \"%.2f\" $value }}%)。"

*****************************************************

(6)将要监控的应用服务加入到prometheus.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
scrape_configs:
- job_name: 'GW'
static_configs:
- targets:
- 192.168.1.1
metrics_path: /snmp
params:
auth: [public_v2]
module: [if_mib,system,ucd_system_stats,ucd_memory,ucd_la_table,ip_mib]
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 本机IP:9116

- job_name: 'snmp-exporter'
static_configs:
- targets: ['本机IP:9116']