当前位置: 首页 > news >正文

【Prometheus+Grafana实战:搭建监控系统(含告警配置)】

什么是Prometheus和Grafana?

  • Prometheus:一款开源的监控告警工具,擅长时序数据存储和多维度查询(通过PromQL),采用Pull模型主动抓取目标指标。
  • Grafana:数据可视化平台,支持多种数据源(如Prometheus),通过丰富的仪表盘展示监控数据。
  • 核心协作流程
    • Exporters(如Node Exporter)采集指标 → Prometheus存储并计算 → Grafana可视化展示 → Alertmanager触发告警。

监控系统核心流程:

  1. 数据采集
    📥 Exporters(如 node_exportermysqld_exporter)从目标系统(主机、MySQL等)收集指标。
  2. 数据存储与计算
    🗃️ Prometheus 定期从 Exporters 拉取(Pull) 数据,存储为时序数据,并通过 PromQL 进行实时计算。
  3. 可视化展示
    📊 Grafana 从 Prometheus 读取数据,通过预定义仪表盘(如ID 1860)展示监控图表。
  4. 告警触发与通知
    🔔 Prometheus 根据告警规则(如CPU > 85%)触发告警 → Alertmanager 分组、路由告警 → 通过邮件/Slack通知用户。

与Zabbix的对比与优势

  • 数据模型:Prometheus的多维标签比Zabbix的扁平键值更灵活。
  • 扩展性:通过Exporters轻松集成新系统,无需定制脚本。
  • 云原生支持:天然适配Kubernetes,适合容器化环境。

建议从监控主机和现有Docker服务入手,逐步扩展至MySQL、Tomcat,最终实现全栈监控+告警闭环。

组件介绍

1、数据采集类(Exporters)

组件名称核心功能适用场景官方文档
Node Exporter采集主机基础指标(CPU、内存、磁盘、网络等)监控物理机/虚拟机性能GitHub
cAdvisor采集容器资源使用指标(CPU、内存、网络、文件系统)监控 Docker 容器GitHub
MySQL Exporter采集 MySQL 数据库性能指标(查询数、连接数等)监控 MySQL 数据库状态GitHub
JMX Exporter将 Java 应用的 JMX 指标转换为 Prometheus 格式监控 Tomcat、Kafka 等 Java 应用GitHub
Blackbox Exporter通过 HTTP/HTTPS、TCP、ICMP 探测服务可用性监控网站可用性、端口存活状态GitHub
SNMP Exporter采集网络设备(交换机、路由器)的 SNMP 指标监控网络设备性能GitHub
  • cAdvisor google镜像gcr.io/cadvisor/cadvisor网络无法pull可使用bitnami/cadvisor:0.52.1

2、数据存储与处理类

组件名称核心功能适用场景
Prometheus Server时序数据库,存储监控数据,支持 PromQL 查询核心组件,必选
Thanos提供 Prometheus 高可用、长期存储和全局查询大规模监控集群数据聚合
VictoriaMetrics高性能时序数据库,兼容 Prometheus 协议替代 Prometheus TSDB,适合海量数据

3、可视化与告警类

组件名称核心功能适用场景
Grafana可视化平台,支持多种数据源和仪表盘模板数据展示,必选
Alertmanager告警路由、去重、静默,支持邮件/Slack/Webhook集中管理告警通知
Grafana Loki日志聚合系统,与 Prometheus 指标联动监控日志数据(需搭配 Promtail)

4、辅助工具类

组件名称核心功能适用场景
Pushgateway接收短期任务(如批处理作业)的指标推送监控 Cron 任务、一次性脚本
Prometheus Operator在 Kubernetes 中自动化管理 Prometheus 配置Kubernetes 环境监控部署
Grafana Tempo分布式追踪系统,与 Prometheus 指标联动链路追踪与性能分析

一、Server端配置

1. 配置文件目录结构

root@host4:/opt/monitor# tree
.
├── alertmanager.yml                 # Alertmanager配置
├── alert_rules.yml			    # 告警规则
├── docker-compose.yml		# Compose主文件
└── prometheus.yml			# Prometheus主配置
├── grafana-provisioning
│   ├── alerting			     #存储告警规则配置文件,用于预定义告警条件与通知策略
│   ├── dashboards			   #存放仪表板JSON配置文件,支持自动加载/更新仪表板(无需手动创建)
│   ├── datasources			    #配置数据源连接信息,支持多数据源并行配置(Prometheus/MySQL等)
│   │   └── prometheus.yml
│   ├── notifiers				#定义告警通知渠道(邮件/钉钉/Slack等),与alerting/目录规则联动实现告警推送
│   └── plugins				    #放置预安装插件(如可视化插件或数据源插件),容器启动时自动加载插件二进制文

2. 关键配置文件示例

docker-compose.yml - Compose主文件

