Prometheus Prometheus

用 node_exporter 和 cAdvisor 监控主机及其容器

一起运行 Prometheus、node_exporter 和 cAdvisor,抓取两者,并确认目标健康。

14 min 初级

主机级指标(CPU、内存、磁盘、网络)和每个容器的指标来自两个不同的 exporter。本指南用 Docker Compose 将 Prometheus 与两者一起运行,配置 Prometheus 抓取它们,并在下一篇指南把数据交给仪表板之前确认它在工作。

三个部分

  • Prometheus 本身:按计划抓取目标并存储结果。
  • node_exporter:暴露主机操作系统自身的指标,CPU、内存、磁盘、网络,位于 9100 端口的 /metrics。
  • cAdvisor(Container Advisor,由 Google 维护):暴露每个容器的资源使用情况,CPU、内存、I/O,位于 8080 端口的 /metrics。

两个 exporter 都需要看到普通容器看不到的东西:node_exporter 需要主机的根文件系统和进程命名空间,才能准确地报告主机而不仅仅是它自己的容器,而 cAdvisor 需要访问容器运行时自身的数据,才能报告主机上运行的每个容器,而不只是它自己。

用于三者的 Docker Compose

version: "3"

volumes:
  prometheus-data:

services:
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus-data:/prometheus
    command:
      - "--config.file=/etc/prometheus/prometheus.yml"
      - "--storage.tsdb.retention.time=15d"

  node-exporter:
    image: prom/node-exporter:latest
    container_name: node-exporter
    pid: host
    volumes:
      - /:/host:ro,rslave
    command:
      - "--path.rootfs=/host"

  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    container_name: cadvisor
    ports:
      - "8080:8080"
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro

node-exporter 的 pid: host 和只读的根目录挂载,让它能够报告主机而不是它自己的隔离容器视图;--path.rootfs=/host 告诉它被挂载的根目录在容器内实际落在哪里。cadvisor 出于同样的原因需要它自己一组对主机运行时状态的只读挂载:没有它们,它只能看到自己,而看不到主机上的其他容器。这里没有任何东西需要对主机的写权限,每个挂载都是只读的,当安全评审问这些容器实际能做什么时,值得记住这一点。

配置 Prometheus 抓取两者

# prometheus.yml
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"]

global.scrape_interval 并不是 Prometheus 内置的默认值(那是一分钟);像大多数入门示例那样把它显式设为 15 秒,是值得遵循的惯例,因为这个频率足以提供灵敏的仪表板,又不会产生过多的抓取量。每个 job_name 是你选择的任意标签,附加到该 job 抓取的每个序列上,这正是你之后在查询中区分”这个指标来自 node-exporter”与”这个指标来自 cadvisor”的方式。目标通过它们的 Compose 服务名(node-exporter、cadvisor)来寻址,因为同一 Compose 网络上的容器会自动通过服务名相互解析;这里不需要容器 IP 地址或 localhost。

启动并确认目标健康

docker compose up -d

在浏览器中打开 http://localhost:9090/targets。每个已配置的 job 都应显示为 UP。如果有一个不是,请先检查该容器自己的日志,并确认你能直接访问它的 /metrics 端点(从主机执行 curl http://localhost:9100/metrics,或 docker exec 进入 Prometheus 容器并 curl 目标的 Compose 服务名),再去假设问题出在 Prometheus 的配置而不是目标本身。

在 Prometheus 自己的 Graph 页面上,试一个快速的健全性检查:

up{job="node-exporter"}

up 是 Prometheus 为每个目标自己生成的合成指标,上次抓取成功时为 1,失败时为 0,这使它成为直接通过 PromQL 而不是 Targets 页面检查目标健康的快捷方式。

继续之前的一点说明

无论是 Prometheus 的 UI 还是 cAdvisor 的 UI,默认都不带认证或 TLS。对于本意是在可信网络内被抓取和查询的东西,这是合理的默认设置,但这意味着这些端口不应在没有添加访问控制的情况下直接暴露到公共互联网,无论是在它们前面放置带认证的反向代理,还是一开始就只让它们可从内部网络访问。

两个 exporter 都向 Prometheus 上报之后,下一篇指南介绍如何用 Grafana 把它变成真正的仪表板。

热门指南