## 19.1 Prometheus + Grafana Prometheus 和 Grafana 是目前最流行的开源监控组合,前者负责数据采集与存储,后者负责数据可视化。 [Prometheus](https://prometheus.io/) 是一个开源的系统监控和报警工具包。它受 Google Borgmon 的启发,由 SoundCloud 在 2012 年创建。 ### 19.1.1 架构简介 Prometheus 的主要组件包括: * **Prometheus Server**:核心组件,负责收集和存储时间序列数据。 * **Exporters**:负责向 Prometheus 暴露监控数据 (如 Node Exporter,cAdvisor)。 * **Alertmanager**:处理报警发送。 * **Pushgateway**:用于支持短生命周期的 Job 推送数据。 ### 19.1.2 快速部署 我们可以使用 Docker Compose 快速部署一套 Prometheus + Grafana 监控环境。 本节示例使用了: * `node-exporter`:采集宿主机指标 (CPU、内存、磁盘、网络等)。 * `cAdvisor`:采集容器指标 (容器 CPU/内存/网络 IO、文件系统等)。 在生产环境中,建议将 Prometheus 的数据目录做持久化,并显式配置数据保留周期。 #### 1. 准备配置文件 创建 `prometheus.yml`: ```yaml global: scrape_interval: 15s scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090'] - job_name: 'node-exporter' static_configs: - targets: ['node-exporter:9100'] - job_name: 'cadvisor' static_configs: - targets: ['cadvisor:8080'] rule_files: - /etc/prometheus/rules.yml ``` #### 2. 编写 Docker Compose 文件 创建 `compose.yaml` (或 `docker-compose.yml`): ```yaml services: prometheus: image: prom/prometheus:latest volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml - ./rules.yml:/etc/prometheus/rules.yml - prometheus_data:/prometheus ports: - "9090:9090" command: - --config.file=/etc/prometheus/prometheus.yml - --storage.tsdb.path=/prometheus - --storage.tsdb.retention.time=15d networks: - monitoring grafana: image: grafana/grafana:latest ports: - "3000:3000" environment: - GF_SECURITY_ADMIN_PASSWORD=admin networks: - monitoring depends_on: - prometheus node-exporter: image: prom/node-exporter:latest ports: - "9100:9100" networks: - monitoring cadvisor: image: gcr.io/cadvisor/cadvisor:latest ports: - "8080:8080" volumes: - /:/rootfs:ro - /var/run:/var/run:ro - /sys:/sys:ro - /var/lib/docker/:/var/lib/docker:ro networks: - monitoring networks: monitoring: volumes: prometheus_data: ``` #### 3. 启动服务 ```bash $ docker compose up -d ``` 启动后,访问以下地址: * Prometheus: `http://localhost:9090` * Grafana:`http://localhost:3000` (默认账号密码:admin/admin) ### 19.1.3 配置 Grafana 面板 1. 在 Grafana 中添加 Prometheus 数据源,URL 填写 `http://prometheus:9090`。 2. 导入现成的 Dashboard 模板,例如 [Node Exporter Full](https://grafana.com/grafana/dashboards/1860) (ID:1860) 和 [Docker Container](https://grafana.com/grafana/dashboards/193) (ID:193)。 这样,你就拥有了一个直观的容器监控大屏。 ### 19.1.4 生产要点与告警闭环 完成部署后,建议补齐以下生产要点。 #### 指标采集的“最小闭环” 1. 在 Prometheus 页面打开 **Status -> Targets**,确认 `prometheus`、`node-exporter`、`cadvisor` 的 `State` 均为 `UP`。 2. 在 **Graph** 中尝试查询: * `up` * `rate(container_cpu_usage_seconds_total[5m])` 3. 在 Grafana Dashboard 中重点关注: * 宿主机 CPU/Load/内存/磁盘 * 容器 CPU/内存使用率、容器重启次数 如果你发现“面板为空”,通常不是 Grafana 的问题,而是 Prometheus 没抓到数据或查询标签与 Dashboard 不匹配。 #### 常见问题排查 * **Target down**:检查容器网络是否互通,端口是否暴露到同一网络,以及 exporter 是否在容器内正常监听。 * **cAdvisor 无数据或报错**:确认挂载了 Docker 目录与宿主机的 `/sys`、`/var/run` 等路径,并确保宿主机上 Docker 运行正常。 * **指标缺失**:确认你的 Docker/内核版本与 cAdvisor 兼容;对于 containerd 等运行时,采集方式会不同。 #### 关键指标速查 (节点/容器) 在生产环境排障时,建议优先关注下面几类指标,并在 Grafana 面板中建立对应的常用视图。 * **节点 CPU 使用率**:`100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)` * **节点内存使用率**:`(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100` * **节点磁盘空间使用率**:`(1 - (node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"})) * 100` * **容器 CPU**:`sum by (name) (rate(container_cpu_usage_seconds_total[5m]))` * **容器内存**:`sum by (name) (container_memory_working_set_bytes)` 说明:不同版本的 cAdvisor/Docker 对 label 命名可能存在差异 (如 `name`、`container`、`container_name`),如果查询为空,建议先用 `label_values(container_cpu_usage_seconds_total, __name__)` 或在 Prometheus 的图形界面查看可用 label。 #### Targets down 排错清单 当 **Status -> Targets** 出现 `DOWN` 时,建议按以下顺序排查: 1. **网络连通性**:Prometheus 容器是否能解析并访问目标 (同一 Docker network、DNS、端口)。 2. **端口/路径**:确认 exporter 监听端口与 Prometheus 配置一致;必要时在 Prometheus 容器内 `curl http://node-exporter:9100/metrics`。 3. **权限/挂载**:cAdvisor 需要访问宿主机 `/sys`、`/var/lib/docker` 等挂载路径,缺失会导致指标不全或报错。 4. **时间问题**:宿主机与容器时间偏差过大可能导致“数据看起来断档”,需要检查 NTP/时区配置。 5. **目标本身异常**:确认 exporter 容器是否在重启,查看 `docker logs`。 #### 告警 (Alertmanager) 建议 生产环境建议引入 Alertmanager 做告警聚合与路由,并在 Prometheus 中配置 `alerting` 与 `rule_files`。 为了保持“最小告警闭环”,建议至少覆盖两类告警: * **采集链路告警**:例如 `up == 0`,用于发现 exporter 或网络故障。 * **资源风险告警**:例如节点磁盘空间不足,用于提前发现容量风险。 ##### 1. 准备告警规则文件 创建 `rules.yml`: ```yaml groups: - name: docker_practice rules: - alert: PrometheusTargetDown expr: up == 0 for: 2m labels: severity: warning annotations: summary: "Prometheus 抓取目标不可达" description: "Job={{ $labels.job }}, Instance={{ $labels.instance }}" - alert: HostDiskSpaceLow expr: | (node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"}) < 0.10 for: 10m labels: severity: critical annotations: summary: "磁盘可用空间不足" description: "Instance={{ $labels.instance }}, Mountpoint={{ $labels.mountpoint }}" ``` 说明:这里的规则是“可用空间低于 10%”的阈值告警,并非“未来 24 小时写满”的预测。生产环境建议针对特定文件系统与挂载点做更精确的过滤。 ##### 2. 配置 Prometheus 加载规则并接入 Alertmanager 修改 `prometheus.yml`,增加: ```yaml rule_files: - /etc/prometheus/rules.yml alerting: alertmanagers: - static_configs: - targets: ["alertmanager:9093"] ``` 并在 Compose 中挂载规则文件。 ##### 3. 部署 Alertmanager 创建 `alertmanager.yml`: ```yaml route: receiver: default receivers: - name: default webhook_configs: - url: http://example.com/webhook ``` 再在 `compose.yaml` 增加服务: ```yaml alertmanager: image: prom/alertmanager:latest volumes: - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml ports: - "9093:9093" networks: - monitoring ``` 生产环境中,建议将告警发送到可追踪的渠道 (如 IM 机器人、事件平台、工单系统),并在告警中附带 Dashboard 链接与排障入口,避免告警成为噪声。 #### 建议的文件清单 为了避免示例难以复现,建议在同一目录下准备以下文件: * `compose.yaml`:Prometheus、Grafana、exporters、Alertmanager 的部署文件 * `prometheus.yml`:Prometheus 抓取配置与告警配置 * `rules.yml`:告警规则 * `alertmanager.yml`:告警路由与接收器配置