services:# Prometheus核心服务prometheus:image: prom/prometheus:v3.4.0container_name: prometheusrestart: unless-stoppednetworks:- monitor-netports:- "9090:9090"volumes:- prometheus_data:/prometheus                # 时序数据库持久化存储- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro  # 主配置文件注入- ./alert_rules.yml:/etc/prometheus/alert_rules.yml:ro # 告警规则注入command:- --config.file=/etc/prometheus/prometheus.yml- --storage.tsdb.retention.time=30d          # 数据保留30天- --web.enable-lifecycle                     # 启用配置热加载environment:- TZ=Asia/Shanghai                           # 时区设置deploy:resources:limits:cpus: '1.0'memory: 2G# Grafana可视化grafana:image: grafana/grafana:10.1.5container_name: grafanarestart: unless-stoppednetworks:- monitor-netports:- "3000:3000"volumes:- grafana_data:/var/lib/grafana              # 配置/仪表盘持久化- ./grafana-provisioning:/etc/grafana/provisioning # 预配置仪表盘environment:- GF_SECURITY_ADMIN_PASSWORD=L1L7WxZ443iyZd  #必须修改为复杂密码
#      - GF_SERVER_DOMAIN=monitor.yourcompany.com   # 生产域名,若没有域名可注释或删除此行- GF_SERVER_SERVE_FROM_SUB_PATH=true        # 强制使用IP访问(可选)- GF_SERVER_ENABLE_GZIP=true- GF_USERS_ALLOW_SIGN_UP=false               # 禁用公开注册- GF_AUTH_DISABLE_LOGIN_FORM=false            # SSO登录,需正确配置代理认证(需后端支持)- GF_AUTH_PROXY_ENABLED=false                 #代理认证
#      - GF_AUTH_PROXY_HEADER_NAME=X-WEBAUTH-USER   #代理认证- GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS=false- GF_DATABASE_TYPE=postgres- GF_DATABASE_HOST=postgres- GF_DATABASE_USER=grafana- GF_DATABASE_PASSWORD=L1L7WxZ443iyZd- GF_LIVE_ENABLED=false- GF_PLUGINS_DISABLE_AUTOLOAD=true  # 禁用插件自动加载
#      - GF_PATHS_PLUGINS=/var/lib/grafana/plugins  # 显式指定插件路径
#      - GF_DEFAULT_PLUGINS_PATH=/dev/null          # 禁用默认插件路径depends_on:postgres:condition: service_healthy  # 等待 PostgreSQL 健康检查通过prometheus:condition: service_started  # 确保 Prometheus 已启动deploy:resources:limits:cpus: '0.5'memory: 1G# Node Exporter示例 (按需部署到各主机)node-exporter:image: prom/node-exporter:v1.9.1container_name: node-exporterrestart: unless-stoppednetworks:- monitor-netports:- "9100:9100"volumes:- /proc:/host/proc:ro- /run/udev:/run/udev:ro #获取磁盘设备信息- /sys:/host/sys:ro- /:/rootfs:rocommand:- --path.procfs=/host/proc- --path.sysfs=/host/sysdeploy:resources:limits:cpus: '0.2'memory: 256M# 容器监控(可选)cadvisor:image: bitnami/cadvisor:0.52.1
#    image: google/cadvisor:v0.33.0user: "0:996"  # root 用户 + docker 组 GIDcontainer_name: cadvisorrestart: unless-stoppednetworks:- monitor-netports:- "8080:8080"volumes:- /:/rootfs:ro,rslave                       # 只读挂载防止篡改- /var/run:/var/run:ro,rslave- /sys:/sys:ro,rslave- /var/lib/docker:/var/lib/docker:ro,rslave #解决日志中 Failed to get system UUID 警告- /etc/machine-id:/etc/machine-id:ro  #挂载 /dev/disk:更精确的磁盘监控- /dev/disk:/dev/disk:roprivileged: true                               # 必须权限
#    command:
#      - --docker_only=true  #仅监控 Docker 容器(隐式禁用 CRI-O/Podman 检测)
#      - --disable_metrics=hugetlb,advtcp,udp  # 可选:禁用不常用指标(减少日志干扰)deploy:resources:limits:cpus: '0.5'memory: 1Gpostgres:image: postgres:15restart: alwayshealthcheck:test: ["CMD-SHELL", "pg_isready -U grafana -d grafana || exit 1"]interval: 5stimeout: 5sretries: 10networks:- monitor-netenvironment:POSTGRES_USER: grafanaPOSTGRES_PASSWORD: L1L7WxZ443iyZdPOSTGRES_DB: grafanaPOSTGRES_HOST_AUTH_METHOD: scram-sha-256  # 启用加密认证POSTGRES_INITDB_ARGS: "--auth-host=scram-sha-256 --auth-local=scram-sha-256" #安全加固volumes:- postgres_data:/var/lib/postgresql/datadeploy:resources:limits:memory: 512M# 自定义网络隔离监控系统流量
networks:monitor-net:driver: bridgeattachable: truevolumes:prometheus_data: {}  # Prometheus时序数据持久化grafana_data: {}     # Grafana配置/仪表盘数据持久化postgres_data: {}

核心必选模块

服务名必要性说明
prometheus必选监控数据存储与计算核心,不可缺失
grafana必选可视化必备组件
node-exporter必选采集主机基础指标(CPU/内存/磁盘等)

按需选装模块

服务名必要性场景建议
cadvisor可选需监控Docker容器时启用
alertmanager可选需告警通知时启用(初期可跳过,后续添加)

prometheus.yml - Prometheus抓取目标配置

global:                 # 全局采集参数scrape_interval: 15s  # 抓取间隔evaluation_interval: 15s # 告警规则评估间隔# 告警规则加载
rule_files:             # 告警规则文件路径- "/etc/prometheus/alert_rules.yml"# 抓取目标配置
scrape_configs:         # 监控目标定义- job_name: "node"    # 监控组名称 static_configs:- targets: ["node-exporter:9100"]  # 监控本机node-exporter- job_name: "docker"static_configs:- targets: ["cadvisor:8080"]       # 监控容器# 示例:添加其他主机监控(需对应主机部署node-exporter)- job_name: "host1-node" # 监控其他主机示例static_configs:- targets: ["192.168.0.221:9100"] # 修改为host1的实际IP(需确保host1的node_exporter已运行)# 监控 MySQL Exporter- job_name: "mysql"                   # MySQL监控示例(需先部署mysqld_exporter)scrape_interval: 30s  # 降低抓取频率(根据负载调整)static_configs:- targets: ["192.168.0.221:9104"]params:collect[]:  # 指定需要收集的指标组(减少冗余数据)- standard- engine_innodb
#    scheme: https                        # 若启用HTTPStls_config:insecure_skip_verify: true         # 跳过证书验证(生产环境建议配置CA)

alert_rules.yml - 告警规则定义

groups:
- name: host-alertsrules:- alert: HighCpuUsageexpr: 100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85for: 5mlabels:severity: criticalannotations:summary: "High CPU usage on {{ $labels.instance }}"

alertmanager.yml - 告警通知配置

route:group_by: ['alertname']  # 按告警名称分组group_wait: 30s          # 同一组告警等待时间group_interval: 5m       # 发送新告警间隔repeat_interval: 4h      # 重复发送相同告警间隔receiver: 'email-notice' # 默认接收器receivers:
- name: 'email-notice'email_configs:- to: 'admin@yourcompany.com'			# 修改为实际接收邮箱from: 'alert@monitor.com'smarthost: 'smtp.yourcompany.com:587'	# 根据邮箱服务商修改auth_username: 'alert@monitor.com'		# 发件邮箱账号auth_password: 'your-smtp-password'		# 邮箱SMTP授权码(非登录密码)send_resolved: true

grafana-provisioning/datasources/prometheus.yml - Grafana数据源预配置

apiVersion: 1
datasources:- name: Prometheustype: prometheusurl: http://prometheus:9090access: proxyisDefault: true

3. 部署前准备

# 创建配置文件目录
mkdir -p /opt/monitor/{grafana-provisioning/dashboards,grafana-provisioning/datasources,grafana-provisioning/alerting,grafana-provisioning/notifiers,grafana-provisioning/plugins}# 生成配置文件(手动填充上述示例内容)
touch /opt/monitor/docker-compose.yml
touch /opt/monitor/prometheus.yml
touch /opt/monitor/alert_rules.yml
touch /opt/monitor/alertmanager.yml
touch /opt/monitor/grafana-provisioning/datasources/prometheus.yml# 设置文件权限(防止容器权限问题)
chmod -R 755 /opt/monitor/grafana-provisioning

4. 启动服务

cd /opt/monitor
docker compose up -d  # 后台启动

