4. 使用文件服务发现

任务目标

在Prometheus中,当需要监控的目标列表频繁变化(如容器IP变动、自动扩缩容节点)时,手动修改static_configs并重启服务不可接受。本案例通过JSON文件定义目标列表,配置file_sd_configs让Prometheus自动感知文件变更并动态更新抓取目标,全程无需重启。

环境与依赖

  • 已安装Prometheus(本案例以v2.x为例,Linux/macOS均可)
  • 准备两个用于验证的HTTP服务端点(可用node_exporter或任意暴露/metrics的测试服务)

实现步骤

1. 创建目标JSON文件

创建目录/etc/prometheus/targets/,在其中新建文件web-servers.json,内容如下:

[
  {
    "targets": ["192.168.1.101:9100", "192.168.1.102:9100"],
    "labels": {
      "env": "prod",
      "job": "web-node"
    }
  }
]

文件格式说明:顶层为数组,每个元素是一个目标组。每个组必须包含targets字段(字符串数组,格式为host:port),可选labels字段为组内所有目标附加公共标签。Prometheus支持JSON和YAML两种格式,文件扩展名需为.json或.yml/.yaml。

2. 配置Prometheus使用文件服务发现

在prometheus.yml中,将原有的static_configs替换为file_sd_configs:

scrape_configs:
  - job_name: 'web-servers'
    file_sd_configs:
      - files:
          - /etc/prometheus/targets/*.json
        refresh_interval: 30s

关键参数说明:

  • files:支持通配符路径,Prometheus会监控匹配文件的内容变化。
  • refresh_interval:指定Prometheus重新读取文件的时间间隔,默认5分钟,此处设为30秒便于快速验证。

运行与验证

启动Prometheus

./prometheus --config.file=prometheus.yml

验证动态更新

  1. 初始状态检查:启动后访问http://localhost:9090/targets,应能看到web-servers任务下有两个目标,状态为UP(假设两个端点均正常暴露/metrics)。
  2. 修改JSON文件:编辑web-servers.json,将targets数组改为只保留192.168.1.101:9100,保存文件。
  3. 等待刷新周期:最多等待30秒(即refresh_interval配置值)。
  4. 确认更新生效:刷新/targets页面,此时应只显示一个目标;同时Prometheus日志中会输出类似Discoverer file_sd returned 1 targets的信息,表明文件变更已被自动加载。

通过判定标准:无需重启Prometheus进程,仅修改JSON文件并在一个刷新周期后,/targets页面中的目标列表与实际文件内容一致,即验证通过。

常见问题

  • JSON格式错误:Prometheus无法解析文件时,会在日志中输出Error reading file,且保留上一次成功加载的目标列表。可用python -m json.tool web-servers.json校验格式。
  • 文件路径权限:确保Prometheus进程对目标目录有读权限,否则日志会报open /etc/prometheus/targets/*.json: permission denied。
  • 标签覆盖:若JSON中定义了job标签,会覆盖scrape_config中设置的job_name,抓取任务名称以标签值为准。
file_sd_configs 动态发现流程 JSON目标文件 web-servers.json targets: [IP:9100,...] labels: env=prod 读取 Prometheus file_sd_configs refresh_interval: 30s 自动重新加载文件 抓取 监控目标 192.168.1.101:9100 192.168.1.102:9100 /metrics 端点 文件变更 → 自动发现新目标列表 验证要点: 1. 修改JSON文件后,等待一个 refresh_interval 周期 2. 访问 /targets 页面,确认目标列表已自动更新,无需重启Prometheus