点击展开更新日志

2025

08-24

【新增】komari

09-22

【新增】Grafana

  • 部署
  • 配置文件
  • Windows exporter
  • Grafana dashboard

nexttime

会有些什么呢(❁´◡`❁)

源起

最主要的原因还是折腾

Komari 监控面板

Komari-轻量级的自托管服务器监控工具

源起

为了监控手上的几台的服务器,简单看一下内存硬盘网络的情况,最初是想要统计加到 Grafana 上的,毕竟之前弄好了嘛,但一时之间找不到合适的监控模板,于是干脆就用一个单独的模板来做监控得了。

最初是选择的 哪吒监控V1,实际部署之后发现个别使用 IPv4 节点会是不是断联,估计可能是 haproxy 和采集间隔的缘故,暂时不知道怎么改,兜兜转转换到了 Komari。一套下来感觉还不错,暂时选择了这套。

需求

如果是将 dashboard 部署在公网服务器上,操作会简单一点,可是呢,我想把 dashboard 部署在内网环境,主要还是因为使用场景基本都在内网,想要把所有容器统一管理起来,真要说有什么必要的理由貌似也没有。但这样就会引出一个新的问题,互联网上的服务器如何连接到内网的 dashboard,因此,一个公网地址是必要的。

到这里,整理一下我的部署需求:

  1. 内网部署,监控内网及互联网服务器(Linux, Windows)
  2. 容器部署
  3. 界面美观可自定义

根据部署过程中遇到的问题,实现以上需求的资源需求如下:

  • 【必需】公网地址:如果有IPv4最好,但至少要有 IPv6
  • 【必需】Docker环境:本地已安装Docker环境
  • 【可选】带公网IPv6的服务器:如果没有公网IPv4出口那么这个就是必需的,需要做中转。
  • 【推荐】SSH工具:既然都用Linux了,怎么没有一个趁手的工具呢

关于公网 IPv6 的检查,并非用 ip 命令看到存在 IPv6 就可以,需要用 ping -6 aliyun.com 检查是否可以ping通,才能说明该服务器 IPv6 是否支持对外访问,重点是服务器要能够访问 IPv6,否则也是徒劳。

比如阿里云的ECS虽然提供IPv6,支持IPv6访问,但服务器本身不能够访问外部IPv6地址,需要单独购买流量费。

环境

  • 内网服务器intA:具有公网IPv6,
  • 具有公网IPv6服务器extB
  • 阿里云服务器extC:不支持对外IPv6访问
  • 域名 data.example.com 已绑定到 extB 的地址

部署

Dashboard 部署

假设本地 Docker 环境已就绪,有顺畅访问 Github 及拉取 Docker 镜像的手段。

创建 compose 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
services:
komari:
image: ghcr.io/komari-monitor/komari:latest
container_name: komari
ports:
- "25774:25774"
volumes:
- ./data:/app/data
environment:
# 可选:自定义初始管理员账号
# ADMIN_USERNAME: admin
# ADMIN_PASSWORD: yourpassword
restart: unless-stopped

启动

1
docker compose up -d

获取账号密码

1
docker logs komari

查看日志获取登录用户名和密码。

登录管理页面

http://<IP>:25774

密码可能是做了限制不允许输入 / ,但是可以选择粘贴,因此:

  • 更改为不包含 / 的新密码
  • 利用密码管理工具记住自动填充

Nginx 反向代理

一般情况下自然不可能记端口访问,因此我们需要配置一层代理,以Openresty为例:

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
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
# komari.xxx.top: 内网访问域名
# data.example.com: IPv4服务器探针上报域名
server_name komari.xxx.top data.example.com;

# SSL
ssl_certificate /usr/local/openresty/nginx/ssl/xxx.top.crt;
ssl_certificate_key /usr/local/openresty/nginx/ssl/xxx.top.pem;

# security
include nginxconfig.io/security.conf;

# logging
access_log /logs/access_komari.log cloudflare buffer=512k flush=1m;
error_log /logs/error_komari.log warn;

# reverse proxy
location / {
proxy_pass http://127.0.0.1:25774;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

# WebSocket 代理
location /ws/ {
proxy_pass http://127.0.0.1:25774;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

}

# HTTP redirect
server {
listen 80;
listen [::]:80;
server_name komari.xxx.top;
return 301 https://komari.xxx.top$request_uri;
}

此时就能够用域名访问后台,后续探针上报地址也就使用域名了。

DDNS 配置

既然我们的服务部署在内网,想要公网上的服务器连接上,自然还需要有一个公网访问的地址:

  • 公网IPv4:
    • 这种情况下只需要将域名绑定到IP,后续就能够直接用域名部署代理了,不需要额外的操作,后续操作直接跳过。
  • 公网IPv6
    • 如果恰好和我一样只有v6的地址,就需要稍微折腾一下,以下操作仅针对只有公网IPv6的情况:
  1. 部署 ddns-go-jeessy2
  2. 将以上访问域名 komari.xxx.top 添加绑定
  3. 外网验证解析访问是否正常。

具体部署操作可以参考文档说明或者后面有空再补充。

手动部署代理——支持对外IPv6公网

对于extB服务器的情况:

  1. 具有公网IPv4
  2. 具有对外IPv6:
    1
    2
    3
    4
    5
    6
    7
    8
    root@Debian12:~# ping -6 aliyun.com
    PING aliyun.com(2401:b180:1:60::6 (2401:b180:1:60::6)) 56 data bytes
    64 bytes from 2401:b180:1:60::6 (2401:b180:1:60::6): icmp_seq=1 ttl=85 time=152 ms
    64 bytes from 2401:b180:1:60::6 (2401:b180:1:60::6): icmp_seq=2 ttl=85 time=152 ms
    ^C
    --- aliyun.com ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1001ms
    rtt min/avg/max/mdev = 152.093/152.106/152.119/0.013 ms

这种情况下可以直接配置:

  1. 登录到 komari 后台手动添加一个节点,复制部署指令
  2. SSH 登录到待部署代理服务器 extB,粘贴指令执行
  3. 安装完成后回到后台检查是否已获取节点信息,如果没有,使用命令查看代理启动日志排查:
    1
    systemctl status komari-agent

手动部署代理——不支持对外IPv6公网

如果对于extC服务器的情况:

1
2
3
[root@aliyun ~]# ping -6 aliyun.com
PING aliyun.com(2401:b180:1:60::5 (2401:b180:1:60::5)) 56 data bytes
...

直接执行部署指令是连接不上server的,因此需要找一个中间服务器做代理,比如 extB——有公网IPv4能够接收extC的请求,也能够访问只有 IPv6 的dashboard,因此部署步骤如下:

  1. 在 extB 上部署 haproxy(也可以选择Nginx,图简单我直接用TCP)
    因安装步骤写在这里略显冗余,放在另一篇了。
  2. 配置到 data.example.com 的转发配置,端口自定义,比如8080,如果有白名单配置也需要添加extC的IP到白名单,重启服务;
  3. 修改部署指令
    1
    bash <(curl -sL https://raw.githubusercontent.com/komari-monitor/komari-agent/refs/heads/main/install.sh) -e https://data.example.com:8080 -t abcdefg

    将内网的面板地址更换为绑定 extB 服务器的域名+端口

  4. 如果一切顺利,dashboard上应该就能看到了

手动部署代理-无root权限

此类情况适用于希望将 serv00 这样的服务器也加入监控,直接使用部署指令没有权限,而且脚本也没有支持 FreeBSD,因此只能手动下载 agent。

  1. 从 Github 找到对应的agent下载地址:https://github.com/komari-monitor/komari-agent/releases,比如选择 freebsd-amd64

  2. 下载到用户目录

    1
    2
    3
    mkdir -p application/komari-agent
    cd application/komari-agent
    wget https://github.com/komari-monitor/komari-agent/releases/download/1.0.62/komari-agent-freebsd-amd64
  3. 创建启动脚本

    1
    2
    3
    4
    5
    6
    7
    vim start-agent.sh

    # 添加以下内容

    #!/bin/bash

    /home/User/application/komari-agent/komari-agent-freebsd-amd64 -e https://data.example.com:8080 -t abcdefg12345 >> /home/User/application/komari-agent/komari-agent.log
  4. 启动脚本

    1
    2
    3
    chmod +x start-agent.sh
    ./start-agent.sh
    # pm2 start start-agent.sh --name komari

    pm2 的安装晚点补充

自动发现

参考:Agent 自动发现

对于需要批量部署和管理 Agent 实例,可以在管理后台生成自动发现密钥,使用以下命令安装 Agent:

1
2
3
4
5
6
7
8
9
10
11
12
# Linux/macOS
bash <(curl -sL https://raw.githubusercontent.com/komari-monitor/komari-agent/refs/heads/main/install.sh) \
-e <ENDPOINT> \
--auto-discovery <AD KEY> \
--disable-web-ssh \
--interval 5.0 \
--max-retries 5 \
--reconnect-interval 10 \
--info-report-interval 15

# Windows
powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "iwr 'https://raw.githubusercontent.com/komari-monitor/komari-agent/refs/heads/main/install.ps1' -UseBasicParsing -OutFile 'install.ps1'; & '.\install.ps1' '-e' 'https://your-komari-server.com' '--auto-discovery' 'your-ad-key' '--disable-web-ssh' '--interval' '5.0' '--max-retries' '5' '--reconnect-interval' '10' '--info-report-interval' '15'"
  • -e, --endpoint komari 服务器地址,需要能够访问,比如: https://data.example.com:8080
  • --auto-discovery 自动发现密钥,用于批量注册 Agent

卸载代理

参考: Komari Agent 卸载指南

  1. 停止并禁用服务

    1
    2
    systemctl stop komari-agent
    systemctl disable komari-agent
  2. 删除服务文件

    1
    2
    rm /etc/systemd/system/komari-agent.service
    systemctl daemon-reload
  3. 删除安装文件

    1
    rm -rf /opt/komari /var/log/komari

一键删除:

1
sudo systemctl stop komari-agent && sudo systemctl disable komari-agent && sudo rm -f /etc/systemd/system/komari-agent.service && sudo systemctl daemon-reload && sudo rm -rf /opt/komari /var/log/komari

Grafana 监控系统

实际上 Grafana 本身并不提供监控能力,这一套搭建下来涉及几个组件:

  • Grafana:前端展示,大屏监控指标及告警
  • Prometheus:指标采集,从各个客户端获取主机信息(需要在客户端安装采集器代理)
  • 采集器:安装在客户端上向 Prometheus 上报指标
  • loki:日志存储处理
  • alloy:promtail 的新一代日志采集 agent

因此根据需要酌情选择就好。

参考资料:这两个地方能确保获取最新最可靠的资料

部署

以下 compose 文件参考了多方资料,主要是 Grafana 官方文档和一些佬的博客,因当时没有记录所以暂时先不补充参考资料,后续找到了再补。

包含了上面提到的几乎所有组件(除windows_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
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
networks:
loki:
name: loki
driver: bridge

volumes:
prometheus:
grafana:
alertmanager-data:
loki:

services:
# Since the Loki containers are running as user 10001 and the mounted data volume is owned by root,
# Loki would not have permissions to create the directories.
# Therefore the init container changes permissions of the mounted directory.
# loki数据目录权限设置
init:
image: &lokiImage grafana/loki:latest
container_name: loki_init
user: root
entrypoint:
- "chown"
# - "10001:10001"
- "10001"
- "/loki"
volumes:
- loki:/loki
networks:
- loki

# Grafana
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "3004:3000"
environment:
# - GF_AUTH_ANONYMOUS_ENABLED=true
# - GF_AUTH_DISABLE_LOGIN_FORM=true
# - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin@123
- GF_USERS_ALLOW_SIGN_UP=false
# - GF_AUTH_PROXY_HEADER_PROPERTY=alertmanager
volumes:
- ./config/datasources.yaml:/etc/grafana/provisioning/datasources/datasources.yml
- grafana:/var/lib/grafana
- ./config/grafana.ini:/etc/grafana/grafana.ini
- ./logs/grafana:/var/log/grafana
healthcheck:
test:
[
"CMD-SHELL",
"wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1",
]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
networks:
- loki

# Prometheus
prometheus:
image: prom/prometheus:v3.5.0
container_name: prometheus
ports:
- 9090:9090
volumes:
- ./config/prometheus.yaml:/etc/prometheus/prometheus.yml
- ./config/alert.rules.yml:/etc/prometheus/alert.rules.yml
- prometheus:/prometheus
command:
[
'--log.level=debug',
'--config.file=/etc/prometheus/prometheus.yml',
'--enable-feature=remote-write-receiver',
'--query.lookback-delta=30s'
]
restart: unless-stopped
networks:
- loki

# 日志存储
minio:
image: minio/minio
container_name: loki_minio
entrypoint:
- sh
- -euc
- |
mkdir -p /data/loki-data && \
mkdir -p /data/loki-ruler &&
minio server --address "0.0.0.0:9000" --console-address "0.0.0.0:9001" /data
environment:
- MINIO_ROOT_USER=loki
- MINIO_ROOT_PASSWORD=loki
- MINIO_PROMETHEUS_AUTH_TYPE=public
- MINIO_UPDATE=off
ports:
- "9000"
- "9001"
volumes:
- ./data/minio:/data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 15s
timeout: 20s
retries: 5
restart: unless-stopped
networks:
- loki

# 作为 loki 读写分离的网关入口,部署了两个实例分别处理读写
loki-gateway:
image: nginx:latest
container_name: loki_gateway
volumes:
- ./config/nginx.conf:/etc/nginx/nginx.conf
ports:
# - "8089:80"
- "3100"
healthcheck:
test: ["CMD", "service", "nginx", "status"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
networks:
- loki

loki-read:
image: *lokiImage
container_name: loki_read
volumes:
- ./config:/etc/loki/
ports:
- "3100"
- "7946"
# uncomment to use interactive debugging
# - "40000-40002:40000" # makes the replicas available on ports 40000, 40001, 40002
command: "-config.file=/etc/loki/loki.yaml -target=read -legacy-read-mode=false"
networks:
- loki
restart: unless-stopped
healthcheck:
test:
[
"CMD-SHELL",
"wget --no-verbose --tries=1 --spider http://localhost:3100/ready || exit 1",
]
interval: 10s
timeout: 5s
retries: 5

loki-write:
image: *lokiImage
container_name: loki_write
volumes:
- ./config:/etc/loki/
ports:
- "3100"
- "7946"
# uncomment to use interactive debugging
# - "50000-50002:40000" # makes the replicas available on ports 50000, 50001, 50002
command: "-config.file=/etc/loki/loki.yaml -target=write"
networks:
- loki
restart: unless-stopped
healthcheck:
test:
[
"CMD-SHELL",
"wget --no-verbose --tries=1 --spider http://localhost:3100/ready || exit 1",
]
interval: 10s
timeout: 5s
retries: 5

# 索引规则处理后端
loki-backend:
image: *lokiImage
container_name: loki_backend
volumes:
- ./config:/etc/loki/
- ./rules:/loki/rules:ro
# only needed for interactive debugging with dlv
# cap_add:
# - SYS_PTRACE
# security_opt:
# - apparmor=unconfined
ports:
- "3100"
- "7946"
# uncomment to use interactive debugging
# - "60000-60002:40000" # makes the replicas available on ports 60000, 60001, 60002
command: "-config.file=/etc/loki/loki.yaml -target=backend -legacy-read-mode=false"
networks:
- loki
restart: unless-stopped

# 告警管理器,Grafana 也自带,非必要
alertmanager:
image: prom/alertmanager:latest
container_name: alertmanager
restart: unless-stopped
ports:
- "9093:9093"
volumes:
- "./config:/config"
- ./config/templates:/etc/alertmanager/templates
- alertmanager-data:/data
command: --config.file=/config/alertmanager.yml --log.level=debug
networks:
- loki

alloy:
image: grafana/alloy:latest
container_name: alloy
ports:
- 12345:12345
volumes:
- ./config/config.alloy:/etc/alloy/config.alloy
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./logs:/app-logs
command: run --server.http.listen-addr=0.0.0.0:12345 --storage.path=/var/lib/alloy/data /etc/alloy/config.alloy
restart: unless-stopped
networks:
- loki


node-exporter:
image: prom/node-exporter:latest
container_name: node_exporter
ports:
- 9100:9100
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
# network_mode: host
pid: host
restart: unless-stopped
volumes:
- '/proc:/host/proc:ro'
- '/sys:/host/sys:ro'
- '/:/rootfs:ro,rslave'
networks:
- loki

cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
container_name: cadvisor
hostname: cadvisor
restart: unless-stopped
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
privileged: true
ports:
- "8083:8080"
devices:
- /dev/kmsg:/dev/kmsg
networks:
- loki
deploy:
resources:
limits:
memory: 256M
cpus: '0.5'

配置文件

如果是按照以上文件进行部署,配置文件统一放在与 docker-compose.yml 同级 config 目录下:

  • alertmanager.yml: 告警管理配置
  • alert.rules.yml: 告警规则
  • config.alloy: alloy 采集器代理配置
  • datasources.yaml: Grafana 数据源配置
  • grafana.ini: Grafana 配置
  • loki.yaml: loki 日志采集配置
  • nginx.conf loki网关配置
  • prometheus.yaml:
  • templates/: 告警通知模板

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
global:
smtp_from: [email protected]
smtp_smarthost: smtp.qiye.aliyun.com:465
smtp_auth_username: 'notice'
smtp_auth_password: '<PASS>'
smtp_require_tls: true
resolve_timeout: 5m

templates:
- '/etc/alertmanager/templates/*.tmpl'

route:
receiver: 'default-receiver'
group_wait: 30s
group_interval: 30m
group_by: [ 'alertname', 'service' ]

receivers:
- name: 'default-receiver'
email_configs:
- to: '[email protected]'
send_resolved: true
html: '{{ template "email.default.html" . }}'

# 抑制规则 - 减少重复告警
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'service']

alert.rules.yml

1
2
3
4
5
6
7
8
9
10
11
groups:
- name: host-alerts
rules:
- alert: HighCpuUsage
expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
labels:
severity: warning
annotations:
summary: "高CPU使用率 (实例 {{ $labels.instance }})"
description: "CPU使用率超过80%,当前值为 {{ $value }}%"

config.alloy

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
// docker 日志发现
discovery.docker "docker_logs" {
host = "unix:///var/run/docker.sock"
}

// 提取标签
discovery.relabel "logs_integrations_docker" {
targets = []

rule {
source_labels = ["__meta_docker_container_name"]
regex = "/(.*)"
target_label = "service"
}
}

// docker 日志处理
loki.source.docker "default" {
host = "unix:///var/run/docker.sock"
targets = discovery.docker.docker_logs.targets
labels = {"platform" = "docker"}
relabel_rules = discovery.relabel.logs_integrations_docker.rules
forward_to = [loki.write.local.receiver]
}


// Loki 写入日志
loki.write "loki_api" {
endpoint {
url = "http://loki-gateway:3100/loki/api/v1/push"
tenant_id = "docker"
}

datasource.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
apiVersion: 1
datasources:
- name: Loki
type: loki
access: proxy
orgId: 1
url: http://loki-gateway:3100
basicAuth: false
isDefault: true
version: 1
editable: false
jsonData:
httpHeaderName1: "X-Scope-OrgID"
secureJsonData:
httpHeaderValue1: "docker"

- access: proxy
basicAuth: false
editable: true
isDefault: false
name: prometheus
type: prometheus
uid: prometheus
url: http://prometheus:9090
version: 1

grafana.ini

不挂载 ini 配置启动一次后从容器复制默认配置出来再挂载重新启动。

loki.yaml

参考实例仓库地址:https://github.com/grafana/loki-fundamentals

nginx.conf

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
```

**prometheus.yaml**

```yaml
global:
scrape_interval: 5s
evaluation_interval: 10s # 规则评估间隔
scrape_timeout: 3s # 抓取超时时间

# 告警规则
rule_files:
- "/etc/prometheus/alert.rules.yml"

# 告警配置
alerting:
alertmanagers:
- scheme: http
path_prefix: /
static_configs:
- targets: ['alertmanager:9093']
# basic_auth:
# username: 'alertmanager'
# password: 'alertmanager@2025'
# 抓取配置
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets:
- 'prometheus:9090'

- job_name: 'loki'
dns_sd_configs:
- names:
- loki-read
- loki-write
- loki-backend
type: A
port: 3100

# 监控 Node Exporter:宿主机指标
- job_name: 'node'
static_configs:
- targets: ['node-exporter:9100']
relabel_configs:
- source_labels: [__address__]
target_label: instance
- replacement: "Docker-Host"
target_label: job
- job_name: 'alertmanager'
static_configs:
- targets: ['alertmanager:9093']

nginx.conf

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
error_log  /dev/stderr;
pid /run/nginx.pid;
worker_rlimit_nofile 8192;

events {
worker_connections 4096; ## Default: 1024
}

http {
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] $status '
'"$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /dev/stderr main;
sendfile on;
tcp_nopush on;

upstream read {
server loki-read:3100;
}

upstream write {
server loki-write:3100;
}

upstream cluster {
server loki-read:3100;
server loki-write:3100;
}

server {
listen 80;
listen 3100;

location = /ring {
proxy_pass http://cluster$request_uri;
}

location = /memberlist {
proxy_pass http://cluster$request_uri;
}

location = /config {
proxy_pass http://cluster$request_uri;
}

location = /metrics {
proxy_pass http://cluster$request_uri;
}

location = /ready {
proxy_pass http://cluster$request_uri;
}

location = /loki/api/v1/push {
proxy_pass http://write$request_uri;
}

location = /loki/api/v1/tail {
proxy_pass http://read$request_uri;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}

location ~ /loki/api/.* {
proxy_pass http://read$request_uri;
}
}
}

Windows exporter

这部分单独拎出来,如果需要监控其它 Windows 主机,可以考虑安装 Windows 采集器,使用 windows_exporter

GitHub 仓库已经提供了详细的安装说明和参数配置,因此不做详细赘述,仅介绍我的安装内容。

  1. Release 下载二进制安装包,我选择 exe 格式;
  2. 将安装包拷贝到程序目录:C:\Program Files\windows_exporter (这个也是默认安装目录);
  3. 新建配置文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
collectors:
enabled: cpu,cpu_info,diskdrive,logical_disk,memory,net,os,physical_disk,service,smb,system
collector:
service:
include: "windows_exporter"
log:
level: info
scrape:
timeout-margin: 0.5
telemetry:
path: /metrics
web:
listen-address: "192.168.7.7:9182" # 也可以用0.0.0.0/127.0.0.1

关于采集器的选择,以上是我的配置,根据需要选择即可,如果在 Grafana 或 Prometheus 中发现某些指标不存在,大概率是没有启动响应的采集器,关于采集器的指标和一些使用可以参考 采集器文档

还有一点需要说明,有些 Grafana 模板可能比较老,某些指标名在新版本采集器做了更改,就需要自己对照文档进行修正了,如果不清楚怎么改,可以参照下面 Grafana 配置部分。

  1. 打开 cmd,执行程序,检查是否存在报错
  2. 添加为 windows 服务:如何添加Windows服务
  3. 打开 【高级安全 Windows Defender 防火墙】放行端口;
  4. 在 Prometheus 配置新增采集点:
1
2
3
- job_name: 'win11'
static_configs:
- targets: ['192.168.7.7:9182']
  1. 打开 Prometheus 检查采集是否正常

Grafana Dashboard

🍁 终于来到了这一步了吗!

如果经过上面一系列操作已经全部都跑起来了,我们就可以进入 Grafana 的配置了。

  1. 首先在数据源检查是否正常:因为我们已经通过配置进行了配置,这里应该就可以直接看到已经存在 lokiprometheus 了;
  2. 在【仪表盘】,选择【导入】模板,可以从 模板市场 选择一个合适的,点进详情页之后可以看到ID,我的推荐是:
  • Docker容器:15120
  • Windows:20763 这个模板第一次添加大概率全都没有数据,因为指标名变了。
  1. 可以从右上角【个人资料】修改默认仪表盘,每次登录就可以直接看到了

在稍微熟悉之后,就可以自定义自己的面板了,grafana 提供了多种数据显示格式,拖动组件使用指标值构建,比较方便。这里针对 20763 模板数据指标不存在的情况进行说明:

在每个组件的右上角展开选择【编辑】,修改下方指标表达式,一般就是新版本采集器指标名变了找不到,这个时候就参考 windows_exporter GitHub 指标说明进行一一修正即可,如果对表达式不满意也可以自己调整。

iKuai Prometheus Exporter

Github 仓库地址:https://github.com/jakeslee/ikuai-exporter

虽然已经很久没有更新了,但是还是可以用。

  1. docker-compose.yml
1
2
3
4
5
6
7
8
9
10
11
services:
ikuai_exporter:
image: jakes/ikuai-exporter:latest
container_name: iKuai_exporter
restart: unless-stopped
ports:
- 9090:9090
environment:
IK_URL: 192.168.1.2
IK_USER: prometheus
IK_PWD: prometheus
  1. 在 ikuai 后台新建一个只读权限的 prometheus 用户
  2. prometheus.yml 中引入
  3. 检查指标是否正常:http://localhost:9090
  4. 导入 Grafana 面板ID:19247

正常情况下,导入之后应该几乎没有数据,因为指标名对不上,因此需要编辑面板,参考默认指标名与 metrics 实际情况进行调整。

另一个可选的项目是 ikuai-aio,将 ikuai exporter+ grafana + prometheus 打包到了一起,如果还没有单独部署 grafana 这套可以直接用这个。

PVE exporter

起因是上个周日起床,打开电脑,准备先美美刷会B站,发现怎么上不了网,一开始还以为是不是代理的问题,重新打开也不行,甚至部署的 uptime-kuma 全都红了。阿哲,看来眼路由器是正常的欸,然后怀疑是 OpenWrt 的问题,因为之前也出现过卡死的情况导致没网,加上电脑配的网关地址就是 Op,基本怀疑是这玩意可能有问题。登录 PVE 控制台一看,直接满屏的 OutOfMemory,赶紧把内存从512M增加到1024M,重启,果然恢复了。然后这两天就想着抽空给 PVE 加个监控,万一后面又挂了至少能及时知道。

  1. 安装 Python3.9+,在 PVE 9版本默认安装了 3.13 的python了;
  2. 安装 pip: apt install python3-pip
  3. 安装 PVE exporter:
1
2
3
python -m venv prometheus # 创建虚拟环境,名为 prometheus
source prometheus/bin/activate # 激活环境
pip install prometheus-pve-exporter
  1. 新增配置文件: /etc/prometheus/pve.yml
1
2
3
4
5
6
7
8
9
mkdir -p /etc/prometheus
cat <<EOF > /etc/prometheus/pve.yml
default:
user: prometheus@pve
token_name: "your-token-id"
token_value: "..."
verify_ssl: false
EOF

  1. 添加服务:
1
2
3
4
5
6
7
8
9
10
11
12
13
cat <<EOF> /etc/systemd/system/prometheus-pve-exporter.service
[Unit]
Description=Prometheus exporter for Proxmox VE
Documentation=https://github.com/znerol/prometheus-pve-exporter

[Service]
Restart=always
User=root
ExecStart=/opt/prometheus-pve-exporter/bin/pve_exporter --no-collector.config --config.file /etc/prometheus/pve.yml

[Install]
WantedBy=multi-user.target
EOF
  1. 重载 systemd
1
2
3
systemctl daemon-reload
systemctl start prometheus-pve-exporter
systemctl status prometheus-pve-exporter
  1. Prometheus 配置
1
2
3
4
5
6
7
8
9
10
11
scrape_configs:
- job_name: 'pve'
static_configs:
- targets:
- 192.168.1.2:9221 # Proxmox VE node with PVE exporter.
- 192.168.1.3:9221 # Proxmox VE node with PVE exporter.
metrics_path: /pve
params:
module: [default]
cluster: ['1']
node: ['1']

还有一种情况是 PVE exporter 没有和 PVE 部署在一起,还需要额外配置,比如和 Prometheus 部署在一起:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
scrape_configs:
- job_name: 'pve'
static_configs:
- targets:
- 192.168.1.2 # Proxmox VE node.
- 192.168.1.3 # Proxmox VE node.
metrics_path: /pve
params:
module: [default]
cluster: ['1']
node: ['1']
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 127.0.0.1:9221 # PVE exporter.