5. 部署后验证

  • 检查容器状态

    docker compose ps  # 确保所有服务状态为 "Up"
    docker compose logs #查看全部日志
    docker compose logs --no-color | grep -i -E "error|fail|exception|warning|timeout"
    
  • 访问服务

    • Grafana: http://host4-ip:3000(默认账号admin/YourStrongPassword
    • Prometheus: http://host4-ip:9090/targets 查看抓取目标状态
  • 导入仪表盘

    1. Grafana中导航至 Create > Import,输入仪表盘ID(如1860
    2. 选择Prometheus数据源

二、客户端配置

我这里准备在host1:192.168.0.221配置客户端,上面已安装mysql, tomcat

1. 配置Node Exporter(监控主机资源)

在每台客户端主机(host1)创建以下 docker-compose.node.yml 文件:

services:node-exporter:image: prom/node-exporter:v1.9.1container_name: node-exporterrestart: unless-stoppedports:- "9100:9100"volumes:- /proc:/host/proc:ro- /sys:/host/sys:ro- /:/rootfs:ro- /run/udev:/run/udev:ro #获取磁盘设备信息command:- --path.procfs=/host/proc- --path.sysfs=/host/sysnetworks:- app_ry-networkdeploy:resources:limits:cpus: '0.2'memory: 256Mnetworks:app_ry-network:driver: bridgeexternal: true

启动服务:

docker-compose -f docker-compose.node.yml up -d

检查是否有数据: 192.168.0.221:9100/metrics


2. 配置MySQL Exporter(监控MySQL)

创建 MySQL 监控专用用户

  1. 登录 MySQL
    在 MySQL 所在的主机(host1)上,使用管理员账号登录 MySQL:

    mysql -u root -p
    
  2. 创建监控用户并授权
    执行以下 SQL 语句,创建 exporter 用户并授予最小必要权限:

    CREATE USER 'exporter'@'%' IDENTIFIED BY 'your.secure.password1' WITH MAX_USER_CONNECTIONS 3;
    GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'%';
    FLUSH PRIVILEGES;
    mysql -uexporter -pyour.secure.password1
    
    • your.secure.password:替换为强密码(需与后续 mysqld-exporter 配置一致)。
    • MAX_USER_CONNECTIONS 3:限制最大连接数,防止监控占用过多资源。

在MySQL所在主机(host1)创建 docker-compose.mysql-exporter.yml

创建my.cnf

cat my.cnf
[client]
user = exporter
password = your.secure.password1
host = ry-mysql  # 关键:指定 MySQL 容器的主机名
port = 3306      # 可选:显式指定端口
#[client.servers] #可配置多个连接
#user = bar
#password = bar123
services:mysqld-exporter:image: prom/mysqld-exporter:v0.17.2container_name: mysqld-exporterrestart: unless-stoppedports:- "9104:9104"networks:- app_ry-network #与mysql同一网络volumes:- ./my.cnf:/.my.cnfdeploy:resources:limits:cpus: '0.5'memory: 512Mnetworks:app_ry-network:driver: bridgeexternal: true  # 关键:声明为外部网络

启动服务:

docker-compose -f docker-compose.mysql-exporter.yml up -d

验证: 192.168.0.221:9104/metrics 是否有数据


3. 配置Tomcat JMX Exporter(监控Tomcat)

集成 JMX Exporter 到 Tomcat 容器:

  1. 创建JMX配置文件 jmx-config.yml
nano jmx-config.yml
rules:- pattern: ".*"
  1. 下载 JMX Exporter 文件

Release 1.3.0 / 2025-05-16 · prometheus/jmx_exporter

  1. 修改Tomcat的 docker-compose.yml,添加JMX Exporter参数:
services:ry-tomcat:image: harbor.host3/ruoyi/ry-tomcat:39environment:CATALINA_OPTS: "-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=12345 -Dcom.sun.management.jmxremote.rmi.port=12346 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=192.168.0.221 -javaagent:/jmx/jmx_prometheus_javaagent-1.3.0.jar=9404:/jmx/jmx-config.yml"volumes:- ./jmx-config.yml:/jmx/jmx-config.yml  # 挂载配置文件- ./jmx_prometheus_javaagent-1.3.0.jar:/jmx/jmx_prometheus_javaagent-1.3.0.jar  # 挂载 Agentports:- "9404:9404"  # 新增:暴露 JMX Exporter 的 HTTP 端口

测试连接

192.168.0.221:9404/metrics 搜索应有mysql_up 1

  1. 确认 Prometheus 抓取配置

      - job_name: "tomcat"static_configs:- targets: ["192.168.0.221:9404"]
    

    热加载(推荐)
    Prometheus 支持通过 API 热加载配置,无需重启:

    curl -X POST http://prometheus-host:9090/-/reload
    curl -X POST http://192.168.0.224:9090/-/reload
    

    前提:启动 Prometheus 时需添加 --web.enable-lifecycle 参数(已在您的 docker-compose.yml 中配置)。

参数必要性作用
-Dcom.sun.management.jmxremote必要启用 JMX 远程管理功能,无此参数无法通过 JMX 连接。
-Dcom.sun.management.jmxremote.port=12345必要指定 JMX 连接的端口,Prometheus 通过此端口访问 JMX 数据。
-Dcom.sun.management.jmxremote.rmi.port=12346可选指定 RMI 通信端口,仅在需要远程方法调用(RMI)时使用,通常与 JMX 端口一致可省略。
-Dcom.sun.management.jmxremote.ssl=false可选禁用 SSL 加密。生产环境建议启用 SSL(设置为 true),测试环境可禁用。
-Dcom.sun.management.jmxremote.authenticate=false可选禁用认证。生产环境必须启用认证(设置为 true),测试环境可禁用。
-Djava.rmi.server.hostname=192.168.0.221必要指定 RMI 通信的主机名,容器化环境中必须设置为宿主机 IP 或可解析的域名。

启用 JMX 认证的步骤(生产环境建议配置)

  1. 生成密码文件
    创建 jmxremote.password 文件(示例内容):

    monitor  password123  # 用户名和密码
    
  2. 设置文件权限

    chmod 600 jmxremote.password  # 仅允许所有者读写
    
  3. 修改 Tomcat 配置

    environment:CATALINA_OPTS: "...-Dcom.sun.management.jmxremote.authenticate=true-Dcom.sun.management.jmxremote.password.file=/etc/prometheus/ssl/jmxremote.password"
    volumes:- ./jmxremote.password:/etc/prometheus/ssl/jmxremote.password
    

Prometheus 是否需要调整配置?

  • 无需调整:JMX Exporter 在 HTTP 模式下会将 JMX 数据转换为 Prometheus 兼容的指标,认证由 JMX Exporter 处理。
  • 例外情况:如果直接通过 JMX 协议抓取(非 HTTP 模式),需在 Prometheus 配置中提供凭据。但您当前使用 HTTP 模式,无需额外配置。

4. 配置Prometheus服务端(host4)

修改 prometheus.yml,添加新的抓取目标:

scrape_configs:# 原有配置...- job_name: "host1-node" # 监控host1static_configs:- targets: ["192.168.0.221:9100"] # 修改为host1的实际IP(需确保host1的node_exporter已运行)# 监控 MySQL Exporter- job_name: "mysql"                   # MySQL监控示例(需先部署mysqld_exporter)scrape_interval: 30s  # 降低抓取频率(根据负载调整)static_configs:- targets: ["192.168.0.221:9104"]params:collect[]:  # 指定需要收集的指标组(减少冗余数据)- standard- engine_innodb  # 监控 MySQL Exporter- job_name: "tomcat"static_configs:- targets: ["192.168.0.221:9404"]

热加载配置(或重启Prometheus):

curl -X POST http://192.168.0.224:9090/-/reload

前提:启动 Prometheus 时需添加 --web.enable-lifecycle 参数(已在您的 docker-compose.yml 中配置)。

网页上可查看状态

http://192.168.0.224:9090/targets
在这里插入图片描述


5. Grafana操作步骤

  1. 登录Grafana:访问 http://192.168.0.221:3000,使用管理员账号登录。
  2. 导入仪表板
    • 点击左侧菜单 ➔ DashboardsNewImport
    • 输入仪表板ID(例如:8919 用于Node Exporter,11323 用于MySQL)。load

在这里插入图片描述

  • 选择数据源为 Prometheus, Import

在这里插入图片描述

  1. 验证数据
  • 在仪表板中选择对应的监控目标,查看指标是否正常显示。

在这里插入图片描述

6.更多 Grafana 仪表板模板

  • 官方模板库
    Grafana 官方提供了丰富的仪表板模板,涵盖 MySQL、Node Exporter、JVM 等各类监控场景。访问 Grafana Dashboards,搜索关键词如 MySQLNode ExporterPrometheus,筛选高评分模板。例如:
    • MySQL 监控:ID 7362(更详细的性能分析)、12826(分库分表监控)。
    • 主机监控:ID 1860(Node Exporter 增强版)、11074(多维度资源展示)。
    • 容器监控:ID 315(Docker 容器资源使用)。
  • 社区推荐模板
    部分模板针对特定场景优化,例如:
    • 综合监控:ID 10000(集成主机、MySQL、Redis 等指标)。
    • 告警关联视图:ID 6663(展示告警与指标的关联性)。
  • 自定义模板
    若现有模板不满足需求,可基于已有模板修改或自行创建。Grafana 支持通过 JSON 文件导入导出,结合 PromQL 灵活定制。

三、配置告警规则

  • 配置Alertmanager
    定义告警规则(如CPU>80%),集成邮件、Slack等通知渠道。

1. 安装 Alertmanager

推荐安装位置:与 Prometheus 同Server主机(host4),确保网络互通。
使用 Docker Compose 安装:在现有的 docker-compose.yml 中添加 Alertmanager 服务:

  alertmanager:profiles:- alertmanagerimage: prom/alertmanager:v0.28.1container_name: alertmanagerrestart: unless-stoppednetworks:- monitor-netports:- "9093:9093"volumes:- ./alertmanager.yml:/etc/alertmanager/alertmanager.yml:rocommand:- --config.file=/etc/alertmanager/alertmanager.yml- --cluster.advertise-address=alertmanager:9093depends_on:- prometheusdeploy:resources:limits:cpus: '0.3'memory: 512M

启动服务

#profiles:
#      - alertmanager
#使用profiles需指定名称启动,也可去除同时启动
docker compose --profile alertmanager up -d alertmanager

2. 配置 Alertmanager 邮件通知

步骤 1:创建 alertmanager.yml 文件

qq邮箱示例

https://mail.qq.com/–>登录–>设置–>账号–>POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务

开启服务获取授权码

route:group_by: ['alertname']  # 按告警名称分组group_wait: 30s          # 同一组告警等待时间group_interval: 5m       # 发送新告警间隔repeat_interval: 4h      # 重复发送相同告警间隔receiver: 'email-notice' # 默认接收器retry_interval: 1m       # 重试间隔,默认 5mreceivers:
- name: 'email-notice'email_configs:- to: 'aaa@qq.com'	      # 接收告警的邮箱from: 'xxx@qq.com'	# SMTP 服务器地址(根据邮箱服务商修改)smarthost: 'smtp.qq.com:465'	# 根据邮箱服务商修改auth_username: 'xx@qq.com'	# SMTP 登录账号auth_password: 'xxxxx'		# 邮箱SMTP授权码(非登录密码)send_resolved: true              # 发送告警恢复通知require_tls: false  # 禁用 STARTTLShello: 'qq.com'     # 指定 SMTP 服务器的 HELO 标识tls_config:insecure_skip_verify: true  # 忽略证书验证(可选)(测试环境)# server_name: smtp.qq.com  # 生产环境建议填写

常见邮箱 SMTP 配置示例

邮箱服务商SMTP 地址端口加密方式
Gmailsmtp.gmail.com587STARTTLS
QQ 邮箱smtp.qq.com465SSL
企业邮箱smtp.yourcompany.com25

3. 配置 Prometheus 告警规则

步骤 1:创建告警规则文件 alert_rules.yml

groups:
- name: host-alertsrules:- alert: HighCpuUsageexpr: 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85for: 5mlabels:severity: criticalannotations:summary: "实例 {{ $labels.instance }} CPU 使用率过高"description: "CPU 使用率持续5分钟超过85%,当前值为 {{ $value }}%"- alert: LowMemoryAvailableexpr: (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100) < 10for: 10mlabels:severity: warningannotations:summary: "实例 {{ $labels.instance }} 可用内存不足"description: "可用内存低于10%,当前剩余 {{ $value | humanize }}%"- name: mysql-alertsrules:- alert: MysqlDownexpr: mysql_up == 0for: 1mlabels:severity: criticalannotations:summary: "MySQL 服务不可用"description: "MySQL 实例 {{ $labels.instance }} 已宕机超过1分钟"

步骤 2:在 prometheus.yml 中引用告警规则

rule_files:- "/etc/prometheus/alert_rules.yml"  # 容器内路径(需挂载)alerting:alertmanagers:- static_configs:- targets: ['alertmanager:9093']  # Alertmanager 服务地址

步骤 3:重启 Prometheus 服务

docker compose restart prometheus

4. 验证告警配置

步骤 1:访问 Prometheus 告警页面
打开 http://192.168.0.224:9090/alerts,检查告警规则是否加载成功,状态是否为正常。

在这里插入图片描述

步骤 2:触发测试告警

  • 模拟高 CPU 使用率

    stress -c 2  # 在监控的主机上运行(需安装 stress 工具)
    
  • 手动停止 MySQL 服务

    docker stop ry-mysql
    

步骤 3:查看 Alertmanager 界面
访问 http://host4:9093,确认告警是否显示,并检查邮件是否收到通知。

在这里插入图片描述

在这里插入图片描述


5. 其他告警配置选项

1. 多通知渠道集成

Alertmanager 支持以下通知方式(需在 alertmanager.yml 中配置):

  • Slack

    - name: 'slack-notice'slack_configs:- api_url: 'https://hooks.slack.com/services/XXXX/YYYY/ZZZZ'channel: '#alerts'
    
  • Webhook(对接企业微信、钉钉):

    - name: 'webhook-notice'webhook_configs:- url: 'http://webhook-server:5000/alert'
    
  • PagerDuty

    - name: 'pagerduty-notice'pagerduty_configs:- service_key: 'your-pagerduty-key'
    

2. 告警分组与抑制

  • 分组(Grouping):将相似告警合并发送,减少通知噪音。

  • 抑制(Inhibition):当某类告警触发时,抑制其他相关告警。

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

3. 静默(Silence)

在 Alertmanager 界面中设置临时静默,屏蔽特定时间段或条件的告警。

4.其他告警通知方式(短信/钉钉/企业微信)

若需发送短信,可通过以下方式集成:

1. 通过短信网关 API
receivers:
- name: 'sms-notice'webhook_configs:- url: 'http://sms-gateway-api:8080/send'send_resolved: truehttp_config:basic_auth:username: 'api-user'password: 'api-password'
2. 通过钉钉机器人
receivers:
- name: 'dingtalk-notice'webhook_configs:- url: 'https://oapi.dingtalk.com/robot/send?access_token=xxxx'send_resolved: true
3. 通过企业微信
receivers:
- name: 'wecom-notice'wechat_configs:- corp_id: 'your-corp-id'to_party: '2'agent_id: '1000002'api_secret: 'your-api-secret'


6.故障排查指南

问题现象排查步骤
告警未触发检查 Prometheus 的 /alerts 页面,确认规则语法正确且表达式返回值符合预期。
邮件未收到验证 SMTP 配置,检查 Alertmanager 日志 docker logs alertmanager
Alertmanager 无法连接 Prometheus确认 Prometheus 的 alerting 配置中地址正确,网络互通。
1. 部署与配置问题

问题1:Prometheus 配置文件语法错误

  • 日志错误示例

    level=error ts=2024-03-01T12:00:00Z caller=main.go:123 err="error loading config from \"/etc/prometheus/prometheus.yml\": parsing YAML file: yaml: line 5: did not find expected key"
    
  • 解决方案
    使用 promtool 工具验证配置文件语法:

    docker exec prometheus promtool check config /etc/prometheus/prometheus.yml
    

    修复提示的语法错误(如缩进、冒号缺失)。


问题2:Grafana 数据源配置错误

  • 日志错误示例

    t=2024-03-01T12:00:00Z lvl=eror msg="Failed to query Prometheus" error="client_error: client error: 404"
    
  • 解决方案
    检查 grafana-provisioning/datasources/prometheus.ymlurl 配置:

    # 确保地址为 Prometheus 容器名称(容器内通信)
    url: http://prometheus:9090
    

    重启 Grafana 服务:

    docker compose restart grafana
    

问题3:Alertmanager 集群通信失败

  • 错误日志

    time=2025-05-26T21:33:45.119Z level=ERROR source=main.go:259 msg="unable to initialize gossip mesh" err="create memberlist: Failed to get final advertise address: Failed to parse advertise address \"alertmanager\""
    
  • 原因

    • 单机部署 Alertmanager 时未禁用集群模式,导致尝试初始化 Gossip 协议失败。
    • 容器名 alertmanager 无法解析为有效 IP。
  • 解决方案
    禁用集群模式

    # docker-compose.yml 中 Alertmanager 的配置
    services:alertmanager:command:- --config.file=/etc/alertmanager/alertmanager.yml- --cluster.listen-address=  # 禁用集群模式
    

问题一:JMX Exporter 参数格式错误导致 Tomcat 启动失败

  • 错误日志

    java.lang.ClassNotFoundException: org.apache.juli.ClassLoaderLogManager
    
  • 原因

    • CATALINA_OPTS 参数未正确使用 YAML 多行语法。
    • JMX Exporter 的 Agent 路径或配置文件未挂载。
  • 解决方案
    修正参数格式和挂载路径

    # docker-compose.yml 中 Tomcat 的配置
    services:ry-tomcat:environment:CATALINA_OPTS: "-javaagent:/jmx/jmx_prometheus_javaagent-1.3.0.jar=9404:/jmx/jmx-config.yml"volumes:- ./jmx-config.yml:/jmx/jmx-config.yml- ./jmx_prometheus_javaagent-1.3.0.jar:/jmx/jmx_prometheus_javaagent-1.3.0.jar
    

问题二:Alertmanager TLS 配置冲突

  • 错误日志

    level=WARN source=notify.go:866 msg="Notify attempt failed" err="'require_tls' is true but \"smtp.qq.com:465\" does not advertise STARTTLS"
    
  • 原因

    • QQ 邮箱的 465 端口使用 SSL 加密,但 Alertmanager 默认要求 STARTTLS。
  • 解决方案
    显式禁用 TLS 并指定 SSL 端口

    # alertmanager.yml 中的 SMTP 配置
    email_configs:
    - smarthost: 'smtp.qq.com:465'require_tls: false  # 禁用 STARTTLS
    

2. 网络与连接问题

问题3:Prometheus 无法连接 Exporter(Targets 显示 DOWN)

  • 日志错误示例

    level=error ts=2024-03-01T12:00:00Z caller=scrape.go:1320 msg="Error scraping target" target="http://192.168.0.221:9100/metrics" err="Get \"http://192.168.0.221:9100/metrics\": context deadline exceeded"
    
  • 解决方案

    • 检查 Exporter 端口是否暴露:

      docker ps --filter "name=node-exporter" --format "{{.Ports}}"
      
    • 测试网络连通性:

      curl http://192.168.0.221:9100/metrics  # 在 Prometheus 容器内执行
      
    • 确保 Docker 网络配置一致(使用同一自定义网络)。


问题4:Alertmanager 无法接收 Prometheus 告警

  • 日志错误示例(Prometheus 日志):

    level=error ts=2024-03-01T12:00:00Z caller=notifier.go:256 component=notifier alertmanager=http://alertmanager:9093/api/v2/alerts count=1 msg="Error sending alert" err="Post \"http://alertmanager:9093/api/v2/alerts\": dial tcp: lookup alertmanager on 127.0.0.11:53: no such host"
    
  • 解决方案
    prometheus.yml 中确认 Alertmanager 地址正确:

    alerting:alertmanagers:- static_configs:- targets: ['alertmanager:9093']  # 使用容器名称而非IP
    

    确保 docker-compose.yml 中 Alertmanager 与 Prometheus 共享同一网络。


3. 数据采集与指标问题

问题5:Exporter 未暴露指标(/metrics 端点无数据)

  • 日志错误示例(Node Exporter 日志):

    level=error ts=2024-03-01T12:00:00Z caller=collector.go:123 msg="collector failed" name=meminfo err="could not get meminfo: open /host/proc/meminfo: no such file or directory"
    
  • 解决方案
    检查 Exporter 的挂载路径是否正确(如 Node Exporter):

    volumes:- /proc:/host/proc:ro  # 必须挂载宿主机 /proc- /sys:/host/sys:ro
    

    重启 Exporter 并验证:

    curl http://localhost:9100/metrics | grep "node_"
    

问题6:Grafana 仪表盘显示 “No Data”

  • 日志错误示例(Grafana 日志):

    t=2024-03-01T12:00:00Z lvl=eror msg="Query error" error="invalid parameter 'query': parse error at char 15: syntax error: unexpected IDENT, expecting string or number"
    
  • 解决方案

    • 检查 PromQL 语法(如 node_memory_MemAvailable_bytes 是否拼写正确)。

    • 确认 Prometheus 中存在对应指标:

      curl http://prometheus:9090/api/v1/label/__name__/values | jq  # 列出所有指标名
      

4. 告警配置与通知问题

问题7:告警规则未触发(Prometheus 无告警)

  • 日志错误示例(Prometheus 日志):

    level=warn ts=2024-03-01T12:00:00Z caller=manager.go:654 component="rule manager" msg="Evaluating rule failed" rule="alert=HighCpuUsage" err="invalid expression type \"\" for range query, must be Scalar or instant Vector"
    
  • 解决方案
    检查告警规则的 expr 表达式是否为合法 PromQL(需返回瞬时向量):

    # 错误示例(缺少聚合函数)
    expr: node_cpu_seconds_total{mode="idle"} > 85# 正确示例(使用 avg 聚合)
    expr: 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100 > 85
    

问题8:Alertmanager 发送邮件失败

  • 日志错误示例(Alertmanager 日志):

    level=error ts=2024-03-01T12:00:00Z caller=notify.go:674 component=dispatcher msg="Error on notify" err="*email.loginAuth auth: 550 User has no permission"
    
  • 解决方案
    检查 alertmanager.yml 的 SMTP 配置(以 QQ 邮箱为例):

    receivers:- name: 'email-notice'email_configs:- to: 'user@qq.com'from: 'sender@qq.com'smarthost: 'smtp.qq.com:465'auth_username: 'sender@qq.com'auth_password: 'xxxxx'  # 使用 SMTP 授权码,非登录密码require_tls: false       # 禁用 STARTTLStls_config:insecure_skip_verify: true  # 测试环境跳过证书验证
    

    确保邮箱已开启 SMTP 服务并生成授权码。


5. 权限与安全设置问题

问题9:容器因权限问题无法启动

  • 日志错误示例(cAdvisor 日志):

    F0301 12:00:00.000000       1 cadvisor.go:175] Failed to start container manager: inotify_add_watch /sys/fs/cgroup/cpuacct,cpu: permission denied
    
  • 解决方案
    docker-compose.yml 中为 cAdvisor 添加特权模式:

    cadvisor:privileged: true  # 必须开启特权模式volumes:- /:/rootfs:ro,rslave- /var/run:/var/run:ro,rslave
    

