点击展开更新日志
【新增】Grafana
部署
配置文件
Windows exporter
Grafana dashboard
源起
最主要的原因还是折腾
Komari 监控面板
Komari-轻量级的自托管服务器监控工具
源起
为了监控手上的几台的服务器,简单看一下内存硬盘网络的情况,最初是想要统计加到 Grafana 上的,毕竟之前弄好了嘛,但一时之间找不到合适的监控模板,于是干脆就用一个单独的模板来做监控得了。
最初是选择的 哪吒监控V1 ,实际部署之后发现个别使用 IPv4 节点会是不是断联,估计可能是 haproxy 和采集间隔的缘故,暂时不知道怎么改,兜兜转转换到了 Komari 。一套下来感觉还不错,暂时选择了这套。
需求
如果是将 dashboard 部署在公网服务器上,操作会简单一点,可是呢,我想把 dashboard 部署在内网环境,主要还是因为使用场景基本都在内网,想要把所有容器统一管理起来,真要说有什么必要的理由貌似也没有。但这样就会引出一个新的问题,互联网上的服务器如何连接到内网的 dashboard,因此,一个公网地址是必要的。
到这里,整理一下我的部署需求:
内网部署,监控内网及互联网服务器(Linux, Windows)
容器部署
界面美观可自定义
根据部署过程中遇到的问题,实现以上需求的资源需求如下:
【必需】公网地址:如果有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: restart: unless-stopped
启动
获取账号密码
查看日志获取登录用户名和密码。
登录管理页面
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; server_name komari.xxx.top data.example.com; ssl_certificate /usr/local/openresty/nginx/ssl/xxx.top.crt; ssl_certificate_key /usr/local/openresty/nginx/ssl/xxx.top.pem; include nginxconfig.io/security.conf; access_log /logs/access_komari.log cloudflare buffer=512k flush=1m; error_log /logs/error_komari.log warn; 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 ; } 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 ; } } server { listen 80; listen [::]:80; server_name komari.xxx.top; return 301 https://komari.xxx.top$request_uri ; }
此时就能够用域名访问后台,后续探针上报地址也就使用域名了。
DDNS 配置
既然我们的服务部署在内网,想要公网上的服务器连接上,自然还需要有一个公网访问的地址:
公网IPv4:
这种情况下只需要将域名绑定到IP,后续就能够直接用域名部署代理了,不需要额外的操作,后续操作直接跳过。
公网IPv6
如果恰好和我一样只有v6的地址,就需要稍微折腾一下,以下操作仅针对只有公网IPv6 的情况:
部署 ddns-go-jeessy2
将以上访问域名 komari.xxx.top 添加绑定
外网验证解析访问是否正常。
具体部署操作可以参考文档说明或者后面有空再补充。
手动部署代理——支持对外IPv6公网
对于extB 服务器的情况:
具有公网IPv4
具有对外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
这种情况下可以直接配置:
登录到 komari 后台手动添加一个节点,复制部署指令
SSH 登录到待部署代理服务器 extB,粘贴指令执行
安装完成后回到后台检查是否已获取节点信息,如果没有,使用命令查看代理启动日志排查: 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,因此部署步骤如下:
在 extB 上部署 haproxy(也可以选择Nginx,图简单我直接用TCP)
因安装步骤写在这里略显冗余,放在另一篇了。
配置到 data.example.com 的转发配置,端口自定义,比如8080,如果有白名单配置也需要添加extC的IP到白名单,重启服务;
修改部署指令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 服务器的域名+端口
如果一切顺利,dashboard上应该就能看到了
手动部署代理-无root权限
此类情况适用于希望将 serv00 这样的服务器也加入监控,直接使用部署指令没有权限,而且脚本也没有支持 FreeBSD,因此只能手动下载 agent。
从 Github 找到对应的agent下载地址:https://github.com/komari-monitor/komari-agent/releases,比如选择 freebsd-amd64
下载到用户目录
1 2 3 mkdir -p application/komari-agentcd application/komari-agentwget https://github.com/komari-monitor/komari-agent/releases/download/1.0.62/komari-agent-freebsd-amd64
创建启动脚本
1 2 3 4 5 6 7 vim start-agent.sh /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
启动脚本
1 2 3 chmod +x start-agent.sh./start-agent.sh
pm2 的安装晚点补充
自动发现
参考:Agent 自动发现
对于需要批量部署和管理 Agent 实例,可以在管理后台生成自动发现密钥,使用以下命令安装 Agent:
1 2 3 4 5 6 7 8 9 10 11 12 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 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 2 systemctl stop komari-agent systemctl disable komari-agent
删除服务文件
1 2 rm /etc/systemd/system/komari-agent.servicesystemctl daemon-reload
删除安装文件
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: init: image: &lokiImage grafana/loki:latest container_name: loki_init user: root entrypoint: - "chown" - "10001" - "/loki" volumes: - loki:/loki networks: - loki grafana: image: grafana/grafana:latest container_name: grafana ports: - "3004:3000" environment: - GF_SECURITY_ADMIN_USER=admin - GF_SECURITY_ADMIN_PASSWORD=admin@123 - GF_USERS_ALLOW_SIGN_UP=false 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: 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-gateway: image: nginx:latest container_name: loki_gateway volumes: - ./config/nginx.conf:/etc/nginx/nginx.conf ports: - "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" 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" 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 ports: - "3100" - "7946" command: "-config.file=/etc/loki/loki.yaml -target=backend -legacy-read-mode=false" networks: - loki restart: unless-stopped 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' 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' ] 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 - 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; } 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 仓库已经提供了详细的安装说明和参数配置,因此不做详细赘述,仅介绍我的安装内容。
从 Release 下载二进制安装包,我选择 exe 格式;
将安装包拷贝到程序目录:C:\Program Files\windows_exporter (这个也是默认安装目录);
新建配置文件:
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"
关于采集器的选择,以上是我的配置,根据需要选择即可,如果在 Grafana 或 Prometheus 中发现某些指标不存在,大概率是没有启动响应的采集器,关于采集器的指标和一些使用可以参考 采集器文档 。
还有一点需要说明,有些 Grafana 模板可能比较老,某些指标名在新版本采集器做了更改,就需要自己对照文档进行修正了,如果不清楚怎么改,可以参照下面 Grafana 配置部分。
打开 cmd,执行程序,检查是否存在报错
添加为 windows 服务:如何添加Windows服务
打开 【高级安全 Windows Defender 防火墙】放行端口;
在 Prometheus 配置新增采集点:
1 2 3 - job_name: 'win11' static_configs: - targets: ['192.168.7.7:9182' ]
打开 Prometheus 检查采集是否正常
Grafana Dashboard
🍁 终于来到了这一步了吗!
如果经过上面一系列操作已经全部都跑起来了,我们就可以进入 Grafana 的配置了。
首先在数据源检查是否正常:因为我们已经通过配置进行了配置,这里应该就可以直接看到已经存在 loki 和 prometheus 了;
在【仪表盘】,选择【导入】模板,可以从 模板市场 选择一个合适的,点进详情页之后可以看到ID ,我的推荐是:
Docker容器:15120
Windows:20763 这个模板第一次添加大概率全都没有数据,因为指标名变了。
可以从右上角【个人资料】修改默认仪表盘,每次登录就可以直接看到了
在稍微熟悉之后,就可以自定义自己的面板了,grafana 提供了多种数据显示格式,拖动组件使用指标值构建,比较方便。这里针对 20763 模板数据指标不存在的情况进行说明:
在每个组件的右上角展开选择【编辑】,修改下方指标表达式,一般就是新版本采集器指标名变了找不到,这个时候就参考 windows_exporter GitHub 指标说明进行一一修正即可,如果对表达式不满意也可以自己调整。
iKuai Prometheus Exporter
Github 仓库地址:https://github.com/jakeslee/ikuai-exporter
虽然已经很久没有更新了,但是还是可以用。
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
在 ikuai 后台新建一个只读权限的 prometheus 用户
在 prometheus.yml 中引入
检查指标是否正常:http://localhost:9090
导入 Grafana 面板ID:19247
正常情况下,导入之后应该几乎没有数据,因为指标名对不上,因此需要编辑面板,参考默认指标名与 metrics 实际情况进行调整。
另一个可选的项目是 ikuai-aio ,将 ikuai exporter+ grafana + prometheus 打包到了一起,如果还没有单独部署 grafana 这套可以直接用这个。
PVE exporter
起因是上个周日起床,打开电脑,准备先美美刷会B站,发现怎么上不了网,一开始还以为是不是代理的问题,重新打开也不行,甚至部署的 uptime-kuma 全都红了。阿哲,看来眼路由器是正常的欸,然后怀疑是 OpenWrt 的问题,因为之前也出现过卡死的情况导致没网,加上电脑配的网关地址就是 Op,基本怀疑是这玩意可能有问题。登录 PVE 控制台一看,直接满屏的 OutOfMemory,赶紧把内存从512M增加到1024M,重启,果然恢复了。然后这两天就想着抽空给 PVE 加个监控,万一后面又挂了至少能及时知道。
安装 Python3.9+,在 PVE 9版本默认安装了 3.13 的python了;
安装 pip: apt install python3-pip;
安装 PVE exporter:
1 2 3 python -m venv prometheus source prometheus/bin/activate pip install prometheus-pve-exporter
新增配置文件: /etc/prometheus/pve.yml
1 2 3 4 5 6 7 8 9 mkdir -p /etc/prometheuscat <<EOF > /etc/prometheus/pve.yml default: user: prometheus@pve token_name: "your-token-id" token_value: "..." verify_ssl: false EOF
添加服务:
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
重载 systemd
1 2 3 systemctl daemon-reload systemctl start prometheus-pve-exporter systemctl status prometheus-pve-exporter
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 - 192.168 .1 .3 :9221 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 - 192.168 .1 .3 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