3. 配置 Prometheus Targets:静态配置与多模式服务发现
在 APM 监控体系中,正确、高效地配置采集目标(Targets)是保证数据完整性与系统稳定性的基石。Prometheus 支持通过多种机制发现需要监控的端点,从最简单的静态列表到基于基础设施元数据的动态服务发现。本章将依次讲解静态配置、基于文件的服务发现、基于 Consul 的服务发现、基于 Kubernetes 的服务发现,以及如何检查与维护 Targets 的健康状态。
3.1 静态配置
静态配置是最直接的方式,适合基础设施稳定、变更不频繁的场景。在 prometheus.yml 的 scrape_configs 下直接写入 targets 列表。
scrape_configs:
- job_name: 'node-exporter'
static_configs:
- targets: ['192.168.1.10:9100', '192.168.1.11:9100']
labels:
group: 'production'
- targets: ['192.168.1.20:9100']
labels:
group: 'staging'
- 原理:Prometheus 在启动时解析静态配置,将给定的 endpoint 列表直接注册为 Targets。
- 实现流程:编辑 YAML → 重启 Prometheus 或发送
SIGHUP信号重载配置。 - 调试:访问
/targets页面(状态页)可查看静态 Targets 是否已加载。
3.2 基于文件的服务发现
基于文件的服务发现(file_sd_configs)允许将 Targets 存储在独立的 JSON 或 YAML 文件中。Prometheus 会定期自动读取这些文件,无需重启进程。
scrape_configs:
- job_name: 'web-app'
file_sd_configs:
- files:
- 'targets/web/*.json'
refresh_interval: 30s
目标文件内容(targets/web/app.json)
[
{
"targets": ["10.0.0.1:8080", "10.0.0.2:8080"],
"labels": {
"app": "frontend",
"env": "prod"
}
}
]
- 适用场景:目标变动较频繁但尚未引入服务注册中心的中型集群,或需要与外部脚本集成的场景。
- 调试与验证:修改文件后等待
refresh_interval周期,或直接触发 Prometheus 重载。检查/targets页面中对应 job 的发现状态。 - 常见错误:文件格式错误(如 JSON 缺少逗号)、路径不存在或权限不足。Prometheus 日志会打印
file_sd: error reading targets file相关警告。
rename 到目标路径。3.3 基于 Consul 的服务发现
Consul 是一个流行的服务发现与配置管理工具。Prometheus 通过 consul_sd_configs 直接从 Consul 的分布式键值存储中获取服务端点。
scrape_configs:
- job_name: 'consul-services'
consul_sd_configs:
- server: 'http://consul.example.com:8500'
services: ['api', 'gateway', 'worker']
relabel_configs:
- source_labels: [__meta_consul_node]
target_label: instance
- Consul 中的每个服务实例必须注册了健康检查,且状态为
passing。 - Prometheus 会定期查询 Consul Catalog API(默认间隔
30s)。 - 通过
relabel_configs将 Consul 元数据(如节点、标签、数据中心)映射到 Prometheus 标签。 - 调试:使用
curl http://<prometheus>:9090/api/v1/targets查看 discovered_labels。 - 性能:当业务规模较大(500+ 服务)时,可适当增加
refresh_interval或使用datacenter过滤以减少 API 调用。
3.4 基于 Kubernetes 的服务发现
在容器化/云原生环境中,Kubernetes 服务发现是最常用的模式。Prometheus 支持从 K8s API Server 获取 Pod、Service、Node、Endpoint 等资源信息。
scrape_configs:
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app]
action: keep
regex: my-app
- source_labels: [__address__]
action: replace
regex: (.+):(.+)
replacement: $1:9100
target_label: __address__
| role 类型 | 发现对象 | 常用场景 |
|---|---|---|
pod | Pod IP + 容器端口 | 直接抓取 Pod 暴露的指标接口 |
service | Service ClusterIP + 端口 | 通过 Service 负载均衡抓取 |
node | 节点的 IP | 抓取 Node Exporter 等节点级指标 |
endpoint | Endpoints 对象 | 与 Service 结合使用 |
- 部署前提:Prometheus 需具备对 K8s API Server 的访问权限。通常通过 RBAC 创建 ServiceAccount 并挂载 。
- 调试:Pod 内的 Prometheus 可使用
kubectl logs查看 API 调用日志;外部 Prometheus 需确保网络可达。 - 性能优化:对于大规模集群(1000+ Pods),启用
kubernetes_sd_configs的selectors过滤 namespace 或标签,减少 API 返回的数据量。
3.5 检查 Target 健康状态
无论使用哪种发现方式,最终都需要验证 Targets 是否被成功识别且健康。Prometheus 提供内置状态页和 API 用于诊断。
3.5.1 通过 UI 检查
访问 http://<prometheus>:9090/targets,页面列出所有 Job 下每个 Target 的 State(UP / DOWN / UNKNOWN)、最后抓取时间、抓取耗时及标签。点击“Show Unhealthy”可快速定位问题目标。
3.5.2 通过 API 检查
curl http://localhost:9090/api/v1/targets | jq '.data.activeTargets[] | {job: .labels.job, instance: .labels.instance, health: .health}'
返回的 JSON 中包含 health 字段("up" 或 "down")以及 lastError(最后一次抓取错误信息)。
3.5.3 指标告警集成
Prometheus 自身会暴露 up{job=~".+"} 指标,值 1 表示健康、0 表示抓取失败。可基于此指标创建告警规则:
groups:
- name: target-health
rules:
- alert: TargetDown
expr: up == 0
for: 1m
annotations:
summary: "Target {{ $labels.job }}/{{ $labels.instance }} is down"
3.6 归纳对比
| 发现方式 | 配置复杂度 | 动态性 | 适合规模 | 依赖 |
|---|---|---|---|---|
| 静态配置 | 低 | 无(需重启或重载) | 小(<200) | 无 |
| 文件发现 | 低 | 自动重读文件 | 中(200~1000) | 文件系统 |
| Consul 发现 | 中 | 自动轮询 API | 中-大(500~5000) | Consul 集群 |
| K8s 发现 | 高 | 自动监听 API | 大(1000+) | K8s Cluster |
1. 静态配置中 target 的 IP:PORT 遗漏冒号或写错端口。
2. 文件发现中 JSON/YAML 必须符合严格的格式,不要使用制表符。
3. Consul 发现需要确保 Prometheus 与 Consul 网络可达,且 Consul 中已注册健康通过的服务。
4. K8s 发现时 Pod 无法抓取自身(循环抓取),需使用
__meta_kubernetes_pod_annotation_prometheus_io_scrape 注解控制。