问题10:Grafana 登录失败(权限不足)

  • 日志错误示例

    t=2024-03-01T12:00:00Z lvl=eror msg="Failed to login" error="invalid username or password"
    
  • 解决方案
    重置管理员密码(通过环境变量或配置文件):

    environment:- GF_SECURITY_ADMIN_PASSWORD=NewPassword123  # 在 docker-compose.yml 中设置
    

    重启 Grafana 后使用新密码登录。

问题一:MySQL 用户权限不足

  • 错误日志

    time=2025-05-26T19:02:01.678Z level=ERROR source=exporter.go:131 msg="Error opening connection to database" err="Access denied for user 'exporter'@'%'"
    
  • 原因

    • exporter 用户缺少 PROCESSREPLICATION CLIENTSELECT 权限。
  • 解决方案
    授予权限并刷新

    -- 在 MySQL 中执行
    GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'%';
    FLUSH PRIVILEGES;
    


6. 容器化环境中的特殊问题

问题11:Docker 容器间网络不通

  • 日志错误示例(Prometheus Targets 页面显示 Connection refused)。

  • 解决方案
    确保所有服务使用同一 Docker 网络:

    # docker-compose.yml
    networks:monitor-net:driver: bridgeservices:prometheus:networks:- monitor-netgrafana:networks:- monitor-net
    

    检查容器 IP:

    docker network inspect monitor-net
    

问题12:容器挂载卷权限错误

  • 日志错误示例(Grafana 日志):

    t=2024-03-01T12:00:00Z lvl=eror msg="Failed to provision plugins" error="mkdir /var/lib/grafana/plugins: permission denied"
    
  • 解决方案
    调整宿主机目录权限(确保容器用户可读写):

    chmod -R 755 /opt/monitor/grafana-provisioning  # 宿主目录权限
    

    或在 docker-compose.yml 中指定用户:

    grafana:user: "472:472"  # Grafana 默认用户ID
    

7.完整实例文档

global:# The smarthost and SMTP sender used for mail notifications.smtp_smarthost: 'localhost:25'smtp_from: 'alertmanager@example.org'# The root route on which each incoming alert enters.
route:# The root route must not have any matchers as it is the entry point for# all alerts. It needs to have a receiver configured so alerts that do not# match any of the sub-routes are sent to someone.receiver: 'team-X-mails'# The labels by which incoming alerts are grouped together. For example,# multiple alerts coming in for cluster=A and alertname=LatencyHigh would# be batched into a single group.## To aggregate by all possible labels use '...' as the sole label name.# This effectively disables aggregation entirely, passing through all# alerts as-is. This is unlikely to be what you want, unless you have# a very low alert volume or your upstream notification system performs# its own grouping. Example: group_by: [...]group_by: ['alertname', 'cluster']# When a new group of alerts is created by an incoming alert, wait at# least 'group_wait' to send the initial notification.# This way ensures that you get multiple alerts for the same group that start# firing shortly after another are batched together on the first# notification.group_wait: 30s# When the first notification was sent, wait 'group_interval' to send a batch# of new alerts that started firing for that group.group_interval: 5m# If an alert has successfully been sent, wait 'repeat_interval' to# resend them.repeat_interval: 3h# All the above attributes are inherited by all child routes and can# overwritten on each.# The child route trees.routes:# This route performs a regular expression match on alert labels to# catch alerts that are related to a list of services.- matchers:- service=~"^(foo1|foo2|baz)$"receiver: team-X-mails# The service has a sub-route for critical alerts, any alerts# that do not match, i.e. severity != critical, fall-back to the# parent node and are sent to 'team-X-mails'routes:- matchers:- severity="critical"receiver: team-X-pager- matchers:- service="files"receiver: team-Y-mailsroutes:- matchers:- severity="critical"receiver: team-Y-pager# This route handles all alerts coming from a database service. If there's# no team to handle it, it defaults to the DB team.- matchers:- service="database"receiver: team-DB-pager# Also group alerts by affected database.group_by: [alertname, cluster, database]routes:- matchers:- owner="team-X"receiver: team-X-pager- matchers:- owner="team-Y"receiver: team-Y-pager# Inhibition rules allow to mute a set of alerts given that another alert is
# firing.
# We use this to mute any warning-level notifications if the same alert is
# already critical.
inhibit_rules:
- source_matchers:- severity="critical"target_matchers:- severity="warning"# Apply inhibition if the alertname is the same.# CAUTION: #   If all label names listed in `equal` are missing #   from both the source and target alerts,#   the inhibition rule will apply!equal: ['alertname']receivers:
- name: 'team-X-mails'email_configs:- to: 'team-X+alerts@example.org, team-Y+alerts@example.org'- name: 'team-X-pager'email_configs:- to: 'team-X+alerts-critical@example.org'pagerduty_configs:- routing_key: <team-X-key>- name: 'team-Y-mails'email_configs:- to: 'team-Y+alerts@example.org'- name: 'team-Y-pager'pagerduty_configs:- routing_key: <team-Y-key>- name: 'team-DB-pager'pagerduty_configs:- routing_key: <team-DB-key>

四、配置 HTTPS 及认证授权(nginx)

推荐 Prometheus 使用 HTTP,TLS 交由 NGINX 的主要原因:


✅ 1:职责分离,简化配置和维护

组件主要职责
Prometheus专注于数据抓取、存储与查询
NGINX专注于反向代理、TLS 终端、访问控制

让 NGINX 负责 TLS 意味着你只需配置一次 HTTPS,不管后端是 Prometheus、Grafana 还是其他服务,都可以共用这套 TLS 配置。这符合**“单一职责原则”**。


✅ 2:HTTPS 配置在 Prometheus 中更复杂、可维护性差

如果你坚持在 Prometheus 中启用 TLS,你需要:

  • 生成/维护一份有效证书(哪怕是自签名)
  • 配置 web.config.file,并将证书和私钥挂载进去
  • 每次证书更新要重启容器或 reload Prometheus

而在 NGINX 中,TLS 是它的第一职责,证书热重载也更成熟。


✅ 3:Prometheus 并非为生产 HTTPS 暴露而优化

Prometheus 的官方文档中对 HTTPS 支持是 “experimental(实验性)”,其主要目标是供后端服务抓取数据,而不是作为前端暴露 HTTPS 服务。反而用反向代理(如 NGINX 或 Traefik)是更常见的部署方式。


✅4:Docker 容器内部使用 HTTPS 是性能浪费

容器之间通信时,TLS 加密并没有太多意义(因为已经在同一个网络或通过 Kubernetes 网络策略隔离),使用 HTTPS 会带来额外的:

  • CPU 消耗(TLS 握手和加解密)
  • 连接复杂度
  • 不必要的证书信任验证问题(如自签名证书总是出 warning)

✅ 5:统一入口便于做访问控制和认证

你可以在 NGINX 统一做这些事情:

  • 基于路径的认证(例如 Grafana 加认证,Prometheus 只读)
  • IP 限制、速率限制、防火墙策略
  • OAuth 或 LDAP 等集成

这让整个系统更加安全、集中控制。

如果你有特殊安全需求(比如 Prometheus 暴露在公网且不能使用 NGINX),那确实可以考虑启用 Prometheus 自带的 TLS,但默认建议就是走 NGINX。


4.1.自定义 Host + 自签名证书的(测试环境)

#域名映射

# Linux
echo "192.168.0.224 monitor.host4" | sudo tee -a /etc/hosts

Windows:

  • C:\Windows\system32\drivers\etc\hosts

  • 添加一行

    • 192.168.0.224 monitor.host4
#证书存放目录
mkdir -p /opt/monitor/ssl && cd /opt/monitor/ssl
# 生成证书和私钥
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes \-subj "/CN=monitor.host4" \-addext "subjectAltName=DNS:monitor.host4,IP:192.168.0.224"
sudo chmod 644 /opt/monitor/ssl/*.pem
# 生成的 cert.pem 和 key.pem 用于后续配置

1. 修改配置文件

grafana-provisioning/datasources/prometheus.yml

apiVersion: 1
datasources:- name: Prometheustype: prometheusurl: http://prometheus:9090/prometheusaccess: proxyisDefault: true

docker-compose.yml

# Prometheusprometheus:command:- --web.route-prefix=/prometheus #- --web.external-url=/prometheus ## Grafanagrafana:environment:- GF_SERVER_ROOT_URL=https://monitor.host4/grafana/- GF_SERVER_SERVE_FROM_SUB_PATH=true
参数/变量组件含义
--web.route-prefix=/prometheusPrometheus指定 Prometheus 在 HTTP 服务端挂载的路径前缀。 所有内置页面和 API(如 /api/v1/query/graph)都将自动变为 /prometheus/api/v1/.../prometheus/graph
--web.external-url=/prometheusPrometheus告诉 Prometheus 当它生成跳转链接或 HTML 静态资源 URL 时,以此路径为根。 通常与 --web.route-prefix 配合使用,确保它发出的 <a href><script src> 正确指向子路径。
GF_SERVER_ROOT_URL=https://monitor.host4/grafana/Grafana配置 Grafana 自身生成的所有绝对跳转和资源链接的根 URL。 例如登录后重定向、仪表盘中的静态文件等,都以这个地址开头。末尾的 / 很关键,要与 NGINX 的子路径对应。
GF_SERVER_SERVE_FROM_SUB_PATH=trueGrafana告诉 Grafana “我部署在子路径下,请在内部路由中自动加上你在 GF_SERVER_ROOT_URL 里指定的那个子路径”。 只有开启后,Grafana 才会识别并正确处理 /grafana/... 这类 URI。

Prometheus

  • 外层 NGINX 反代到 /prometheus/,然后转发到容器内部的同一路径。
  • Prometheus 内部页面、API 都挂到这个子路径下,生成链接也会带上该前缀。

Grafana

  • 外层 NGINX 反代到 /grafana/,容器内部同样映射到 /grafana/
  • GF_SERVER_ROOT_URL 定义了用户在浏览器看到的根地址;
  • GF_SERVER_SERVE_FROM_SUB_PATH=true 让 Grafana 的内部路由和静态文件请求都带上子路径。

2. 安装 Nginx

宿主机直接安装(推荐)

sudo apt install -y nginx
  • 优点

    • 证书自动续期(Certbot + Cron)。
    • 性能更优,适合生产环境。
  • 缺点:

    • 依赖宿主机环境,可能与其他服务冲突。

通过Docker 部署 Nginx

# docker-compose.yml
services:nginx:image: nginx:latestports:- "80:80"- "443:443"volumes:- ./nginx.conf:/etc/nginx/nginx.conf- /opt/monitor/ssl/cert.pem:/etc/nginx/cert.pem- /opt/monitor/ssl/key.pem:/etc/nginx/key.pem- /etc/letsencrypt:/etc/letsencrypt:ro  # 若用 Let's Encryptnetworks:- monitor-net
  • 优点

    • 环境隔离,配置独立。
    • 与 Prometheus/Grafana 容器网络互通。
  • 缺点

    • 证书续期需手动处理(需挂载 Certbot 容器或宿主机路径)。
    • 性能略低于宿主机直接安装。

3. 配置 Nginx HTTPS 反向代理

创建配置文件 /etc/nginx/sites-available/monitor.conf

nano /etc/nginx/sites-available/monitor.conf

server {listen 80;server_name monitor.host4;return 301 https://$host$request_uri;
}server {listen 443 ssl;server_name monitor.host4;ssl_certificate /opt/monitor/ssl/cert.pem;ssl_certificate_key /opt/monitor/ssl/key.pem;# 强制 TLS 1.2+ 并优化加密套件ssl_protocols TLSv1.2 TLSv1.3;ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;ssl_prefer_server_ciphers on;# /grafana 不带斜杠时补全location = /grafana {return 301 /grafana/;}# 根路径直接跳到 /grafana/location = / {return 302 /grafana/;}# Grafana 子路径代理——保持后端同样的 /grafana/ 前缀location /grafana/ {# 直接把 /grafana/… → 后端的 /grafana/…proxy_pass http://192.168.0.224:3000/grafana/;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 支持proxy_http_version 1.1;proxy_set_header Upgrade           $http_upgrade;proxy_set_header Connection        "upgrade";# 自签证书时可关验证proxy_ssl_verify off;# 不做任何 Location 改写proxy_redirect off;}# Prometheus 代理配置location /prometheus/ {proxy_pass http://192.168.0.224:9090/prometheus/;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;proxy_http_version 1.1;proxy_set_header Upgrade           $http_upgrade;proxy_set_header Connection        "upgrade";# 自签证书时可关验证proxy_ssl_verify off;proxy_redirect off;}
}

3. 启用配置并重启 Nginx

sudo ln -s /etc/nginx/sites-available/monitor.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl restart nginx
4.浏览器导入证书
  1. 导入证书
    • 下载 cert.pem 到本地。
    • Edge 浏览器:设置 → 隐私 →安全性 → 管理证书 → 导入(右下角选择所有文件) → 选择 cert.pem
    • 选择受信任的根证书颁发机构
  2. 访问测试
    • 输入 https://monitor.host4,忽略安全警告(或信任证书)。

在这里插入图片描述


4.2.有域名并配置公网解析

1. 使用 Let’s Encrypt 证书(必须提供合法域名)

# 1. 安装 Certbot
sudo apt update 
sudo apt install -y snapd
sudo snap install core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot# 2. 申请证书(需替换为你的域名)
sudo certbot --nginx \-d monitor.host4 \--agree-tos \--redirect \--no-eff-email \-m your-email@example.com
#验证与续期
sudo certbot renew --dry-run
#如果没有报错,系统会自动在到期前续期,并在续期后自动重载 NGINX(Certbot 会安装好相应的 systemd / cron 钩子)。

--nginx:Certbot 会自动检测你的 NGINX 配置并插入新的 ssl_certificate/ssl_certificate_key 指令。

-d monitor.host4:确保 DNS 已经把 monitor.host4 指向你的服务器公网 IP。

--redirect:自动把 HTTP 跳到 HTTPS。

-m:你注册的邮箱,会在续期失败时给你警告。

2. 强化 NGINX 安全头

在你的 server { … } 块(listen 443)内,添加:

  # HSTS:强制浏览器只用 HTTPS,180 天add_header Strict-Transport-Security "max-age=15552000; includeSubDomains; preload" always;# 防点击劫持add_header X-Frame-Options "SAMEORIGIN" always;# 防止 MIME 类型嗅探add_header X-Content-Type-Options "nosniff" always;# 防止跨站脚本add_header X-XSS-Protection "1; mode=block" always;# 引用来源策略add_header Referrer-Policy "no-referrer-when-downgrade" always;

保存后:

sudo nginx -t && sudo systemctl reload nginx

3. 访问控制与认证

3.1 对 Grafana 启用 Basic Auth(可选二次认证)

location /grafana/ { … } 前面添加一段:

    auth_basic "Monitoring";auth_basic_user_file /etc/nginx/.grafana_htpasswd;

生成密码文件(Ubuntu 自带 apache2-utils):

sudo apt install -y apache2-utils
sudo htpasswd -c /etc/nginx/.grafana_htpasswd admin
# 系统提示输入密码

然后 reload NGINX。

3.2 Prometheus 层面 IP 白名单

location /prometheus/ { … } 中加入:

    allow 10.0.0.0/8;      # 允许内网allow 192.168.0.0/16;  # 允许局域网deny all;              # 其它一律拒绝

4. 日志集中与监控

4.1 NGINX 日志格式

http { … } 中定义:

log_format monitor '$remote_addr - $remote_user [$time_local] ''"$request" $status $body_bytes_sent ''"$http_referer" "$http_user_agent" ''rt=$request_time ua="$upstream_addr" us="$upstream_status" ut="$upstream_response_time"';
access_log /var/log/nginx/monitor-access.log monitor;

reload NGINX。

4.2 收集到集中系统
  • 如果用 ELK/EFK/Loki,请在日志集中系统里配置对应的 Filebeat/Promtail 采集 /var/log/nginx/monitor-access.log,并做字段解析。
  • 设置关键 URL(/grafana/login/prometheus/query)的 5xx/401/429 报警。

5. 服务自身监控与告警

5.1 安装 NGINX Exporter

在 Prometheus 下加入 NGINX Exporter(Docker 示例):

services:nginx-exporter:image: nginx/nginx-prometheus-exporter:0.13.0ports:- "9113:9113"env:- NGINX_STATUS_URL=http://host.docker.internal/nginx_status

并在主 NGINX 加入 stub_status

location /nginx_status {stub_status on;allow 127.0.0.1;deny all;
}
5.2 在 Prometheus 抓取
- job_name: 'nginx'static_configs:- targets: ['nginx-exporter:9113']
5.3 告警示例

alert_rules.yml 中加入:

groups:- name: nginx_alertsrules:- alert: NginxHigh5xxRateexpr: rate(nginx_http_requests_total{status=~"5.."}[5m]) > 0.1for: 5mlabels:severity: criticalannotations:summary: "High HTTP 5xx rate on NGINX"

6. 备份与恢复

6.1 Grafana Dashboards
docker exec grafana grafana-cli dashboards export-all --output /var/lib/grafana/dashboards-backup.json

定时把 /var/lib/grafana/dashboards-backup.json 同步到备份存储。

6.2 Prometheus TSDB 快照
curl -XPOST http://localhost:9090/api/v1/admin/tsdb/snapshot
# 会在 data/snapshots 目录生成快照,定时拷贝到远程存储

7. 自动化与 CI/CD

  • 把 NGINX 配置、Docker Compose 文件 放到 Git 仓库;
  • 使用 GitLab CI / GitHub Actions 在合并后自动执行 lint 检查 (nginx -tdocker-compose config)、推送到测试环境、通过 Smoke Test 再部署到生产。
  • 版本控制:打标签、打版本包;部署时记录变更日志。

最终验证清单

  1. 浏览器打开 https://monitor.host4/ → 自动跳 /grafana//prometheus/,页面无 Mixed‑Content 警告。
  2. 查看浏览器开发者工具:所有资源都走 HTTPS。
  3. curl -I https://monitor.host4/grafana/
    • 302 → /grafana/login
    • 包含 Strict-Transport-Security 头。
  4. Prometheus 路径、Grafana 路径都做了访问认证与 IP/Basic Auth 控制。
  5. 日志被正确收集到集中系统,且已有告警规则生效。
  6. 证书续期脚本通过 certbot renew --dry-run
  7. 定时备份脚本落地、可恢复。

相关文章:

  • HTTP代理的实际用处有哪些?HTTP代理强在哪里?
  • 54、C# 委托 (Delegate)
  • 专栏更新通知
  • 如何手搓一个查询天气的mcp server
  • 【全因子组及排序】2022-1-23
  • 【计算机网络】IPv6和NAT网络地址转换
  • DeepSeek R1模型已完成小版本试升级
  • jQuery和CSS3卡片列表布局特效
  • 桃黑黑反斗战
  • Spring AI 整合聊天模型之智谱AI
  • 华为OD最新机试真题-按单词下标区间翻转文章内容-OD统一考试(B卷)
  • B3694 数列离散化
  • 【人工智能】微调革命:释放大模型的无限潜能
  • 基于seal密码库的格加密算法的原理、实现与应用
  • Shell - ​​Here Document(HereDoc)
  • AI Agent工具全景解析:从Coze到RAGflow,探索智能体自动化未来!
  • 制作一款打飞机游戏61:轨迹调度
  • git提交更改
  • 使用Milvus运行一个Milvus单机版实例
  • TypeScript知识点梳理
  • 湖南网站建设开发公司/关键词seo排名公司
  • xmlrpc wordpress关闭/pc网站优化排名
  • 网站策划运营方案/百度指数查询工具app
  • 右键网站 选择添加ftp站点/域名查询万网
  • linux网站架设怎么做/怎么制作网站平台
  • 网站设计怎么写/b站推广网站入口